Skip to content

Commit

Permalink
Fix nasa#1538, add capability to generate multiple tables
Browse files Browse the repository at this point in the history
Adds a "install_custom.cmake" hook that can be put into a CPU-specific
subdirectory under the "defs" directory, that can perform extra
installation steps as required for the project/mission.

Tweaks the "add_cfe_tables" function such that it can also be called from
the install_custom.cmake script to generate additional/alternative table
binary files for that CPU.

The main update is that it uses the "APP_NAME" parameter to associate
the table files with the app library, so the same set of include files
can be used.  This relies on the target-scope properties being used.
Historically that string wasn't verified, it could have been any unique
string, but now it should match the app if this is to work as expected.
  • Loading branch information
jphickey committed May 18, 2021
1 parent 84ba9a9 commit a47a581
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 72 deletions.
166 changes: 94 additions & 72 deletions cmake/arch_build.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -148,80 +148,100 @@ endfunction(add_cfe_app_dependency)
#
function(add_cfe_tables APP_NAME TBL_SRC_FILES)

# The table source must be compiled using the same "include_directories"
# as any other target, but it uses the "add_custom_command" so there is
# no automatic way to do this (at least in the older cmakes)

# Create the intermediate table objects using the target compiler,
# then use "elf2cfetbl" to convert to a .tbl file
set(TBL_LIST)
foreach(TBL ${TBL_SRC_FILES} ${ARGN})

# Get name without extension (NAME_WE) and append to list of tables
get_filename_component(TBLWE ${TBL} NAME_WE)

foreach(TGT ${APP_STATIC_TARGET_LIST} ${APP_DYNAMIC_TARGET_LIST})
set(TABLE_DESTDIR "${CMAKE_CURRENT_BINARY_DIR}/tables_${TGT}")
file(MAKE_DIRECTORY ${TABLE_DESTDIR})
list(APPEND TBL_LIST "${TABLE_DESTDIR}/${TBLWE}.tbl")

# Check if an override exists at the mission level (recommended practice)
# This allows a mission to implement a customized table without modifying
# the original - this also makes for easier merging/updating if needed.
if (EXISTS "${MISSION_DEFS}/tables/${TGT}_${TBLWE}.c")
set(TBL_SRC "${MISSION_DEFS}/tables/${TGT}_${TBLWE}.c")
elseif (EXISTS "${MISSION_SOURCE_DIR}/tables/${TGT}_${TBLWE}.c")
set(TBL_SRC "${MISSION_SOURCE_DIR}/tables/${TGT}_${TBLWE}.c")
elseif (EXISTS "${MISSION_DEFS}/tables/${TBLWE}.c")
set(TBL_SRC "${MISSION_DEFS}/tables/${TBLWE}.c")
elseif (EXISTS "${MISSION_SOURCE_DIR}/tables/${TBLWE}.c")
set(TBL_SRC "${MISSION_SOURCE_DIR}/tables/${TBLWE}.c")
elseif (EXISTS "${MISSION_DEFS}/${TGT}/tables/${TBLWE}.c")
set(TBL_SRC "${MISSION_DEFS}/${TGT}/tables/${TBLWE}.c")
elseif (IS_ABSOLUTE "${TBL}")
set(TBL_SRC "${TBL}")
else()
set(TBL_SRC "${CMAKE_CURRENT_SOURCE_DIR}/${TBL}")
endif()
if (TGTNAME)
set (TABLE_TGTLIST ${TGTNAME})
else()
set (TABLE_TGTLIST ${TGTLIST_${APP_NAME}})
endif()

if (NOT EXISTS "${TBL_SRC}")
message(FATAL_ERROR "ERROR: No source file for table ${TBLWE}")
else()
message("NOTE: Selected ${TBL_SRC} as source for ${TBLWE}")
endif()
# The first parameter should match the name of an app that was
# previously defined using "add_cfe_app". If target-scope properties
# are used for include directories and compile definitions, this is needed
# to compile tables with the same include path/definitions as the app has.
# However historically this could have been any string, which still works
# if directory-scope properties are used for includes, so this is not
# an error.
if (NOT TARGET ${APP_NAME})
message("NOTE: \"${APP_NAME}\" passed to add_cfe_tables is not a previously-defined application target")
endif()

# The table source must be compiled using the same "include_directories"
# as any other target, but it uses the "add_custom_command" so there is
# no automatic way to do this (at least in the older cmakes)

# Create the intermediate table objects using the target compiler,
# then use "elf2cfetbl" to convert to a .tbl file
foreach(TBL ${TBL_SRC_FILES} ${ARGN})

# Get name without extension (NAME_WE) and append to list of tables
get_filename_component(TBLWE ${TBL} NAME_WE)

foreach(TGT ${TABLE_TGTLIST})
set(TABLE_LIBNAME "${TGT}_${APP_NAME}_${TBLWE}")
set(TABLE_DESTDIR "${CMAKE_CURRENT_BINARY_DIR}/${TABLE_LIBNAME}")
set(TABLE_BINARY "${TABLE_DESTDIR}/${TBLWE}.tbl")
file(MAKE_DIRECTORY ${TABLE_DESTDIR})

# Check if an override exists at the mission level (recommended practice)
# This allows a mission to implement a customized table without modifying
# the original - this also makes for easier merging/updating if needed.
if (EXISTS "${MISSION_DEFS}/tables/${TGT}_${TBLWE}.c")
set(TBL_SRC "${MISSION_DEFS}/tables/${TGT}_${TBLWE}.c")
elseif (EXISTS "${MISSION_SOURCE_DIR}/tables/${TGT}_${TBLWE}.c")
set(TBL_SRC "${MISSION_SOURCE_DIR}/tables/${TGT}_${TBLWE}.c")
elseif (EXISTS "${MISSION_DEFS}/${TGT}/tables/${TBLWE}.c")
set(TBL_SRC "${MISSION_DEFS}/${TGT}/tables/${TBLWE}.c")
elseif (EXISTS "${MISSION_DEFS}/tables/${TBLWE}.c")
set(TBL_SRC "${MISSION_DEFS}/tables/${TBLWE}.c")
elseif (EXISTS "${MISSION_SOURCE_DIR}/tables/${TBLWE}.c")
set(TBL_SRC "${MISSION_SOURCE_DIR}/tables/${TBLWE}.c")
elseif (IS_ABSOLUTE "${TBL}")
set(TBL_SRC "${TBL}")
else()
set(TBL_SRC "${CMAKE_CURRENT_SOURCE_DIR}/${TBL}")
endif()

if (NOT EXISTS "${TBL_SRC}")
message(FATAL_ERROR "ERROR: No source file for table ${TBLWE}")
else()
message("NOTE: Selected ${TBL_SRC} as source for ${APP_NAME}.${TBLWE} on ${TGT}")

# NOTE: On newer CMake versions this should become an OBJECT library which makes this simpler.
# On older versions one may not referece the TARGET_OBJECTS property from the custom command.
# As a workaround this is built into a static library, and then the desired object is extracted
# before passing to elf2cfetbl. It is roundabout but it works.
add_library(${TABLE_LIBNAME} STATIC ${TBL_SRC})
target_link_libraries(${TABLE_LIBNAME} PRIVATE core_api)
if (TARGET ${APP_NAME})
target_include_directories(${TABLE_LIBNAME} PRIVATE $<TARGET_PROPERTY:${APP_NAME},INCLUDE_DIRECTORIES>)
target_compile_definitions(${TABLE_LIBNAME} PRIVATE $<TARGET_PROPERTY:${APP_NAME},COMPILE_DEFINITIONS>)
endif()

# IMPORTANT: This rule assumes that the output filename of elf2cfetbl matches
# the input file name but with a different extension (.o -> .tbl)
# The actual output filename is embedded in the source file (.c), however
# this must match and if it does not the build will break. That's just the
# way it is, because NO make system supports changing rules based on the
# current content of a dependency (rightfully so).
add_custom_command(
OUTPUT ${TABLE_BINARY}
COMMAND ${CMAKE_COMMAND}
-DCMAKE_AR=${CMAKE_AR}
-DTBLTOOL=${MISSION_BINARY_DIR}/tools/elf2cfetbl/elf2cfetbl
-DLIB=$<TARGET_FILE:${TABLE_LIBNAME}>
-P ${CFE_SOURCE_DIR}/cmake/generate_table.cmake
DEPENDS ${MISSION_BINARY_DIR}/tools/elf2cfetbl/elf2cfetbl ${TABLE_LIBNAME}
WORKING_DIRECTORY ${TABLE_DESTDIR}
)

# Add a custom target to invoke the elf2cfetbl tool to generate the tbl file,
# and install that binary file to the staging area.
add_custom_target(${TABLE_LIBNAME}_tbl ALL DEPENDS ${TABLE_BINARY})
install(FILES ${TABLE_BINARY} DESTINATION ${TGT}/${INSTALL_SUBDIR})
endif()
endforeach()
endforeach()

# NOTE: On newer CMake versions this should become an OBJECT library which makes this simpler.
# On older versions one may not referece the TARGET_OBJECTS property from the custom command.
# As a workaround this is built into a static library, and then the desired object is extracted
# before passing to elf2cfetbl. It is roundabout but it works.
add_library(${TGT}_${TBLWE}-obj STATIC ${TBL_SRC})
target_link_libraries(${TGT}_${TBLWE}-obj PRIVATE core_api)

# IMPORTANT: This rule assumes that the output filename of elf2cfetbl matches
# the input file name but with a different extension (.o -> .tbl)
# The actual output filename is embedded in the source file (.c), however
# this must match and if it does not the build will break. That's just the
# way it is, because NO make system supports changing rules based on the
# current content of a dependency (rightfully so).
add_custom_command(
OUTPUT "${TABLE_DESTDIR}/${TBLWE}.tbl"
COMMAND ${CMAKE_COMMAND}
-DCMAKE_AR=${CMAKE_AR}
-DTBLTOOL=${MISSION_BINARY_DIR}/tools/elf2cfetbl/elf2cfetbl
-DLIB=$<TARGET_FILE:${TGT}_${TBLWE}-obj>
-P ${CFE_SOURCE_DIR}/cmake/generate_table.cmake
DEPENDS ${MISSION_BINARY_DIR}/tools/elf2cfetbl/elf2cfetbl ${TGT}_${TBLWE}-obj
WORKING_DIRECTORY ${TABLE_DESTDIR}
)
# Create the install targets for all the tables
install(FILES ${TABLE_DESTDIR}/${TBLWE}.tbl DESTINATION ${TGT}/${INSTALL_SUBDIR})
endforeach(TGT ${APP_STATIC_TARGET_LIST} ${APP_DYNAMIC_TARGET_LIST})


endforeach(TBL ${TBL_SRC_FILES} ${ARGN})

# Make a custom target that depends on all the tables
add_custom_target(${APP_NAME}_tables ALL DEPENDS ${TBL_LIST})

endfunction(add_cfe_tables)

Expand Down Expand Up @@ -689,6 +709,8 @@ function(process_arch SYSVAR)
# Target to generate the actual executable file
add_subdirectory(cmake/target ${TGTNAME})

include(${MISSION_DEFS}/${TGTNAME}/install_custom.cmake OPTIONAL)

foreach(INSTFILE ${${TGTNAME}_FILELIST})
if(EXISTS ${MISSION_DEFS}/${TGTNAME}/${INSTFILE})
set(FILESRC ${MISSION_DEFS}/${TGTNAME}/${INSTFILE})
Expand Down
1 change: 1 addition & 0 deletions cmake/generate_table.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ if (NOT RESULT EQUAL 0)
endif()

# Finally invoke the table tool (elf2cfetbl) on the object
message("Executing Process: ${TBLTOOL} ${OBJNAME}")
execute_process(COMMAND ${TBLTOOL} "${OBJNAME}"
RESULT_VARIABLE RESULT
)
Expand Down

0 comments on commit a47a581

Please sign in to comment.