Skip to content

Commit

Permalink
Merge pull request #143 from jphickey:fix-142-move-scripts
Browse files Browse the repository at this point in the history
Fix #142, move scripts for table building to elf2cfetbl tool
  • Loading branch information
dzbaker committed Jan 17, 2024
2 parents fff5e4b + e67b220 commit a1c42e1
Show file tree
Hide file tree
Showing 6 changed files with 218 additions and 4 deletions.
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)/$(<)"

0 comments on commit a1c42e1

Please sign in to comment.