From 71ae2ced99f6236b5c5dc69a89839cc058e3ea3c Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Mon, 2 Mar 2026 16:43:13 +0100 Subject: [PATCH] adds generation of version header file --- CMakeLists.txt | 194 ++++++++++++++++++++++------------------- cmake/Versioning.cmake | 166 +++++++++++++++++++++++++++++++++++ src/scc_ver.h.in | 15 ++++ 3 files changed, 284 insertions(+), 91 deletions(-) create mode 100644 cmake/Versioning.cmake create mode 100644 src/scc_ver.h.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 6c8f9f1f..f37ed768 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,8 +11,8 @@ option(FULL_TRACE_TYPE_LIST "Test for extended set of templated datatypes" OFF) #Note: this needs to match the SystemC kernel build options option(SC_WITH_PHASE_CALLBACKS "Whether SystemC is built with simulation phase callbacks" OFF) option(SC_WITH_PHASE_CALLBACK_TRACING "whether SystemC was build with phase callbacks for tracing. It needs to match the SystemC build configuration" OFF) -set(SCC_ARCHIVE_DIR_MODIFIER "" CACHE STRING "additional directory levels to store static library archives") -set(SCC_LIBRARY_DIR_MODIFIER "" CACHE STRING "additional directory levels to store libraries") +set(SCC_ARCHIVE_DIR_MODIFIER "" CACHE STRING "additional directory levels to store static library archives") +set(SCC_LIBRARY_DIR_MODIFIER "" CACHE STRING "additional directory levels to store libraries") option(WITH_SCP4SCC "adds SCP compatibility layer for SCC, cannot be used together with a copy of SCP" OFF) option(ENABLE_CLANG_FORMAT "Enable clang-format targets" OFF) @@ -20,13 +20,13 @@ include(Common) if(CMAKE_PROJECT_NAME STREQUAL "scc") message(STATUS "Building SCC in standalone mode") - set(CMAKE_CXX_STANDARD_REQUIRED ON) - set(CMAKE_CXX_EXTENSIONS OFF) - set(CMAKE_POSITION_INDEPENDENT_CODE ON) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CXX_EXTENSIONS OFF) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) include(GNUInstallDirs) - - if (APPLE) + + if(APPLE) # From systemc CMakeLists.txt: "It's OK that _sc_main, __sanitizer_start_switch_fiber, and # __sanitizer_finish_switch_fiber are undefined symbols." set(CMAKE_EXE_LINKER_FLAGS "-Wl,-U,_sc_main,-U,___sanitizer_start_switch_fiber,-U,___sanitizer_finish_switch_fiber" CACHE INTERNAL "" FORCE) @@ -35,27 +35,27 @@ if(CMAKE_PROJECT_NAME STREQUAL "scc") option(ENABLE_CLANG_TIDY "Add clang-tidy automatically to builds" OFF) option(BUILD_SCC_LIB_ONLY "Build only the library (no examples" OFF) option(INSTALL_DEPENDENCIES "Should dependencies be installed when installing SCC" OFF) - set(CLANG_FORMAT_EXCLUDE_PATTERNS "/third_party/" "/build/" ".direnv") + set(CLANG_FORMAT_EXCLUDE_PATTERNS "/third_party/" "/build/" ".direnv") if(ENABLE_CLANG_FORMAT) - find_package(ClangFormat) + find_package(ClangFormat) endif() else() option(BUILD_SCC_LIB_ONLY "Build only the library (no examples" ON) - set(CLANG_FORMAT_EXCLUDE_PATTERNS ${CLANG_FORMAT_EXCLUDE_PATTERNS} "/third_party/" PARENT_SCOPE) + set(CLANG_FORMAT_EXCLUDE_PATTERNS ${CLANG_FORMAT_EXCLUDE_PATTERNS} "/third_party/" PARENT_SCOPE) endif() set(SCC_CMAKE_CONFIG_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/scc) if(BUILD_SCC_LIB_ONLY) - message(STATUS "SCC: Building only library") + message(STATUS "SCC: Building only library") else() - message(STATUS "SCC: Building library, tests, and examples") + message(STATUS "SCC: Building library, tests, and examples") endif() ############################################################################### # build the SCC ############################################################################### -if (ENABLE_CLANG_TIDY) - find_program (CLANG_TIDY_EXE NAMES "clang-tidy" PATHS /usr/bin ) - if (CLANG_TIDY_EXE) +if(ENABLE_CLANG_TIDY) + find_program(CLANG_TIDY_EXE NAMES "clang-tidy" PATHS /usr/bin) + if(CLANG_TIDY_EXE) message(STATUS "clang-tidy found: ${CLANG_TIDY_EXE}") set(CLANG_TIDY_CHECKS "-*") set(CLANG_TIDY_CHECKS "${CLANG_TIDY_CHECKS},modernize-avoid-bind.PermissiveParameterList") @@ -114,11 +114,11 @@ endif() find_package(Catch2 QUIET) if(MSVC) - add_compile_options(/vmg /MP /W3 /wd4244 /wd4267 /wd4996 -DNOMINMAX /EHsc) + add_compile_options(/vmg /MP /W3 /wd4244 /wd4267 /wd4996 -DNOMINMAX /EHsc) link_directories(${Boost_LIBRARY_DIRS}) endif() include(SystemCPackage) - + include(CheckSymbolExists) # Check for function getenv() check_symbol_exists(getenv "stdlib.h" HAVE_GETENV) @@ -140,15 +140,15 @@ if(SystemC_FOUND) add_subdirectory(src/sysc) add_subdirectory(third_party) if(NOT BUILD_SCC_LIB_ONLY) - if (NOT (DEFINED CMAKE_CXX_CLANG_TIDY OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")) + if(NOT (DEFINED CMAKE_CXX_CLANG_TIDY OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")) add_subdirectory(examples) endif() - if(Catch2_FOUND) - message(STATUS "SCC: Including Catch2 based tests") - include(Catch) - set(WITH_SCP4SCC ON) - add_subdirectory(tests) - endif() + if(Catch2_FOUND) + message(STATUS "SCC: Including Catch2 based tests") + include(Catch) + set(WITH_SCP4SCC ON) + add_subdirectory(tests) + endif() endif() # Define the scc library @@ -157,8 +157,8 @@ if(SystemC_FOUND) if(HAVE_GETENV) target_compile_definitions(scc INTERFACE HAVE_GETENV) endif() - - target_include_directories(scc INTERFACE + + target_include_directories(scc INTERFACE $ $ ) @@ -173,50 +173,62 @@ if(SystemC_FOUND) PUBLIC_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/src/scc.h ) - if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") - #set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--export-all-symbols") - add_library(scc-shared SHARED $ - $ - $ - $ - $ - ) - target_include_directories(scc-shared INTERFACE $ - $ - $ - $ - $ - ) - set_target_properties(scc-shared PROPERTIES CXX_VISIBILITY_PRESET hidden) - target_link_libraries(scc-shared PUBLIC $ - $ - $ - $ - $ - ) -# set(LIB_LIST $ -# $ -# $ -# $ -# $ -# ) -# message("LIB_LIST=${LIB_LIST}") -# add_library(scc-shared SHARED src/scc.h) -# target_link_libraries(scc-shared PUBLIC -# -Wl,--whole-archive -# scc-util -# scc-sysc -# interfaces -# scv-tr -# tlm-interfaces -# -Wl,--no-whole-archive -# ) -# - if(TARGET Boost::stacktrace_backtrace) - target_link_libraries(scc-shared PUBLIC Boost::stacktrace_backtrace dl) - endif() - add_library(scc::scc-shared ALIAS scc-shared) - endif() + include(Versioning) + scc_configure_version( + TARGET scc + NAMESPACE SCC + OUTPUT_HEADER ${CMAKE_BINARY_DIR}/generated/scc_ver.h + ABI_VERSION 5 + USE_GIT + # RELEASE_ENFORCE_TAG + REPRODUCIBLE + INSTALL_HEADER + ) + + if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + #set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--export-all-symbols") + add_library(scc-shared SHARED $ + $ + $ + $ + $ + ) + target_include_directories(scc-shared INTERFACE $ + $ + $ + $ + $ + ) + set_target_properties(scc-shared PROPERTIES CXX_VISIBILITY_PRESET hidden) + target_link_libraries(scc-shared PUBLIC $ + $ + $ + $ + $ + ) + # set(LIB_LIST $ + # $ + # $ + # $ + # $ + # ) + # message("LIB_LIST=${LIB_LIST}") + # add_library(scc-shared SHARED src/scc.h) + # target_link_libraries(scc-shared PUBLIC + # -Wl,--whole-archive + # scc-util + # scc-sysc + # interfaces + # scv-tr + # tlm-interfaces + # -Wl,--no-whole-archive + # ) + # + if(TARGET Boost::stacktrace_backtrace) + target_link_libraries(scc-shared PUBLIC Boost::stacktrace_backtrace dl) + endif() + add_library(scc::scc-shared ALIAS scc-shared) + endif() install(TARGETS scc EXPORT scc-targets @@ -224,33 +236,33 @@ if(SystemC_FOUND) LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}${SCC_LIBRARY_DIR_MODIFIER} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}${SCC_LIBRARY_DIR_MODIFIER}${SCC_ARCHIVE_DIR_MODIFIER} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - ) - install(EXPORT scc-targets + ) + install(EXPORT scc-targets FILE scc-targets.cmake DESTINATION ${SCC_CMAKE_CONFIG_DIR} NAMESPACE scc:: + ) + if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + install(TARGETS scc-shared + EXPORT scc-shared-targets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}${SCC_LIBRARY_DIR_MODIFIER} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}${SCC_LIBRARY_DIR_MODIFIER}${SCC_ARCHIVE_DIR_MODIFIER} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + ) + install(EXPORT scc-shared-targets + FILE scc-shared-targets.cmake + DESTINATION ${SCC_CMAKE_CONFIG_DIR} + NAMESPACE scc:: ) - if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") - install(TARGETS scc-shared - EXPORT scc-shared-targets - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}${SCC_LIBRARY_DIR_MODIFIER} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}${SCC_LIBRARY_DIR_MODIFIER}${SCC_ARCHIVE_DIR_MODIFIER} - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - ) - install(EXPORT scc-shared-targets - FILE scc-shared-targets.cmake - DESTINATION ${SCC_CMAKE_CONFIG_DIR} - NAMESPACE scc:: - ) - endif() + endif() include(CMakePackageConfigHelpers) write_basic_package_version_file( ${CMAKE_CURRENT_BINARY_DIR}/scc-config-version.cmake VERSION ${PROJECT_VERSION} COMPATIBILITY AnyNewerVersion ) - + configure_package_config_file( ${CMAKE_CURRENT_LIST_DIR}/cmake/scc-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/scc-config.cmake @@ -265,7 +277,7 @@ else() add_subdirectory(third_party) endif() if(BUILD_SCC_DOCUMENTATION) - get_property(GENERATORS_FOLDER GLOBAL PROPERTY CONAN_GENERATORS_FOLDER ) + get_property(GENERATORS_FOLDER GLOBAL PROPERTY CONAN_GENERATORS_FOLDER) if(EXISTS "${GENERATORS_FOLDER}/conan_toolchain.cmake") include(${GENERATORS_FOLDER}/conan_toolchain.cmake) endif() @@ -276,13 +288,13 @@ endif() ############################################################################### install(DIRECTORY contrib/pysysc contrib/d3-hwschematic DESTINATION share - PATTERN ".gitignore" EXCLUDE + PATTERN ".gitignore" EXCLUDE PATTERN "PySysC_SCC.egg*" EXCLUDE PATTERN "build" EXCLUDE - ) +) install(DIRECTORY cmake DESTINATION share - ) +) if(CMAKE_PROJECT_NAME STREQUAL "scc") if(INSTALL_DEPENDENCIES) install(CODE "set(CMAKE_INSTALL_LIBDIR \"${CMAKE_INSTALL_LIBDIR}\")") diff --git a/cmake/Versioning.cmake b/cmake/Versioning.cmake new file mode 100644 index 00000000..c7f95e0a --- /dev/null +++ b/cmake/Versioning.cmake @@ -0,0 +1,166 @@ +include_guard(GLOBAL) + +function(scc_configure_version) + set(options + USE_GIT + RELEASE_ENFORCE_TAG + RELEASE_FAIL_DIRTY + INSTALL_HEADER + REPRODUCIBLE + ) + + set(oneValueArgs + TARGET + NAMESPACE + OUTPUT_HEADER + ABI_VERSION + TAG_PREFIX + ) + + cmake_parse_arguments(SCC "${options}" "${oneValueArgs}" "" ${ARGN}) + + if(NOT PROJECT_VERSION) + message(FATAL_ERROR "project(VERSION ...) is required") + endif() + + if(NOT SCC_TARGET OR NOT SCC_NAMESPACE OR NOT SCC_OUTPUT_HEADER) + message(FATAL_ERROR "TARGET, NAMESPACE and OUTPUT_HEADER required") + endif() + + set(VERSION_FULL "${PROJECT_VERSION}") + set(VERSION_MAJOR "${PROJECT_VERSION_MAJOR}") + set(VERSION_MINOR "${PROJECT_VERSION_MINOR}") + + # ------------------------------------------------------------ + # ABI version (explicit only) + # ------------------------------------------------------------ + if(SCC_ABI_VERSION) + set(ABI_VERSION "${SCC_ABI_VERSION}") + else() + set(ABI_VERSION "0") # default safe ABI + endif() + + # ------------------------------------------------------------ + # Git metadata + # ------------------------------------------------------------ + set(GIT_HASH "unknown") + set(GIT_DESCRIBE "") + set(GIT_DIRTY OFF) + + if(SCC_USE_GIT) + find_package(Git QUIET) + if(GIT_FOUND) + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + + execute_process( + COMMAND ${GIT_EXECUTABLE} describe --tags --dirty --always + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_DESCRIBE + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + + string(FIND "${GIT_DESCRIBE}" "-dirty" DIRTY_POS) + if(NOT DIRTY_POS EQUAL -1) + set(GIT_DIRTY ON) + endif() + endif() + endif() + + # ------------------------------------------------------------ + # Tag enforcement (exact match, optional prefix) + # ------------------------------------------------------------ + if(SCC_RELEASE_ENFORCE_TAG) + if(SCC_TAG_PREFIX) + set(EXPECTED_TAG "${SCC_TAG_PREFIX}${PROJECT_VERSION}") + else() + set(EXPECTED_TAG "${PROJECT_VERSION}") + endif() + + if(NOT GIT_DESCRIBE STREQUAL "${EXPECTED_TAG}") + message(FATAL_ERROR + "Release requires git tag '${EXPECTED_TAG}'") + endif() + endif() + + if(SCC_RELEASE_FAIL_DIRTY AND GIT_DIRTY) + message(FATAL_ERROR + "Release build from dirty working tree not allowed") + endif() + + # ------------------------------------------------------------ + # Reproducible timestamp support + # ------------------------------------------------------------ + if(SCC_REPRODUCIBLE AND DEFINED ENV{SOURCE_DATE_EPOCH}) + math(EXPR _epoch "$ENV{SOURCE_DATE_EPOCH}") + string(TIMESTAMP BUILD_TIMESTAMP "%Y-%m-%dT%H:%M:%SZ" + UTC ${_epoch}) + else() + string(TIMESTAMP BUILD_TIMESTAMP "%Y-%m-%dT%H:%M:%SZ" UTC) + endif() + + # ------------------------------------------------------------ + # Build metadata + # ------------------------------------------------------------ + if(CMAKE_BUILD_TYPE) + set(BUILD_TYPE "${CMAKE_BUILD_TYPE}") + else() + set(BUILD_TYPE "multi-config") + endif() + + set(COMPILER_ID "${CMAKE_CXX_COMPILER_ID}") + set(COMPILER_VERSION "${CMAKE_CXX_COMPILER_VERSION}") + + # ------------------------------------------------------------ + # Generate header + # ------------------------------------------------------------ + get_filename_component(_outdir ${SCC_OUTPUT_HEADER} DIRECTORY) + file(MAKE_DIRECTORY ${_outdir}) + + configure_file( + ${CMAKE_CURRENT_LIST_DIR}/src/scc_ver.h.in + ${SCC_OUTPUT_HEADER} + @ONLY + ) + + target_include_directories(${SCC_TARGET} + INTERFACE + $ + $ + ) + + # ------------------------------------------------------------ + # Shared library ABI / SOVERSION + # ------------------------------------------------------------ + get_target_property(_type ${SCC_TARGET} TYPE) + if(_type STREQUAL "SHARED_LIBRARY") + set_target_properties(${SCC_TARGET} PROPERTIES + VERSION ${VERSION_FULL} + SOVERSION ${ABI_VERSION} + ) + endif() + + # ------------------------------------------------------------ + # CPack propagation + # ------------------------------------------------------------ + set(CPACK_PACKAGE_VERSION "${VERSION_FULL}" PARENT_SCOPE) + + # ------------------------------------------------------------ + # Optional install + # ------------------------------------------------------------ + if(SCC_INSTALL_HEADER) + install(FILES ${SCC_OUTPUT_HEADER} + DESTINATION include) + endif() + + message(STATUS "Configured ${SCC_NAMESPACE} version ${VERSION_FULL}") + message(STATUS " ABI version: ${ABI_VERSION}") + message(STATUS " Git: ${GIT_HASH}") + message(STATUS " Dirty: ${GIT_DIRTY}") +endfunction() diff --git a/src/scc_ver.h.in b/src/scc_ver.h.in new file mode 100644 index 00000000..3dad5a63 --- /dev/null +++ b/src/scc_ver.h.in @@ -0,0 +1,15 @@ +#pragma once + +#define @SCC_NAMESPACE@_VERSION "@VERSION_FULL@" +#define @SCC_NAMESPACE@_VERSION_MAJOR @VERSION_MAJOR@ +#define @SCC_NAMESPACE@_VERSION_MINOR @VERSION_MINOR@ +#define @SCC_NAMESPACE@_ABI_VERSION "@ABI_VERSION@" + +#define @SCC_NAMESPACE@_GIT_HASH "@GIT_HASH@" +#define @SCC_NAMESPACE@_GIT_DIRTY @GIT_DIRTY@ + +#define @SCC_NAMESPACE@_BUILD_TIMESTAMP "@BUILD_TIMESTAMP@" +#define @SCC_NAMESPACE@_BUILD_TYPE "@BUILD_TYPE@" + +#define @SCC_NAMESPACE@_COMPILER_ID "@COMPILER_ID@" +#define @SCC_NAMESPACE@_COMPILER_VERSION "@COMPILER_VERSION@" \ No newline at end of file