diff --git a/Core/Code/CppMicroServices/CMake/usFunctionEmbedResources.cmake b/Core/Code/CppMicroServices/CMake/usFunctionEmbedResources.cmake index c34601206a..c559177c5e 100644 --- a/Core/Code/CppMicroServices/CMake/usFunctionEmbedResources.cmake +++ b/Core/Code/CppMicroServices/CMake/usFunctionEmbedResources.cmake @@ -1,145 +1,147 @@ #! Embed resources into a shared library or executable. #! #! This CMake function uses an external command line program to generate a source #! file containing data from external resources such as text files or images. The path #! to the generated source file is appended to the \c src_var variable. #! #! Each module can call this function (at most once) to embed resources and make them #! available at runtime through the Module class. Resources can also be embedded into #! executables, using the EXECUTABLE_NAME argument instead of LIBRARY_NAME. #! #! Example usage: #! \verbatim #! set(module_srcs ) #! usFunctionEmbedResources(module_srcs #! LIBRARY_NAME "mylib" #! ROOT_DIR resources #! FILES config.properties logo.png #! ) #! \endverbatim #! #! \param LIBRARY_NAME (required if EXECUTABLE_NAME is empty) The library name of the module #! which will include the generated source file, without extension. #! \param EXECUTABLE_NAME (required if LIBRARY_NAME is empty) The name of the executable #! which will include the generated source file. #! \param COMPRESSION_LEVEL (optional) The zip compression level. Defaults to the default zip #! level. Level 0 disables compression. #! \param COMPRESSION_THRESHOLD (optional) The compression threshold ranging from 0 to 100 for #! actually compressing the resource data. The default threshold is 30, meaning a size #! reduction of 30 percent or better results in the resource data being compressed. #! \param ROOT_DIR (optional) The root path for all resources listed after the FILES argument. #! If no or a relative path is given, it is considered relativ to the current CMake source directory. #! \param FILES (optional) A list of resources (paths to external files in the file system) relative #! to the ROOT_DIR argument or the current CMake source directory if ROOT_DIR is empty. #! #! The ROOT_DIR and FILES arguments may be repeated any number of times to merge files from #! different root directories into the embedded resource tree (hence the relative file paths #! after the FILES argument must be unique). #! function(usFunctionEmbedResources src_var) set(prefix US_RESOURCE) set(arg_names LIBRARY_NAME EXECUTABLE_NAME COMPRESSION_LEVEL COMPRESSION_THRESHOLD ROOT_DIR FILES) foreach(arg_name ${arg_names}) set(${prefix}_${arg_name}) endforeach(arg_name) set(cmd_line_args ) set(absolute_res_files ) set(current_arg_name DEFAULT_ARGS) set(current_arg_list) set(current_root_dir ${CMAKE_CURRENT_SOURCE_DIR}) foreach(arg ${ARGN}) list(FIND arg_names "${arg}" is_arg_name) if(is_arg_name GREATER -1) set(${prefix}_${current_arg_name} ${current_arg_list}) set(current_arg_name "${arg}") set(current_arg_list) else() set(current_arg_list ${current_arg_list} "${arg}") if(current_arg_name STREQUAL "ROOT_DIR") set(current_root_dir "${arg}") if(NOT IS_ABSOLUTE ${current_root_dir}) set(current_root_dir "${CMAKE_CURRENT_SOURCE_DIR}/${current_root_dir}") endif() if(NOT IS_DIRECTORY ${current_root_dir}) message(SEND_ERROR "The ROOT_DIR argument is not a directory: ${current_root_dir}") endif() get_filename_component(current_root_dir "${current_root_dir}" REALPATH) file(TO_NATIVE_PATH "${current_root_dir}" current_root_dir_native) list(APPEND cmd_line_args -d "${current_root_dir_native}") elseif(current_arg_name STREQUAL "FILES") set(res_file "${current_root_dir}/${arg}") file(TO_NATIVE_PATH "${res_file}" res_file_native) if(IS_DIRECTORY ${res_file}) message(SEND_ERROR "A resource cannot be a directory: ${res_file_native}") endif() if(NOT EXISTS ${res_file}) message(SEND_ERROR "Resource does not exists: ${res_file_native}") endif() list(APPEND absolute_res_files ${res_file}) file(TO_NATIVE_PATH "${arg}" res_filename_native) list(APPEND cmd_line_args "${res_filename_native}") endif() endif(is_arg_name GREATER -1) endforeach(arg ${ARGN}) set(${prefix}_${current_arg_name} ${current_arg_list}) if(NOT src_var) message(SEND_ERROR "Output variable name not specified.") endif() if(US_RESOURCE_EXECUTABLE_NAME AND US_RESOURCE_LIBRARY_NAME) message(SEND_ERROR "Only one of LIBRARY_NAME or EXECUTABLE_NAME can be specified.") endif() if(NOT US_RESOURCE_LIBRARY_NAME AND NOT US_RESOURCE_EXECUTABLE_NAME) message(SEND_ERROR "LIBRARY_NAME or EXECUTABLE_NAME argument not specified.") endif() if(NOT US_RESOURCE_FILES) message(WARNING "No FILES argument given. Skipping resource processing.") return() endif() list(GET cmd_line_args 0 first_arg) if(NOT first_arg STREQUAL "-d") set(cmd_line_args -d "${CMAKE_CURRENT_SOURCE_DIR}" ${cmd_line_args}) endif() if(US_RESOURCE_COMPRESSION_LEVEL) set(cmd_line_args -c ${US_RESOURCE_COMPRESSION_LEVEL} ${cmd_line_args}) endif() if(US_RESOURCE_COMPRESSION_THRESHOLD) set(cmd_line_args -t ${US_RESOURCE_COMPRESSION_THRESHOLD} ${cmd_line_args}) endif() if(US_RESOURCE_LIBRARY_NAME) set(us_cpp_resource_file "${CMAKE_CURRENT_BINARY_DIR}/${US_RESOURCE_LIBRARY_NAME}_resources.cpp") set(us_lib_name ${US_RESOURCE_LIBRARY_NAME}) else() set(us_cpp_resource_file "${CMAKE_CURRENT_BINARY_DIR}/${US_RESOURCE_EXECUTABLE_NAME}_resources.cpp") set(us_lib_name "\"\"") endif() set(resource_compiler ${CppMicroServices_RCC_EXECUTABLE}) if(TARGET ${CppMicroServices_RCC_EXECUTABLE_NAME}) set(resource_compiler ${CppMicroServices_RCC_EXECUTABLE_NAME}) + elseif(NOT resource_compiler) + message(FATAL_ERROR "The CppMicroServices resource compiler was not found. Check the CppMicroServices_RCC_EXECUTABLE CMake variable.") endif() add_custom_command( OUTPUT ${us_cpp_resource_file} COMMAND ${resource_compiler} "${us_lib_name}" ${us_cpp_resource_file} ${cmd_line_args} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${absolute_res_files} ${resource_compiler} COMMENT "Generating embedded resource file ${us_cpp_resource_name}" ) set(${src_var} "${${src_var}};${us_cpp_resource_file}" PARENT_SCOPE) endfunction() diff --git a/Core/Code/CppMicroServices/CMakeLists.txt b/Core/Code/CppMicroServices/CMakeLists.txt index 534a6a3b65..bed7726a9c 100644 --- a/Core/Code/CppMicroServices/CMakeLists.txt +++ b/Core/Code/CppMicroServices/CMakeLists.txt @@ -1,359 +1,357 @@ project(CppMicroServices) set(${PROJECT_NAME}_MAJOR_VERSION 0) set(${PROJECT_NAME}_MINOR_VERSION 99) set(${PROJECT_NAME}_PATCH_VERSION 0) set(${PROJECT_NAME}_VERSION ${${PROJECT_NAME}_MAJOR_VERSION}.${${PROJECT_NAME}_MINOR_VERSION}.${${PROJECT_NAME}_PATCH_VERSION}) cmake_minimum_required(VERSION 2.8) #----------------------------------------------------------------------------- # Update CMake module path #------------------------------------------------------------------------------ set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMake ${CMAKE_MODULE_PATH} ) #----------------------------------------------------------------------------- # CMake function(s) and macro(s) #----------------------------------------------------------------------------- include(MacroParseArguments) include(CheckCXXSourceCompiles) include(usFunctionCheckCompilerFlags) include(usFunctionEmbedResources) include(usFunctionGetGccVersion) include(usFunctionGenerateModuleInit) #----------------------------------------------------------------------------- # Init output directories #----------------------------------------------------------------------------- set(US_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") set(US_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib") set(US_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin") foreach(_type ARCHIVE LIBRARY RUNTIME) if(NOT CMAKE_${_type}_OUTPUT_DIRECTORY) set(CMAKE_${_type}_OUTPUT_DIRECTORY ${US_${_type}_OUTPUT_DIRECTORY}) endif() endforeach() #----------------------------------------------------------------------------- # Set a default build type if none was specified #----------------------------------------------------------------------------- if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message(STATUS "Setting build type to 'Debug' as none was specified.") set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE) # Set the possible values of build type for cmake-gui set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") endif() #----------------------------------------------------------------------------- # CMake options #----------------------------------------------------------------------------- function(us_cache_var _var_name _var_default _var_type _var_help) set(_advanced 0) set(_force) foreach(_argn ${ARGN}) if(_argn STREQUAL ADVANCED) set(_advanced 1) elseif(_argn STREQUAL FORCE) set(_force FORCE) endif() endforeach() if(US_IS_EMBEDDED) if(NOT DEFINED ${_var_name} OR _force) set(${_var_name} ${_var_default} PARENT_SCOPE) endif() else() set(${_var_name} ${_var_default} CACHE ${_var_type} "${_var_help}" ${_force}) if(_advanced) mark_as_advanced(${_var_name}) endif() endif() endfunction() # Determine if we are being build inside a larger project if(NOT DEFINED US_IS_EMBEDDED) if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) set(US_IS_EMBEDDED 0) else() set(US_IS_EMBEDDED 1) set(CppMicroServices_EXPORTS 1) endif() endif() us_cache_var(US_ENABLE_AUTOLOADING_SUPPORT OFF BOOL "Enable module auto-loading support") us_cache_var(US_ENABLE_SERVICE_FACTORY_SUPPORT ON BOOL "Enable Service Factory support" ADVANCED) us_cache_var(US_ENABLE_THREADING_SUPPORT OFF BOOL "Enable threading support") us_cache_var(US_ENABLE_DEBUG_OUTPUT OFF BOOL "Enable debug messages" ADVANCED) us_cache_var(US_ENABLE_RESOURCE_COMPRESSION ON BOOL "Enable resource compression" ADVANCED) us_cache_var(US_BUILD_SHARED_LIBS ON BOOL "Build shared libraries") us_cache_var(US_BUILD_TESTING OFF BOOL "Build tests") if(MSVC10 OR MSVC11) # Visual Studio 2010 and newer have support for C++11 enabled by default set(US_USE_C++11 1) else() us_cache_var(US_USE_C++11 OFF BOOL "Enable the use of C++11 features" ADVANCED) endif() us_cache_var(US_NAMESPACE "us" STRING "The namespace for the C++ micro services entities") us_cache_var(US_HEADER_PREFIX "" STRING "The file name prefix for the public C++ micro services header files") us_cache_var(US_BASECLASS_NAME "" STRING "The fully-qualified name of the base class") if(US_ENABLE_SERVICE_FACTORY_SUPPORT) us_cache_var(US_BASECLASS_PACKAGE "" STRING "The name of the package providing the base class definition" ADVANCED) set(bc_inc_d_doc "A list of include directories containing the header files for the base class") us_cache_var(US_BASECLASS_INCLUDE_DIRS "" STRING "${bc_inc_d_doc}" ADVANCED) set(bc_lib_d_doc "A list of library directories for the base class") us_cache_var(US_BASECLASS_LIBRARY_DIRS "" STRING "${bc_lib_d_doc}" ADVANCED) set(bc_lib_doc "A list of libraries needed for the base class") us_cache_var(US_BASECLASS_LIBRARIES "" STRING "${bc_lib_doc}" ADVANCED) us_cache_var(US_BASECLASS_HEADER "" STRING "The name of the header file containing the base class declaration" ADVANCED) endif() set(BUILD_SHARED_LIBS ${US_BUILD_SHARED_LIBS}) # Sanity checks if(US_ENABLE_SERVICE_FACTORY_SUPPORT OR US_BUILD_TESTING) if(US_BASECLASS_PACKAGE) find_package(${US_BASECLASS_PACKAGE} REQUIRED) # Try to get the include dirs foreach(_suffix DIRECTORIES DIRS DIRECTORY DIR) if(${US_BASECLASS_PACKAGE}_INCLUDE_${_suffix} AND NOT US_BASECLASS_INCLUDE_DIRS) us_cache_var(US_BASECLASS_INCLUDE_DIRS "${${US_BASECLASS_PACKAGE}_INCLUDE_${_suffix}}" STRING "${bc_inc_d_doc}" FORCE) break() endif() endforeach() # Try to get the library dirs foreach(_suffix DIRECTORIES DIRS DIRECTORY DIR) if(${US_BASECLASS_PACKAGE}_LIBRARY_${_suffix} AND NOT US_BASECLASS_LIBRARY_DIRS) us_cache_var(US_BASECLASS_LIBRARY_DIRS "${${US_BASECLASS_PACKAGE}_LIBRARY_${_suffix}}" STRING "${bc_lib_d_doc}" FORCE) break() endif() endforeach() # Try to get the libraries foreach(_suffix LIBRARIES LIBS LIBRARY LIB) if(${US_BASECLASS_PACKAGE}_${_suffix} AND NOT US_BASECLASS_LIBRARIES) us_cache_var(US_BASECLASS_LIBRARIES "${${US_BASECLASS_PACKAGE}_${_suffix}}" STRING "${bc_lib_doc}" FORCE) break() endif() endforeach() if(NOT US_BASECLASS_NAME) message(FATAL_ERROR "US_BASECLASS_NAME not set") elseif(NOT US_BASECLASS_HEADER) message(FATAL_ERROR "US_BASECLASS_HEADER not set") endif() endif() if(US_ENABLE_SERVICE_FACTORY_SUPPORT AND US_BASECLASS_NAME AND NOT US_BASECLASS_HEADER) message(FATAL_ERROR "US_ENABLE_SERVICE_FACTORY_SUPPORT requires a US_BASECLASS_HEADER value") endif() endif() set(_us_baseclass_default 0) if(NOT US_BASECLASS_NAME) message(WARNING "Using build in base class \"::${US_NAMESPACE}::Base\"") set(_us_baseclass_default 1) set(US_BASECLASS_NAME "${US_NAMESPACE}::Base") set(US_BASECLASS_HEADER "usBase.h") endif() if(US_BUILD_TESTING AND US_BASECLASS_NAME AND NOT US_BASECLASS_HEADER) message(FATAL_ERROR "US_BUILD_TESTING requires a US_BASECLASS_HEADER value") endif() set(US_BASECLASS_INCLUDE "#include <${US_BASECLASS_HEADER}>") string(REPLACE "::" ";" _bc_token "${US_BASECLASS_NAME}") list(GET _bc_token -1 _bc_name) list(REMOVE_AT _bc_token -1) set(US_BASECLASS_FORWARD_DECLARATION "") foreach(_namespace_tok ${_bc_token}) if(_namespace_tok) set(US_BASECLASS_FORWARD_DECLARATION "${US_BASECLASS_FORWARD_DECLARATION}namespace ${_namespace_tok} { ") endif() endforeach() set(US_BASECLASS_FORWARD_DECLARATION "${US_BASECLASS_FORWARD_DECLARATION}class ${_bc_name}; ") foreach(_namespace_tok ${_bc_token}) if(_namespace_tok) set(US_BASECLASS_FORWARD_DECLARATION "${US_BASECLASS_FORWARD_DECLARATION}}") endif() endforeach() #----------------------------------------------------------------------------- # US C/CXX Flags #----------------------------------------------------------------------------- set(US_C_FLAGS "${COVERAGE_C_FLAGS} ${ADDITIONAL_C_FLAGS}") set(US_CXX_FLAGS "${COVERAGE_CXX_FLAGS} ${ADDITIONAL_CXX_FLAGS}") # This is used as a preprocessor define set(US_USE_CXX11 ${US_USE_C++11}) # Set C++ compiler flags if(NOT MSVC) foreach(_cxxflag -Werror -Wall -Wextra -Wpointer-arith -Winvalid-pch -Wcast-align -Wwrite-strings -Woverloaded-virtual -Wnon-virtual-dtor -Wold-style-cast -Wstrict-null-sentinel -Wsign-promo -fdiagnostics-show-option -D_FORTIFY_SOURCE=2) usFunctionCheckCompilerFlags(${_cxxflag} US_CXX_FLAGS) endforeach() if(US_USE_C++11) usFunctionCheckCompilerFlags("-std=c++0x" US_CXX_FLAGS) endif() endif() if(CMAKE_COMPILER_IS_GNUCXX) usFunctionGetGccVersion(${CMAKE_CXX_COMPILER} GCC_VERSION) # With older versions of gcc the flag -fstack-protector-all requires an extra dependency to libssp.so. # If the gcc version is lower than 4.4.0 and the build type is Release let's not include the flag. if(${GCC_VERSION} VERSION_GREATER "4.4.0" OR (CMAKE_BUILD_TYPE STREQUAL "Debug" AND ${GCC_VERSION} VERSION_LESS "4.4.0")) usFunctionCheckCompilerFlags("-fstack-protector-all" US_CXX_FLAGS) endif() if(MINGW) # suppress warnings about auto imported symbols set(US_CXX_FLAGS "-Wl,--enable-auto-import ${US_CXX_FLAGS}") # we need to define a Windows version set(US_CXX_FLAGS "-D_WIN32_WINNT=0x0500 ${US_CXX_FLAGS}") else() # Enable visibility support if(NOT ${GCC_VERSION} VERSION_LESS "4.5") usFunctionCheckCompilerFlags("-fvisibility=hidden -fvisibility-inlines-hidden" US_CXX_FLAGS) endif() endif() elseif(MSVC) set(US_CXX_FLAGS "/MP /wd4996 ${US_CXX_FLAGS}") endif() if(NOT US_IS_EMBEDDED) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${US_CXX_FLAGS}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${US_C_FLAGS}") endif() #----------------------------------------------------------------------------- # US Link Flags #----------------------------------------------------------------------------- set(US_LINK_FLAGS ) if(NOT MSVC) foreach(_linkflag -Wl,--no-undefined) set(_add_flag) usFunctionCheckCompilerFlags("${_linkflag}" _add_flag) if(_add_flag) set(US_LINK_FLAGS "${US_LINK_FLAGS} ${_linkflag}") endif() endforeach() endif() #----------------------------------------------------------------------------- # US Header Checks #----------------------------------------------------------------------------- include(CheckIncludeFile) CHECK_INCLUDE_FILE(stdint.h HAVE_STDINT) #----------------------------------------------------------------------------- # US include dirs and libraries #----------------------------------------------------------------------------- set(US_INCLUDE_DIRS ${PROJECT_BINARY_DIR}/include ) set(US_INTERNAL_INCLUDE_DIRS ${PROJECT_BINARY_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/src/util ${CMAKE_CURRENT_SOURCE_DIR}/src/service ${CMAKE_CURRENT_SOURCE_DIR}/src/module ) if(US_ENABLE_SERVICE_FACTORY_SUPPORT) list(APPEND US_INTERNAL_INCLUDE_DIRS ${US_BASECLASS_INCLUDE_DIRS}) endif() # link libraries for third party libs if(US_IS_EMBEDDED) set(US_LINK_LIBRARIES ${US_EMBEDDING_LIBRARY}) else() set(US_LINK_LIBRARIES ${PROJECT_NAME}) endif() # link libraries for the CppMicroServices lib set(_link_libraries ) if(UNIX) list(APPEND _link_libraries dl) endif() list(APPEND US_LINK_LIBRARIES ${_link_libraries}) if(US_ENABLE_SERVICE_FACTORY_SUPPORT) list(APPEND US_LINK_LIBRARIES ${US_BASECLASS_LIBRARIES}) endif() set(US_LINK_DIRS ) if(US_ENABLE_SERVICE_FACTORY_SUPPORT) list(APPEND US_LINK_DIRS ${US_BASECLASS_LIBRARY_DIRS}) endif() #----------------------------------------------------------------------------- # Source directory #----------------------------------------------------------------------------- set(us_config_h_file "${PROJECT_BINARY_DIR}/include/usConfig.h") configure_file(usConfig.h.in ${us_config_h_file}) set(US_RCC_EXECUTABLE_NAME usResourceCompiler) set(CppMicroServices_RCC_EXECUTABLE_NAME ${US_RCC_EXECUTABLE_NAME}) -set(US_RCC_EXECUTABLE "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${US_RCC_EXECUTABLE_NAME}") -set(CppMicroServices_RCC_EXECUTABLE ${US_RCC_EXECUTABLE}) add_subdirectory(tools) add_subdirectory(src) #----------------------------------------------------------------------------- # US testing #----------------------------------------------------------------------------- if(US_BUILD_TESTING) enable_testing() add_subdirectory(test) endif() #----------------------------------------------------------------------------- # Documentation #----------------------------------------------------------------------------- add_subdirectory(documentation) #----------------------------------------------------------------------------- # Last configuration steps #----------------------------------------------------------------------------- configure_file(${PROJECT_NAME}Config.cmake.in ${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake @ONLY) diff --git a/Core/Code/CppMicroServices/CppMicroServicesConfig.cmake.in b/Core/Code/CppMicroServices/CppMicroServicesConfig.cmake.in index 027a0a7555..293031cb43 100644 --- a/Core/Code/CppMicroServices/CppMicroServicesConfig.cmake.in +++ b/Core/Code/CppMicroServices/CppMicroServicesConfig.cmake.in @@ -1,16 +1,19 @@ set(@PROJECT_NAME@_INCLUDE_DIRS @US_INCLUDE_DIRS@) set(@PROJECT_NAME@_INTERNAL_INCLUDE_DIRS @US_INTERNAL_INCLUDE_DIRS@) set(@PROJECT_NAME@_LIBRARIES @US_LINK_LIBRARIES@) set(@PROJECT_NAME@_LIBRARY_DIRS @CMAKE_LIBRARY_OUTPUT_DIRECTORY@) set(@PROJECT_NAME@_SOURCES @US_SOURCES@) set(@PROJECT_NAME@_PUBLIC_HEADERS @US_PUBLIC_HEADERS@) set(@PROJECT_NAME@_PRIVATE_HEADERS @US_PRIVATE_HEADERS@) set(@PROJECT_NAME@_SOURCE_DIR @CMAKE_CURRENT_SOURCE_DIR@) -set(CppMicroServices_RCC_EXECUTABLE @US_RCC_EXECUTABLE@) -set(CppMicroServices_RCC_EXECUTABLE_NAME @US_RCC_EXECUTABLE_NAME@) +set(CppMicroServices_RCC_EXECUTABLE_NAME @CppMicroServices_RCC_EXECUTABLE_NAME@) + +find_program(CppMicroServices_RCC_EXECUTABLE ${CppMicroServices_RCC_EXECUTABLE_NAME} + PATHS "@CMAKE_RUNTIME_OUTPUT_DIRECTORY@" + PATH_SUFFIXES Release Debug RelWithDebInfo MinSizeRel) include(@CMAKE_CURRENT_SOURCE_DIR@/CMake/usFunctionGenerateModuleInit.cmake) include(@CMAKE_CURRENT_SOURCE_DIR@/CMake/usFunctionEmbedResources.cmake)