Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #1170, refactor target config objects #1174

Merged
merged 1 commit into from
Mar 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions cmake/generate_build_env.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
##################################################################
#
# cFS version metadata collection script
#
# This small script runs at build time (as opposed to prep time)
# and is intended to extract information about the current
# build environment - this may change after initial makefile creation
#
##################################################################

# All 3 of these may be passed via environment variables to force a particular
# date, user, or hostname i.e. if hoping to reproduce an exact binary of a prior build
# They are free-form strings, will be built/linked into the final CONFIGDATA object.

# Get the current date and time
set(BUILDDATE $ENV{BUILDDATE})
if (NOT BUILDDATE)
execute_process(
COMMAND date "+%Y%m%d%H%M"
OUTPUT_VARIABLE BUILDDATE
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif(NOT BUILDDATE)

# Get the build host
set(BUILDHOST $ENV{HOSTNAME})
if (NOT BUILDHOST)
execute_process(
COMMAND hostname
OUTPUT_VARIABLE BUILDHOST
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif (NOT BUILDHOST)

# Get the user ID
set(BUILDUSER $ENV{USER})
if (NOT BUILDUSER)
execute_process(
COMMAND whoami
OUTPUT_VARIABLE BUILDUSER
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif (NOT BUILDUSER)

# Use configure_file() command to generate the final output file because this can detect
# and only update it if it changes.
set(CFE_KEYVALUE_TABLE_NAME "CFE_BUILD_ENV_TABLE")
configure_file(${BIN}/cfe_build_env.in ${BIN}/src/cfe_build_env_table.c @ONLY)
75 changes: 75 additions & 0 deletions cmake/generate_git_module_version.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
##################################################################
#
# cFS version metadata collection script
#
# This small script runs at build time (as opposed to prep time)
# and is intended to extract version metadata from the current source
# tree. It is done each time that the code is built, since the
# metadata could change at any time (i.e. a different branch could
# be checked out, or additional changes committed)
#
# Currently only git is supported as a version control source, however
# it could be extended to others by adding the appropriate command
#
##################################################################

set(GIT_EXECUTABLE git)

function(get_version DEP)
if (DEP STREQUAL "MISSION")
set(NAME ${MISSION_NAME})
set(DIR ${MISSION_SOURCE_DIR})
else()
if(EXISTS ${${DEP}_MISSION_DIR}/version_info.cmake)
include(${${DEP}_MISSION_DIR}/version_info.cmake)
else()
set(NAME ${DEP})
endif()
set(DIR ${${DEP}_MISSION_DIR})
endif()
message("inside get_version for ${DEP}")
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --tags --always --dirty
WORKING_DIRECTORY ${DIR}
OUTPUT_VARIABLE GIT_DESC_OUTPUT
RESULT_VARIABLE GIT_RESULT
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)

# Export output to parent scope
set(${DEP}_NAME "${NAME}" PARENT_SCOPE)

# If result was successful, then string-ify it, otherwise use NULL
if (GIT_RESULT EQUAL 0)
set(${DEP}_VERSION "\"git:${GIT_DESC_OUTPUT}\"" PARENT_SCOPE)
else()
set(${DEP}_VERSION "NULL" PARENT_SCOPE)
endif()

endfunction()


# First read in any variables that are passed in from the parent process
# There may be many of these and they may not all be passable via -D options
file(STRINGS "${BIN}/mission_vars.cache" PARENTVARS)
set(VARNAME)
foreach(PV ${PARENTVARS})
if (VARNAME)
set(${VARNAME} ${PV})
set(VARNAME)
else()
set(VARNAME ${PV})
endif()
endforeach(PV ${PARENTVARS})

# Get version for all mission apps/dependencies (they may be different)
foreach(DEP "MISSION" ${MISSION_DEPS})
get_version(${DEP})
endforeach()


# Use configure_file() command to generate the final output file because this can detect
# and only update it if it changes.
set(CFE_KEYVALUE_TABLE_NAME "CFE_MODULE_VERSION_TABLE")
configure_file(${BIN}/cfe_module_version.in ${BIN}/src/cfe_module_version_table.c @ONLY)
102 changes: 91 additions & 11 deletions cmake/mission_build.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,95 @@ function(initialize_globals)

endfunction(initialize_globals)

##################################################################
#
# FUNCTION: generate_build_version_templates
#
# Generates file templates for use with configure_file() which is
# invoked at build time to get the required information.
#
# Note that some information may change between generation and build
# times, hence why only a template can be generated here, the final
# file content must be generated via a build rule.
#
function(generate_build_version_templates)

# File header for build info template (tag file as auto-generated)
string(CONCAT GENERATED_FILE_HEADER
"/* This file is auto-generated from CMake build system. Do not manually edit! */\n"
"#include \"target_config.h\"\n"
"const CFE_ConfigKeyValue_t @CFE_KEYVALUE_TABLE_NAME@[] = {\n"
)

# File trailer for build info template
string(CONCAT GENERATED_FILE_TRAILER
"{ NULL, NULL } /* End of list */\n"
"};\n"
"/* End of file */\n"
)

# These variables are deferred until build time
foreach (VAR BUILDDATE BUILDUSER BUILDHOST)
list (APPEND GENERATED_FILE_CONTENT "{ \"${VAR}\", \"@${VAR}@\" },")
endforeach ()
string(REPLACE ";" "\n" GENERATED_FILE_CONTENT "${GENERATED_FILE_CONTENT}")

# Write a template for build/config information
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/cfe_generated_file.h.in ${CMAKE_BINARY_DIR}/cfe_build_env.in)

# Content for version info - all are deferred until build time
set(GENERATED_FILE_CONTENT)
foreach(DEP "MISSION" ${MISSION_DEPS})
list (APPEND GENERATED_FILE_CONTENT "{ \"${DEP}\", @${DEP}_VERSION@ },")
endforeach()
string(REPLACE ";" "\n" GENERATED_FILE_CONTENT "${GENERATED_FILE_CONTENT}")

# Write a template for version information
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/cfe_generated_file.h.in ${CMAKE_BINARY_DIR}/cfe_module_version.in)

# The actual version information (to fill out the template above) is obtained at build time
# via a script that is executed as a build target. If this script exists in the mission defs
# directory (user-supplied) then use that. Otherwise a pre-canned "git" version is included
# as a fallback, which should work for source trees assembled via git submodules or subtrees.
if (EXISTS "${MISSION_DEFS}/generate_module_version.cmake")
set(VERSION_SCRIPT "${MISSION_DEFS}/generate_module_version.cmake")
else()
set(VERSION_SCRIPT "${CFE_SOURCE_DIR}/cmake/generate_git_module_version.cmake")
endif()

add_custom_target(cfe-module-version
COMMAND
${CMAKE_COMMAND} -D BIN=${CMAKE_BINARY_DIR}
-P "${VERSION_SCRIPT}"
WORKING_DIRECTORY
${CMAKE_SOURCE_DIR}
VERBATIM
)

add_custom_target(cfe-build-env
COMMAND
${CMAKE_COMMAND} -D BIN=${CMAKE_BINARY_DIR}
-P "${CFE_SOURCE_DIR}/cmake/generate_build_env.cmake"
WORKING_DIRECTORY
${CMAKE_SOURCE_DIR}
VERBATIM
)

# Content for build info - these vars can be evaulated right now, no need to defer
set(GENERATED_FILE_HEADER "/* Automatically generated from CMake build system */")
string(CONCAT GENERATED_FILE_CONTENT
"const char CFE_MISSION_NAME[] = \"${MISSION_NAME}\";\n"
"const char CFE_MISSION_CONFIG[] = \"${MISSIONCONFIG}\";\n"
)
set(GENERATED_FILE_TRAILER "/* End of file */")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/cfe_generated_file.h.in ${CMAKE_BINARY_DIR}/src/cfe_mission_strings.c)

add_custom_target(mission-version
DEPENDS cfe-module-version cfe-build-env
)

endfunction(generate_build_version_templates)


##################################################################
#
Expand Down Expand Up @@ -267,17 +356,8 @@ function(prepare)
endif (NOT "${${VARL}}" STREQUAL "")
endforeach(VARL ${VARLIST})
file(WRITE "${CMAKE_BINARY_DIR}/mission_vars.cache" "${MISSION_VARCACHE}")

# Generate version information for the executable file. This is done by executing a small CMAKE
# at _build_ time (not at prep time since it might change between now and then) that collects
# the info out of the version control system in use (git is currently assumed).
add_custom_target(mission-version
COMMAND
${CMAKE_COMMAND} -D BIN=${CMAKE_BINARY_DIR}
-P ${CFE_SOURCE_DIR}/cmake/version.cmake
WORKING_DIRECTORY
${CMAKE_SOURCE_DIR}
)

generate_build_version_templates()

# Generate the tools for the native (host) arch
add_subdirectory(${MISSION_SOURCE_DIR}/tools tools)
Expand Down
115 changes: 96 additions & 19 deletions cmake/target/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,108 @@ if (NOT DEFINED ${TGTNAME}_PROCESSORID)
message(FATAL_ERROR "${TGTNAME}_PROCESSORID must be defined to link a final exe")
endif (NOT DEFINED ${TGTNAME}_PROCESSORID)

# Create a file for the statically-linked module list for this target
# do this for both PSP and CFS static modules
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/psp_module_list.inc.tmp"
"/* Automatically generated based on target config */\n")
string(CONCAT GENERATED_FILE_HEADER
"/* This file is auto-generated from CMake build system. Do not manually edit! */\n"
"#include \"target_config.h\"\n"
)

string(CONCAT GENERATED_FILE_TRAILER
"/* End of file */\n"
)

# Generate a list of PSP modules along with a pointer to its API structure/entry point
set(GENERATED_EXTERNS)
set(GENERATED_KEYVALS)
foreach(PSPMOD ${${TGTNAME}_PSP_MODULELIST})
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/psp_module_list.inc.tmp" "LOAD_PSP_MODULE(${PSPMOD})\n")
list(APPEND GENERATED_EXTERNS "extern char CFE_PSP_${PSPMOD}_API;\n")
list(APPEND GENERATED_KEYVALS "{ .Name = \"${PSPMOD}\", .Api = &CFE_PSP_${PSPMOD}_API },\n")
endforeach(PSPMOD ${${TGTNAME}_PSP_MODULELIST})
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${CMAKE_CURRENT_BINARY_DIR}/psp_module_list.inc.tmp"
"${CMAKE_CURRENT_BINARY_DIR}/psp_module_list.inc")
file (REMOVE "${CMAKE_CURRENT_BINARY_DIR}/psp_module_list.inc.tmp")

file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cfs_static_symbol_list.inc.tmp"
"/* Automatically generated based on target config */\n")
string(CONCAT GENERATED_FILE_CONTENT
${GENERATED_EXTERNS}
"const CFE_StaticModuleLoadEntry_t CFE_PSP_MODULE_LIST[] = {\n"
${GENERATED_KEYVALS}
"{ NULL } /* End of list */\n"
"};\n"
)

configure_file(${CFE_SOURCE_DIR}/cmake/cfe_generated_file.h.in ${CMAKE_CURRENT_BINARY_DIR}/cfe_psp_module_list.c)

# Generate lists of modules that will be statically linked into this CFE core target
set(GENERATED_ENTRIES_CORE_MODULES)
foreach(DEP ${MISSION_CORE_MODULES})
list(APPEND GENERATED_ENTRIES_CORE_MODULES "{ \"${DEP}\" },\n")
endforeach()

set(GENERATED_ENTRIES_STATIC_APPS)
foreach(DEP ${${TGTNAME}_STATIC_APPLIST})
list(APPEND GENERATED_ENTRIES_STATIC_APPS "{ \"${DEP}\" },\n")
endforeach()

string(CONCAT GENERATED_FILE_CONTENT
"CFE_ConfigName_t CFE_CORE_MODULE_LIST[] = {\n"
${GENERATED_ENTRIES_CORE_MODULES}
"{ NULL } /* End of list */\n"
"};\n"
"CFE_ConfigName_t CFE_STATIC_APP_LIST[] = {\n"
${GENERATED_ENTRIES_STATIC_APPS}
"{ NULL } /* End of list */\n"
"};\n"
)

configure_file(${CFE_SOURCE_DIR}/cmake/cfe_generated_file.h.in ${CMAKE_CURRENT_BINARY_DIR}/cfe_static_module_list.c)

# Generate a list of symbol names that must be known at runtime without OS loader support
set(GENERATED_EXTERNS)
set(GENERATED_KEYVALS)
foreach(CFSSYM ${${TGTNAME}_STATIC_SYMLIST})
file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/cfs_static_symbol_list.inc.tmp" "STATIC_CFS_SYMBOL(${CFSSYM})\n")
string(REPLACE "," ";" CFSSYM "${CFSSYM}")
list(GET CFSSYM 0 SYM_NAME)
list(GET CFSSYM 1 SYM_MODULE)
list(APPEND GENERATED_EXTERNS "extern void ${SYM_NAME} (void);\n")
list(APPEND GENERATED_KEYVALS "{ .Name = \"${SYM_NAME}\", .Address = &{SYM_NAME}, .Module = \"${SYM_MODULE}\" },")
endforeach(CFSSYM ${${TGTNAME}_STATIC_SYMLIST})
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${CMAKE_CURRENT_BINARY_DIR}/cfs_static_symbol_list.inc.tmp"
"${CMAKE_CURRENT_BINARY_DIR}/cfs_static_symbol_list.inc")
file (REMOVE "${CMAKE_CURRENT_BINARY_DIR}/cfs_static_symbol_list.inc.tmp")

string(CONCAT GENERATED_FILE_HEADER
"/* This file is auto-generated from CMake build system. Do not manually edit! */\n"
"#include \"osapi-module.h\"\n"
)

string(CONCAT GENERATED_FILE_CONTENT
${GENERATED_EXTERNS}
"OS_static_symbol_record_t OS_STATIC_SYMBOL_TABLE[] = {\n"
${GENERATED_KEYVALS}
"{ NULL } /* End of list */\n"
"};\n"
)

configure_file(${CFE_SOURCE_DIR}/cmake/cfe_generated_file.h.in ${CMAKE_CURRENT_BINARY_DIR}/cfe_static_symbol_list.c)

add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cfe_build_env_table.c
COMMAND ${CMAKE_COMMAND} -E copy
${MISSION_BINARY_DIR}/src/cfe_build_env_table.c
${CMAKE_CURRENT_BINARY_DIR}/cfe_build_env_table.c
DEPENDS
${MISSION_BINARY_DIR}/src/cfe_build_env_table.c
)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cfe_module_version_table.c
COMMAND ${CMAKE_COMMAND} -E copy
${MISSION_BINARY_DIR}/src/cfe_module_version_table.c
${CMAKE_CURRENT_BINARY_DIR}/cfe_module_version_table.c
DEPENDS
${MISSION_BINARY_DIR}/src/cfe_module_version_table.c
)

# Target for the final executable
add_executable(core-${TGTNAME} src/target_config.c)
add_executable(core-${TGTNAME}
${MISSION_BINARY_DIR}/src/cfe_mission_strings.c
${CMAKE_CURRENT_BINARY_DIR}/cfe_module_version_table.c
${CMAKE_CURRENT_BINARY_DIR}/cfe_build_env_table.c
${CMAKE_CURRENT_BINARY_DIR}/cfe_psp_module_list.c
${CMAKE_CURRENT_BINARY_DIR}/cfe_static_symbol_list.c
${CMAKE_CURRENT_BINARY_DIR}/cfe_static_module_list.c
src/target_config.c
)

target_compile_definitions(core-${TGTNAME} PRIVATE
CFE_DEFAULT_MODULE_EXTENSION="${CMAKE_SHARED_MODULE_SUFFIX}"
Expand All @@ -54,8 +132,7 @@ target_compile_definitions(core-${TGTNAME} PRIVATE
CFE_CPU_ID_VALUE=${${TGTNAME}_PROCESSORID}
)

target_include_directories(core-${TGTNAME} PRIVATE
"${CMAKE_CURRENT_BINARY_DIR}"
target_include_directories(core-${TGTNAME} PRIVATE
"${CMAKE_BINARY_DIR}/${CFE_CORE_TARGET}/inc"
)

Expand Down
Loading