Skip to content

Commit ddddd17

Browse files
committed
Fix #2289, implement common search routine for config files
2 parents eef72cc + 810d203 commit ddddd17

File tree

1 file changed

+101
-39
lines changed

1 file changed

+101
-39
lines changed

cmake/global_functions.cmake

+101-39
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,91 @@
33
# cFS Mission global CMake function definitions
44
#
55
# This is included by the top-level script and can define
6-
# common routines and variables that may be referenced in both
6+
# common routines and variables that may be referenced in both
77
# the mission (non-arch) and arch-specific builds
88
#
99
##################################################################
1010

1111
include(CMakeParseArguments)
1212

13+
##################################################################
14+
#
15+
# FUNCTION: cfe_locate_implementation_file
16+
#
17+
# The CFE/CFS build permits users to modify or tune system behavior by
18+
# providing customized versions of configuration files and tables.
19+
#
20+
# This function locates the preferred version of a file to use, by following
21+
# a priority-based search scheme. Users can put their preferred version of
22+
# a file in their MISSION_DEFS directory, based on a file naming convention.
23+
#
24+
# If no version of the file is found there, a default/fallback version can
25+
# be specified as well, which can be part of the module source.
26+
#
27+
function(cfe_locate_implementation_file OUTPUT_VAR FILE_NAME)
28+
29+
cmake_parse_arguments(LOCATEIMPL_ARG "OPTIONAL;ALLOW_LIST" "FALLBACK_FILE" "PREFIX;SUBDIR" ${ARGN})
30+
31+
# Always check for filename matches directly in the MISSION_DEFS dir
32+
set(IMPL_SEARCH_BASEDIRS "${MISSION_DEFS}/")
33+
# The prefix could also be a subdir, but do not repeat the mission name
34+
foreach (PREFIX ${LOCATEIMPL_ARG_PREFIX})
35+
if (NOT "${MISSIONCONFIG}" STREQUAL "${PREFIX}")
36+
list(APPEND IMPL_SEARCH_BASEDIRS "${MISSION_DEFS}/${PREFIX}/")
37+
endif()
38+
endforeach()
39+
set(ADD_SUBDIRS)
40+
foreach (SUBDIR ${LOCATEIMPL_ARG_SUBDIR})
41+
foreach (BASEDIR ${IMPL_SEARCH_BASEDIRS})
42+
list(APPEND ADD_SUBDIRS "${BASEDIR}${SUBDIR}/")
43+
endforeach()
44+
endforeach()
45+
list(APPEND IMPL_SEARCH_BASEDIRS ${ADD_SUBDIRS})
46+
47+
# Build the list of possible locations for this file in REVERSE priority order
48+
set(IMPL_SEARCH_PATH)
49+
if (LOCATEIMPL_ARG_FALLBACK_FILE)
50+
if (IS_ABSOLUTE "${LOCATEIMPL_ARG_FALLBACK_FILE}")
51+
list(APPEND IMPL_SEARCH_PATH "${LOCATEIMPL_ARG_FALLBACK_FILE}")
52+
else()
53+
list(APPEND IMPL_SEARCH_PATH "${CMAKE_CURRENT_LIST_DIR}/${LOCATEIMPL_ARG_FALLBACK_FILE}")
54+
endif()
55+
endif()
56+
57+
# Check for the existence of the file in each of the dirs
58+
foreach(BASEDIR ${IMPL_SEARCH_BASEDIRS})
59+
list(APPEND IMPL_SEARCH_PATH "${BASEDIR}${FILE_NAME}")
60+
61+
# A target-specific prefixed filename gets priority over a direct filename match
62+
# But do not include this variant if the prefix is already part of the basedir
63+
foreach (PREFIX ${LOCATEIMPL_ARG_PREFIX})
64+
if (NOT "${BASEDIR}" MATCHES "/${PREFIX}/")
65+
list(APPEND IMPL_SEARCH_PATH "${BASEDIR}${PREFIX}_${FILE_NAME}")
66+
endif()
67+
endforeach()
68+
endforeach()
69+
70+
set(SELECTED_FILE)
71+
foreach (CHECK_FILE ${IMPL_SEARCH_PATH})
72+
if (EXISTS "${CHECK_FILE}")
73+
list(APPEND SELECTED_FILE ${CHECK_FILE})
74+
endif()
75+
endforeach()
76+
77+
if (SELECTED_FILE)
78+
message(STATUS "Using file: ${SELECTED_FILE} for ${FILE_NAME}")
79+
elseif(NOT LOCATEIMPL_ARG_OPTIONAL)
80+
message(FATAL_ERROR "No implementation for ${FILE_NAME} found")
81+
endif()
82+
83+
# Export the result to the caller
84+
if (NOT LOCATEIMPL_ARG_ALLOW_LIST AND SELECTED_FILE)
85+
list(GET SELECTED_FILE -1 SELECTED_FILE)
86+
endif()
87+
set(${OUTPUT_VAR} ${SELECTED_FILE} PARENT_SCOPE)
88+
89+
endfunction()
90+
1391
##################################################################
1492
#
1593
# FUNCTION: generate_c_headerfile
@@ -78,48 +156,32 @@ function(generate_config_includefile)
78156
set(GENCONFIG_ARG_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/inc")
79157
endif (NOT GENCONFIG_ARG_OUTPUT_DIRECTORY)
80158

81-
set(WRAPPER_FILE_CONTENT)
82-
set(ITEM_FOUND FALSE)
159+
if (IS_CFS_ARCH_BUILD)
160+
set(ARCH_PREFIXES ${BUILD_CONFIG})
161+
else()
162+
set(ARCH_PREFIXES)
163+
endif()
83164

84-
# Assemble a list of file names to test for
85-
# Check for existence of a file in defs directory with an exact matching name
86-
# Then Check for existence of file(s) with a matching prefix+suffix
87-
set(CHECK_PATH_LIST "${MISSION_DEFS}/${GENCONFIG_ARG_FILE_NAME}")
88165
if (GENCONFIG_ARG_MATCH_SUFFIX)
89-
foreach(PREFIX ${GENCONFIG_ARG_PREFIXES} ${GENCONFIG_ARG_UNPARSED_ARGUMENTS})
90-
list(APPEND CHECK_PATH_LIST "${MISSION_DEFS}/${PREFIX}_${GENCONFIG_ARG_MATCH_SUFFIX}")
91-
endforeach()
92-
endif(GENCONFIG_ARG_MATCH_SUFFIX)
93-
94-
# Check for existence of files, and add to content if present
95-
# Note that all files are appended/concatenated together.
96-
foreach(SRC_LOCAL_PATH ${CHECK_PATH_LIST})
97-
if (EXISTS "${SRC_LOCAL_PATH}")
98-
file(TO_NATIVE_PATH "${SRC_LOCAL_PATH}" SRC_NATIVE_PATH)
99-
list(APPEND WRAPPER_FILE_CONTENT "#include \"${SRC_NATIVE_PATH}\"\n")
100-
set(ITEM_FOUND TRUE)
101-
else()
102-
list(APPEND WRAPPER_FILE_CONTENT "/* ${SRC_LOCAL_PATH} does not exist */\n")
103-
endif (EXISTS "${SRC_LOCAL_PATH}")
104-
endforeach()
105-
106-
# If _no_ files were found in the above loop,
107-
# then check for and use the fallback file.
108-
# (if specified by the caller it should always exist)
109-
# Also produce a message on the console showing whether mission config or fallback was used
110-
if (ITEM_FOUND)
111-
message(STATUS "Generated ${GENCONFIG_ARG_FILE_NAME} from ${MISSION_DEFS} configuration")
112-
elseif (GENCONFIG_ARG_FALLBACK_FILE)
113-
file(TO_NATIVE_PATH "${GENCONFIG_ARG_FALLBACK_FILE}" SRC_NATIVE_PATH)
114-
list(APPEND WRAPPER_FILE_CONTENT
115-
"\n\n/* No configuration for ${GENCONFIG_ARG_FILE_NAME}, using fallback */\n"
116-
"#include \"${GENCONFIG_ARG_FALLBACK_FILE}\"\n")
117-
message(STATUS "Using ${GENCONFIG_ARG_FALLBACK_FILE} for ${GENCONFIG_ARG_FILE_NAME}")
166+
set(TGTFILE ${GENCONFIG_ARG_MATCH_SUFFIX})
118167
else()
119-
message("ERROR: No implementation for ${GENCONFIG_ARG_FILE_NAME} found")
120-
message(FATAL_ERROR "Tested: ${CHECK_PATH_LIST}")
168+
set(TGTFILE ${GENCONFIG_ARG_FILE_NAME})
121169
endif()
122170

171+
# Use the common search function to find the candidate(s)
172+
cfe_locate_implementation_file(SRC_LOCAL_PATH_LIST "${TGTFILE}"
173+
ALLOW_LIST
174+
FALLBACK_FILE "${GENCONFIG_ARG_FALLBACK_FILE}"
175+
PREFIX ${GENCONFIG_ARG_PREFIXES} ${ARCH_PREFIXES}
176+
SUBDIR config
177+
)
178+
179+
set(WRAPPER_FILE_CONTENT)
180+
foreach(SELECTED_FILE ${SRC_LOCAL_PATH_LIST})
181+
file(TO_NATIVE_PATH "${SELECTED_FILE}" SRC_NATIVE_PATH)
182+
list(APPEND WRAPPER_FILE_CONTENT "#include \"${SRC_NATIVE_PATH}\"\n")
183+
endforeach()
184+
123185
# Generate a header file
124186
generate_c_headerfile("${GENCONFIG_ARG_OUTPUT_DIRECTORY}/${GENCONFIG_ARG_FILE_NAME}" ${WRAPPER_FILE_CONTENT})
125187

@@ -139,7 +201,7 @@ endfunction(generate_config_includefile)
139201
#
140202
# This function then sets up the following variables in the global scope:
141203
# TGTSYS_LIST: list of CPU architectures used in the build. Note this
142-
# will always contain a "native" target (for tools at least) which
204+
# will always contain a "native" target (for tools at least) which
143205
# is forced to be last.
144206
# MISSION_APPS: list of all applications in this build
145207
# MISSION_PSPMODULES: list of all psp modules in this build

0 commit comments

Comments
 (0)