diff --git a/Fw/Types/CMakeLists.txt b/Fw/Types/CMakeLists.txt index 3698ad4edc6..74bd8c43ff5 100644 --- a/Fw/Types/CMakeLists.txt +++ b/Fw/Types/CMakeLists.txt @@ -1,6 +1,7 @@ #### # F prime CMakeLists.txt: #### +include(global_interface) register_fprime_module( Fw_Types SOURCES @@ -17,7 +18,7 @@ register_fprime_module( AUTOCODER_INPUTS "${CMAKE_CURRENT_LIST_DIR}/Types.fpp" DEPENDS - __fprime_config # Only module that should ever list __fprime_config in DEPENDS. Use Fw_Types instead. + ${FPRIME_GLOBAL_INTERFACE_TARGET} # Most users should prefer Fw_Types instead over the direct global interface. REQUIRES_IMPLEMENTATIONS Fw_StringFormat Fw_StringScan diff --git a/cmake/API.cmake b/cmake/API.cmake index 3d9cb4eeaf3..5eb04bf7014 100644 --- a/cmake/API.cmake +++ b/cmake/API.cmake @@ -17,14 +17,11 @@ include(module) include(config_assembler) include(sub-build/sub-build) include(fprime-util) +include(global_interface) + set(FPRIME_TARGET_LIST "" CACHE INTERNAL "FPRIME_TARGET_LIST: custom fprime targets" FORCE) set(FPRIME_UT_TARGET_LIST "" CACHE INTERNAL "FPRIME_UT_TARGET_LIST: custom fprime targets" FORCE) set(FPRIME_AUTOCODER_TARGET_LIST "" CACHE INTERNAL "FPRIME_AUTOCODER_TARGET_LIST: custom fprime targets" FORCE) -set(FPRIME_GLOBAL_INTERFACE_TARGET "_fprime_global_interface_target" CACHE INTERNAL "FPRIME_GLOBAL_INTERFACE_TARGETS: global interface targets" FORCE) -# Create a singleton global interface target -if (NOT TARGET "${FPRIME_GLOBAL_INTERFACE_TARGET}") - add_library("${FPRIME_GLOBAL_INTERFACE_TARGET}" INTERFACE) -endif() #### # Macro `skip_on_sub_build`: @@ -106,8 +103,8 @@ endmacro() # directories. This creates a directed acyclic graph of modules, one subgraph of which will be built # for each executable/module/library defined in the system. The subgraph should also be a DAG. # -# This directory is computed based off the closest path in `FPRIME_BUILD_LOCATIONS`. It must be set to -# be used. Otherwise, an error will occur. `EXCLUDE_FROM_ALL` can also be supplied. +# This directory is computed based off the closest path in `FPRIME_LOCATIONS` of the global interface. +# # See: https://cmake.org/cmake/help/latest/command/add_fprime_subdirectory.html # # **Note:** Replaces CMake `add_subdirectory` call in order to automate the [binary_dir] argument. @@ -469,16 +466,19 @@ function(fprime_add_config_build_target) # The new module should include the root configuration directory fprime_target_include_directories("${INTERNAL_MODULE_NAME}" PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/..") - # The configuration target should depend on the new module + # When the configuration is marked as BASE_CONFIG, this implies that the entire build system should have access to + # the configuration. Thus, we link the configuration module into the global interface target allowing any module + # to pull in the dependency. if (INTERNAL_BASE_CONFIG) - target_link_libraries("${FPRIME__INTERNAL_CONFIG_TARGET_NAME}" INTERFACE "${INTERNAL_MODULE_NAME}") + target_link_libraries("${FPRIME_GLOBAL_INTERFACE_TARGET}" INTERFACE "${INTERNAL_MODULE_NAME}") endif() # Set up the new module to be marked as FPRIME_CONFIGURATION append_list_property("${INTERNAL_MODULE_NAME}" GLOBAL PROPERTY "FPRIME_CONFIG_MODULES") set_property(TARGET "${INTERNAL_MODULE_NAME}" PROPERTY FPRIME_CONFIGURATION TRUE) # Targets likely do not exist yet, so just aggregate the complete list of chosen implementations # for processing later - append_list_property("${INTERNAL_CHOOSES_IMPLEMENTATIONS}" TARGET "${FPRIME__INTERNAL_CONFIG_TARGET_NAME}" PROPERTY FPRIME_CHOSEN_IMPLEMENTATIONS) + append_list_property("${INTERNAL_CHOOSES_IMPLEMENTATIONS}" TARGET "${FPRIME_GLOBAL_INTERFACE_TARGET}" PROPERTY + FPRIME_CHOSEN_IMPLEMENTATIONS) # Static libraries must be position independent when building shared libraries get_target_property(CONFIG_LIBRARY_TYPE "${INTERNAL_MODULE_NAME}" TYPE) @@ -734,12 +734,13 @@ endfunction() # Macro `register_fprime_project`: # # Used to register an F Prime project. This will do the following: -# 1. Add the current source directory to the FPRIME_BUILD_LOCATIONS property -# 2. Add the current source directory to the global include directories -# 3. Add the current binary directory to the global include directories -# 4. Add the current source directory to the CMAKE_PATH_PREFIX variable for this module +# 1. Add the current source directory to the FPRIME_LOCATIONS property of the global interface +# 2. Add the current binary directory to the FPRIME_LOCATIONS property of the global interface +# 3. Add the current source directory to the global include directories +# 4. Add the current binary directory to the global include directories +# 5. Add the current source directory to the CMAKE_PATH_PREFIX variable for this module # This allows it to be found and used by other modules in the build system. It ensures that the components are properly -# slotted underneath this library for the purposed of include path and target names. +# slotted underneath this library for the purpose of include path and target names. # Args: none ##### macro(register_fprime_project) @@ -750,19 +751,15 @@ macro(register_fprime_project) endif() # Add to the build locations property - append_list_property("${CMAKE_CURRENT_SOURCE_DIR}" GLOBAL PROPERTY FPRIME_PROJECT_LOCATIONS) - # Add source and binaries to the interface includes of our singular global interface target - target_include_directories("${FPRIME_GLOBAL_INTERFACE_TARGET}" INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}") - target_include_directories("${FPRIME_GLOBAL_INTERFACE_TARGET}" INTERFACE "${CMAKE_CURRENT_BINARY_DIR}") + fprime_add_location_pair("${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}") - # Backwards compatibility: update the build locations variable as well - set(FPRIME_BUILD_LOCATIONS "${CMAKE_CURRENT_SOURCE_DIR};${FPRIME_BUILD_LOCATIONS}" CACHE INTERNAL "FPRIME_BUILD_LOCATIONS: list of source directories containing fprime modules" FORCE) # Backwards compatibility: bridge the interface target include directories back into the include_directories directive include_directories("$") - # Update the CMAKE_MODULE_PATH for this particular project - get_property(FPRIME_PROJECT_LOCATIONS GLOBAL PROPERTY FPRIME_PROJECT_LOCATIONS) - foreach (PROJECT_LOCATION IN LISTS FPRIME_PROJECT_LOCATIONS) + # Update the CMAKE_MODULE_PATH for this particular project. This has to be done for each project because + # CMAKE_MODULE_PATH is not a cache variable. + get_property(FPRIME_LOCATIONS TARGET "${FPRIME_GLOBAL_INTERFACE_TARGET}" PROPERTY FPRIME_LOCATIONS) + foreach (PROJECT_LOCATION IN LISTS FPRIME_LOCATIONS) list(APPEND CMAKE_MODULE_PATH "${PROJECT_LOCATION}/cmake") endforeach() set(FPRIME_CURRENT_PROJECT_PATH "${CMAKE_CURRENT_SOURCE_DIR}") diff --git a/cmake/FPrime.cmake b/cmake/FPrime.cmake index 42d1b6a2d62..6a8de88135d 100644 --- a/cmake/FPrime.cmake +++ b/cmake/FPrime.cmake @@ -12,6 +12,7 @@ include(utilities) include(options) include(sanitizers) # Enable sanitizers if they are requested include(required) +include(global_interface) include(config_assembler) include(fprime-util) @@ -30,21 +31,9 @@ if (IS_DIRECTORY "${FPRIME_PROJECT_ROOT}/_fprime_packages") endif() endif() -# Setup fprime library locations -list(REMOVE_DUPLICATES FPRIME_LIBRARY_LOCATIONS) +# Adds the historical locations to the global interface target. +fprime_add_historical_locations() -# F Prime build locations represent the root of the module paths in F Prime. This allows us to detect module names from the -# paths to given files. -# Now that modules can build within the build cache, the build cache locations (root, F-Prime) are added to the list of -# locations. This allows for the detection of modules that are built within the build cache. -set(FPRIME_BUILD_LOCATIONS "${FPRIME_FRAMEWORK_PATH}" ${FPRIME_LIBRARY_LOCATIONS} "${FPRIME_PROJECT_ROOT}" - "${CMAKE_BINARY_DIR}/F-Prime" "${CMAKE_BINARY_DIR}" CACHE INTERNAL "List of root locations for F Prime modules" FORCE) -list(REMOVE_DUPLICATES FPRIME_BUILD_LOCATIONS) -resolve_path_variables(FPRIME_BUILD_LOCATIONS) - -# Message describing the fprime setup -fprime_cmake_status("[FPRIME] Module locations: ${FPRIME_BUILD_LOCATIONS}") -fprime_cmake_status("[FPRIME] Installation directory: ${CMAKE_INSTALL_PREFIX}") include(platform/platform) # Now that module locations are known, load platform settings fprime_validate_platform() @@ -66,21 +55,6 @@ include(API) include(sub-build/sub-build) # C and C++ settings for building the framework include(settings) -#### -# Function `fprime_setup_global_includes`: -# -# Adds basic include directories that make fprime work. This ensures that configuration, framework, and project all -# function as expected. This will also include the internal build-cache directories. -#### -function(fprime_setup_global_includes) - # Setup the global include directories that exist outside of the build cache - include_directories("${FPRIME_FRAMEWORK_PATH}") - include_directories("${FPRIME_PROJECT_ROOT}") - - # Setup the include directories that exist within the build-cache - include_directories("${CMAKE_BINARY_DIR}") - include_directories("${CMAKE_BINARY_DIR}/F-Prime") -endfunction(fprime_setup_global_includes) #### # Function `fprime_detect_libraries`: @@ -162,7 +136,6 @@ macro(fprime_initialize_build_system) get_property(_FPRIME_BUILD_SYSTEM_LOADED GLOBAL PROPERTY FPRIME_BUILD_SYSTEM_LOADED) if (NOT _FPRIME_BUILD_SYSTEM_LOADED) cmake_minimum_required(VERSION 3.18) - fprime_setup_global_includes() fprime_detect_libraries() fprime_setup_standard_targets() fprime_setup_override_targets() @@ -178,6 +151,9 @@ macro(fprime_initialize_build_system) run_sub_build(info-cache ${SUB_BUILD_TARGETS}) # Import the pre-computed properties! include("${CMAKE_BINARY_DIR}/fprime_module_info.cmake") + get_property(FPRIME_SUB_BUILD_LOCATIONS TARGET ${FPRIME_GLOBAL_INTERFACE_TARGET} PROPERTY FPRIME_SUB_BUILD_LOCATIONS) + fprime_cmake_status("[FPRIME] Module locations: ${FPRIME_SUB_BUILD_LOCATIONS}") + fprime_cmake_status("[FPRIME] Installation directory: ${CMAKE_INSTALL_PREFIX}") endif() endif() endmacro(fprime_initialize_build_system) diff --git a/cmake/autocoder/fpp.cmake b/cmake/autocoder/fpp.cmake index 53c172d1570..3779e812c3a 100644 --- a/cmake/autocoder/fpp.cmake +++ b/cmake/autocoder/fpp.cmake @@ -188,6 +188,31 @@ function(fpp_info MODULE_NAME AC_INPUT_FILES) set(FPP_IMPORTS "${STDOUT}" PARENT_SCOPE) endfunction(fpp_info) +function(fpp_autocoder_variables FPP_IMPORTS) + # Resolve the current binary directory. This is necessary because fpp tools run in the JVM. + # The JVM resolves all paths, and thus if a path is passed in unresolved form, fpp would see + # it as a different file. + set(CMAKE_CURRENT_BINARY_DIR_RESOLVED "${CMAKE_CURRENT_BINARY_DIR}") + resolve_path_variables(CMAKE_CURRENT_BINARY_DIR_RESOLVED) + # Read the locations from the global interface target. These are normalized when set as the property. + # We then convert this list to a comma-separated list for passing to FPP. + get_property(FPRIME_LOCATIONS TARGET "${FPRIME_GLOBAL_INTERFACE_TARGET}" PROPERTY FPRIME_LOCATIONS) + string(REGEX REPLACE ";" "," FPRIME_LOCATIONS_COMMA_SEP "${FPRIME_LOCATIONS}") + # fpp imports also need to be a comma-separated list + string(REGEX REPLACE ";" "," FPP_IMPORTS_COMMA_SEP "${FPP_IMPORTS}") + + # If imports exist, then we need to prepend the -i flag for fpp + set(IMPORT_FLAGS) + if (FPP_IMPORTS_COMMA_SEP) + set(IMPORT_FLAGS "-i" "${FPP_IMPORTS_COMMA_SEP}") + endif() + + # Now set the variables for the FPP autocoder in parent scope + set(FPP_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR_RESOLVED}" PARENT_SCOPE) + set(FPP_LOCATIONS_COMMA_SEP "${FPRIME_LOCATIONS_COMMA_SEP}" PARENT_SCOPE) + set(FPP_IMPORT_FLAGS "${IMPORT_FLAGS}" PARENT_SCOPE) +endfunction(fpp_autocoder_variables) + #### # Function `fpp_setup_autocode`: # @@ -201,16 +226,9 @@ function(fpp_setup_autocode MODULE_NAME AC_INPUT_FILES) message(FATAL_ERROR "fpp tools not found, please install them onto your system path") endif() fpp_info("${MODULE_NAME}" "${AC_INPUT_FILES}") - set(CMAKE_BINARY_DIR_RESOLVED "${CMAKE_BINARY_DIR}") - set(CMAKE_CURRENT_BINARY_DIR_RESOLVED "${CMAKE_CURRENT_BINARY_DIR}") - resolve_path_variables(CMAKE_BINARY_DIR_RESOLVED CMAKE_CURRENT_BINARY_DIR_RESOLVED) - string(REGEX REPLACE ";" "," FPRIME_BUILD_LOCATIONS_COMMA_SEP "${FPRIME_BUILD_LOCATIONS}") - string(REGEX REPLACE ";" "," FPP_IMPORTS_COMMA_SEP "${FPP_IMPORTS}") - set(IMPORTS) - if (FPP_IMPORTS_COMMA_SEP) - set(IMPORTS "-i" "${FPP_IMPORTS_COMMA_SEP}") - endif() - # Separate the source files into the CPP + fpp_autocoder_variables("${FPP_IMPORTS}") + + # Separate the source files into the various types generated by the fpp tools. set(GENERATED_CPP) set(GENERATED_DICT) foreach(GENERATED IN LISTS GENERATED_FILES) @@ -234,8 +252,8 @@ function(fpp_setup_autocode MODULE_NAME AC_INPUT_FILES) if (GENERATED_CPP) add_custom_command( OUTPUT ${GENERATED_CPP} - COMMAND ${FPP_TO_CPP} "-d" "${CMAKE_CURRENT_BINARY_DIR_RESOLVED}" ${IMPORTS} ${AC_INPUT_FILES} - "-p" "${FPRIME_BUILD_LOCATIONS_COMMA_SEP},${CMAKE_BINARY_DIR_RESOLVED}" + COMMAND ${FPP_TO_CPP} "-d" "${FPP_OUTPUT_DIRECTORY}" ${FPP_IMPORT_FLAGS} ${AC_INPUT_FILES} + "-p" "${FPP_LOCATIONS_COMMA_SEP}" DEPENDS ${FILE_DEPENDENCIES} ) endif() @@ -248,7 +266,7 @@ function(fpp_setup_autocode MODULE_NAME AC_INPUT_FILES) "--executable" "${FPP_TO_DICT}" "--cmake-bin-dir" "${CMAKE_CURRENT_BINARY_DIR}" "--jsonVersionFile" "${FPRIME_JSON_VERSION_FILE}" - ${IMPORTS} ${AC_INPUT_FILES} + ${FPP_IMPORT_FLAGS} ${AC_INPUT_FILES} DEPENDS ${FILE_DEPENDENCIES} ${FPRIME_JSON_VERSION_FILE} version_generate diff --git a/cmake/autocoder/fpp_ut.cmake b/cmake/autocoder/fpp_ut.cmake index 615220549aa..9b518f3fb51 100644 --- a/cmake/autocoder/fpp_ut.cmake +++ b/cmake/autocoder/fpp_ut.cmake @@ -32,19 +32,14 @@ function(fpp_ut_setup_autocode MODULE_NAME AC_INPUT_FILES) message(FATAL_ERROR "fpp tools not found, please install them onto your system path") endif() fpp_info("${MODULE_NAME}" "${AC_INPUT_FILES}") - string(REGEX REPLACE ";" "," FPRIME_BUILD_LOCATIONS_COMMA_SEP "${FPRIME_BUILD_LOCATIONS}") - string(REGEX REPLACE ";" "," FPP_IMPORTS_COMMA_SEP "${FPP_IMPORTS}") - set(IMPORTS) - if (FPP_IMPORTS_COMMA_SEP) - set(IMPORTS "-i" "${FPP_IMPORTS_COMMA_SEP}") - endif() + fpp_autocoder_variables("${FPP_IMPORTS}") # Separate the source files into the CPP set(GENERATED_AI) set(GENERATED_CPP) foreach(GENERATED IN LISTS UNITTEST_FILES) list(APPEND GENERATED_CPP "${GENERATED}") endforeach() - set(CLI_ARGS ${FPP_TO_CPP} "-u" "-d" "${CMAKE_CURRENT_BINARY_DIR}" ${IMPORTS} ${AC_INPUT_FILES} "-p" "${FPRIME_BUILD_LOCATIONS_COMMA_SEP},${CMAKE_BINARY_DIR}") + set(CLI_ARGS ${FPP_TO_CPP} "-u" "-d" "${FPP_OUTPUT_DIRECTORY}" ${FPP_IMPORT_FLAGS} ${AC_INPUT_FILES} "-p" "${FPP_LOCATIONS_COMMA_SEP}") get_target_property(UT_AUTO_HELPERS "${MODULE_NAME}" FPRIME_UT_AUTO_HELPERS) if (UT_AUTO_HELPERS) list(APPEND CLI_ARGS "-a") diff --git a/cmake/config_assembler.cmake b/cmake/config_assembler.cmake index 631a141be65..467d7944067 100644 --- a/cmake/config_assembler.cmake +++ b/cmake/config_assembler.cmake @@ -4,9 +4,7 @@ # CMake configuration handling function. #### include_guard() -# Create a target to act as an interface to all fprime configuration modules -set(FPRIME__INTERNAL_CONFIG_TARGET_NAME "__fprime_config" CACHE INTERNAL "Internal name of the config target" FORCE) -add_library(${FPRIME__INTERNAL_CONFIG_TARGET_NAME} INTERFACE) + #### # Function `fprime__internal_process_configuration_sources`: diff --git a/cmake/global_interface.cmake b/cmake/global_interface.cmake new file mode 100644 index 00000000000..99e56e5b28b --- /dev/null +++ b/cmake/global_interface.cmake @@ -0,0 +1,84 @@ +#### +# global_interface.cmake: +# +# This file provides an internal global interface target for use in the F Prime build system. Its job is to act as a +# singular target that has all the global properties that the build system requires. These include: +# +# 0. FPRIME_LOCATIONS: list of all "root" locations (source, binary) +# 1. FPRIME_SOURCE_LOCATIONS: list of all "root" locations of the project used for inferring target names. +# 2. FPRIME_BINARY_LOCATIONS: list of all binary equivalents of FPRIME_SOURCE_LOCATIONS in the build cache. +# 3. INTERFACE_INCLUDE_DIRECTORIES: list of all include directories that apply to all targets in the build system. +# a. These include all FPRIME_SOURCE_LOCATIONS, FPRIME_BINARY_LOCATIONS, and configuration directories +# 4. FPRIME_CHOSEN_IMPLEMENTATIONS: list of all chosen implementations for selectable build modules. +# +# The global interface target also links to all BASE_CONFIG configuration modules. This allows modules to depend on, +# and receive include directories for all base configurations. +# +# The target's name is stored in the FPRIME_GLOBAL_INTERFACE_TARGET cache variable and is available to all projects. +# Users must include this file to ensure that, should they be the first to need this target, it will be created. +# +# A global target is preferable to global properties as it has several advantages. First, it allows for transitive +# properties for things like include paths. Second, its F Prime properties can be used in generator expressions. +# +# CACHE VARIABLES: +# - FPRIME_GLOBAL_INTERFACE_TARGET: the name of the global interface target. Used when interfacing with the target +# +#### +include_guard() +include(utilities) +# Create a target for use as the global interface for cross-build properties. Then create a variable to store the name. +set(FPRIME_GLOBAL_INTERFACE_TARGET "__fprime_global_interface" CACHE INTERNAL "Target name of global interface" FORCE) +if (NOT TARGET ${FPRIME_GLOBAL_INTERFACE_TARGET}) + add_library(${FPRIME_GLOBAL_INTERFACE_TARGET} INTERFACE) +endif() + +#### +# Function `fprime_add_location_pair`: +# +# This function adds a source location and its corresponding binary location to the global interface target. This +# includes adding the SOURCE to FPRIME_SOURCE_LOCATIONS, the BINARY to FPRIME_BINARY_LOCATIONS and updating the +# INTERFACE_INCLUDE_DIRECTORIES and FPRIME_LOCATIONS property with both locations. +# +# Arguments: +# - `SOURCE`: the source location to add +# - `BINARY`: the binary location to add +# Returns: None +#### +function(fprime_add_location_pair SOURCE BINARY) + resolve_path_variables(SOURCE BINARY) + # First update the target properties with the appropriate locations. + append_list_property("${SOURCE}" TARGET "${FPRIME_GLOBAL_INTERFACE_TARGET}" PROPERTY FPRIME_SOURCE_LOCATIONS) + append_list_property("${BINARY}" TARGET "${FPRIME_GLOBAL_INTERFACE_TARGET}" PROPERTY FPRIME_BINARY_LOCATIONS) + append_list_property("${SOURCE}" TARGET "${FPRIME_GLOBAL_INTERFACE_TARGET}" PROPERTY FPRIME_LOCATIONS) + append_list_property("${BINARY}" TARGET "${FPRIME_GLOBAL_INTERFACE_TARGET}" PROPERTY FPRIME_LOCATIONS) + # Add source and binaries to the interface includes of our singular global interface target + target_include_directories("${FPRIME_GLOBAL_INTERFACE_TARGET}" INTERFACE "${SOURCE}") + target_include_directories("${FPRIME_GLOBAL_INTERFACE_TARGET}" INTERFACE "${BINARY}") +endfunction(fprime_add_location_pair) + +#### +# Function `fprime_add_historical_locations`: +# +# This function adds the list of historical locations to the global interface target. This is done for backwards +# compatibility with older versions of F Prime. This includes the following historical locations: +# - FPRIME_PROJECT_ROOT: the root source directory of the project, from settings.ini +# - FPRIME_FRAMEWORK_PATH: the source directory of the F Prime framework, from settings.ini +# - FPRIME_LIBRARY_LOCATIONS: the list of the library locations of the project, from settings.ini +# +# > [!WARNING] +# > This function and associated variables are deprecated. New projects and code should not use these variables. +# +# Arguments: None +# Returns: None +#### +function(fprime_add_historical_locations) + if (DEFINED FPRIME_PROJECT_ROOT) + fprime_add_location_pair("${FPRIME_PROJECT_ROOT}" "${CMAKE_BINARY_DIR}") + endif() + if (DEFINED FPRIME_FRAMEWORK_PATH) + fprime_add_location_pair("${FPRIME_FRAMEWORK_PATH}" "${CMAKE_BINARY_DIR}/F-Prime") + endif() + foreach(LIBRARY_LOCATION IN LISTS FPRIME_LIBRARY_LOCATIONS) + fprime_add_location_pair("${LIBRARY_LOCATION}" "${CMAKE_BINARY_DIR}") + endforeach() +endfunction(fprime_add_historical_locations) \ No newline at end of file diff --git a/cmake/options.cmake b/cmake/options.cmake index dcf0d96f090..9578a990415 100644 --- a/cmake/options.cmake +++ b/cmake/options.cmake @@ -33,7 +33,6 @@ if (FPRIME_LOADED_VIA_FIND_PACKAGE AND NOT DEFINED FPRIME_SETTINGS_FILE set(CMAKE_INSTALL_PREFIX "${PROJECT_SOURCE_DIR}/build-artifacts" CACHE PATH "Install dir" FORCE) endif() - #### # `CMAKE_TOOLCHAIN_FILE:` # diff --git a/cmake/sub-build/sub-build-config.cmake b/cmake/sub-build/sub-build-config.cmake index 23793c62e6b..b515338f19a 100644 --- a/cmake/sub-build/sub-build-config.cmake +++ b/cmake/sub-build/sub-build-config.cmake @@ -17,7 +17,6 @@ set(FPRIME_SUB_BUILD_EXCLUDED_CACHE_VARIABLES CMAKE_EDIT_COMMAND CMAKE_HOME_DIRECTORY CMAKE_INSTALL_NAME_TOOL - FPRIME_BUILD_LOCATIONS FPRIME_SUB_BUILD FPRIME_VERSION_SCRIPT CMAKE_C_COMPILER_FORCED diff --git a/cmake/target/sub-build/module_info.cmake b/cmake/target/sub-build/module_info.cmake index 472ffa154d2..09d8ec2f9ae 100644 --- a/cmake/target/sub-build/module_info.cmake +++ b/cmake/target/sub-build/module_info.cmake @@ -11,7 +11,6 @@ set(FPRIME__INTERNAL_PROPERTY_WRITER "${PYTHON}" "${CMAKE_CURRENT_LIST_DIR}/../t set(FPRIME__INTERNAL_CAT "${PYTHON}" "${CMAKE_CURRENT_LIST_DIR}/../tools/cat.py" CACHE INTERNAL "Internal helper for module_info to concatenate files" FORCE) - #### # Function `module_info_add_global_target`: # @@ -25,7 +24,11 @@ function(module_info_add_global_target CUSTOM_TARGET_NAME) add_custom_target("module_info" COMMAND "${FPRIME__INTERNAL_PROPERTY_WRITER}" "--file" "${MODULE_INFO_FILE}.part" SET GLOBAL PROPERTY FPRIME_BASE_CHOSEN_IMPLEMENTATIONS - "$" + "$" + COMMAND_EXPAND_LISTS + COMMAND "${FPRIME__INTERNAL_PROPERTY_WRITER}" "--file" "${MODULE_INFO_FILE}.part" "--append" + SET TARGET ${FPRIME_GLOBAL_INTERFACE_TARGET} PROPERTY FPRIME_SUB_BUILD_LOCATIONS + "$" COMMAND_EXPAND_LISTS COMMAND "${FPRIME__INTERNAL_CAT}" $ diff --git a/cmake/test/data/cmake/target/test_recursion.cmake b/cmake/test/data/cmake/target/test_recursion.cmake index 4c5acb81ba4..67627fa34a8 100644 --- a/cmake/test/data/cmake/target/test_recursion.cmake +++ b/cmake/test/data/cmake/target/test_recursion.cmake @@ -4,6 +4,7 @@ # This target sets up a test target for checking the right recursive dependencies come in #### include(utilities) +include(global_interface) # Current full dependency list for TestDeployment (mostly via Svc_CmdDispatcher) set(EXPECTED_FULL_DEPENDENCIES Fw @@ -61,7 +62,7 @@ set(EXPECTED_FULL_DEPENDENCIES TestLibrary_TestComponent UnixPlatformTypes Utils_Hash - __fprime_config + ${FPRIME_GLOBAL_INTERFACE_TARGET} default_config ) diff --git a/cmake/utilities.cmake b/cmake/utilities.cmake index 04a70bb24be..f4d99d400ee 100644 --- a/cmake/utilities.cmake +++ b/cmake/utilities.cmake @@ -4,6 +4,7 @@ # Utility and support functions for the fprime CMake build system. #### include_guard() +include(global_interface) set_property(GLOBAL PROPERTY C_CPP_ASM_REGEX ".*\.(c|cpp|cc|cxx|S|asm)$") #### @@ -252,16 +253,22 @@ endfunction() #### # Function `get_nearest_build_root`: # -# Finds the nearest build root from ${FPRIME_BUILD_LOCATIONS} that is a parent of DIRECTORY_PATH. +# Finds the nearest location in FPRIME_LOCATIONS to the given path. This is used for calculating module names, include +# paths, and relative asserts. FPRIME_LOCATIONS is derived from the global interface target. +# +# Note: historically these were called "build roots". # # - **DIRECTORY_PATH:** path to detect nearest build root -# Return: nearest parent from ${FPRIME_BUILD_LOCATIONS} +# Return: nearest parent from FPRIME_LOCATIONS as read from the global interface target property FPRIME_LOCATIONS #### function(get_nearest_build_root DIRECTORY_PATH) - get_filename_component(DIRECTORY_PATH "${DIRECTORY_PATH}" ABSOLUTE) + resolve_path_variables(DIRECTORY_PATH) set(FOUND_BUILD_ROOT "${DIRECTORY_PATH}") set(LAST_REL "${DIRECTORY_PATH}") - foreach(FPRIME_BUILD_LOC ${FPRIME_BUILD_LOCATIONS} ${CMAKE_BINARY_DIR}/F-Prime ${CMAKE_BINARY_DIR}) + + # Read the know locations (up to this point) and look for the closest one. + get_property(FPRIME_ALL_LOCATIONS TARGET "${FPRIME_GLOBAL_INTERFACE_TARGET}" PROPERTY FPRIME_LOCATIONS) + foreach(FPRIME_BUILD_LOC IN LISTS FPRIME_ALL_LOCATIONS) get_filename_component(FPRIME_BUILD_LOC "${FPRIME_BUILD_LOC}" ABSOLUTE) file(RELATIVE_PATH TEMP_MODULE ${FPRIME_BUILD_LOC} ${DIRECTORY_PATH}) string(LENGTH "${LAST_REL}" LEN1) @@ -271,11 +278,13 @@ function(get_nearest_build_root DIRECTORY_PATH) set(LAST_REL "${TEMP_MODULE}") endif() endforeach() + # Report when this file is not anchored under any known location. if ("${FOUND_BUILD_ROOT}" STREQUAL "${DIRECTORY_PATH}") message(FATAL_ERROR "No build root found for: ${DIRECTORY_PATH}") endif() set(FPRIME_CLOSEST_BUILD_ROOT "${FOUND_BUILD_ROOT}" PARENT_SCOPE) endfunction() + #### # Function `get_module_name`: # diff --git a/default/config/CMakeLists.txt b/default/config/CMakeLists.txt index 8955ca8f1ba..24b3430bbc8 100644 --- a/default/config/CMakeLists.txt +++ b/default/config/CMakeLists.txt @@ -40,4 +40,6 @@ register_fprime_config( "${CMAKE_CURRENT_LIST_DIR}/CRCCheckerConfig.hpp" "${CMAKE_CURRENT_LIST_DIR}/FileManagerConfig.hpp" BASE_CONFIG + DEPENDS + "${FPRIME_GLOBAL_INTERFACE_TARGET}" )