diff --git a/cmake/API.cmake b/cmake/API.cmake index dd89e4c3c3..a7688192e1 100644 --- a/cmake/API.cmake +++ b/cmake/API.cmake @@ -13,6 +13,7 @@ #### 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) #### # Function `add_fprime_subdirectory`: # @@ -423,7 +424,8 @@ endfunction(register_fprime_ut) macro(register_fprime_target TARGET_FILE_PATH) # Normal registered targets don't run in prescan if (NOT DEFINED FPRIME_PRESCAN) - register_fprime_target_helper("${TARGET_FILE_PATH}" FPRIME_TARGET_LIST) + register_fprime_list_helper("${TARGET_FILE_PATH}" FPRIME_TARGET_LIST) + setup_global_target("${TARGET_FILE_PATH}") endif() endmacro(register_fprime_target) @@ -438,35 +440,53 @@ endmacro(register_fprime_target) macro(register_fprime_ut_target TARGET_FILE_PATH) # UT targets only allowed when testing if (BUILD_TESTING AND NOT DEFINED FPRIME_PRESCAN) - register_fprime_target_helper("${TARGET_FILE_PATH}" FPRIME_UT_TARGET_LIST) + register_fprime_list_helper("${TARGET_FILE_PATH}" FPRIME_UT_TARGET_LIST) + setup_global_target("${TARGET_FILE_PATH}") endif() endmacro(register_fprime_ut_target) #### -# Macro `register_fprime_target_helper`: +# Macro `register_fprime_list_helper`: # # Helper function to do the actual registration. Also used to side-load prescan to bypass the not-on-prescan check. #### -macro(register_fprime_target_helper TARGET_FILE_PATH TARGET_LIST) +macro(register_fprime_list_helper TARGET_FILE_PATH TARGET_LIST) include("${TARGET_FILE_PATH}") # Prevent out-of-order setups get_property(MODULE_DETECTION_STARTED GLOBAL PROPERTY MODULE_DETECTION SET) if (MODULE_DETECTION_STARTED) message(FATAL_ERROR "Cannot register fprime target after including subdirectories or FPrime-Code.cmake'") endif() - # Get the target list to add this target to or use default - set(LIST_NAME FPRIME_TARGET_LIST) - if (${ARGC} GREATER 1) - set(LIST_NAME "${ARGV1}") - endif() get_property(TARGETS GLOBAL PROPERTY "${TARGET_LIST}") if (NOT TARGET_FILE_PATH IN_LIST TARGETS) - set_property(GLOBAL APPEND PROPERTY "${LIST_NAME}" "${TARGET_FILE_PATH}") - setup_global_target("${TARGET_FILE_PATH}") + set_property(GLOBAL APPEND PROPERTY "${TARGET_LIST}" "${TARGET_FILE_PATH}") endif() -endmacro(register_fprime_target_helper) +endmacro(register_fprime_list_helper) +#### +# Macro `register_fprime_build_autocoder`: +# +# This function allows users to register custom autocoders into the build system. These autocoders will execute during +# the build process. An autocoder is defined in a CMake file and must do three things: +# 1. Call one of `autocoder_setup_for_individual_sources()` or `autocoder_setup_for_multiple_sources()` from file scope +# 2. Implement `_is_supported(AC_POSSIBLE_INPUT_FILE)` returning true the autocoder processes given source +# 3. Implement `_setup_autocode AC_INPUT_FILE)` to run the autocoder on files filter by item 2. +# See: [Autocoders](dev/autocoder_integration.md). +# +# This function takes in either a file path to a CMake file defining an autocoder target, or an short include path that accomplishes +# the same thing. Note: make sure the directory is on the CMake include path to use the second form. +# +# **TARGET_FILE_PATH:** include path or file path file defining above functions +### +macro(register_fprime_build_autocoder TARGET_FILE_PATH) + # Normal registered targets don't run in prescan + message(STATUS "Registering custom autocoder: ${TARGET_FILE_PATH}") + if (NOT DEFINED FPRIME_PRESCAN) + register_fprime_list_helper("${TARGET_FILE_PATH}" FPRIME_AUTOCODER_TARGET_LIST) + endif() +endmacro(register_fprime_build_autocoder) + #### Documentation links # Next Topics: # - Setting Options: [Options](Options.md) are used to vary a CMake build. diff --git a/cmake/FPrime.cmake b/cmake/FPrime.cmake index e859782589..20d493a1b1 100644 --- a/cmake/FPrime.cmake +++ b/cmake/FPrime.cmake @@ -61,9 +61,10 @@ endforeach() include_directories("${FPRIME_FRAMEWORK_PATH}") include_directories("${FPRIME_CONFIG_DIR}") -# To prescan, either we register the prescan target or we run the prescan CMake +# To prescan,register target process around safety check if (DEFINED FPRIME_PRESCAN) - register_fprime_target_helper(target/prescan FPRIME_TARGET_LIST) + register_fprime_list_helper(target/prescan FPRIME_TARGET_LIST) + setup_global_target(target/prescan) else() perform_prescan() endif() @@ -71,6 +72,8 @@ endif() # FPP locations must come at the front of the list, then build register_fprime_target(target/fpp_locs) register_fprime_target(target/build) +register_fprime_build_autocoder(autocoder/fpp) +register_fprime_build_autocoder(autocoder/ai_xml) register_fprime_target(target/noop) register_fprime_target(target/version) register_fprime_target(target/dict) diff --git a/cmake/target/build.cmake b/cmake/target/build.cmake index 81f000bfde..366ba8f68f 100644 --- a/cmake/target/build.cmake +++ b/cmake/target/build.cmake @@ -114,7 +114,8 @@ endfunction() function(build_add_module_target MODULE TARGET SOURCES DEPENDENCIES) get_target_property(MODULE_TYPE "${MODULE}" FP_TYPE) message(STATUS "Adding ${MODULE_TYPE}: ${MODULE}") - run_ac_set("${SOURCES}" autocoder/fpp autocoder/ai_xml) + get_property(CUSTOM_AUTOCODERS GLOBAL PROPERTY FPRIME_AUTOCODER_TARGET_LIST) + run_ac_set("${SOURCES}" ${CUSTOM_AUTOCODERS}) resolve_dependencies(RESOLVED ${DEPENDENCIES} ${AC_DEPENDENCIES} ) build_setup_build_module("${MODULE}" "${SOURCES}" "${AC_GENERATED}" "${AC_SOURCES}" "${RESOLVED}") # Special flags applied to modules when compiling with testing enabled diff --git a/docs/UsersGuide/dev/target-integration.md b/docs/UsersGuide/dev/target-integration.md index 3823f3f347..98a4f77d19 100644 --- a/docs/UsersGuide/dev/target-integration.md +++ b/docs/UsersGuide/dev/target-integration.md @@ -11,7 +11,7 @@ globally. Module targets run on every module defining the `_register_fpr targets run on deployments defined with the `_register_fprime_deployment` calls, and global targets run once. Targets are CMake files that define three functions, one for each level, and are described below. The filename of this -CMake without the `.cmake` extension is determines the`` name. e.g. `utility.cmake` will define the `utility` +CMake without the `.cmake` extension determines the`` name. e.g. `utility.cmake` will define the `utility` target. Targets stages are defined in the following order: