From 93ec299b0ea9f57d941d7b5161ef8a283817bc9b Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Tue, 27 Feb 2018 14:21:18 -0600 Subject: [PATCH] Add independent config directory and let users set default dirs. Use standard endline. Regularize capitalization of CMake directives. Revise CMake installation with an eye toward more modern versions of CMake. Set explicit installation directory permissions so it works regardless of user's umask. --- CMakeLists.txt | 25 +++++--- .../InstallDirectoryPermissions.cmake | 14 +++++ application.cpp | 61 ++++++++++++------- include/appbase/application.hpp | 25 +++++++- 4 files changed, 91 insertions(+), 34 deletions(-) create mode 100644 CMakeModules/InstallDirectoryPermissions.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 4b8607bc7..5f7ab147e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,11 +2,15 @@ project( AppBase ) cmake_minimum_required( VERSION 2.8.12 ) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules") + +include( InstallDirectoryPermissions ) + file(GLOB HEADERS "include/appbase/*.hpp") set(CMAKE_EXPORT_COMPILE_COMMANDS "ON") -SET(BOOST_COMPONENTS) -LIST(APPEND BOOST_COMPONENTS thread +set(BOOST_COMPONENTS) +list(APPEND BOOST_COMPONENTS thread date_time filesystem system @@ -15,7 +19,7 @@ LIST(APPEND BOOST_COMPONENTS thread unit_test_framework locale) -FIND_PACKAGE(Boost 1.60 REQUIRED COMPONENTS ${BOOST_COMPONENTS}) +find_package(Boost 1.60 REQUIRED COMPONENTS ${BOOST_COMPONENTS}) set( Boost_USE_STATIC_LIBS ON CACHE STRING "ON or OFF" ) if( APPLE ) @@ -48,13 +52,18 @@ target_link_libraries( appbase ${Boost_LIBRARIES}) target_include_directories( appbase PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" ${Boost_INCLUDE_DIR}) -INSTALL( TARGETS +set_target_properties( appbase PROPERTIES PUBLIC_HEADER "${HEADERS}" ) + +set(CPACK_PACKAGING_INSTALL_PREFIX /) + +install( TARGETS appbase - RUNTIME DESTINATION bin - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib + RUNTIME DESTINATION usr/bin + LIBRARY DESTINATION usr/lib + ARCHIVE DESTINATION usr/lib + PUBLIC_HEADER DESTINATION usr/include/appbase ) -INSTALL( FILES ${HEADERS} DESTINATION "include/appbase" ) +install_directory_permissions( DIRECTORY usr/include/appbase ) add_subdirectory( examples ) diff --git a/CMakeModules/InstallDirectoryPermissions.cmake b/CMakeModules/InstallDirectoryPermissions.cmake new file mode 100644 index 000000000..b13a80692 --- /dev/null +++ b/CMakeModules/InstallDirectoryPermissions.cmake @@ -0,0 +1,14 @@ +# Fix directory permissions after installation of header files (primarily). +macro(install_directory_permissions) + cmake_parse_arguments(ARG "" "DIRECTORY" "" ${ARGN}) + set(dir ${ARG_DIRECTORY}) + install(DIRECTORY DESTINATION ${dir} + DIRECTORY_PERMISSIONS OWNER_READ + OWNER_WRITE + OWNER_EXECUTE + GROUP_READ + GROUP_EXECUTE + WORLD_READ + WORLD_EXECUTE + ) +endmacro(install_directory_permissions) diff --git a/application.cpp b/application.cpp index 3fe9a99fc..d508f3341 100644 --- a/application.cpp +++ b/application.cpp @@ -22,7 +22,8 @@ class application_impl { options_description _app_options; options_description _cfg_options; - bfs::path _data_dir; + bfs::path _data_dir{"data-dir"}; + bfs::path _config_dir{"config-dir"}; bfs::path _logging_conf{"logging.json"}; uint64_t _version; @@ -43,6 +44,14 @@ uint64_t application::version() const { return my->_version; } +void application::set_default_data_dir(const bfs::path& data_dir) { + my->_data_dir = data_dir; +} + +void application::set_default_config_dir(const bfs::path& config_dir) { + my->_config_dir = config_dir; +} + bfs::path application::get_logging_conf() const { return my->_logging_conf; } @@ -81,8 +90,9 @@ void application::set_program_options() app_cli_opts.add_options() ("help,h", "Print this help message and exit.") ("version,v", "Print version information.") - ("data-dir,d", bpo::value()->default_value( "data-dir" ), "Directory containing configuration file config.ini") - ("config,c", bpo::value()->default_value( "config.ini" ), "Configuration file name relative to data-dir") + ("data-dir,d", bpo::value(), "Directory containing program runtime data") + ("config-dir", bpo::value(), "Directory containing configuration files such as config.ini") + ("config,c", bpo::value()->default_value( "config.ini" ), "Configuration file name relative to config-dir") ("logconf,l", bpo::value()->default_value( "logging.json" ), "Logging configuration file name/path for library users"); my->_cfg_options.add(app_cfg_opts); @@ -106,33 +116,34 @@ bool application::initialize_impl(int argc, char** argv, vector(); + if( options.count( "data-dir" ) ) { + bfs::path data_dir = options["data-dir"].as(); if( data_dir.is_relative() ) data_dir = bfs::current_path() / data_dir; + my->_data_dir = data_dir; } - my->_data_dir = data_dir; - bfs::path logconf = data_dir / "logging.json"; - if( options.count("logconf") ) - { - logconf = options["logconf"].as(); - if( logconf.is_relative() ) - logconf = data_dir / logconf; + if( options.count( "config-dir" ) ) { + bfs::path config_dir = options["config-dir"].as(); + if( config_dir.is_relative() ) + config_dir = bfs::current_path() / config_dir; + my->_config_dir = config_dir; } + + bfs::path logconf = options["logconf"].as(); + if( logconf.is_relative() ) + logconf = my->_config_dir / logconf; my->_logging_conf = logconf; - bfs::path config_file_name = data_dir / "config.ini"; + bfs::path config_file_name = my->_config_dir / "config.ini"; if( options.count( "config" ) ) { config_file_name = options["config"].as(); if( config_file_name.is_relative() ) - config_file_name = data_dir / config_file_name; + config_file_name = my->_config_dir / config_file_name; } if(!bfs::exists(config_file_name)) { - if(config_file_name.compare(data_dir / "config.ini") != 0) + if(config_file_name.compare(my->_config_dir / "config.ini") != 0) { cout << "Config file " << config_file_name << " missing." << std::endl; return false; @@ -208,23 +219,23 @@ void application::write_default_config(const bfs::path& cfg_file) { for(const boost::shared_ptr od : my->_cfg_options.options()) { if(!od->description().empty()) - out_cfg << "# " << od->description() << "\n"; + out_cfg << "# " << od->description() << std::endl; boost::any store; if(!od->semantic()->apply_default(store)) - out_cfg << "# " << od->long_name() << " = \n"; + out_cfg << "# " << od->long_name() << " = " << std::endl; else { auto example = od->format_parameter(); if(example.empty()) // This is a boolean switch - out_cfg << od->long_name() << " = " << "false\n"; + out_cfg << od->long_name() << " = " << "false" << std::endl; else { // The string is formatted "arg (=)" example.erase(0, 6); example.erase(example.length()-1); - out_cfg << od->long_name() << " = " << example << "\n"; + out_cfg << od->long_name() << " = " << example << std::endl; } } - out_cfg << "\n"; + out_cfg << std::endl; } out_cfg.close(); } @@ -245,8 +256,12 @@ abstract_plugin& application::get_plugin(const string& name)const { return *ptr; } -bfs::path application::data_dir()const { +bfs::path application::data_dir() const { return my->_data_dir; } +bfs::path application::config_dir() const { + return my->_config_dir; +} + } /// namespace appbase diff --git a/include/appbase/application.hpp b/include/appbase/application.hpp index fbe4b3d09..1e79c2501 100644 --- a/include/appbase/application.hpp +++ b/include/appbase/application.hpp @@ -23,6 +23,28 @@ namespace appbase { * @return Version output with -v/--version */ uint64_t version() const; + /** @brief Set default data directory + * + * @param data_dir Default data directory to use if not specified + * on the command line. + */ + void set_default_data_dir(const bfs::path& data_dir = "data-dir"); + /** @brief Get data directory + * + * @return Data directory, possibly from command line + */ + bfs::path data_dir() const; + /** @brief Set default config directory + * + * @param config_dir Default configuration directory to use if not + * specified on the command line. + */ + void set_default_config_dir(const bfs::path& config_dir = "etc"); + /** @brief Get config directory + * + * @return Config directory, possibly from command line + */ + bfs::path config_dir() const; /** @brief Get logging configuration path. * * @return Logging configuration location from command line @@ -78,9 +100,6 @@ namespace appbase { return *ptr; } - bfs::path data_dir()const; - - boost::asio::io_service& get_io_service() { return *io_serv; } protected: template