diff --git a/CMakeLists.txt b/CMakeLists.txt index 895e9d7..f3baa08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,197 +1,201 @@ cmake_minimum_required(VERSION 3.3.0) # Start project, set version here. project("RoSA") # NOTE: Adjust the variables version and release in docs/conf.py according to # version changes here. set(ROSA_VERSION_MAJOR 0) set(ROSA_VERSION_MINOR 1) set(ROSA_VERSION_PATCH 0) +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + # Add path for custom modules set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" ) # Package information if( NOT PACKAGE_VERSION ) set(PACKAGE_VERSION "${ROSA_VERSION_MAJOR}.${ROSA_VERSION_MINOR}.${ROSA_VERSION_PATCH}") endif() set(PACKAGE_NAME "Research on Self-Awareness Framework") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "david.juhasz@tuwien.ac.at") #TODO: cpack? # Sanity check we are to make out-of-tree build if( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR ) message(FATAL_ERROR "In-source builds are not allowed.") endif() string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE) # Set various paths set(ROSA_MAIN_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(ROSA_MAIN_INCLUDE_DIR ${ROSA_MAIN_SRC_DIR}/include) set(ROSA_MAIN_BIN_DIR ${ROSA_MAIN_SRC_DIR}/bin) set(ROSA_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) set(ROSA_RUNTIME_OUTPUT_INTDIR ${ROSA_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin) set(ROSA_LIBRARY_OUTPUT_INTDIR ${ROSA_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib) set(ROSA_EXEC_BINARY_DIR ${ROSA_BINARY_DIR}/bin) set(ROSA_LIBRARY_DIR ${ROSA_BINARY_DIR}/lib) set(ROSA_INCLUDE_DIR ${ROSA_BINARY_DIR}/include) set(ROSA_MAIN_MODULE_DIR ${ROSA_MAIN_SRC_DIR}/modules) # Add some generic helpers. include(AddCMakeTools) # Set build options option(ROSA_INCLUDE_TOOLS "Generate build targets for RoSA tools." ON) option(ROSA_INCLUDE_EXAMPLES "Generate build targets for RoSA examples." ON) option(ROSA_ENABLE_PEDANTIC "Compile with pedantic enabled." ON) # Assertions are always enabled for Debug builds, this option is respected only # for non-Debug builds. option(ROSA_ENABLE_ASSERTIONS "Enable assertions for non-Debug builds." OFF) option(ROSA_ENABLE_CLANG_TIDY "Run clang-tidy checks when building RoSA." OFF) option(ROSA_INCLUDE_CLANG_FORMAT "Generate build target for formatting RoSA sources with clang-format." OFF) option(ROSA_INCLUDE_DOCS "Generate build targets for RoSA documentation." ON) option(ROSA_BUILD_DOCS "Build RoSA documentation." OFF) option(ROSA_ENABLE_DOXYGEN "Use doxygen to generate RoSA API documentation." OFF) option(ROSA_ENABLE_SPHINX "Use Sphinx to generate RoSA documentation." OFF) set(ROSA_LOG_LEVEL "" CACHE STRING "Level of logging to be used.") set(ROSA_INCLUDE_APPS "" CACHE STRING "Generate build targets for the defined RoSA applications.") # All options referred to from HandleROSAOptions have to be specified # BEFORE this include, otherwise options will not be correctly set on # first cmake run include(config-ix) include(HandleROSAOptions) # Configure the ROSA configuration header file. if( NOT ROSA_LOG_LEVEL STREQUAL "") if( ${ROSA_LOG_LEVEL} EQUAL 5 ) set(ROSA_LOG_LEVEL_INT -1) else() set(ROSA_LOG_LEVEL_INT ${ROSA_LOG_LEVEL}) endif() else() set(ROSA_LOG_LEVEL_INT -1) endif() configure_file( ${ROSA_MAIN_INCLUDE_DIR}/rosa/config/rosa_config.h.cmake ${ROSA_INCLUDE_DIR}/rosa/config/rosa_config.h ) # Handling modules set(CXXOPTS_BUILD_TESTS OFF) file(COPY ${ROSA_MAIN_MODULE_DIR}/cxxopts/include/cxxopts.hpp DESTINATION ${ROSA_INCLUDE_DIR}/cxxopts ) # They are not referenced. See set_output_directory(). set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${ROSA_EXEC_BINARY_DIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${ROSA_LIBRARY_DIR}) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${ROSA_LIBRARY_DIR}) # Set include directories set(CMAKE_INCLUDE_CURRENT_DIR ON) include_directories(${ROSA_INCLUDE_DIR} ${ROSA_MAIN_INCLUDE_DIR}) # Set up YCM set(CMAKE_EXPORT_COMPILE_COMMANDS 1) message("Set compilation_database_folder in .ymc_extra_conf.py in the source directory if you want to use YMC.") # Add parts of the project include(AddROSATools) add_subdirectory(lib) add_subdirectory(apps) add_subdirectory(modules) if( ROSA_INCLUDE_TOOLS ) add_subdirectory(tools) endif() if( ROSA_INCLUDE_EXAMPLES ) add_subdirectory(examples) endif() if( ROSA_INCLUDE_DOCS ) add_subdirectory(docs) endif() #TODO: install? # Print summary set(ROSA_ENABLE_ASSERTIONS_STR "OFF") if( ROSA_ENABLE_ASSERTIONS_INT EQUAL 1 ) set(ROSA_ENABLE_ASSERTIONS_STR "ON") endif() set(LOG_LEVEL_STR "disabled") if( NOT ROSA_LOG_LEVEL STREQUAL "" ) if( ${ROSA_LOG_LEVEL} EQUAL 0 ) set(LOG_LEVEL_STR "ERROR") elseif( ${ROSA_LOG_LEVEL} EQUAL 1 ) set(LOG_LEVEL_STR "WARNING") elseif( ${ROSA_LOG_LEVEL} EQUAL 2 ) set(LOG_LEVEL_STR "INFO") elseif( ${ROSA_LOG_LEVEL} EQUAL 3 ) set(LOG_LEVEL_STR "DEBUG") elseif( ${ROSA_LOG_LEVEL} EQUAL 4 ) set(LOG_LEVEL_STR "TRACE") elseif( ${ROSA_LOG_LEVEL} EQUAL 5 ) set(LOG_LEVEL_STR "disabled") else() set(LOG_LEVEL_STR "invalid") endif() endif() message(STATUS "\n====================| Build Summary |====================" "\n" "\nRoSA version: ${PACKAGE_VERSION}" "\n" "\nBuild type: ${CMAKE_BUILD_TYPE}" "\nAssertions: ${ROSA_ENABLE_ASSERTIONS_STR}" "\nClang-tidy: ${ROSA_ENABLE_CLANG_TIDY}" "\nClang-format: ${ROSA_INCLUDE_CLANG_FORMAT}" "\nLog level: ${LOG_LEVEL_STR}" "\n" "\nBuild apps: ${ROSA_INCLUDE_APPS}" "\nBuild tools: ${ROSA_INCLUDE_TOOLS}" "\nBuild examples: ${ROSA_INCLUDE_EXAMPLES}" "\nInclude docs: ${ROSA_INCLUDE_DOCS}" "\nBuild docs: ${ROSA_BUILD_DOCS}" "\n -enable doxygen: ${ROSA_ENABLE_DOXYGEN}" "\n -enable Sphinx: ${ROSA_ENABLE_SPHINX}" "\n" "\nCC: ${CMAKE_C_COMPILER}" "\nCFLAGS: ${CMAKE_C_FLAGS}" "\nCXX: ${CMAKE_CXX_COMPILER}" "\nCXXFLAGS: ${CMAKE_CXX_FLAGS}" "\nLIBRARIES: ${LD_FLAGS}" "\n" "\nSource directory: ${ROSA_MAIN_SRC_DIR}" "\nBuild directory: ${ROSA_BINARY_DIR}" "\nExecutable path: ${ROSA_EXEC_BINARY_DIR}" "\nLibrary path: ${ROSA_LIBRARY_DIR}" "\nGenerator: ${CMAKE_GENERATOR}" "\n" "\n===========================================================\n") - diff --git a/cmake/modules/HandleROSAOptions.cmake b/cmake/modules/HandleROSAOptions.cmake index ea2e470..c9e7f39 100644 --- a/cmake/modules/HandleROSAOptions.cmake +++ b/cmake/modules/HandleROSAOptions.cmake @@ -1,224 +1,185 @@ # This CMake module is responsible for interpreting the user defined ROSA_ # options and executing the appropriate CMake commands to realize the users' # selections. include(CheckCCompilerFlag) include(CheckCXXCompilerFlag) if ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" ) set(ROSA_COMPILER_IS_CLANG ON) # Enforce minimum version. if ( CMAKE_CXX_COMPILER_VERSION VERSION_LESS "3.9.0" ) message(FATAL_ERROR "Insufficient LLVM version") endif() else() set(ROSA_COMPILER_IS_CLANG OFF) endif() if( CMAKE_COMPILER_IS_GNUCXX ) set(ROSA_COMPILER_IS_GCC_COMPATIBLE ON) elseif( MSVC ) set(ROSA_COMPILER_IS_GCC_COMPATIBLE OFF) elseif( ROSA_COMPILER_IS_CLANG ) set(ROSA_COMPILER_IS_GCC_COMPATIBLE ON) else() message(FATAL_ERROR "Unexpected C++ compiler!") endif() function(append value) foreach(variable ${ARGN}) set(${variable} "${${variable}} ${value}" PARENT_SCOPE) endforeach(variable) endfunction() function(append_if condition value) if (${condition}) foreach(variable ${ARGN}) set(${variable} "${${variable}} ${value}" PARENT_SCOPE) endforeach(variable) endif() endfunction() function(remove value) foreach(variable ${ARGN}) string(REPLACE "${value}" "" NEWVAR "${${variable}}") set(${variable} "${NEWVAR}" PARENT_SCOPE) endforeach(variable) endfunction() # NDEBUG on non-Debug builds append("-DNDEBUG" CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO CMAKE_C_FLAGS_MINSIZEREL) # Assertions are always enabled on Debug builds, this is interesting for # non-Debug builds. if( NOT "${uppercase_CMAKE_BUILD_TYPE}" STREQUAL "DEBUG" AND ${ROSA_ENABLE_ASSERTIONS} ) # MSVC doesn't like _DEBUG on release builds. See PR 4379. if( NOT MSVC ) add_definitions( -D_DEBUG ) set(ENABLE_ASSERTIONS "1") else() set(ENABLE_ASSERTIONS "0") endif() # On non-Debug builds we NDEBUG, but in this case we need to undefine it: add_definitions(-UNDEBUG) # Also remove /D NDEBUG to avoid MSVC warnings about conflicting defines. foreach (flags_var_to_scrub CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO CMAKE_C_FLAGS_MINSIZEREL) string (REGEX REPLACE "(^| )[/-]D *NDEBUG($| )" " " "${flags_var_to_scrub}" "${${flags_var_to_scrub}}") endforeach() endif() set(ROSA_ENABLE_ASSERTIONS_INT -1) if( "${uppercase_CMAKE_BUILD_TYPE}" STREQUAL "DEBUG" OR ${ROSA_ENABLE_ASSERTIONS} ) set(ROSA_ENABLE_ASSERTIONS_INT 1) endif() if( ROSA_COMPILER_IS_GCC_COMPATIBLE ) append("-Wall -Wextra -Wdocumentation -Werror" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) append_if(ROSA_ENABLE_PEDANTIC "-pedantic -Wno-long-long" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) append("-fno-rtti -fno-exceptions" CMAKE_CXX_FLAGS) append("-Wno-c++1z-compat" CMAKE_CXX_FLAGS) - check_cxx_compiler_flag("-std=c++17" CXX_SUPPORTS_CXX17) - if ( CXX_SUPPORTS_CXX17 ) - append("-std=c++17" CMAKE_CXX_FLAGS) - else() - message(FATAL_ERROR "RoSA requires C++17 support but the '-std=c++17' flag isn't supported.") - endif() - - check_c_compiler_flag("-std=c11" C_SUPPORTS_C11) - if ( C_SUPPORTS_C11 ) - append("-std=c11" CMAKE_C_FLAGS) - else() - message(FATAL_ERROR "RoSA requires C11 support but the '-std=c11' flag isn't supported.") - endif() - elseif ( MSVC ) if (ROSA_COMPILER_IS_CLANG) # Remove/adjsut incorrect flags that might be generated automatically. foreach (flags_var_to_scrub CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELWITHDEBINFO CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO CMAKE_C_FLAGS_MINSIZEREL) string (REGEX REPLACE "(^| )-Wall($| )" " " "${flags_var_to_scrub}" "${${flags_var_to_scrub}}") string (REGEX REPLACE "(^| )-frtti($| )" " " "${flags_var_to_scrub}" "${${flags_var_to_scrub}}") string (REGEX REPLACE "(^| )-fexceptions($| )" " " "${flags_var_to_scrub}" "${${flags_var_to_scrub}}") string (REGEX REPLACE "(^| )-fno-inline($| )" " -Ob0 " "${flags_var_to_scrub}" "${${flags_var_to_scrub}}") string (REGEX REPLACE "(^| )-gline-tables-only($| )" " " "${flags_var_to_scrub}" "${${flags_var_to_scrub}}") message("${flags_var_to_scrub}: ${${flags_var_to_scrub}}") endforeach() endif() # Flags matching GCC-compatible "-Wall -Wextra -Werror". # NOTE: Do not use -Wall for MSVC because it generates silly warning (e.g., # warnings about things in external libraries), use -W4 instead. append("/W4 /WX" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) if ( ROSA_COMPILER_IS_CLANG ) # GCC-compatible flags without corresponding MSVC options. append("-Wdocumentation" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) # The flag "-pedantic" is not in the MSVC flavour. append_if(ROSA_ENABLE_PEDANTIC "-Wno-long-long" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) endif() # Flags matching GCC-compatible "-fno-rtti". append("/GR-" CMAKE_CXX_FLAGS) # NOTE: We cannot disable unwind semantics (i.e., -fno-exceptions) for Windows # libraries... append("/EHsc" CMAKE_CXX_FLAGS) if ( ROSA_COMPILER_IS_CLANG ) append("-Wno-c++1z-compat" CMAKE_CXX_FLAGS) # MSVC puts there some garbage which needs to be ignored... append("-Qunused-arguments" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) endif() - if ( ROSA_COMPILER_IS_CLANG ) - - check_cxx_compiler_flag("-std=c++17" CXX_SUPPORTS_CXX17) - if ( CXX_SUPPORTS_CXX17 ) - append("-std=c++17" CMAKE_CXX_FLAGS) - else() - message(FATAL_ERROR "RoSA requires C++17 support but the '-std=c++17' flag isn't supported.") - endif() - - check_c_compiler_flag("-std=c11" C_SUPPORTS_C11) - if ( C_SUPPORTS_C11 ) - append("-std=c11" CMAKE_C_FLAGS) - else() - message(FATAL_ERROR "RoSA requires C11 support but the '-std=c11' flag isn't supported.") - endif() - - else () - - check_cxx_compiler_flag("/std:c++17 /permissive-" CXX_SUPPORTS_CXX17) - if ( CXX_SUPPORTS_CXX17 ) - append("/std:c++17 /permissive-" CMAKE_CXX_FLAGS) - else() - message(FATAL_ERROR "RoSA requires C++17 support but the '/std:c++17 /permissive-' flags aren't supported.") - endif() - - message(WARNING "RoSA is supposed to use C11 code in C files, which MSVC might not fully support.") + if ( MSVC ) # Make MSVC ignore warning C4514 about unreferenced inline functions. append("/nowarn:4514") # Make MSVC ignore warning LNK4221 in libraries. The warning is caused by # empty object files that correspond to the empty .cpp files, which we have # for generating compile database entries for all header files. append("/IGNORE:4221" CMAKE_STATIC_LINKER_FLAGS) # Let's make the compiler handle a big number of sections in object files. append("/bigobj" CMAKE_CXX_FLAGS) endif() endif() if( ROSA_ENABLE_CLANG_TIDY ) # Set clang-tidy arguments, use the same for both C and CXX. set(CMAKE_C_CLANG_TIDY "${CLANGTIDY_EXECUTABLE};-header-filter=.*") set(CMAKE_CXX_CLANG_TIDY ${CMAKE_C_CLANG_TIDY}) # Apply suggested fixes if requested. append_if(ROSA_CLANG_TIDY_FIX ",-fix" CMAKE_C_CLANG_TIDY CMAKE_CXX_CLANG_TIDY) endif( ROSA_ENABLE_CLANG_TIDY ) if( ROSA_INCLUDE_APPS STREQUAL "") message(STATUS "Include all apps by default.") SUBDIRLIST(ROSA_INCLUDE_APPS ${ROSA_MAIN_SRC_DIR}/apps) else() message(STATUS "Include apps: ${ROSA_INCLUDE_APPS}.") endif()