Skip to content

Commit

Permalink
Compile with appbase
Browse files Browse the repository at this point in the history
  • Loading branch information
mvandeberg committed Aug 3, 2017
1 parent 75d1841 commit 7859cd6
Show file tree
Hide file tree
Showing 29 changed files with 2,707 additions and 0 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ project( Steem )
cmake_minimum_required( VERSION 3.2 )

set( BLOCKCHAIN_NAME "Steem" )
set( CMAKE_CXX_STANDARD 14 )

set( GUI_CLIENT_EXECUTABLE_NAME Steem )
set( CUSTOM_URL_SCHEME "gcs" )
Expand Down
2 changes: 2 additions & 0 deletions libraries/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
add_subdirectory( fc )
add_subdirectory( schema )
add_subdirectory( appbase )
add_subdirectory( chainbase )
add_subdirectory( chain )
add_subdirectory( protocol )
add_subdirectory( net )
add_subdirectory( utilities )
add_subdirectory( app )
add_subdirectory( plugins )
add_subdirectory( new_plugins )
add_subdirectory( wallet )
add_subdirectory( manifest )
59 changes: 59 additions & 0 deletions libraries/appbase/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Defines AppBase library target.
project( AppBase )
cmake_minimum_required( VERSION 2.8.12 )

file(GLOB HEADERS "include/appbase/*.hpp")

set(CMAKE_EXPORT_COMPILE_COMMANDS "ON")
SET(BOOST_COMPONENTS)
LIST(APPEND BOOST_COMPONENTS thread
date_time
system
filesystem
chrono
program_options
unit_test_framework
locale)

FIND_PACKAGE(Boost 1.60 REQUIRED COMPONENTS ${BOOST_COMPONENTS})
set( Boost_USE_STATIC_LIBS ON CACHE STRING "ON or OFF" )

if( APPLE )
# Apple Specific Options Here
message( STATUS "Configuring ChainBase on OS X" )
set( CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=c++14 -stdlib=libc++ -Wall -Wno-conversion -Wno-deprecated-declarations" )
else( APPLE )
# Linux Specific Options Here
message( STATUS "Configuring ChainBase on Linux" )
set( CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -std=c++14 -Wall" )
set( rt_library rt )
set( pthread_library pthread)
if ( FULL_STATIC_BUILD )
set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++ -static-libgcc")
endif ( FULL_STATIC_BUILD )
endif( APPLE )


if(ENABLE_COVERAGE_TESTING)
SET(CMAKE_CXX_FLAGS "--coverage ${CMAKE_CXX_FLAGS}")
endif()

add_library( appbase
application.cpp
)

target_link_libraries( appbase ${Boost_LIBRARIES})

target_include_directories( appbase
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" ${Boost_INCLUDE_DIR})

INSTALL( TARGETS
appbase

RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
INSTALL( FILES ${HEADERS} DESTINATION "include/appbase" )

add_subdirectory( examples )
110 changes: 110 additions & 0 deletions libraries/appbase/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
AppBase
--------------

The AppBase library provides a basic framework for building applications from
a set of plugins. AppBase manages the plugin life-cycle and ensures that all
plugins are configured, initialized, started, and shutdown in the proper order.

## Key Features

- Dynamically Specify Plugins to Load
- Automaticly Load Dependent Plugins in Order
- Plugins can specify commandline arguments and configuration file options
- Program gracefully exits from SIGINT and SIGTERM
- Minimal Dependencies (Boost 1.60, c++14)

## Defining a Plugin

A simple example of a 2-plugin application can be found in the /examples directory. Each plugin has
a simple life cycle:

1. Initialize - parse configuration file options
2. Startup - start executing, using configuration file options
3. Shutdown - stop everything and free all resources

All plugins complete the Initialize step before any plugin enters the Startup step. Any dependent plugin specified
by `APPBASE_PLUGIN_REQUIRES` will be Initialized or Started prior to the plugin being Initialized or Started.

Shutdown is called in the reverse order of Startup.

```
class net_plugin : public appbase::plugin<net_plugin>
{
public:
net_plugin(){};
~net_plugin(){};
APPBASE_PLUGIN_REQUIRES( (chain_plugin) );
virtual void set_program_options( options_description& cli, options_description& cfg ) override
{
cfg.add_options()
("listen-endpoint", bpo::value<string>()->default_value( "127.0.0.1:9876" ), "The local IP address and port to listen for incoming connections.")
("remote-endpoint", bpo::value< vector<string> >()->composing(), "The IP address and port of a remote peer to sync with.")
("public-endpoint", bpo::value<string>()->default_value( "0.0.0.0:9876" ), "The public IP address and port that should be advertized to peers.")
;
}
void plugin_initialize( const variables_map& options ) { std::cout << "initialize net plugin\n"; }
void plugin_startup() { std::cout << "starting net plugin \n"; }
void plugin_shutdown() { std::cout << "shutdown net plugin \n"; }
};
int main( int argc, char** argv ) {
try {
appbase::app().register_plugin<net_plugin>(); // implict registration of chain_plugin dependency
if( !appbase::app().initialize( argc, argv ) )
return -1;
appbase::app().startup();
appbase::app().exec();
} catch ( const boost::exception& e ) {
std::cerr << boost::diagnostic_information(e) << "\n";
} catch ( const std::exception& e ) {
std::cerr << e.what() << "\n";
} catch ( ... ) {
std::cerr << "unknown exception\n";
}
std::cout << "exited cleanly\n";
return 0;
}
```

This example can be used like follows:

```
./examples/appbase_example --plugin net_plugin
initialize chain plugin
initialize net plugin
starting chain plugin
starting net plugin
^C
shutdown net plugin
shutdown chain plugin
exited cleanly
```

### Boost ASIO

AppBase maintains a singleton `application` instance which can be accessed via `appbase::app()`. This
application owns a `boost::asio::io_service` which starts running when appbase::exec() is called. If
a plugin needs to perform IO or other asynchronous operations then it should dispatch it via
`app().get_io_service().post( lambda )`.

Because the app calls `io_service::run()` from within `application::exec()` all asynchronous operations
posted to the io_service should be run in the same thread.

## Graceful Exit

To trigger a graceful exit call `appbase::app().quit()` or send SIGTERM or SIGINT to the process.

## Dependencies

1. c++14 or newer (clang or g++)
2. Boost 1.60 or newer compiled with C++14 support

To compile boost with c++14 use:

./b2 ... cxxflags="-std=c++0x -stdlib=libc++" linkflags="-stdlib=libc++" ...


Loading

0 comments on commit 7859cd6

Please sign in to comment.