diff --git a/CHANGELOG.md b/CHANGELOG.md index b1a09f6..5cab31c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## Development Build: equuleus-rc1+dev10 +- updating ELF2CFETBL to use new versioning system +- move scripts for table building to elf2cfetbl tool +- See and + ## Development Build: v3.3.0-rc4+dev36 - Adds CheckStatus helper functions - Reduce cyclomatic complexity of GetElfHeader diff --git a/CMakeLists.txt b/CMakeLists.txt index a4e2fea..818065d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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="$" + 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) diff --git a/elf2cfetbl.c b/elf2cfetbl.c index 210983b..9ceb94a 100644 --- a/elf2cfetbl.c +++ b/elf2cfetbl.c @@ -1264,7 +1264,15 @@ int32 ProcessCmdLineOptions(int ArgumentCount, char *Arguments[]) void OutputVersionInfo(void) { - printf("\n%s\n", ELF2CFETBL_VERSION_STRING); + char VersionString[ELF2CFETBL_CFG_MAX_VERSION_STR_LEN]; + + snprintf(VersionString, ELF2CFETBL_CFG_MAX_VERSION_STR_LEN, + "%s %s %s (Codename %s), Last Official Release: %s %s)", + "elf2cfetbl", ELF2CFETBL_REVISION == 0 ? "Development Build" : "Release", + ELF2CFETBL_VERSION, ELF2CFETBL_BUILD_CODENAME, "elf2cfetbl", + ELF2CFETBL_LAST_OFFICIAL); + + printf("\n%s\n", VersionString); } /** diff --git a/elf2cfetbl_version.h b/elf2cfetbl_version.h index 4528223..fa0dca3 100644 --- a/elf2cfetbl_version.h +++ b/elf2cfetbl_version.h @@ -28,16 +28,22 @@ /* * Development Build Macro Definitions */ -#define ELF2CFETBL_BUILD_NUMBER 36 /*!< @brief Number of commits since baseline */ -#define ELF2CFETBL_BUILD_BASELINE \ - "v3.3.0-rc4" /*!< @brief Development Build: git tag that is the base for the current */ +#define ELF2CFETBL_BUILD_NUMBER 10 /*!< @brief Number of commits since baseline */ +#define ELF2CFETBL_BUILD_BASELINE "equuleues-rc1" /*!< @brief Development Build: git tag that is the base for the current */ +#define ELF2CFETBL_BUILD_DEV_CYCLE "equuleus-rc2" /**< @brief Development: Release name for current development cycle */ +#define ELF2CFETBL_BUILD_CODENAME "Equuleus" /**< @brief: Development: Code name for the current build */ /* * Version Macros, see \ref cfsversions for definitions. */ #define ELF2CFETBL_MAJOR_VERSION 3 /*!< @brief Major version number */ #define ELF2CFETBL_MINOR_VERSION 1 /*!< @brief Minor version number */ -#define ELF2CFETBL_REVISION 99 /*!< @brief Revision version number. Value of 99 indicates a development version.*/ +#define ELF2CFETBL_REVISION 0 /*!< @brief Revision version number. Value of 0 indicates a development version.*/ + +/** + * @brief Last official release. + */ +#define ELF2CFETBL_LAST_OFFICIAL "v3.1.0" /*! * @brief Mission revision. @@ -61,13 +67,12 @@ */ #define ELF2CFETBL_VERSION ELF2CFETBL_BUILD_BASELINE ELF2CFETBL_STR(ELF2CFETBL_BUILD_NUMBER) -/*! @brief Development Build Version String. - * @details Reports the current development build's baseline, number, and name. Also includes a note about the latest - * official version. @n See @ref cfsversions for format differences between development and release versions. +/** + * @brief Max Version String length. + * + * Maximum length that an elf2cfetbl version string can be. + * */ -#define ELF2CFETBL_VERSION_STRING \ - " elf2cfetbl Development Build\n" \ - " " ELF2CFETBL_VERSION " (Codename: Draco)\n" /* Codename for current development */ \ - " Last Official Release: elf2cfetbl v3.1.0" /* For full support please use official release version */ +#define ELF2CFETBL_CFG_MAX_VERSION_STR_LEN 256 #endif /* ELF2CFETBL_VERSION_H */ diff --git a/scripts/add_cfe_tables_impl.cmake b/scripts/add_cfe_tables_impl.cmake new file mode 100644 index 0000000..845e203 --- /dev/null +++ b/scripts/add_cfe_tables_impl.cmake @@ -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="\"$\"" + ) + + 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) diff --git a/scripts/elf2cfetbl_rules.mk b/scripts/elf2cfetbl_rules.mk new file mode 100644 index 0000000..c174435 --- /dev/null +++ b/scripts/elf2cfetbl_rules.mk @@ -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 $(@))" diff --git a/scripts/generate_elf_table_rules.cmake b/scripts/generate_elf_table_rules.cmake new file mode 100644 index 0000000..12da18b --- /dev/null +++ b/scripts/generate_elf_table_rules.cmake @@ -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}) diff --git a/scripts/table_rule_template.d.in b/scripts/table_rule_template.d.in new file mode 100644 index 0000000..4fa6648 --- /dev/null +++ b/scripts/table_rule_template.d.in @@ -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} diff --git a/scripts/tabletool_rule.mk b/scripts/tabletool_rule.mk new file mode 100644 index 0000000..6b34c75 --- /dev/null +++ b/scripts/tabletool_rule.mk @@ -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)/$(<)"