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 #142, move scripts for table building to elf2cfetbl tool #143

Merged
merged 1 commit into from
Jan 18, 2024
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
29 changes: 25 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
# CMake snippet for building elf2cfetbl
#
include_directories(${MISSION_BINARY_DIR}/inc)
include_directories(${osal_MISSION_DIR}/src/os/inc)
include_directories(${cfe-core_MISSION_DIR}/src/inc)

project(CFS_TABLETOOL C)

add_executable(elf2cfetbl elf2cfetbl.c)

install(TARGETS elf2cfetbl DESTINATION host)
# Export relevant information so the parent script can invoke the tool
set(CFS_TABLETOOL_SCRIPT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/scripts" CACHE INTERNAL "CFS table tool script directory")

add_custom_target(tabletool-execute
COMMAND $(MAKE)
CC="${CMAKE_C_COMPILER}"
CFLAGS="${CMAKE_C_FLAGS}"
AR="${CMAKE_AR}"
TBLTOOL="$<TARGET_FILE:elf2cfetbl>"
cfetables
WORKING_DIRECTORY
"${MISSION_BINARY_DIR}/tables"
DEPENDS
mission-cfetables
elf2cfetbl
)

add_dependencies(mission-all tabletool-execute)
add_dependencies(mission-install tabletool-execute)
add_dependencies(mission-prebuild elf2cfetbl)

install(DIRECTORY ${CMAKE_BINARY_DIR}/tables/staging/ DESTINATION .)


install(TARGETS elf2cfetbl DESTINATION host)
124 changes: 124 additions & 0 deletions scripts/add_cfe_tables_impl.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
##################################################################
#
# FUNCTION: do_add_cfe_tables_impl
#
# Simplified routine to add CFS tables to be built with an app
#
# For apps with just a single table, the TABLE_FQNAME may be the
# same as the app name, which is simple.
#
# For apps with multiple tables, the TABLE_FQNAME may be of the
# form "${ADDTBL_ARG_APP_NAME}.${TABLE_NAME}" where ${ADDTBL_ARG_APP_NAME} refers to an
# app target that was registered via the "add_cfe_app" function.
#
# Note that for backward compatibility, any name will be accepted
# for TABLE_FQNAME. However if this function cannot determine which
# app the table is associated with, it will only have a default set
# of INCLUDE_DIRECTORIES when building the C source file(s). By
# associating a table with an app using the conventions above, the
# INCLUDE_DIRECTORIES from the parent app will be used when building the
# tables.
#
# This function produces one or more library targets in CMake, using names
# of the form: "tblobj_${ADDTBL_ARG_TARGET_NAME}_{TABLE_FQNAME}" where TGT reflects the name
# of the target from targets.cmake and TABLE_FQNAME reflects the first
# parameter to this function.
#
function(do_add_cfe_tables_impl TABLE_FQNAME)

cmake_parse_arguments(ADDTBL_ARG "" "APP_NAME;TARGET_NAME;INSTALL_SUBDIR" "" ${ARGN})

set(TEMPLATE_FILE "${CFS_TABLETOOL_SCRIPT_DIR}/table_rule_template.d.in")
set(TABLE_GENSCRIPT "${CFS_TABLETOOL_SCRIPT_DIR}/generate_elf_table_rules.cmake")
set(TABLE_LIBNAME "tblobj_${ADDTBL_ARG_TARGET_NAME}_${TABLE_FQNAME}")

set(TABLE_CMD_OPTS
-DTEMPLATE_FILE="${TEMPLATE_FILE}"
-DAPP_NAME="${ADDTBL_ARG_APP_NAME}"
-DTARGET_NAME="${ADDTBL_ARG_TARGET_NAME}"
-DARCHIVE_FILE="\"$<TARGET_FILE:${TABLE_LIBNAME}>\""
)

if (ADDTBL_ARG_INSTALL_SUBDIR)
list(APPEND TABLE_CMD_OPTS
-DINSTALL_SUBDIR="${ADDTBL_ARG_INSTALL_SUBDIR}"
)
endif()

# If there is an ${ADDTBL_ARG_APP_NAME}.table target defined, make
# things depend on that. Otherwise just depend on core_api.
set(TABLE_DEPENDENCIES core_api)
if (TARGET ${ADDTBL_ARG_APP_NAME}.table)
list(APPEND TABLE_DEPENDENCIES ${ADDTBL_ARG_APP_NAME}.table)
endif()

# Note that the file list passed in are just a default - we now need
# to find the active source, which typically comes from the MISSION_DEFS dir.
# The TABLE_SELECTED_SRCS will become this list of active/selected source files
set(TABLE_SELECTED_SRCS)
foreach(TBL ${ADDTBL_ARG_UNPARSED_ARGUMENTS})

# The file source basename (without directory or ext) should be the same as the table
# binary filename with a ".tbl" extension (this is the convention assumed by elf2cfetbl)
get_filename_component(TABLE_SRC_NEEDED ${TBL} NAME)
get_filename_component(TABLE_BASENAME ${TBL} NAME_WE)
set(TABLE_RULEFILE "${MISSION_BINARY_DIR}/tables/${ADDTBL_ARG_TARGET_NAME}_${TABLE_FQNAME}.${TABLE_BASENAME}.d")


# 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.
# Note this path list is in reverse-priority order, and only a single file
# will be end up being selected.
cfe_locate_implementation_file(TBL_SRC "${TABLE_SRC_NEEDED}"
FALLBACK_FILE "${CMAKE_CURRENT_SOURCE_DIR}/${TBL}"
PREFIX "${ADDTBL_ARG_TARGET_NAME}"
SUBDIR tables
)

list(APPEND TABLE_SELECTED_SRCS ${TBL_SRC})

set_property(SOURCE "${TBL_SRC}" APPEND PROPERTY COMPILE_DEFINITIONS
CFE_TABLE_NAME=${TABLE_BASENAME}
)

# Note the table is not generated directly here, as it may require the native system compiler, so
# the call to the table tool (elf2cfetbl in this build) is deferred to the parent scope. Instead, this
# generates a file that captures the state (include dirs, source files, targets) for use in a future step.
add_custom_command(
OUTPUT "${TABLE_RULEFILE}"
COMMAND ${CMAKE_COMMAND}
${TABLE_CMD_OPTS}
-DOUTPUT_FILE="${TABLE_RULEFILE}"
-DTABLE_NAME="${TABLE_BASENAME}"
-DSOURCES="${TBL_SRC}"
-DOBJEXT="${CMAKE_C_OUTPUT_EXTENSION}"
-P "${TABLE_GENSCRIPT}"
WORKING_DIRECTORY
${MISSION_BINARY_DIR}/tables
DEPENDS
${TABLE_TEMPLATE}
${TABLE_GENSCRIPT}
${TABLE_DEPENDENCIES}
)

# Add a custom target to generate the config file
add_custom_target(generate_table_${ADDTBL_ARG_TARGET_NAME}_${ADDTBL_ARG_APP_NAME}_${TABLE_BASENAME}
DEPENDS "${TABLE_RULEFILE}" ${TABLE_LIBNAME}
)
add_dependencies(cfetables generate_table_${ADDTBL_ARG_TARGET_NAME}_${ADDTBL_ARG_APP_NAME}_${TABLE_BASENAME})

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

# NOTE: On newer CMake versions this should become an OBJECT library which makes this simpler.
# On older versions one may not reference 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 EXCLUDE_FROM_ALL ${TABLE_SELECTED_SRCS})
target_compile_definitions(${TABLE_LIBNAME} PRIVATE
CFE_CPU_NAME=${ADDTBL_ARG_TARGET_NAME}
)
target_link_libraries(${TABLE_LIBNAME} ${TABLE_DEPENDENCIES})


endfunction(do_add_cfe_tables_impl)
10 changes: 10 additions & 0 deletions scripts/elf2cfetbl_rules.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Rule for traditional CFE table generation via elf2cfetbl

# The dependency of this target should always be an absolute pathname to
# the intermediate library file as it is generated by a CMake script via
# the TARGET_FILE property. Therefore, the same path should still work
# after the "cd" command. The "cd" is so the ar tool writes the object file
# into a separate dir, in case of similarly-named files on different cpus.
elf/%:
@mkdir -pv "$(dir $(@))"
cd "$(dir $(@))" && $(AR) x "$(<)" "$(notdir $(@))"
34 changes: 34 additions & 0 deletions scripts/generate_elf_table_rules.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
##################################################################
#
# Sub-script to capture the table compile/generation environment
#
# This small script runs at build time (as opposed to prep time)
# which captures a set of environment metadata
#
# It must be done this way such that generator expressions will
# be evaluated now, during the arch build process, rather than
# deferring the evaluation to the parent build where they may
# have different values.
#
##################################################################

set(STAGING_DIR staging ${TARGET_NAME} ${INSTALL_SUBDIR})
string(REPLACE ";" "/" STAGING_DIR "${STAGING_DIR}")

set(TABLE_BINARY "${STAGING_DIR}/${TABLE_NAME}.tbl")
set(TMP_DIR "elf/${TARGET_NAME}")
set(TABLE_RULES)

foreach(TBL_SRC ${SOURCES})

get_filename_component(DEP_FILE ${TBL_SRC} NAME)
set(DEP_FILE "${TMP_DIR}/${DEP_FILE}${OBJEXT}")
string(APPEND TABLE_RULES
"${DEP_FILE}: ${ARCHIVE_FILE}\n"
"${TABLE_BINARY}: ${DEP_FILE}\n"
"\n"
)

endforeach()

configure_file(${TEMPLATE_FILE} ${OUTPUT_FILE})
10 changes: 10 additions & 0 deletions scripts/table_rule_template.d.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Template for table configuration

cfetables: ${TABLE_BINARY}

${TABLE_BINARY}: CFE_TABLE_CPUNAME := ${TARGET_NAME}
${TABLE_BINARY}: CFE_TABLE_APPNAME := ${APP_NAME}
${TABLE_BINARY}: CFE_TABLE_BASENAME := ${TABLE_NAME}

# Rules to build ${TABLE_BINARY}
${TABLE_RULES}
15 changes: 15 additions & 0 deletions scripts/tabletool_rule.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Makefile for EDS-based CFE table generation
.PHONY: cfetables

cfetables:
@echo "Table build completed"

# The dependency of this rule should always be a relative path starting with elf/,
# at least with the current rule generator script, so it matches the elf/% pattern rule.
# But because elf2cfetbl only writes its output to the current working dir, it has to be run
# after changing dirs into the staging area. Thus the path to the elf file needs to be adjusted.
# Ideally this chould be done with the $(abspath f...) function but this doesn't exist in older versions.
# As a workaround, $CURDIR is used.
staging/%.tbl:
@mkdir -pv "$(dir $(@))"
cd "$(dir $(@))" && $(TBLTOOL) $(TBLTOOL_FLAGS) "$(CURDIR)/$(<)"
Loading