|
9 | 9 | include_guard() |
10 | 10 | include(API) |
11 | 11 | 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() |
29 | 12 |
|
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() |
32 | 60 |
|
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) |
38 | 70 |
|
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.") |
47 | 74 | 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 | + |
53 | 86 | #### |
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. |
55 | 92 | # |
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. |
58 | 94 | # |
| 95 | +# Args: None |
| 96 | +# Returns: None |
59 | 97 | #### |
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}") |
64 | 112 | endmacro() |
0 commit comments