diff --git a/Fw/Types/CMakeLists.txt b/Fw/Types/CMakeLists.txt index 3698ad4edc6..25ac4b22926 100644 --- a/Fw/Types/CMakeLists.txt +++ b/Fw/Types/CMakeLists.txt @@ -17,7 +17,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_project_interface # Only module that should ever list _fprime_project_interface in DEPENDS. Use Fw_Types instead. REQUIRES_IMPLEMENTATIONS Fw_StringFormat Fw_StringScan diff --git a/cmake/API.cmake b/cmake/API.cmake index 3d9cb4eeaf3..73e51526281 100644 --- a/cmake/API.cmake +++ b/cmake/API.cmake @@ -20,11 +20,7 @@ include(fprime-util) 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`: @@ -469,16 +465,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}/..") + # Propagate config include directories to the unified interface target so they are available + # when reading INTERFACE_INCLUDE_DIRECTORIES directly (which is not transitive) + target_include_directories("${FPRIME_PROJECT_INTERFACE_TARGET}" INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/..") # The configuration target should depend on the new module if (INTERNAL_BASE_CONFIG) - target_link_libraries("${FPRIME__INTERNAL_CONFIG_TARGET_NAME}" INTERFACE "${INTERNAL_MODULE_NAME}") + target_link_libraries("${FPRIME_PROJECT_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_PROJECT_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) @@ -751,14 +750,18 @@ macro(register_fprime_project) # 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}") + + # Store source and binary locations as properties on the unified interface target + append_list_property("${CMAKE_CURRENT_SOURCE_DIR}" TARGET "${FPRIME_PROJECT_INTERFACE_TARGET}" PROPERTY FPRIME_SOURCE_LOCATIONS) + append_list_property("${CMAKE_CURRENT_BINARY_DIR}" TARGET "${FPRIME_PROJECT_INTERFACE_TARGET}" PROPERTY FPRIME_BINARY_LOCATIONS) + # Add source and binaries to the interface includes of the unified interface target + target_include_directories("${FPRIME_PROJECT_INTERFACE_TARGET}" INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}") + target_include_directories("${FPRIME_PROJECT_INTERFACE_TARGET}" INTERFACE "${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("$") + include_directories("$") # Update the CMAKE_MODULE_PATH for this particular project get_property(FPRIME_PROJECT_LOCATIONS GLOBAL PROPERTY FPRIME_PROJECT_LOCATIONS) diff --git a/cmake/FPrime.cmake b/cmake/FPrime.cmake index 42d1b6a2d62..fddeb863301 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(project_interface) include(config_assembler) include(fprime-util) @@ -42,6 +43,20 @@ set(FPRIME_BUILD_LOCATIONS "${FPRIME_FRAMEWORK_PATH}" ${FPRIME_LIBRARY_LOCATIONS list(REMOVE_DUPLICATES FPRIME_BUILD_LOCATIONS) resolve_path_variables(FPRIME_BUILD_LOCATIONS) +# Populate the unified project interface target with initial build locations +set(FPRIME_SOURCE_BUILD_LOCATIONS "${FPRIME_FRAMEWORK_PATH}" ${FPRIME_LIBRARY_LOCATIONS} "${FPRIME_PROJECT_ROOT}") +set(FPRIME_BINARY_BUILD_LOCATIONS "${CMAKE_BINARY_DIR}/F-Prime" "${CMAKE_BINARY_DIR}") +resolve_path_variables(FPRIME_SOURCE_BUILD_LOCATIONS) +resolve_path_variables(FPRIME_BINARY_BUILD_LOCATIONS) +foreach(LOC IN LISTS FPRIME_SOURCE_BUILD_LOCATIONS) + append_list_property("${LOC}" TARGET "${FPRIME_PROJECT_INTERFACE_TARGET}" PROPERTY FPRIME_SOURCE_LOCATIONS) + target_include_directories("${FPRIME_PROJECT_INTERFACE_TARGET}" INTERFACE "${LOC}") +endforeach() +foreach(LOC IN LISTS FPRIME_BINARY_BUILD_LOCATIONS) + append_list_property("${LOC}" TARGET "${FPRIME_PROJECT_INTERFACE_TARGET}" PROPERTY FPRIME_BINARY_LOCATIONS) + target_include_directories("${FPRIME_PROJECT_INTERFACE_TARGET}" INTERFACE "${LOC}") +endforeach() + # Message describing the fprime setup fprime_cmake_status("[FPRIME] Module locations: ${FPRIME_BUILD_LOCATIONS}") fprime_cmake_status("[FPRIME] Installation directory: ${CMAKE_INSTALL_PREFIX}") @@ -73,13 +88,8 @@ include(settings) # 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") + # Bridge the unified interface target include directories into the directory-scoped include path + include_directories("$") endfunction(fprime_setup_global_includes) #### diff --git a/cmake/autocoder/fpp.cmake b/cmake/autocoder/fpp.cmake index 53c172d1570..009cf567003 100644 --- a/cmake/autocoder/fpp.cmake +++ b/cmake/autocoder/fpp.cmake @@ -204,7 +204,16 @@ function(fpp_setup_autocode 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}") + get_target_property(FPRIME_SOURCE_LOCS "${FPRIME_PROJECT_INTERFACE_TARGET}" FPRIME_SOURCE_LOCATIONS) + get_target_property(FPRIME_BINARY_LOCS "${FPRIME_PROJECT_INTERFACE_TARGET}" FPRIME_BINARY_LOCATIONS) + if (NOT FPRIME_SOURCE_LOCS) + set(FPRIME_SOURCE_LOCS "") + endif() + if (NOT FPRIME_BINARY_LOCS) + set(FPRIME_BINARY_LOCS "") + endif() + set(FPRIME_BUILD_LOCS ${FPRIME_SOURCE_LOCS} ${FPRIME_BINARY_LOCS}) + string(REGEX REPLACE ";" "," FPRIME_INCLUDE_DIRS_COMMA_SEP "${FPRIME_BUILD_LOCS}") string(REGEX REPLACE ";" "," FPP_IMPORTS_COMMA_SEP "${FPP_IMPORTS}") set(IMPORTS) if (FPP_IMPORTS_COMMA_SEP) @@ -235,7 +244,7 @@ function(fpp_setup_autocode MODULE_NAME AC_INPUT_FILES) 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}" + "-p" "${FPRIME_INCLUDE_DIRS_COMMA_SEP}" DEPENDS ${FILE_DEPENDENCIES} ) endif() diff --git a/cmake/autocoder/fpp_ut.cmake b/cmake/autocoder/fpp_ut.cmake index 615220549aa..1c9c03bf6ef 100644 --- a/cmake/autocoder/fpp_ut.cmake +++ b/cmake/autocoder/fpp_ut.cmake @@ -32,7 +32,16 @@ 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}") + get_target_property(FPRIME_SOURCE_LOCS "${FPRIME_PROJECT_INTERFACE_TARGET}" FPRIME_SOURCE_LOCATIONS) + get_target_property(FPRIME_BINARY_LOCS "${FPRIME_PROJECT_INTERFACE_TARGET}" FPRIME_BINARY_LOCATIONS) + if (NOT FPRIME_SOURCE_LOCS) + set(FPRIME_SOURCE_LOCS "") + endif() + if (NOT FPRIME_BINARY_LOCS) + set(FPRIME_BINARY_LOCS "") + endif() + set(FPRIME_BUILD_LOCS ${FPRIME_SOURCE_LOCS} ${FPRIME_BINARY_LOCS}) + string(REGEX REPLACE ";" "," FPRIME_INCLUDE_DIRS_COMMA_SEP "${FPRIME_BUILD_LOCS}") string(REGEX REPLACE ";" "," FPP_IMPORTS_COMMA_SEP "${FPP_IMPORTS}") set(IMPORTS) if (FPP_IMPORTS_COMMA_SEP) @@ -44,7 +53,7 @@ function(fpp_ut_setup_autocode MODULE_NAME AC_INPUT_FILES) 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" "${CMAKE_CURRENT_BINARY_DIR}" ${IMPORTS} ${AC_INPUT_FILES} "-p" "${FPRIME_INCLUDE_DIRS_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..79972a5f56e 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) +include(project_interface) #### # Function `fprime__internal_process_configuration_sources`: diff --git a/cmake/project_interface.cmake b/cmake/project_interface.cmake new file mode 100644 index 00000000000..21a938f20f8 --- /dev/null +++ b/cmake/project_interface.cmake @@ -0,0 +1,24 @@ +#### +# project_interface.cmake: +# +# Defines the unified F Prime project interface target. This single INTERFACE library +# replaces both the global interface target (formerly in API.cmake) and the configuration +# interface target (formerly in config_assembler.cmake). It aggregates: +# +# - Global include directories (source and binary locations) +# - Build location properties (FPRIME_SOURCE_LOCATIONS, FPRIME_BINARY_LOCATIONS) +# - Configuration module dependencies and chosen implementations +# +# Custom target properties: +# FPRIME_SOURCE_LOCATIONS: list of source directories registered as build locations +# FPRIME_BINARY_LOCATIONS: list of binary directories registered as build locations +# FPRIME_CHOSEN_IMPLEMENTATIONS: list of chosen implementations from config modules +#### +include_guard() + +set(FPRIME_PROJECT_INTERFACE_TARGET "_fprime_project_interface" CACHE INTERNAL + "Unified F Prime project interface target" FORCE) + +if (NOT TARGET "${FPRIME_PROJECT_INTERFACE_TARGET}") + add_library("${FPRIME_PROJECT_INTERFACE_TARGET}" INTERFACE) +endif() diff --git a/cmake/target/sub-build/module_info.cmake b/cmake/target/sub-build/module_info.cmake index 472ffa154d2..2b894181f99 100644 --- a/cmake/target/sub-build/module_info.cmake +++ b/cmake/target/sub-build/module_info.cmake @@ -25,7 +25,7 @@ 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_CAT}" $ diff --git a/cmake/test/data/cmake/target/test_recursion.cmake b/cmake/test/data/cmake/target/test_recursion.cmake index 4c5acb81ba4..51ffe82b190 100644 --- a/cmake/test/data/cmake/target/test_recursion.cmake +++ b/cmake/test/data/cmake/target/test_recursion.cmake @@ -61,7 +61,7 @@ set(EXPECTED_FULL_DEPENDENCIES TestLibrary_TestComponent UnixPlatformTypes Utils_Hash - __fprime_config + _fprime_project_interface default_config ) diff --git a/cmake/utilities.cmake b/cmake/utilities.cmake index 04a70bb24be..d05d044a239 100644 --- a/cmake/utilities.cmake +++ b/cmake/utilities.cmake @@ -248,7 +248,6 @@ function(linker_only OUTPUT_VAR TOKEN) endfunction() - #### # Function `get_nearest_build_root`: # @@ -259,9 +258,19 @@ endfunction() #### function(get_nearest_build_root DIRECTORY_PATH) get_filename_component(DIRECTORY_PATH "${DIRECTORY_PATH}" ABSOLUTE) + # Read build locations from the unified project interface target + get_target_property(SOURCE_LOCS "${FPRIME_PROJECT_INTERFACE_TARGET}" FPRIME_SOURCE_LOCATIONS) + get_target_property(BINARY_LOCS "${FPRIME_PROJECT_INTERFACE_TARGET}" FPRIME_BINARY_LOCATIONS) + if (NOT SOURCE_LOCS) + set(SOURCE_LOCS "") + endif() + if (NOT BINARY_LOCS) + set(BINARY_LOCS "") + endif() + set(ALL_BUILD_LOCATIONS ${SOURCE_LOCS} ${BINARY_LOCS}) 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}) + foreach(FPRIME_BUILD_LOC IN LISTS ALL_BUILD_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)