Skip to content

Commit 12c6e71

Browse files
committed
WIP: almost building
1 parent 02da0ba commit 12c6e71

4 files changed

Lines changed: 105 additions & 63 deletions

File tree

cmake/API.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,7 @@ endfunction()
743743
# Args: none
744744
#####
745745
macro(register_fprime_project)
746+
fprime_initialize_build_system() # Make sure the build system is initialized before registering the project
746747
# Typically it is an error to call register_fprime_project outside the root CMakeLists.txt of a defined `project()`
747748
if (NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
748749
fprime_cmake_warning("register_fprime_project not called in CMakeLists.txt containing a project() declaration")

cmake/FPrime.cmake

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,6 @@ include(required)
1818
include(config_assembler)
1919
include(fprime-util)
2020

21-
# Add project root's cmake folder to module path
22-
# TODO:mstarch:TODO: this refers to the GLOBAL project's root....but is it needed in a world where we could just detect if the CMAKE PROJECT refers to such a place?
23-
if (IS_DIRECTORY "${FPRIME_PROJECT_ROOT}/cmake")
24-
list(APPEND CMAKE_MODULE_PATH "${FPRIME_PROJECT_ROOT}/cmake")
25-
endif()
26-
2721
# Setup fprime library locations
2822
list(REMOVE_DUPLICATES FPRIME_LIBRARY_LOCATIONS)
2923

@@ -44,6 +38,7 @@ fprime_cmake_status("[FPRIME] Module locations: ${FPRIME_BUILD_LOCATIONS}")
4438
fprime_cmake_status("[FPRIME] Installation directory: ${CMAKE_INSTALL_PREFIX}")
4539
include(platform/platform) # Now that module locations are known, load platform settings
4640

41+
4742
# Module setup functions, attaches targets to modules, etc.
4843
include(module)
4944
# Support for autocoder implementations
@@ -145,6 +140,12 @@ macro(fprime_setup_override_targets)
145140
endmacro(fprime_setup_override_targets)
146141

147142
macro(fprime_initialize_build_system)
143+
# Ensure that the build system is loaded only once
144+
get_property(FPRIME_BUILD_SYSTEM_LOADED GLOBAL PROPERTY FPRIME_BUILD_SYSTEM_LOADED)
145+
if (FPRIME_BUILD_SYSTEM_LOADED)
146+
return()
147+
endif()
148+
148149
cmake_minimum_required(VERSION 3.16)
149150
fprime_setup_global_includes()
150151
fprime_detect_libraries()
@@ -174,6 +175,7 @@ endmacro(fprime_initialize_build_system)
174175
function(fprime_setup_included_code)
175176
# Must be done before code is registered but after custom target registration
176177
setup_global_targets()
178+
fprime_setup_platform()
177179
# For BUILD_TESTING builds then set up libraries that support testing
178180
if (BUILD_TESTING AND NOT DEFINED FPRIME_SUB_BUILD_TARGETS)
179181
if (NOT EXISTS "${FPRIME_FRAMEWORK_PATH}/googletest/CMakeLists.txt")
@@ -205,7 +207,9 @@ function(fprime_setup_included_code)
205207
# add_fprime_subdirectory cannot be run until later in the build process. Otherwise detection
206208
# for model specific post processing is messed up. Thus we synthesize the behavior by setting
207209
# the current module and then calling stock "add_subdirectory".
208-
fprime__include_platform_file()
210+
211+
212+
209213
# Add "all" target to top level and a target to match all tests
210214
fprime_util_metadata_add_build_target("all")
211215
if (BUILD_TESTING)
@@ -235,10 +239,3 @@ function(fprime_setup_included_code)
235239
# Always enable UTs for a project
236240
set(__FPRIME_NO_UT_GEN__ OFF)
237241
endfunction(fprime_setup_included_code)
238-
239-
240-
# Load the build system exactly one time
241-
get_property(FPRIME_BUILD_SYSTEM_LOADED GLOBAL PROPERTY FPRIME_BUILD_SYSTEM_LOADED)
242-
if (NOT FPRIME_BUILD_SYSTEM_LOADED)
243-
fprime_initialize_build_system()
244-
endif ()

cmake/options.cmake

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -338,11 +338,7 @@ include(CTest)
338338
####
339339
if (DEFINED FPRIME_FRAMEWORK_PATH)
340340
fprime_cmake_warning("DEPRECATED: FPRIME_FRAMEWORK_PATH should no longer be set.")
341-
get_filename_component(FPRIME_FRAMEWORK_PATH "${FPRIME_FRAMEWORK_PATH}" ABSOLUTE)
342-
# Sanity check the framework path as supplied
343-
if (NOT FPRIME_FRAMEWORK_PATH STREQUAL DETECTED_FRAMEWORK_PATH)
344-
message(FATAL_ERROR "Inconsistent FPrime location: ${FPRIME_FRAMEWORK_PATH}. Check settings.ini")
345-
endif()
341+
get_filename_component(FPRIME_FRAMEWORK_PATH "${FPRIME_FRAMEWORK_PATH}" ABSOLUTE)
346342
endif()
347343

348344
# If defined then force it to be absolute

cmake/platform/platform.cmake

Lines changed: 92 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,56 +9,104 @@
99
include_guard()
1010
include(API)
1111
include(utilities)
12-
# Basic definitions
13-
get_filename_component(TOOLCHAIN_NAME "${CMAKE_TOOLCHAIN_FILE}" NAME_WE)
14-
# Native toolchains use the system name for the toolchain and FPRIME_PLATFORM
15-
if (NOT TOOLCHAIN_NAME)
16-
set(TOOLCHAIN_NAME "${CMAKE_SYSTEM_NAME}")
17-
set(FPRIME_PLATFORM "${CMAKE_SYSTEM_NAME}")
18-
# It is an error to use a "Generic" toolchain without setting FPRIME_PLATFORM correctly
19-
elseif (CMAKE_SYSTEM_NAME STREQUAL "Generic" AND NOT FPRIME_PLATFORM)
20-
message(FATAL_ERROR "Toolchain '${TOOLCHAIN_NAME}' set CMAKE_SYSTEM_NAME to 'Generic' without setting FPRIME_PLATFORM")
21-
# It is an error to set neither of CMAKE_SYSTEM_NAME and FPRIME_PLATFORM
22-
elseif (NOT CMAKE_SYSTEM_NAME AND NOT FPRIME_PLATFORM)
23-
message(FATAL_ERROR "Toolchain '${TOOLCHAIN_NAME}' should set CMAKE_SYSTEM_NAME to 'Generic' and set FPRIME_PLATFORM")
24-
# Fallback to CMAKE_SYSTEM_NAME when only CMAKE_SYSTEM_NAME is set
25-
elseif (NOT FPRIME_PLATFORM)
26-
message(WARNING "Toolchain '${TOOLCHAIN_NAME}' should set CMAKE_SYSTEM_NAME to 'Generic' and set FPRIME_PLATFORM")
27-
set(FPRIME_PLATFORM "${CMAKE_SYSTEM_NAME}")
28-
endif()
2912

30-
# Include platform file based on system name
31-
fprime_cmake_status("Target build toolchain/platform: ${TOOLCHAIN_NAME}/${FPRIME_PLATFORM}")
13+
####
14+
# Function `fprime_validate_platform`:
15+
#
16+
# This function validates the platform setting set by the toolchain file. It ensures that the toolchain file is
17+
# correctly written. When there is not toolchain file, it sets the TOOLCHAIN_NAME and FPRIME_PLATFORM variables in
18+
# the CMake Cache so that the system can use them.
19+
#
20+
# Args: None
21+
# Returns: None
22+
####
23+
function(fprime__validate_platform)
24+
get_filename_component(TOOLCHAIN_NAME "${CMAKE_TOOLCHAIN_FILE}" NAME_WE)
25+
# Native toolchains use the system name for the toolchain and FPRIME_PLATFORM
26+
if (NOT TOOLCHAIN_NAME)
27+
set(TOOLCHAIN_NAME "${CMAKE_SYSTEM_NAME}" CACHE INTERNAL "Set the toolchain name to the system name for native builds" FORCE)
28+
set(FPRIME_PLATFORM "${CMAKE_SYSTEM_NAME}" CACHE INTERNAL "Set the platform name to the system name for native builds" FORCE)
29+
# It is an error to use a "Generic" toolchain without setting FPRIME_PLATFORM correctly
30+
elseif (CMAKE_SYSTEM_NAME STREQUAL "Generic" AND NOT FPRIME_PLATFORM)
31+
message(FATAL_ERROR "Toolchain '${TOOLCHAIN_NAME}' set CMAKE_SYSTEM_NAME to 'Generic' without setting FPRIME_PLATFORM")
32+
# It is an error to set neither of CMAKE_SYSTEM_NAME and FPRIME_PLATFORM
33+
elseif (NOT CMAKE_SYSTEM_NAME AND NOT FPRIME_PLATFORM)
34+
message(FATAL_ERROR "Toolchain '${TOOLCHAIN_NAME}' should set CMAKE_SYSTEM_NAME to 'Generic' and set FPRIME_PLATFORM")
35+
# Fallback to CMAKE_SYSTEM_NAME when only CMAKE_SYSTEM_NAME is set
36+
elseif (NOT FPRIME_PLATFORM)
37+
message(WARNING "Toolchain '${TOOLCHAIN_NAME}' should set CMAKE_SYSTEM_NAME to 'Generic' and set FPRIME_PLATFORM")
38+
set(FPRIME_PLATFORM "${CMAKE_SYSTEM_NAME}" CACHE INTERNAL "Set the platform name to the system name for random toolchain builds" FORCE)
39+
endif()
40+
endfunction()
41+
42+
####
43+
# Function `fprime_find_platform_file`:
44+
#
45+
# Loop through the standard locations for a platform file (**/cmake/platform/${FPRIME_PLATFORM}.cmake) and select the
46+
# first one. If multiple are found, warn the user and use the first one. If none are found, error and exit. The results
47+
# are cached in FPRIME_CACHED_PLATFORM_FILE to avoid re-searching for the platform file.
48+
#
49+
# Args: None
50+
# Returns: None
51+
####
52+
function(fprime_find_platform_file)
53+
fprime_cmake_assert("FPRIME_PLATFORM changed. Please regenerate the build cache." FPRIME_PLATFORM STREQUAL FPRIME_CACHED_PLATFORM OR NOT DEFINED FPRIME_CACHED_PLATFORM)
54+
55+
# Use the cached platform file to avoid the expense of glob-searching for platform files again
56+
if (DEFINED FPRIME_CACHED_PLATFORM_FILE)
57+
set(FOUND_PLATFORM_FILE "${FPRIME_CACHED_PLATFORM_FILE}" PARENT_SCOPE)
58+
return()
59+
endif()
3260

33-
# Output directories
34-
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/${TOOLCHAIN_NAME}")
35-
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/${TOOLCHAIN_NAME}")
36-
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/${TOOLCHAIN_NAME}")
37-
set(EXPECTED_PLATFORM_FILE "")
61+
set(EXPECTED_PLATFORM_FILE)
62+
set(FOUND_PLATFORM_FILE)
63+
file(GLOB_RECURSE POSSIBLE_PLATFORM_FILES
64+
"${FPRIME_GLOBAL_PROJECT_PATH}/*/cmake/platform/${FPRIME_PLATFORM}.cmake"
65+
"${FPRIME_FRAMEWORK_PATH}/cmake/platform/${FPRIME_PLATFORM}.cmake"
66+
${FPRIME_LIBRARY_DECLARATION_SEARCH_PATHS}
67+
)
68+
list(REMOVE_DUPLICATES POSSIBLE_PLATFORM_FILES)
69+
list(LENGTH POSSIBLE_PLATFORM_FILES NUM_POSSIBLE_PLATFORM_FILES)
3870

39-
# Loop over locations of platform files in order: project, libraries, then framework
40-
# TODO:mstarch:TODO: this refers to the GLOBAL project's root, but could be replaced with a loop over build locations or something indicating a list of all projects' roots
41-
foreach(ROOT ${FPRIME_PROJECT_ROOT};${FPRIME_LIBRARY_LOCATIONS};${FPRIME_FRAMEWORK_PATH} )
42-
set(EXPECTED_PLATFORM_FILE "${ROOT}/cmake/platform/${FPRIME_PLATFORM}.cmake")
43-
# Include host machine settings
44-
if (EXISTS "${EXPECTED_PLATFORM_FILE}")
45-
set_property(GLOBAL PROPERTY FPRIME_PLATFORM_FILE "${EXPECTED_PLATFORM_FILE}")
46-
break()
71+
# Check if any platform file was found
72+
if (NUM_POSSIBLE_PLATFORM_FILES EQUAL 0)
73+
fprime_cmake_fatal_error("No platform config for '${FPRIME_PLATFORM}'. Please create: '${FPRIME_PLATFORM}.cmake' or declare_fprime_library for non-standard library locations.")
4774
endif()
48-
endforeach()
49-
# Ensure the last attempt for the platform file was successful, otherwise error.
50-
if (NOT EXISTS "${EXPECTED_PLATFORM_FILE}")
51-
message(FATAL_ERROR "\n[F-PRIME] No platform config for '${FPRIME_PLATFORM}'. Please create: '${FPRIME_PLATFORM}.cmake'\n")
52-
endif()
75+
# Grab the first platform file found and warn if multiple were available
76+
list(GET POSSIBLE_PLATFORM_FILES 0 FIRST_FOUND_PLATFORM_FILE)
77+
if (NUM_POSSIBLE_PLATFORM_FILES GREATER 1)
78+
fprime_cmake_warning("Multiple '${FPRIME_PLATFORM}.cmake' files found: ${POSSIBLE_PLATFORM_FILES}. Using '${FIRST_FOUND_PLATFORM_FILE}'")
79+
endif()
80+
81+
# Cache the results to prevent churn on re-scanning the directory
82+
set(FPRIME_CACHED_PLATFORM "${FPRIME_PLATFORM}" CACHE INTERNAL "Cache the platform for validation and to avoid re-searching for the platform file")
83+
set(FPRIME_CACHED_PLATFORM_FILE "${FIRST_FOUND_PLATFORM_FILE}" CACHE INTERNAL "Cache the platform file for validation and to avoid re-searching for the platform file")
84+
endfunction()
85+
5386
####
54-
# Macro `fprime__include_platform_file`:
87+
# Macro `fprime_setup_platform`:
88+
#
89+
# This macro is the main entry point for setting up the platform. It validates the platform settings, finds the
90+
# platform file, and includes it to set up the platform for the build. It also handles some left-over toolchain
91+
# processing by setting output directories and printing the toolchain information.
5592
#
56-
# Callback function to include the platform file and set up the platform specific module. Defined as a macro so the set variables
57-
# exist in calling scope.
93+
# NOTE: this is a macro so that the included file is included in the scope of the caller.
5894
#
95+
# Args: None
96+
# Returns: None
5997
####
60-
macro(fprime__include_platform_file)
61-
get_property(EXPECTED_PLATFORM_FILE GLOBAL PROPERTY FPRIME_PLATFORM_FILE)
62-
fprime_cmake_status("Including ${EXPECTED_PLATFORM_FILE}")
63-
include("${EXPECTED_PLATFORM_FILE}")
98+
macro(fprime_setup_platform)
99+
fprime__validate_platform()
100+
fprime_find_platform_file()
101+
102+
# Output directories internal to the build cache should be relative to the toolchain
103+
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/${TOOLCHAIN_NAME}")
104+
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/${TOOLCHAIN_NAME}")
105+
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/${TOOLCHAIN_NAME}")
106+
107+
# Include platform file based on system name
108+
fprime_cmake_status("Target build toolchain/platform: ${TOOLCHAIN_NAME}/${FPRIME_CACHED_PLATFORM}")
109+
fprime_cmake_debug_message("Toolchain file: ${CMAKE_TOOLCHAIN_FILE}")
110+
fprime_cmake_debug_message("Platform file: ${FPRIME_CACHED_PLATFORM_FILE}")
111+
include("${FPRIME_CACHED_PLATFORM_FILE}")
64112
endmacro()

0 commit comments

Comments
 (0)