# ############################################################################## # CMake support for the EIVE OBSW # # Author: R. Mueller # ############################################################################## # ############################################################################## # Pre-Project preparation # ############################################################################## cmake_minimum_required(VERSION 3.13) set(OBSW_VERSION_MAJOR_IF_GIT_FAILS 0) set(OBSW_VERSION_MINOR_IF_GIT_FAILS 0) set(OBSW_VERSION_REVISION_IF_GIT_FAILS 0) # set(CMAKE_VERBOSE TRUE) option( EIVE_HARDCODED_TOOLCHAIN_FILE "\ For Linux Board Target BSPs, a default toolchain file will be set. Should be set to OFF \ if a different toolchain file is set externally" ON) if(NOT FSFW_OSAL) set(FSFW_OSAL linux CACHE STRING "OS for the FSFW.") endif() if(TGT_BSP) if(TGT_BSP MATCHES "arm/q7s" OR TGT_BSP MATCHES "arm/raspberrypi" OR TGT_BSP MATCHES "arm/beagleboneblack") option(LINUX_CROSS_COMPILE ON) endif() if(TGT_BSP MATCHES "arm/raspberrypi" OR TGT_BSP MATCHES "arm/beagleboneblack") option(EIVE_BUILD_GPSD_GPS_HANDLER "Build GPSD dependent GPS Handler" OFF) elseif(TGT_BSP MATCHES "arm/q7s") option(EIVE_Q7S_EM "Build configuration for the EM" OFF) option(EIVE_BUILD_GPSD_GPS_HANDLER "Build GPSD dependent GPS Handler" ON) endif() option(EIVE_CREATE_UNIQUE_OBSW_BIN "Append username to generated binary name" ON) else() option(EIVE_CREATE_UNIQUE_OBSW_BIN "Append username to generated binary name" OFF) endif() list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") # Perform steps like loading toolchain files where applicable. include(PreProjectConfig) pre_project_config() # Project Name project(eive-obsw) # Specify the C++ standard set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED True) include(EiveHelpers) option(EIVE_ADD_ETL_LIB "Add ETL library" ON) option(EIVE_ADD_JSON_LIB "Add JSON library" ON) set(OBSW_MAX_SCHEDULED_TCS 500) if(EIVE_Q7S_EM) set(OBSW_Q7S_EM 1 CACHE STRING "Q7S EM configuration") set(INIT_VAL 0) else() set(OBSW_Q7S_EM 0 CACHE STRING "Q7S EM configuration") set(INIT_VAL 1) endif() set(OBSW_ADD_MGT ${INIT_VAL} CACHE STRING "Add MGT module") set(OBSW_ADD_BPX_BATTERY_HANDLER ${INIT_VAL} CACHE STRING "Add MGT module") set(OBSW_ADD_STAR_TRACKER ${INIT_VAL} CACHE STRING "Add Startracker module") set(OBSW_ADD_SUN_SENSORS ${INIT_VAL} CACHE STRING "Add sun sensor module") set(OBSW_ADD_SUS_BOARD_ASS ${INIT_VAL} CACHE STRING "Add sun sensor board assembly") set(OBSW_ADD_ACS_BOARD ${INIT_VAL} CACHE STRING "Add ACS board module") set(OBSW_ADD_ACS_HANDLERS ${INIT_VAL} CACHE STRING "Add ACS handlers") set(OBSW_ADD_RTD_DEVICES ${INIT_VAL} CACHE STRING "Add RTD devices") set(OBSW_ADD_RAD_SENSORS ${INIT_VAL} CACHE STRING "Add Rad Sensor module") set(OBSW_ADD_PL_PCDU ${INIT_VAL} CACHE STRING "Add Payload PCDU modukle") set(OBSW_ADD_SYRLINKS ${INIT_VAL} CACHE STRING "Add Syrlinks module") set(OBSW_ADD_TMP_DEVICES ${INIT_VAL} CACHE STRING "Add TMP devices") set(OBSW_ADD_GOMSPACE_PCDU ${INIT_VAL} CACHE STRING "Add GomSpace PCDU modules") set(OBSW_ADD_RW ${INIT_VAL} CACHE STRING "Add RW modules") # ############################################################################## # Pre-Sources preparation # ############################################################################## # Version handling set(GIT_VER_HANDLING_OK FALSE) if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git) determine_version_with_git("--exclude" "docker_*") set(GIT_INFO ${GIT_INFO} CACHE STRING "Version information retrieved with git describe") if(GIT_INFO) set(GIT_INFO ${GIT_INFO} CACHE STRING "Version information retrieved with git describe") list(GET GIT_INFO 1 OBSW_VERSION_MAJOR) list(GET GIT_INFO 2 OBSW_VERSION_MINOR) list(GET GIT_INFO 3 OBSW_VERSION_REVISION) list(GET GIT_INFO 4 OBSW_VERSION_CST_GIT_SHA1) if(NOT OBSW_VERSION_MAJOR) set(OBSW_VERSION_MAJOR ${OBSW_VERSION_MAJOR_IF_GIT_FAILS}) endif() if(NOT OBSW_VERSION_MINOR) set(FSFW_SUBVERSION ${OBSW_VERSION_MINOR_IF_GIT_FAILS}) endif() if(NOT OBSW_VERSION_REVISION) set(FSFW_REVISION ${OBSW_VERSION_REVISION_IF_GIT_FAILS}) endif() set(GIT_VER_HANDLING_OK TRUE) else() set(GIT_VER_HANDLING_OK FALSE) endif() endif() if(NOT GIT_VER_HANDLING_OK) set(OBSW_VERSION_MAJOR ${OBSW_VERSION_MAJOR_IF_GIT_FAILS}) set(OBSW_VERSION_MINOR ${OBSW_VERSION_MINOR_IF_GIT_FAILS}) set(OBSW_VERSION_REVISION ${OBSW_VERSION_REVISION_IF_GIT_FAILS}) endif() # Set names and variables set(OBSW_NAME ${CMAKE_PROJECT_NAME}) set(WATCHDOG_NAME eive-watchdog) set(SIMPLE_OBSW_NAME eive-simple) set(UNITTEST_NAME eive-unittest) set(LIB_FSFW_NAME fsfw) set(LIB_EIVE_MISSION eive-mission) set(LIB_ETL_TARGET etl::etl) set(LIB_CSP_NAME libcsp) set(LIB_LWGPS_NAME lwgps) set(LIB_ARCSEC wire) set(THIRD_PARTY_FOLDER thirdparty) set(LIB_CXX_FS -lstdc++fs) set(LIB_CATCH2 Catch2) set(LIB_GPS gps) set(LIB_JSON_NAME nlohmann_json::nlohmann_json) set(LIB_DUMMIES dummies) # Set path names set(FSFW_PATH fsfw) set(TEST_PATH test) set(UNITTEST_PATH unittest) set(LINUX_PATH linux) set(COMMON_PATH common) set(DUMMY_PATH dummies) set(WATCHDOG_PATH watchdog) set(COMMON_CONFIG_PATH ${COMMON_PATH}/config) set(UNITTEST_CFG_PATH ${UNITTEST_PATH}/testcfg) set(LIB_EIVE_MISSION_PATH mission) set(LIB_CSP_PATH ${THIRD_PARTY_FOLDER}/libcsp) set(LIB_ETL_PATH ${THIRD_PARTY_FOLDER}/etl) set(LIB_CATCH2_PATH ${THIRD_PARTY_FOLDER}/Catch2) set(LIB_LWGPS_PATH ${THIRD_PARTY_FOLDER}/lwgps) set(LIB_ARCSEC_PATH ${THIRD_PARTY_FOLDER}/arcsec_star_tracker) set(LIB_JSON_PATH ${THIRD_PARTY_FOLDER}/json) set(FSFW_WARNING_SHADOW_LOCAL_GCC OFF) set(EIVE_ADD_LINUX_FILES False) # Analyse different OS and architecture/target options, determine BSP_PATH, # display information about compiler etc. pre_source_hw_os_config() if(TGT_BSP) set(LIBGPS_VERSION_MAJOR 3) # I assume a newer version than 3.17 will be installed on other Linux board # than the Q7S set(LIBGPS_VERSION_MINOR 20) if(TGT_BSP MATCHES "arm/q7s" OR TGT_BSP MATCHES "arm/raspberrypi" OR TGT_BSP MATCHES "arm/beagleboneblack" OR TGT_BSP MATCHES "arm/egse" OR TGT_BSP MATCHES "arm/te0720-1cfa") find_library(${LIB_GPS} gps) set(FSFW_CONFIG_PATH "linux/fsfwconfig") if(NOT BUILD_Q7S_SIMPLE_MODE) set(EIVE_ADD_LINUX_FILES TRUE) set(ADD_CSP_LIB TRUE) set(FSFW_HAL_ADD_LINUX ON) set(FSFW_HAL_LINUX_ADD_LIBGPIOD ON) set(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS ON) endif() endif() if(TGT_BSP MATCHES "arm/raspberrypi") # Used by configure file set(RASPBERRY_PI ON) set(FSFW_HAL_ADD_RASPBERRY_PI ON) endif() if(TGT_BSP MATCHES "arm/egse") # Used by configure file set(EGSE ON) set(FSFW_HAL_LINUX_ADD_LIBGPIOD OFF) set(OBSW_ADD_STAR_TRACKER 1) set(OBSW_DEBUG_STARTRACKER 1) endif() if(TGT_BSP MATCHES "arm/beagleboneblack") # Used by configure file set(BEAGLEBONEBLACK ON) endif() if(TGT_BSP MATCHES "arm/q7s") # Used by configure file set(XIPHOS_Q7S ON) set(LIBGPS_VERSION_MAJOR 3) set(LIBGPS_VERSION_MINOR 17) endif() if(TGT_BSP MATCHES "arm/te0720-1cfa") set(TE0720_1CFA ON) endif() else() # Required by FSFW library set(FSFW_CONFIG_PATH "${BSP_PATH}/fsfwconfig") endif() # Configuration files configure_file(${COMMON_CONFIG_PATH}/commonConfig.h.in commonConfig.h) configure_file(${FSFW_CONFIG_PATH}/FSFWConfig.h.in FSFWConfig.h) configure_file(${BSP_PATH}/OBSWConfig.h.in OBSWConfig.h) if(TGT_BSP MATCHES "arm/q7s") configure_file(${BSP_PATH}/boardconfig/q7sConfig.h.in q7sConfig.h) elseif(TGT_BSP MATCHES "arm/raspberrypi" OR TGT_BSP MATCHES "arm/egse") configure_file(${BSP_PATH}/boardconfig/rpiConfig.h.in rpiConfig.h) endif() configure_file(${WATCHDOG_PATH}/watchdogConf.h.in watchdogConf.h) # Set common config path for FSFW set(FSFW_ADDITIONAL_INC_PATHS "${COMMON_PATH}/config" ${CMAKE_CURRENT_BINARY_DIR}) # ############################################################################## # Executable and Sources # ############################################################################## # global compiler options need to be set before adding executables if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") add_compile_options( "-Wall" "-Wextra" "-Wimplicit-fallthrough=1" "-Wno-unused-parameter" "-Wno-psabi" "-Wduplicated-cond" # check for duplicate conditions "-Wduplicated-branches" # check for duplicate branches "-Wlogical-op" # Search for bitwise operations instead of logical "-Wnull-dereference" # Search for NULL dereference "-Wundef" # Warn if undefind marcos are used "-Wformat=2" # Format string problem detection "-Wformat-overflow=2" # Formatting issues in printf "-Wformat-truncation=2" # Formatting issues in printf "-Wformat-security" # Search for dangerous printf operations "-Wstrict-overflow=3" # Warn if integer overflows might happen "-Warray-bounds=2" # Some array bounds violations will be found "-Wshift-overflow=2" # Search for bit left shift overflows (<c++14) "-Wcast-qual" # Warn if the constness is cast away "-Wstringop-overflow=4" # -Wstack-protector # Emits a few false positives for low level access # -Wconversion # Creates many false positives -Warith-conversion # Use with # Wconversion to find more implicit conversions -fanalyzer # Should be used # to look through problems ) # Remove unused sections. add_compile_options("-ffunction-sections" "-fdata-sections") # Removed unused sections. add_link_options("-Wl,--gc-sections") elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") set(COMPILER_FLAGS "/permissive-") endif() add_library(${LIB_EIVE_MISSION}) add_library(${LIB_DUMMIES}) # Add main executable add_executable(${OBSW_NAME}) set(OBSW_BIN_NAME ${CMAKE_PROJECT_NAME}) set_target_properties(${OBSW_NAME} PROPERTIES OUTPUT_NAME ${OBSW_BIN_NAME}) # Watchdog if(TGT_BSP MATCHES "arm/q7s") add_executable(${WATCHDOG_NAME}) else() add_executable(${WATCHDOG_NAME} EXCLUDE_FROM_ALL) endif() add_subdirectory(${WATCHDOG_PATH}) target_link_libraries(${WATCHDOG_NAME} PUBLIC ${LIB_CXX_FS}) target_include_directories(${WATCHDOG_NAME} PUBLIC ${CMAKE_BINARY_DIR}) # unittests if(NOT TGT_BSP) add_executable(${UNITTEST_NAME}) else() add_executable(${UNITTEST_NAME} EXCLUDE_FROM_ALL) endif() if(EIVE_ADD_ETL_LIB) endif() if(EIVE_ADD_JSON_LIB) add_subdirectory(${LIB_JSON_PATH}) endif() add_subdirectory(thirdparty/rapidcsv) if(EIVE_ADD_LINUX_FILES) add_subdirectory(${LIB_ARCSEC_PATH}) add_subdirectory(${LINUX_PATH}) endif() add_subdirectory(${BSP_PATH}) if(ADD_CSP_LIB) add_subdirectory(${LIB_CSP_PATH}) endif() add_subdirectory(${COMMON_PATH}) add_subdirectory(${DUMMY_PATH}) add_subdirectory(${LIB_LWGPS_PATH}) add_subdirectory(${FSFW_PATH}) add_subdirectory(${LIB_EIVE_MISSION_PATH}) add_subdirectory(${TEST_PATH}) add_subdirectory(${UNITTEST_PATH}) # This should have already been downloaded by the FSFW Still include it to be # safe find_package(etl ${FSFW_ETL_LIB_MAJOR_VERSION} CONFIG QUIET) # Not installed, so use FetchContent to download and provide etl if(NOT etl_FOUND) message( STATUS "No ETL installation was found with find_package. Installing and providing " "etl with FindPackage") include(FetchContent) FetchContent_Declare( etl GIT_REPOSITORY https://github.com/ETLCPP/etl GIT_TAG ${FSFW_ETL_LIB_VERSION}) list(APPEND FSFW_FETCH_CONTENT_TARGETS etl) endif() # Use same Catch2 version as framework if(NOT (TGT_BSP MATCHES "arm/te0720-1cfa") AND NOT (TGT_BSP MATCHES "arm/q7s") AND NOT (TGT_BSP MATCHES "arm/raspberrypi")) # Check whether the user has already installed Catch2 first find_package(Catch2 ${FSFW_CATCH2_LIB_MAJOR_VERSION} CONFIG QUIET) # Not installed, so use FetchContent to download and provide Catch2 if(NOT Catch2_FOUND) message( STATUS "${MSG_PREFIX} Catch2 installation not found. Downloading Catch2 library with FetchContent" ) include(FetchContent) FetchContent_Declare( Catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2.git GIT_TAG ${FSFW_CATCH2_LIB_VERSION}) list(APPEND FSFW_FETCH_CONTENT_TARGETS Catch2) endif() endif() # The documentation for FetchContent recommends declaring all the dependencies # before making them available. We make all declared dependency available here # after their declaration if(FSFW_FETCH_CONTENT_TARGETS) FetchContent_MakeAvailable(${FSFW_FETCH_CONTENT_TARGETS}) if(TARGET etl) add_library(${LIB_ETL_TARGET} ALIAS etl) endif() if(TARGET Catch2) # Fixes regression -preview4, to be confirmed in later releases Related # GitHub issue: https://github.com/catchorg/Catch2/issues/2417 set_target_properties(Catch2 PROPERTIES DEBUG_POSTFIX "") set_target_properties(Catch2 PROPERTIES EXCLUDE_FROM_ALL "true") set_target_properties(Catch2WithMain PROPERTIES EXCLUDE_FROM_ALL "true") endif() endif() # ############################################################################## # Post-Sources preparation # ############################################################################## # Add libraries target_link_libraries(${LIB_EIVE_MISSION} PUBLIC ${LIB_FSFW_NAME} ${LIB_LWGPS_NAME} ${LIB_OS_NAME}) target_link_libraries(${LIB_DUMMIES} PUBLIC ${LIB_FSFW_NAME} ${LIB_JSON_NAME}) target_link_libraries(${OBSW_NAME} PRIVATE ${LIB_EIVE_MISSION} ${LIB_DUMMIES}) if(TGT_BSP MATCHES "arm/q7s") target_link_libraries(${LIB_EIVE_MISSION} PUBLIC ${LIB_GPS} ${LIB_ARCSEC}) endif() target_link_libraries(${UNITTEST_NAME} PRIVATE Catch2 ${LIB_EIVE_MISSION} rapidcsv ${LIB_DUMMIES}) if(TGT_BSP MATCHES "arm/egse") target_link_libraries(${OBSW_NAME} PRIVATE ${LIB_ARCSEC}) endif() if(ADD_CSP_LIB) target_link_libraries(${OBSW_NAME} PRIVATE ${LIB_CSP_NAME}) endif() if(EIVE_ADD_ETL_LIB) target_link_libraries(${LIB_EIVE_MISSION} PUBLIC ${LIB_ETL_TARGET}) endif() if(EIVE_ADD_JSON_LIB) target_link_libraries(${LIB_EIVE_MISSION} PUBLIC ${LIB_JSON_NAME}) endif() target_link_libraries(${LIB_EIVE_MISSION} PUBLIC ${LIB_CXX_FS}) # Add include paths for all sources. target_include_directories( ${LIB_EIVE_MISSION} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${FSFW_CONFIG_PATH} ${CMAKE_CURRENT_BINARY_DIR} ${LIB_ARCSEC_PATH}) target_include_directories( ${LIB_DUMMIES} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${FSFW_CONFIG_PATH} ${CMAKE_CURRENT_BINARY_DIR}) if(TGT_BSP MATCHES "arm/q7s" OR TGT_BSP MATCHES "arm/egse") target_include_directories(${LIB_EIVE_MISSION} PUBLIC ${ARCSEC_LIB_PATH}) endif() if(CMAKE_VERBOSE) message(STATUS "Warning flags: ${WARNING_FLAGS}") endif() if(CMAKE_CROSSCOMPILING) include(HardwareOsPostConfig) post_source_hw_os_config() endif() if(NOT CMAKE_SIZE) set(CMAKE_SIZE size) if(WIN32) set(FILE_SUFFIX ".exe") endif() endif() if(EIVE_BUILD_WATCHDOG) set(TARGET_STRING "OBSW Watchdog") else() if(TGT_BSP) set(TARGET_STRING "Target BSP: ${TGT_BSP}") else() set(TARGET_STRING "Target BSP: Hosted") endif() endif() install(TARGETS ${OBSW_NAME} RUNTIME DESTINATION bin) string(CONCAT POST_BUILD_COMMENT "Build directory: ${CMAKE_BINARY_DIR}\n" "Target OSAL: ${FSFW_OSAL}\n" "Target Build Type: ${CMAKE_BUILD_TYPE}\n" "${TARGET_STRING}") add_custom_command( TARGET ${OBSW_NAME} POST_BUILD COMMAND ${CMAKE_SIZE} ${OBSW_BIN_NAME}${FILE_SUFFIX} COMMENT ${POST_BUILD_COMMENT}) include(BuildType) set_build_type()