From edb90c3cc44196c49388c9426dea156088336790 Mon Sep 17 00:00:00 2001 From: Gulfem Savrun Yeniceri Date: Mon, 4 May 2026 16:39:07 -0700 Subject: [PATCH 1/5] build: Add support for CMake builds 1) Add a root CMakeLists.txt file to provide cross-platform build support, making it easier to link against OpenCSD in large external projects. 2) Generate native CMake package files using OpenCSDConfig.cmake.in template. --- CMakeLists.txt | 188 +++++++++++++++++++++++++++++++++++++++++ OpenCSDConfig.cmake.in | 5 ++ 2 files changed, 193 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 OpenCSDConfig.cmake.in diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000000..3fc3435f2d0a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,188 @@ +################################################################### +# CMake build script for OpenCSD +# Provides core libraries, C-API wrappers, and trace packet lister. +################################################################### +cmake_minimum_required(VERSION 3.10) +project(OpenCSD VERSION 1.8.1 LANGUAGES C CXX) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_POSITION_INDEPENDENT_CODE ON) +set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) + +include(GNUInstallDirs) +include(CTest) + +# Suppress warnings emitted by MSVC/clang-cl and enable exceptions +if(MSVC) + set(OPENCSD_COMPILER_FLAGS /EHsc /W0 /clang:-Wno-invalid-token-paste) +elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR + CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR + CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + set(OPENCSD_COMPILER_FLAGS -Wall -Wno-switch -Wno-deprecated-declarations -Wno-unused-variable -Wno-reorder -Wno-invalid-token-paste -fexceptions) +endif() + +add_library(opencsd_options INTERFACE) +target_compile_options(opencsd_options INTERFACE ${OPENCSD_COMPILER_FLAGS}) +target_include_directories(opencsd_options INTERFACE + $ + $ +) + +# libopencsd +set(OPENCSD_SRCS + decoder/source/cs_frame_mux_data.cpp + decoder/source/ocsd_code_follower.cpp + decoder/source/ocsd_dcd_tree.cpp + decoder/source/ocsd_error.cpp + decoder/source/ocsd_error_logger.cpp + decoder/source/ocsd_gen_elem_list.cpp + decoder/source/ocsd_gen_elem_stack.cpp + decoder/source/ocsd_lib_dcd_register.cpp + decoder/source/ocsd_msg_logger.cpp + decoder/source/ocsd_version.cpp + decoder/source/trc_component.cpp + decoder/source/trc_core_arch_map.cpp + decoder/source/trc_frame_deformatter.cpp + decoder/source/trc_gen_elem.cpp + decoder/source/trc_printable_elem.cpp + decoder/source/trc_ret_stack.cpp + decoder/source/ete/trc_cmp_cfg_ete.cpp + decoder/source/etmv3/trc_cmp_cfg_etmv3.cpp + decoder/source/etmv3/trc_pkt_decode_etmv3.cpp + decoder/source/etmv3/trc_pkt_elem_etmv3.cpp + decoder/source/etmv3/trc_pkt_proc_etmv3.cpp + decoder/source/etmv3/trc_pkt_proc_etmv3_impl.cpp + decoder/source/etmv4/trc_cmp_cfg_etmv4.cpp + decoder/source/etmv4/trc_etmv4_stack_elem.cpp + decoder/source/etmv4/trc_pkt_decode_etmv4i.cpp + decoder/source/etmv4/trc_pkt_elem_etmv4i.cpp + decoder/source/etmv4/trc_pkt_proc_etmv4i.cpp + decoder/source/i_dec/trc_i_decode.cpp + decoder/source/i_dec/trc_idec_arminst.cpp + decoder/source/itm/trc_pkt_decode_itm.cpp + decoder/source/itm/trc_pkt_elem_itm.cpp + decoder/source/itm/trc_pkt_proc_itm.cpp + decoder/source/mem_acc/trc_mem_acc_base.cpp + decoder/source/mem_acc/trc_mem_acc_bufptr.cpp + decoder/source/mem_acc/trc_mem_acc_cache.cpp + decoder/source/mem_acc/trc_mem_acc_cb.cpp + decoder/source/mem_acc/trc_mem_acc_file.cpp + decoder/source/mem_acc/trc_mem_acc_mapper.cpp + decoder/source/pkt_printers/gen_elem_printer.cpp + decoder/source/pkt_printers/raw_frame_printer.cpp + decoder/source/pkt_printers/trc_print_fact.cpp + decoder/source/ptm/trc_cmp_cfg_ptm.cpp + decoder/source/ptm/trc_pkt_decode_ptm.cpp + decoder/source/ptm/trc_pkt_elem_ptm.cpp + decoder/source/ptm/trc_pkt_proc_ptm.cpp + decoder/source/stm/trc_pkt_decode_stm.cpp + decoder/source/stm/trc_pkt_elem_stm.cpp + decoder/source/stm/trc_pkt_proc_stm.cpp +) + +# libopencsd_c_api +set(OPENCSD_C_API_SRCS + decoder/source/c_api/ocsd_c_api.cpp + decoder/source/c_api/ocsd_c_api_custom_obj.cpp +) + +# Core OpenCSD library. Defaults to STATIC to bypass Windows DLL symbol export limitations. +add_library(opencsd ${OPENCSD_SRCS}) +add_library(OpenCSD::opencsd ALIAS opencsd) + +add_library(opencsd_c_api ${OPENCSD_C_API_SRCS}) +add_library(OpenCSD::opencsd_c_api ALIAS opencsd_c_api) + +target_link_libraries(opencsd_c_api PUBLIC opencsd) + +set_target_properties(opencsd PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR} +) + +set_target_properties(opencsd_c_api PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR} +) + +target_link_libraries(opencsd PUBLIC opencsd_options) +target_link_libraries(opencsd_c_api PRIVATE opencsd_options) + +target_include_directories(opencsd PRIVATE decoder/source) +target_include_directories(opencsd_c_api PRIVATE decoder/source) + +if(BUILD_TESTING) +# snapshot_parser_lib +set(SNAPSHOT_PARSER_SRCS + decoder/tests/snapshot_parser_lib/source/device_info.cpp + decoder/tests/snapshot_parser_lib/source/device_parser.cpp + decoder/tests/snapshot_parser_lib/source/snapshot_parser.cpp + decoder/tests/snapshot_parser_lib/source/snapshot_parser_util.cpp + decoder/tests/snapshot_parser_lib/source/snapshot_reader.cpp + decoder/tests/snapshot_parser_lib/source/ss_to_dcdtree.cpp +) + +add_library(snapshot_parser STATIC ${SNAPSHOT_PARSER_SRCS}) +target_include_directories(snapshot_parser PRIVATE + decoder/tests/snapshot_parser_lib/include + decoder/include +) +target_compile_options(snapshot_parser PRIVATE ${OPENCSD_COMPILER_FLAGS}) + +# trc_pkt_lister +add_executable(trc_pkt_lister decoder/tests/source/trc_pkt_lister.cpp) +target_include_directories(trc_pkt_lister PRIVATE + decoder/tests/snapshot_parser_lib/include + decoder/tests/source +) +target_link_libraries(trc_pkt_lister PRIVATE snapshot_parser opencsd) +target_compile_options(trc_pkt_lister PRIVATE ${OPENCSD_COMPILER_FLAGS}) + +endif() # BUILD_TESTING + +install(TARGETS opencsd opencsd_c_api opencsd_options + EXPORT OpenCSDTargets + COMPONENT development + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) + +if(BUILD_TESTING) + install(TARGETS trc_pkt_lister + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) +endif() + +install(DIRECTORY decoder/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + +# Generate the targets file (handles library paths and dependencies automatically) +install(EXPORT OpenCSDTargets + FILE OpenCSDTargets.cmake + NAMESPACE OpenCSD:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/OpenCSD +) + +# Generate the master configuration file +include(CMakePackageConfigHelpers) + +configure_package_config_file( + ${CMAKE_CURRENT_SOURCE_DIR}/OpenCSDConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/OpenCSDConfig.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/OpenCSD +) + +# Generate the version file +write_basic_package_version_file( + ${CMAKE_CURRENT_BINARY_DIR}/OpenCSDConfigVersion.cmake + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion +) + +# Install the configuration files +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/OpenCSDConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/OpenCSDConfigVersion.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/OpenCSD +) diff --git a/OpenCSDConfig.cmake.in b/OpenCSDConfig.cmake.in new file mode 100644 index 000000000000..6665c69c7859 --- /dev/null +++ b/OpenCSDConfig.cmake.in @@ -0,0 +1,5 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/OpenCSDTargets.cmake") + +check_required_components(OpenCSD) From 62d66feb89fb9c9d8a792b4c8725821e34b49bf2 Mon Sep 17 00:00:00 2001 From: Mike Leach Date: Thu, 7 May 2026 15:32:46 +0100 Subject: [PATCH 2/5] build: cmake: Update cmake build for linux and windows. CMake linux build updated to match the existing makefiles full project build by default. CMake windows build updated to ensure full windows build works. Option to build only the static libs retained. Added docs to explain CMake use. Added python helper script to drive cmake tools on each platform for ease of testing CMake builds. Signed-off-by: Mike Leach --- CMakeLists.txt | 471 +++++++++++++++--- .../build/cmake/OpenCSDConfig.cmake.in | 0 decoder/build/cmake/build_cmake.py | 407 +++++++++++++++ decoder/build/cmake/uninstall.cmake.in | 17 + decoder/docs/build_cmake.md | 210 ++++++++ 5 files changed, 1049 insertions(+), 56 deletions(-) rename OpenCSDConfig.cmake.in => decoder/build/cmake/OpenCSDConfig.cmake.in (100%) create mode 100644 decoder/build/cmake/build_cmake.py create mode 100644 decoder/build/cmake/uninstall.cmake.in create mode 100644 decoder/docs/build_cmake.md diff --git a/CMakeLists.txt b/CMakeLists.txt index 3fc3435f2d0a..86df5dce260c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ ################################################################### # CMake build script for OpenCSD -# Provides core libraries, C-API wrappers, and trace packet lister. +# Default mode mirrors the full project Linux makefile target set and output layout. ################################################################### cmake_minimum_required(VERSION 3.10) project(OpenCSD VERSION 1.8.1 LANGUAGES C CXX) @@ -10,26 +10,160 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_POSITION_INDEPENDENT_CODE ON) set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) +option(OPENCSD_BUILD_MIN_LIB_STATIC "Build the minimal static-library-oriented target set for integration into larger environments." OFF) + +if(NOT DEFINED BUILD_TESTING) + if(OPENCSD_BUILD_MIN_LIB_STATIC) + set(BUILD_TESTING OFF CACHE BOOL "Build the testing tree." FORCE) + else() + set(BUILD_TESTING ON CACHE BOOL "Build the testing tree." FORCE) + endif() +endif() + include(GNUInstallDirs) include(CTest) -# Suppress warnings emitted by MSVC/clang-cl and enable exceptions +option(OPENCSD_FULL_PROJECT_LAYOUT "Write outputs into decoder/lib|tests/*/builddir for the full project build." ON) +option(OPENCSD_BUILD_DEV_TARGETS "Build full project development-only targets." OFF) + if(MSVC) - set(OPENCSD_COMPILER_FLAGS /EHsc /W0 /clang:-Wno-invalid-token-paste) + if(OPENCSD_BUILD_MIN_LIB_STATIC) + set(OPENCSD_C_FLAGS) + set(OPENCSD_CXX_FLAGS + /EHsc + /W0 + /clang:-Wno-invalid-token-paste + ) + set(OPENCSD_LINK_FLAGS) + else() + set(OPENCSD_C_FLAGS + /W0 + ) + set(OPENCSD_CXX_FLAGS + /EHsc + /W0 + /clang:-Wno-invalid-token-paste + ) + set(OPENCSD_LINK_FLAGS) + endif() elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") - set(OPENCSD_COMPILER_FLAGS -Wall -Wno-switch -Wno-deprecated-declarations -Wno-unused-variable -Wno-reorder -Wno-invalid-token-paste -fexceptions) + if(OPENCSD_BUILD_MIN_LIB_STATIC) + set(OPENCSD_C_FLAGS) + set(OPENCSD_CXX_FLAGS + -Wall + -Wno-switch + -Wno-deprecated-declarations + -Wno-unused-variable + -Wno-reorder + -Wno-invalid-token-paste + -fexceptions + ) + set(OPENCSD_LINK_FLAGS) + else() + set(OPENCSD_C_FLAGS + -Wall + -Wno-switch + -Wlogical-op + ) + set(OPENCSD_CXX_FLAGS + -Wall + -Wno-switch + -Wno-deprecated-declarations + -Wno-unused-variable + -Wno-reorder + -Wno-invalid-token-paste + -Wlogical-op + -fexceptions + ) + set(OPENCSD_LINK_FLAGS + -Wl,-z,defs + ) + endif() +else() + set(OPENCSD_C_FLAGS) + set(OPENCSD_CXX_FLAGS) + set(OPENCSD_LINK_FLAGS) endif() add_library(opencsd_options INTERFACE) -target_compile_options(opencsd_options INTERFACE ${OPENCSD_COMPILER_FLAGS}) +target_compile_options(opencsd_options INTERFACE + $<$:${OPENCSD_C_FLAGS}> + $<$:${OPENCSD_CXX_FLAGS}> +) +target_link_options(opencsd_options INTERFACE ${OPENCSD_LINK_FLAGS}) target_include_directories(opencsd_options INTERFACE $ $ ) -# libopencsd +set(OPENCSD_LIB_OUT "${CMAKE_CURRENT_SOURCE_DIR}/decoder/lib/builddir") +set(OPENCSD_TLIB_OUT "${CMAKE_CURRENT_SOURCE_DIR}/decoder/tests/lib/builddir") +set(OPENCSD_BIN_OUT "${CMAKE_CURRENT_SOURCE_DIR}/decoder/tests/bin/builddir") + +function(opencsd_set_output_dirs target kind) + if(NOT OPENCSD_FULL_PROJECT_LAYOUT) + return() + endif() + + if(kind STREQUAL "lib") + set(out_dir "${OPENCSD_LIB_OUT}") + elseif(kind STREQUAL "testlib") + set(out_dir "${OPENCSD_TLIB_OUT}") + elseif(kind STREQUAL "bin") + set(out_dir "${OPENCSD_BIN_OUT}") + else() + message(FATAL_ERROR "Unknown output kind '${kind}' for target '${target}'") + endif() + + set_target_properties(${target} PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY "${out_dir}" + LIBRARY_OUTPUT_DIRECTORY "${out_dir}" + RUNTIME_OUTPUT_DIRECTORY "${out_dir}" + ) +endfunction() + +function(opencsd_stage_shared_libs target) + if(NOT OPENCSD_FULL_PROJECT_LAYOUT) + return() + endif() + + foreach(shared_tgt IN ITEMS opencsd opencsd_c_api) + if(WIN32) + add_custom_command(TARGET ${target} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + $ + $/$ + VERBATIM + ) + else() + add_custom_command(TARGET ${target} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + $ + $/$ + COMMAND ${CMAKE_COMMAND} -E create_symlink + $ + $/$ + COMMAND ${CMAKE_COMMAND} -E create_symlink + $ + $/$ + VERBATIM + ) + endif() + endforeach() +endfunction() + +function(opencsd_add_test_executable target) + cmake_parse_arguments(ARG "" "SOURCE" "SOURCES;INCLUDES;LIBS" ${ARGN}) + + add_executable(${target} ${ARG_SOURCE} ${ARG_SOURCES}) + target_include_directories(${target} PRIVATE ${ARG_INCLUDES}) + target_link_libraries(${target} PRIVATE opencsd_options ${ARG_LIBS}) + opencsd_set_output_dirs(${target} "bin") + opencsd_stage_shared_libs(${target}) +endfunction() + set(OPENCSD_SRCS decoder/source/cs_frame_mux_data.cpp decoder/source/ocsd_code_follower.cpp @@ -81,39 +215,11 @@ set(OPENCSD_SRCS decoder/source/stm/trc_pkt_proc_stm.cpp ) -# libopencsd_c_api set(OPENCSD_C_API_SRCS decoder/source/c_api/ocsd_c_api.cpp decoder/source/c_api/ocsd_c_api_custom_obj.cpp ) -# Core OpenCSD library. Defaults to STATIC to bypass Windows DLL symbol export limitations. -add_library(opencsd ${OPENCSD_SRCS}) -add_library(OpenCSD::opencsd ALIAS opencsd) - -add_library(opencsd_c_api ${OPENCSD_C_API_SRCS}) -add_library(OpenCSD::opencsd_c_api ALIAS opencsd_c_api) - -target_link_libraries(opencsd_c_api PUBLIC opencsd) - -set_target_properties(opencsd PROPERTIES - VERSION ${PROJECT_VERSION} - SOVERSION ${PROJECT_VERSION_MAJOR} -) - -set_target_properties(opencsd_c_api PROPERTIES - VERSION ${PROJECT_VERSION} - SOVERSION ${PROJECT_VERSION_MAJOR} -) - -target_link_libraries(opencsd PUBLIC opencsd_options) -target_link_libraries(opencsd_c_api PRIVATE opencsd_options) - -target_include_directories(opencsd PRIVATE decoder/source) -target_include_directories(opencsd_c_api PRIVATE decoder/source) - -if(BUILD_TESTING) -# snapshot_parser_lib set(SNAPSHOT_PARSER_SRCS decoder/tests/snapshot_parser_lib/source/device_info.cpp decoder/tests/snapshot_parser_lib/source/device_parser.cpp @@ -123,25 +229,268 @@ set(SNAPSHOT_PARSER_SRCS decoder/tests/snapshot_parser_lib/source/ss_to_dcdtree.cpp ) -add_library(snapshot_parser STATIC ${SNAPSHOT_PARSER_SRCS}) -target_include_directories(snapshot_parser PRIVATE - decoder/tests/snapshot_parser_lib/include - decoder/include -) -target_compile_options(snapshot_parser PRIVATE ${OPENCSD_COMPILER_FLAGS}) +if(OPENCSD_BUILD_MIN_LIB_STATIC) + add_library(opencsd STATIC ${OPENCSD_SRCS}) + add_library(OpenCSD::opencsd ALIAS opencsd) + target_link_libraries(opencsd PUBLIC opencsd_options) + target_include_directories(opencsd PRIVATE decoder/source) + set_target_properties(opencsd PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR} + ) + + add_library(opencsd_c_api STATIC ${OPENCSD_C_API_SRCS}) + add_library(OpenCSD::opencsd_c_api ALIAS opencsd_c_api) + target_link_libraries(opencsd_c_api PUBLIC opencsd PRIVATE opencsd_options) + target_include_directories(opencsd_c_api PRIVATE decoder/source) + if(WIN32) + target_compile_definitions(opencsd_c_api PUBLIC OCSD_USE_STATIC_C_API) + endif() + set_target_properties(opencsd_c_api PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR} + ) +else() + add_library(opencsd_obj OBJECT ${OPENCSD_SRCS}) + target_link_libraries(opencsd_obj PRIVATE opencsd_options) + target_include_directories(opencsd_obj PRIVATE decoder/source) + + add_library(opencsd SHARED $) + add_library(OpenCSD::opencsd ALIAS opencsd) + target_link_libraries(opencsd PUBLIC opencsd_options) + set_target_properties(opencsd PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR} + ) + if(WIN32) + set_target_properties(opencsd PROPERTIES + RUNTIME_OUTPUT_NAME opencsd + ARCHIVE_OUTPUT_NAME opencsd_dll + ) + endif() + opencsd_set_output_dirs(opencsd "lib") + + add_library(opencsd_static STATIC $) + add_library(OpenCSD::opencsd_static ALIAS opencsd_static) + target_link_libraries(opencsd_static PUBLIC opencsd_options) + set_target_properties(opencsd_static PROPERTIES + OUTPUT_NAME opencsd + ) + opencsd_set_output_dirs(opencsd_static "lib") -# trc_pkt_lister -add_executable(trc_pkt_lister decoder/tests/source/trc_pkt_lister.cpp) -target_include_directories(trc_pkt_lister PRIVATE - decoder/tests/snapshot_parser_lib/include - decoder/tests/source + add_library(opencsd_c_api_obj_shared OBJECT ${OPENCSD_C_API_SRCS}) + target_link_libraries(opencsd_c_api_obj_shared PRIVATE opencsd_options) + target_include_directories(opencsd_c_api_obj_shared PRIVATE decoder/source) + if(WIN32) + target_compile_definitions(opencsd_c_api_obj_shared PRIVATE _OCSD_C_API_DLL_EXPORT) + endif() + + add_library(opencsd_c_api SHARED $) + add_library(OpenCSD::opencsd_c_api ALIAS opencsd_c_api) + if(WIN32) + target_link_libraries(opencsd_c_api PRIVATE opencsd_static opencsd_options) + else() + target_link_libraries(opencsd_c_api PUBLIC opencsd PRIVATE opencsd_options) + endif() + set_target_properties(opencsd_c_api PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR} + ) + if(WIN32) + set_target_properties(opencsd_c_api PROPERTIES + RUNTIME_OUTPUT_NAME opencsd_c_api + ARCHIVE_OUTPUT_NAME opencsd_c_api_dll + ) + endif() + opencsd_set_output_dirs(opencsd_c_api "lib") + + add_library(opencsd_c_api_obj_static OBJECT ${OPENCSD_C_API_SRCS}) + target_link_libraries(opencsd_c_api_obj_static PRIVATE opencsd_options) + target_include_directories(opencsd_c_api_obj_static PRIVATE decoder/source) + if(WIN32) + target_compile_definitions(opencsd_c_api_obj_static PRIVATE OCSD_USE_STATIC_C_API) + endif() + + add_library(opencsd_c_api_static STATIC $) + add_library(OpenCSD::opencsd_c_api_static ALIAS opencsd_c_api_static) + target_link_libraries(opencsd_c_api_static PUBLIC opencsd_static PRIVATE opencsd_options) + if(WIN32) + target_compile_definitions(opencsd_c_api_static INTERFACE OCSD_USE_STATIC_C_API) + endif() + set_target_properties(opencsd_c_api_static PROPERTIES + OUTPUT_NAME opencsd_c_api + ) + opencsd_set_output_dirs(opencsd_c_api_static "lib") + + add_custom_target(libs DEPENDS + opencsd + opencsd_static + opencsd_c_api + opencsd_c_api_static + ) +endif() + +if(BUILD_TESTING) + if(OPENCSD_BUILD_MIN_LIB_STATIC) + add_library(snapshot_parser STATIC ${SNAPSHOT_PARSER_SRCS}) + target_include_directories(snapshot_parser PRIVATE + decoder/tests/snapshot_parser_lib/include + decoder/include + ) + target_link_libraries(snapshot_parser PRIVATE opencsd_options) + + add_executable(trc_pkt_lister decoder/tests/source/trc_pkt_lister.cpp) + target_include_directories(trc_pkt_lister PRIVATE + decoder/tests/snapshot_parser_lib/include + decoder/tests/source + ) + target_link_libraries(trc_pkt_lister PRIVATE snapshot_parser opencsd) + target_compile_options(trc_pkt_lister PRIVATE ${OPENCSD_CXX_FLAGS}) + else() + add_library(snapshot_parser STATIC ${SNAPSHOT_PARSER_SRCS}) + target_include_directories(snapshot_parser PRIVATE + decoder/tests/snapshot_parser_lib/include + decoder/include + ) + target_link_libraries(snapshot_parser PRIVATE opencsd_options) + opencsd_set_output_dirs(snapshot_parser "testlib") + + add_library(echo_test_dcd STATIC + decoder/tests/ext_dcd_test_eg/c_api_echo_test/ext_dcd_echo_test.c + decoder/tests/ext_dcd_test_eg/c_api_echo_test/ext_dcd_echo_test_fact.c + ) + target_include_directories(echo_test_dcd PRIVATE + decoder/tests/ext_dcd_test_eg/c_api_echo_test + decoder/include + ) + target_link_libraries(echo_test_dcd PRIVATE opencsd_options) + opencsd_set_output_dirs(echo_test_dcd "testlib") + + opencsd_add_test_executable(trc_pkt_lister + SOURCE decoder/tests/source/trc_pkt_lister.cpp + INCLUDES + decoder/tests/snapshot_parser_lib/include + decoder/tests/source + LIBS + snapshot_parser + opencsd + ) + + opencsd_add_test_executable(c_api_pkt_print_test + SOURCE decoder/tests/source/c_api_pkt_print_test.c + INCLUDES + decoder/tests/source + decoder/tests/ext_dcd_test_eg/c_api_echo_test + LIBS + echo_test_dcd + opencsd + opencsd_c_api + ) + set_target_properties(c_api_pkt_print_test PROPERTIES + LINKER_LANGUAGE CXX + ) + + opencsd_add_test_executable(mem-buffer-eg + SOURCE decoder/tests/source/mem_buff_demo.cpp + INCLUDES + decoder/tests/source + decoder/tests/snapshot_parser_lib/include + LIBS + snapshot_parser + opencsd + ) + + opencsd_add_test_executable(frame-demux-test + SOURCE decoder/tests/source/frame_demux_test.cpp + INCLUDES + decoder/tests/source + LIBS + opencsd + ) + + opencsd_add_test_executable(ocsd-perr + SOURCE decoder/tests/source/perr.cpp + INCLUDES + decoder/tests/source + LIBS + opencsd + ) + + opencsd_add_test_executable(mem-acc-test + SOURCE decoder/tests/source/mem_acc_test.cpp + INCLUDES + decoder/tests/source + LIBS + opencsd + ) + + opencsd_add_test_executable(itm-decode-test + SOURCE decoder/tests/source/itm_decode_test.cpp + SOURCES + decoder/tests/source/itm_test_data.cpp + INCLUDES + decoder/tests/source + LIBS + opencsd + ) + + if(OPENCSD_BUILD_DEV_TARGETS) + add_executable(trc_pkt_lister_s decoder/tests/source/trc_pkt_lister.cpp) + target_include_directories(trc_pkt_lister_s PRIVATE + decoder/tests/snapshot_parser_lib/include + decoder/tests/source + ) + target_link_libraries(trc_pkt_lister_s PRIVATE + opencsd_options + snapshot_parser + opencsd_static + ) + target_link_options(trc_pkt_lister_s PRIVATE -static) + opencsd_set_output_dirs(trc_pkt_lister_s "bin") + endif() + + add_custom_target(tests DEPENDS + echo_test_dcd + snapshot_parser + trc_pkt_lister + c_api_pkt_print_test + mem-buffer-eg + frame-demux-test + ocsd-perr + mem-acc-test + itm-decode-test + ) + endif() +else() + if(NOT OPENCSD_BUILD_MIN_LIB_STATIC) + add_custom_target(tests) + endif() +endif() + +if(NOT OPENCSD_BUILD_MIN_LIB_STATIC) + find_package(Doxygen QUIET) + if(DOXYGEN_FOUND) + add_custom_target(docs + COMMAND ${DOXYGEN_EXECUTABLE} doxygen_config.dox + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/decoder/docs + ) + endif() +endif() + +set(OPENCSD_INSTALL_TARGETS + opencsd + opencsd_c_api + opencsd_options ) -target_link_libraries(trc_pkt_lister PRIVATE snapshot_parser opencsd) -target_compile_options(trc_pkt_lister PRIVATE ${OPENCSD_COMPILER_FLAGS}) -endif() # BUILD_TESTING +if(NOT OPENCSD_BUILD_MIN_LIB_STATIC) + list(APPEND OPENCSD_INSTALL_TARGETS + opencsd_static + opencsd_c_api_static + ) +endif() -install(TARGETS opencsd opencsd_c_api opencsd_options +install(TARGETS ${OPENCSD_INSTALL_TARGETS} EXPORT OpenCSDTargets COMPONENT development ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} @@ -149,40 +498,50 @@ install(TARGETS opencsd opencsd_c_api opencsd_options RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) -if(BUILD_TESTING) +if(BUILD_TESTING AND NOT OPENCSD_BUILD_MIN_LIB_STATIC) install(TARGETS trc_pkt_lister RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) + + install(FILES decoder/docs/man/trc_pkt_lister.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) endif() -install(DIRECTORY decoder/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +install(DIRECTORY decoder/include/opencsd/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/opencsd) -# Generate the targets file (handles library paths and dependencies automatically) install(EXPORT OpenCSDTargets FILE OpenCSDTargets.cmake NAMESPACE OpenCSD:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/OpenCSD ) -# Generate the master configuration file include(CMakePackageConfigHelpers) configure_package_config_file( - ${CMAKE_CURRENT_SOURCE_DIR}/OpenCSDConfig.cmake.in + ${CMAKE_CURRENT_SOURCE_DIR}/decoder/build/cmake/OpenCSDConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/OpenCSDConfig.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/OpenCSD ) -# Generate the version file write_basic_package_version_file( ${CMAKE_CURRENT_BINARY_DIR}/OpenCSDConfigVersion.cmake VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion ) -# Install the configuration files install(FILES ${CMAKE_CURRENT_BINARY_DIR}/OpenCSDConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/OpenCSDConfigVersion.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/OpenCSD ) + +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/decoder/build/cmake/uninstall.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/uninstall.cmake + @ONLY +) + +add_custom_target(uninstall + COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/uninstall.cmake +) + +add_custom_target(clean_install DEPENDS uninstall) diff --git a/OpenCSDConfig.cmake.in b/decoder/build/cmake/OpenCSDConfig.cmake.in similarity index 100% rename from OpenCSDConfig.cmake.in rename to decoder/build/cmake/OpenCSDConfig.cmake.in diff --git a/decoder/build/cmake/build_cmake.py b/decoder/build/cmake/build_cmake.py new file mode 100644 index 000000000000..fb938ed7d6ba --- /dev/null +++ b/decoder/build/cmake/build_cmake.py @@ -0,0 +1,407 @@ +#!/usr/bin/env python3 +""" +Wrapper around the OpenCSD CMake build. + +Supports the common repo-local workflows: +- configure + build +- build only from a previously configured build tree +- remove a build tree +- optional Debug configuration +- optional minimal library mode +- optional install / uninstall / clean_install targets without rebuilding +""" + +from __future__ import annotations + +import argparse +import os +import pathlib +import shutil +import subprocess +import sys + + +SCRIPT_PATH = pathlib.Path(__file__).resolve() +SCRIPT_DIR = SCRIPT_PATH.parent + + +def find_repo_root(start_dir: pathlib.Path) -> pathlib.Path: + for candidate in (start_dir, *start_dir.parents): + if (candidate / "CMakeLists.txt").is_file() and ( + candidate / "decoder" / "build" / "cmake" + ).is_dir(): + return candidate + raise RuntimeError( + f"could not locate repository root from script path {start_dir}" + ) + + +REPO_ROOT = find_repo_root(SCRIPT_DIR) + + +def default_generator() -> str: + if sys.platform == "win32": + return "Visual Studio 17 2022" + return "Unix Makefiles" + + +def is_multi_config_generator(generator: str) -> bool: + return ( + generator.startswith("Visual Studio") + or generator == "Xcode" + or generator.endswith("Multi-Config") + ) + + +def default_build_config(args: argparse.Namespace) -> str: + if args.config: + return args.config + return "Debug" if args.debug else "Release" + + +def default_platform(generator: str) -> str | None: + if sys.platform == "win32" and generator.startswith("Visual Studio"): + return "x64" + return None + + +def find_windows_cmake() -> str | None: + program_files_x86 = pathlib.Path( + os.environ.get("ProgramFiles(x86)", r"C:\Program Files (x86)") + ) + vswhere = program_files_x86 / "Microsoft Visual Studio" / "Installer" / "vswhere.exe" + if vswhere.is_file(): + try: + result = subprocess.run( + [ + str(vswhere), + "-latest", + "-products", + "*", + "-find", + r"Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe", + ], + check=True, + capture_output=True, + text=True, + ) + cmake_path = result.stdout.strip() + if cmake_path: + return cmake_path + except (OSError, subprocess.CalledProcessError): + pass + + for edition in ("Enterprise", "Professional", "Community", "BuildTools"): + candidate = ( + pathlib.Path(r"C:\Program Files") + / "Microsoft Visual Studio" + / "2022" + / edition + / "Common7" + / "IDE" + / "CommonExtensions" + / "Microsoft" + / "CMake" + / "CMake" + / "bin" + / "cmake.exe" + ) + if candidate.is_file(): + return str(candidate) + + return None + + +def resolve_cmake() -> str: + cmake = shutil.which("cmake") + if cmake: + return cmake + + if sys.platform == "win32": + cmake = find_windows_cmake() + if cmake: + return cmake + + raise RuntimeError( + "could not locate 'cmake' on PATH" + + ( + " or in the Visual Studio bundled CMake location" + if sys.platform == "win32" + else "" + ) + ) + + +def default_build_dir(args: argparse.Namespace) -> pathlib.Path: + name = "build-cmake" + if args.minimal: + name += "-min" + if args.debug: + name += "-debug" + return SCRIPT_DIR / name + + +def run_cmd(cmd: list[str], cwd: pathlib.Path) -> None: + print("+", " ".join(cmd)) + subprocess.run(cmd, cwd=str(cwd), check=True) + + +def is_configured_build_dir(build_dir: pathlib.Path) -> bool: + return (build_dir / "CMakeCache.txt").is_file() + + +def remove_build_dir(build_dir: pathlib.Path) -> None: + if build_dir.exists(): + print(f"+ remove build directory {build_dir}") + shutil.rmtree(build_dir) + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser( + description="Configure and drive the OpenCSD CMake build." + ) + parser.add_argument( + "--build-dir", + type=pathlib.Path, + help=( + "Out-of-source build directory. Defaults to a mode-specific " + "subdirectory under decoder/build/cmake." + ), + ) + parser.add_argument( + "--generator", + help=( + "CMake generator to use. Defaults to " + f'"{default_generator()}" on this platform.' + ), + ) + parser.add_argument( + "--platform", + help=( + "Platform passed to CMake via -A for Visual Studio generators. " + 'Defaults to "x64" on Windows Visual Studio builds.' + ), + ) + parser.add_argument( + "--debug", + action="store_true", + help=( + "Use a Debug build. For single-config generators this sets " + "-DCMAKE_BUILD_TYPE=Debug; for multi-config generators it " + "selects --config Debug." + ), + ) + parser.add_argument( + "--config", + choices=("Debug", "Release"), + help=( + "Build configuration. Defaults to Release, or Debug when " + "--debug is set." + ), + ) + parser.add_argument( + "--minimal", + action="store_true", + help="Configure with -DOPENCSD_BUILD_MIN_LIB_STATIC=ON.", + ) + parser.add_argument( + "--jobs", + type=int, + help="Parallel build job count passed to cmake --build --parallel.", + ) + parser.add_argument( + "--configure-only", + action="store_true", + help="Run CMake configure only.", + ) + parser.add_argument( + "--clean", + action="store_true", + help="Remove the selected build directory before any other action, or remove it and exit if no other action is requested.", + ) + parser.add_argument( + "--no-configure", + action="store_true", + help="Reuse an already configured build directory and skip CMake configure.", + ) + parser.add_argument( + "--no-build", + action="store_true", + help="Skip cmake --build so install/uninstall can operate on a previous build.", + ) + parser.add_argument( + "--install", + action="store_true", + help="Run cmake --install after building.", + ) + parser.add_argument( + "--install-prefix", + type=pathlib.Path, + help="Installation prefix passed to cmake --install.", + ) + parser.add_argument( + "--uninstall", + action="store_true", + help="Run the generated uninstall target after the main action.", + ) + parser.add_argument( + "--clean-install", + action="store_true", + help="Run the generated clean_install target after the main action.", + ) + parser.add_argument( + "--build-testing", + choices=("ON", "OFF"), + help="Explicit BUILD_TESTING setting. If omitted, project defaults apply.", + ) + parser.add_argument( + "--full-project-layout", + choices=("ON", "OFF"), + help="Explicit OPENCSD_FULL_PROJECT_LAYOUT setting. If omitted, project defaults apply.", + ) + args = parser.parse_args() + + if args.configure_only and args.no_configure: + parser.error("--configure-only cannot be used with --no-configure") + if args.install_prefix and not args.install: + parser.error("--install-prefix requires --install") + if args.no_build and args.configure_only: + parser.error("--no-build cannot be used with --configure-only") + if args.clean and args.no_configure: + parser.error("--clean cannot be combined with --no-configure") + if args.clean and args.no_build: + parser.error("--clean cannot be combined with --no-build") + if args.no_build and not (args.install or args.uninstall or args.clean_install): + parser.error( + "--no-build requires one of --install, --uninstall, or --clean-install" + ) + + return args + + +def main() -> int: + args = parse_args() + cmake = resolve_cmake() + generator = args.generator or default_generator() + build_config = default_build_config(args) + platform_name = args.platform or default_platform(generator) + build_dir = (args.build_dir or default_build_dir(args)).resolve() + + if args.debug and args.config == "Release": + raise RuntimeError("--debug cannot be combined with --config Release") + if platform_name and not generator.startswith("Visual Studio"): + raise RuntimeError("--platform is only supported with Visual Studio generators") + + if args.clean: + remove_build_dir(build_dir) + if not ( + args.configure_only + or args.install + or args.uninstall + or args.clean_install + or args.debug + or args.minimal + or args.build_testing + or args.full_project_layout + ): + return 0 + + if args.no_configure: + if not is_configured_build_dir(build_dir): + raise RuntimeError( + f"build directory is not configured: {build_dir}. " + "Run without --no-configure first." + ) + else: + cmake_args = [ + cmake, + "-S", + str(REPO_ROOT), + "-B", + str(build_dir), + "-G", + generator, + ] + + if platform_name: + cmake_args.extend(["-A", platform_name]) + if is_multi_config_generator(generator): + pass + else: + cmake_args.append(f"-DCMAKE_BUILD_TYPE={build_config}") + if args.minimal: + cmake_args.append("-DOPENCSD_BUILD_MIN_LIB_STATIC=ON") + if args.build_testing: + cmake_args.append(f"-DBUILD_TESTING={args.build_testing}") + if args.full_project_layout: + cmake_args.append( + f"-DOPENCSD_FULL_PROJECT_LAYOUT={args.full_project_layout}" + ) + + build_dir.mkdir(parents=True, exist_ok=True) + run_cmd(cmake_args, REPO_ROOT) + + if not args.configure_only and not args.no_build: + build_cmd = [cmake, "--build", str(build_dir)] + if is_multi_config_generator(generator): + build_cmd.extend(["--config", build_config]) + if args.jobs: + build_cmd.extend(["--parallel", str(args.jobs)]) + run_cmd(build_cmd, REPO_ROOT) + + if args.install: + install_cmd = [cmake, "--install", str(build_dir)] + if is_multi_config_generator(generator): + install_cmd.extend(["--config", build_config]) + if args.install_prefix: + install_cmd.extend(["--prefix", str(args.install_prefix.resolve())]) + run_cmd(install_cmd, REPO_ROOT) + + if args.clean_install: + run_cmd( + [ + cmake, + "--build", + str(build_dir), + "--target", + "clean_install", + ] + + ( + ["--config", build_config] + if is_multi_config_generator(generator) + else [] + ), + REPO_ROOT, + ) + elif args.uninstall: + run_cmd( + [ + cmake, + "--build", + str(build_dir), + "--target", + "uninstall", + ] + + ( + ["--config", build_config] + if is_multi_config_generator(generator) + else [] + ), + REPO_ROOT, + ) + + return 0 + + +if __name__ == "__main__": + try: + raise SystemExit(main()) + except subprocess.CalledProcessError as exc: + print(f"command failed with exit code {exc.returncode}", file=sys.stderr) + raise SystemExit(exc.returncode) + except RuntimeError as exc: + print(str(exc), file=sys.stderr) + raise SystemExit(2) + except KeyboardInterrupt: + print("interrupted", file=sys.stderr) + raise SystemExit(130) diff --git a/decoder/build/cmake/uninstall.cmake.in b/decoder/build/cmake/uninstall.cmake.in new file mode 100644 index 000000000000..e0c258ca3d5e --- /dev/null +++ b/decoder/build/cmake/uninstall.cmake.in @@ -0,0 +1,17 @@ +if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") +endif() + +file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +string(REPLACE "\n" ";" files "${files}") + +foreach(file ${files}) + if(file STREQUAL "") + continue() + endif() + + if(IS_SYMLINK "${file}" OR EXISTS "${file}") + message(STATUS "Removing ${file}") + file(REMOVE "${file}") + endif() +endforeach() diff --git a/decoder/docs/build_cmake.md b/decoder/docs/build_cmake.md new file mode 100644 index 000000000000..4a2e6a2407aa --- /dev/null +++ b/decoder/docs/build_cmake.md @@ -0,0 +1,210 @@ +# OpenCSD: Building with CMake + +## Build Modes + +The CMake build now supports two modes: + +- `OPENCSD_BUILD_MIN_LIB_STATIC=ON` + Minimal library/static-oriented build for integration into larger environments: + - builds `opencsd` and `opencsd_c_api` + - builds `snapshot_parser` and `trc_pkt_lister` when `BUILD_TESTING=ON` + - provides `install`, `uninstall`, and `clean_install` targets for the minimal library target set only + +- `OPENCSD_BUILD_MIN_LIB_STATIC=OFF` + Full project build and default mode: + - builds shared and static libraries + - builds the additional full project test/helper targets + - defaults `BUILD_TESTING` to `ON` + - installs the manpage and provides `uninstall` / `clean_install` + - writes outputs into `decoder/lib/builddir`, `decoder/tests/lib/builddir`, and `decoder/tests/bin/builddir` when `OPENCSD_FULL_PROJECT_LAYOUT=ON` + +## Recommended Build Commands + +From the repository root: + +The top-level `CMakeLists.txt` uses support templates from `decoder/build/cmake/`. + +### Linux and Other Single-Config Generators + +Minimal integration build: + +```bash +cmake -S . -B build-original -G "Unix Makefiles" -DBUILD_TESTING=ON -DOPENCSD_BUILD_MIN_LIB_STATIC=ON +cmake --build build-original -j +``` + +Full project build: + +```bash +cmake -S . -B build -G "Unix Makefiles" -DBUILD_TESTING=ON +cmake --build build -j +``` + +Useful variants: + +```bash +cmake -S . -B build-debug -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON +cmake --build build-debug -j +``` + +```bash +cmake -S . -B build-release -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON +cmake --build build-release -j +``` + +Install from an out-of-source build: + +```bash +cmake --install build --prefix /your/install/prefix +``` + +Clean only build outputs: + +```bash +cmake --build build --target clean +``` + +Remove the entire generated build and configuration state: + +```bash +rm -rf build +``` + +### Windows with Visual Studio 2022 + +Use a Visual Studio 2022 generator and pass a configuration at build time. +The helper script and the direct commands below default to `x64`. + +Full project build: + +```powershell +cmake -S . -B build-vs2022 -G "Visual Studio 17 2022" -A x64 -DBUILD_TESTING=ON +cmake --build build-vs2022 --config Release --parallel +``` + +Minimal integration build: + +```powershell +cmake -S . -B build-vs2022-min -G "Visual Studio 17 2022" -A x64 -DBUILD_TESTING=ON -DOPENCSD_BUILD_MIN_LIB_STATIC=ON +cmake --build build-vs2022-min --config Release --parallel +``` + +Debug build: + +```powershell +cmake -S . -B build-vs2022-debug -G "Visual Studio 17 2022" -A x64 -DBUILD_TESTING=ON +cmake --build build-vs2022-debug --config Debug --parallel +``` + +Install from an out-of-source build: + +```powershell +cmake --install build-vs2022 --config Release --prefix C:\temp\opencsd-install +``` + +## Python Helper Script + +The helper script `decoder/build/cmake/build_cmake.py` wraps configure, build, +install, uninstall, and `clean_install` flows. It can be invoked either from +the repository root or from `decoder/build/cmake/`. +If `--build-dir` is omitted, the script creates and reuses mode-specific build +directories under `decoder/build/cmake/`. + +On Windows, the script defaults to the `Visual Studio 17 2022` generator, +selects the `x64` platform for Visual Studio builds, and uses the Visual Studio +bundled `cmake.exe` if `cmake` is not already on `PATH`. +On non-Windows hosts, the default generator remains `Unix Makefiles`. + +### Example Commands + +Configure and build a minimal library tree: + +```bash +python3 decoder/build/cmake/build_cmake.py --minimal +``` + +Remove a build tree: + +```bash +python3 decoder/build/cmake/build_cmake.py --build-dir decoder/build/cmake/build-cmake-min --clean +``` + +Configure and build a debug tree: + +```bash +python3 decoder/build/cmake/build_cmake.py --debug +``` + +Configure, build, and install a minimal tree: + +```bash +python3 decoder/build/cmake/build_cmake.py --minimal --install --install-prefix /tmp/opencsd-install +``` + +Reuse a previously configured build tree and build it without reconfiguring: + +```bash +python3 decoder/build/cmake/build_cmake.py --build-dir decoder/build/cmake/build-cmake-min --no-configure +``` + +Install from a previous build without reconfiguring or rebuilding: + +```bash +python3 decoder/build/cmake/build_cmake.py --build-dir decoder/build/cmake/build-cmake-min --no-configure --no-build --install --install-prefix /tmp/opencsd-install +``` + +Uninstall from a previous build without reconfiguring or rebuilding: + +```bash +python3 decoder/build/cmake/build_cmake.py --build-dir decoder/build/cmake/build-cmake-min --no-configure --no-build --uninstall +``` + +Windows full build from a plain PowerShell prompt: + +```powershell +py -3 decoder/build/cmake/build_cmake.py --build-testing ON +``` + +Windows debug build: + +```powershell +py -3 decoder/build/cmake/build_cmake.py --debug --build-testing ON +``` + +Windows minimal build: + +```powershell +py -3 decoder/build/cmake/build_cmake.py --minimal --build-testing ON +``` + +### Options + +- `-h`, `--help`: Show the command help and exit. +- `--build-dir BUILD_DIR`: Use the given out-of-source build directory. If omitted, the script chooses a default under `decoder/build/cmake/`, such as `decoder/build/cmake/build-cmake`, `decoder/build/cmake/build-cmake-min`, or `decoder/build/cmake/build-cmake-min-debug`. +- `--generator GENERATOR`: Pass an explicit CMake generator. The default is platform-specific: `Visual Studio 17 2022` on Windows, `Unix Makefiles` elsewhere. +- `--platform PLATFORM`: Pass a CMake platform via `-A` for Visual Studio generators. The default is `x64` for Windows Visual Studio builds. +- `--debug`: Use a Debug build. For single-config generators this sets `-DCMAKE_BUILD_TYPE=Debug`; for multi-config generators it selects `--config Debug`. +- `--config {Debug,Release}`: Explicit build configuration. Defaults to `Release`, or `Debug` when `--debug` is set. +- `--minimal`: Configure with `-DOPENCSD_BUILD_MIN_LIB_STATIC=ON`. +- `--jobs JOBS`: Pass a parallelism level to `cmake --build --parallel`. +- `--configure-only`: Run only the CMake configure step. +- `--clean`: Remove the selected build directory before any other action. If no other action is requested, the script removes the directory and exits. +- `--no-configure`: Reuse an existing configured build tree and skip configure. The selected build directory must already contain `CMakeCache.txt`. +- `--no-build`: Skip `cmake --build`. Use this when running `--install`, `--uninstall`, or `--clean-install` against an already built tree. +- `--install`: Run `cmake --install` after configure/build, or against a previous build when combined with `--no-build`. +- `--install-prefix INSTALL_PREFIX`: Pass an installation prefix to `cmake --install`. This requires `--install`. +- `--uninstall`: Run the generated `uninstall` target after the main action. +- `--clean-install`: Run the generated `clean_install` target after the main action. +- `--build-testing {ON,OFF}`: Set `BUILD_TESTING` explicitly instead of using the project default. +- `--full-project-layout {ON,OFF}`: Set `OPENCSD_FULL_PROJECT_LAYOUT` explicitly instead of using the project default. + +### Option Constraints + +- `--configure-only` and `--no-configure` cannot be used together. +- `--clean` cannot be combined with `--no-configure`. +- `--clean` cannot be combined with `--no-build`. +- `--platform` is only valid with Visual Studio generators. +- `--install-prefix` requires `--install`. +- `--debug` cannot be combined with `--config Release`. +- `--no-build` cannot be combined with `--configure-only`. +- `--no-build` must be paired with one of `--install`, `--uninstall`, or `--clean-install`. From 8e64acf3eb2d363893d0f07ee510a7ee072d41ed Mon Sep 17 00:00:00 2001 From: Mike Leach Date: Fri, 15 May 2026 15:28:45 +0100 Subject: [PATCH 3/5] opencsd: tests: Update test script In the python test script ensure that only options after '--' are passed through to the trc_pkt_lister program. Unknown options before this will now result in a error and the script will fail Signed-off-by: Mike Leach --- decoder/docs/test_progs.md | 10 +++++++--- decoder/tests/run_pkt_decode_tests.py | 12 +++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/decoder/docs/test_progs.md b/decoder/docs/test_progs.md index 5a3ab894a560..dc0076a0d2e5 100644 --- a/decoder/docs/test_progs.md +++ b/decoder/docs/test_progs.md @@ -94,14 +94,18 @@ __Runner options__ - `--memacc-req-trace` : set `OPENCSD_MEMACC_REQ_TRACE=1` for all test processes started by the script. - `--diff-only` : run only the result comparison step without running any tests. -Any additional arguments after the script options are passed through to -`trc_pkt_lister`. Use `--` to separate runner options from the packet lister -arguments when needed. +Any additional arguments for `trc_pkt_lister` must appear after `--`. The +Python runner validates all options before `--`, and any unknown option there +is treated as an error instead of being passed through. Example: `python .\decoder\tests\run_pkt_decode_tests.py --suite ete -- --stats` +This will fail because `--stats` is before `--`: + +`python .\decoder\tests\run_pkt_decode_tests.py --suite ete --stats` + __Result comparison__ The script can compare the results created by the current run against a diff --git a/decoder/tests/run_pkt_decode_tests.py b/decoder/tests/run_pkt_decode_tests.py index f460470b1058..8eae29bcf0d6 100644 --- a/decoder/tests/run_pkt_decode_tests.py +++ b/decoder/tests/run_pkt_decode_tests.py @@ -908,6 +908,7 @@ def run_ete_suite( def parse_args(argv: Sequence[str]) -> tuple[argparse.Namespace, list[str]]: parser = argparse.ArgumentParser( description="Run OpenCSD packet decode regression tests on Linux, macOS, or Windows.", + epilog="Pass additional trc_pkt_lister arguments only after '--'.", ) parser.add_argument( "--suite", @@ -977,9 +978,14 @@ def parse_args(argv: Sequence[str]) -> tuple[argparse.Namespace, list[str]]: help="Set OPENCSD_MEMACC_REQ_TRACE=1 for every test process started by this runner.", ) - namespace, passthrough = parser.parse_known_args(argv) - if passthrough and passthrough[0] == "--": - passthrough = passthrough[1:] + passthrough: list[str] = [] + parseable_argv = list(argv) + if "--" in parseable_argv: + separator_index = parseable_argv.index("--") + passthrough = parseable_argv[separator_index + 1 :] + parseable_argv = parseable_argv[:separator_index] + + namespace = parser.parse_args(parseable_argv) diff_results_suffixes = namespace.diff_results_suffix or [] if namespace.diff_previous and diff_results_suffixes: From fd1dc92495b1a1106e63f7dea4e08775ad4f5e4b Mon Sep 17 00:00:00 2001 From: Mike Leach Date: Thu, 14 May 2026 22:40:13 +0100 Subject: [PATCH 4/5] opencsd: Update README and version for v1.8.3-rc1 Signed-off-by: Mike Leach --- README.md | 6 ++++-- decoder/docs/doxygen_config.dox | 2 +- decoder/include/opencsd/ocsd_if_version.h | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 764b2c9829fb..fddddf6ae7b4 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Releases will appear on the master branch in the git repository with an appropri CoreSight Trace Component Support. ---------------------------------- -_Current Version 1.8.2_ +_Current Version 1.8.3-rc1_ ### Current support: @@ -383,7 +383,7 @@ Version and Modification Information - __Bugfix__: etmv4: Packet description string typo fixed. (github #84) - __Bugfix__: stm: Issue with waitASync routine (github #85), fix freq packet handling -- _Version 1.8.2: +- _Version 1.8.2_: - __Update__: tests: add python test script for cross platform use - replace linux only bash scripts. - __Update__: opencsd: memory access - added debug to trace memory accesses by library under control of env var. - __Bugfix__: tests: windows test program names differ from linux ones - fix to make same @@ -392,6 +392,8 @@ Version and Modification Information issues. (github #88) - __Bugfix__: Fix mac-os build for test programs. +- _Version 1.8.3-rc1_: + - __Update__: build: Experimental cmake build files. (github #89) Licence Information =================== diff --git a/decoder/docs/doxygen_config.dox b/decoder/docs/doxygen_config.dox index defa8cfab190..fc951ab6c272 100644 --- a/decoder/docs/doxygen_config.dox +++ b/decoder/docs/doxygen_config.dox @@ -38,7 +38,7 @@ PROJECT_NAME = "OpenCSD - CoreSight Trace Decode Library" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.8.2 +PROJECT_NUMBER = 1.8.3-rc1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/decoder/include/opencsd/ocsd_if_version.h b/decoder/include/opencsd/ocsd_if_version.h index 83475671e354..b117a3850af8 100644 --- a/decoder/include/opencsd/ocsd_if_version.h +++ b/decoder/include/opencsd/ocsd_if_version.h @@ -44,7 +44,7 @@ @{*/ #define OCSD_VER_MAJOR 0x1 /**< Library Major Version */ #define OCSD_VER_MINOR 0x8 /**< Library Minor Version */ -#define OCSD_VER_PATCH 0x2 /**< Library Patch Version */ +#define OCSD_VER_PATCH 0xF3 /**< Library Patch Version */ /** Library version number - MMMMnnpp format. MMMM = major version, @@ -53,7 +53,7 @@ */ #define OCSD_VER_NUM ((OCSD_VER_MAJOR << 16) | (OCSD_VER_MINOR << 8) | OCSD_VER_PATCH) -#define OCSD_VER_STRING "1.8.2" /**< Library Version string */ +#define OCSD_VER_STRING "1.8.3-rc1" /**< Library Version string */ #define OCSD_LIB_NAME "OpenCSD Library" /**< Library name string */ #define OCSD_LIB_SHORT_NAME "OCSD" /**< Library Short name string */ /** @}*/ From c1e1d7d516b90ee72068e7b9d965961ebb509fd0 Mon Sep 17 00:00:00 2001 From: Gulfem Savrun Yeniceri Date: Thu, 28 May 2026 16:50:49 -0700 Subject: [PATCH 5/5] build: Update CMake support 1) Restrict installed headers to match the Makefile, ensuring only sufficient headers for using the C-API are installed. 2) Add an uninstall target to allow removing installed files. 3) Resolve parallel build race conditions and target link failures. --- CMakeLists.txt | 189 +++++++++++++++++++++++++++++++------------------ 1 file changed, 121 insertions(+), 68 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 86df5dce260c..28bec79d45ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,9 +77,13 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR -Wlogical-op -fexceptions ) - set(OPENCSD_LINK_FLAGS - -Wl,-z,defs - ) + if(APPLE) + set(OPENCSD_LINK_FLAGS) + else() + set(OPENCSD_LINK_FLAGS + -Wl,-z,defs + ) + endif() endif() else() set(OPENCSD_C_FLAGS) @@ -129,29 +133,9 @@ function(opencsd_stage_shared_libs target) return() endif() - foreach(shared_tgt IN ITEMS opencsd opencsd_c_api) - if(WIN32) - add_custom_command(TARGET ${target} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different - $ - $/$ - VERBATIM - ) - else() - add_custom_command(TARGET ${target} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_if_different - $ - $/$ - COMMAND ${CMAKE_COMMAND} -E create_symlink - $ - $/$ - COMMAND ${CMAKE_COMMAND} -E create_symlink - $ - $/$ - VERBATIM - ) - endif() - endforeach() + if(TARGET stage_shared_libs) + add_dependencies(${target} stage_shared_libs) + endif() endfunction() function(opencsd_add_test_executable target) @@ -229,28 +213,7 @@ set(SNAPSHOT_PARSER_SRCS decoder/tests/snapshot_parser_lib/source/ss_to_dcdtree.cpp ) -if(OPENCSD_BUILD_MIN_LIB_STATIC) - add_library(opencsd STATIC ${OPENCSD_SRCS}) - add_library(OpenCSD::opencsd ALIAS opencsd) - target_link_libraries(opencsd PUBLIC opencsd_options) - target_include_directories(opencsd PRIVATE decoder/source) - set_target_properties(opencsd PROPERTIES - VERSION ${PROJECT_VERSION} - SOVERSION ${PROJECT_VERSION_MAJOR} - ) - - add_library(opencsd_c_api STATIC ${OPENCSD_C_API_SRCS}) - add_library(OpenCSD::opencsd_c_api ALIAS opencsd_c_api) - target_link_libraries(opencsd_c_api PUBLIC opencsd PRIVATE opencsd_options) - target_include_directories(opencsd_c_api PRIVATE decoder/source) - if(WIN32) - target_compile_definitions(opencsd_c_api PUBLIC OCSD_USE_STATIC_C_API) - endif() - set_target_properties(opencsd_c_api PROPERTIES - VERSION ${PROJECT_VERSION} - SOVERSION ${PROJECT_VERSION_MAJOR} - ) -else() +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") add_library(opencsd_obj OBJECT ${OPENCSD_SRCS}) target_link_libraries(opencsd_obj PRIVATE opencsd_options) target_include_directories(opencsd_obj PRIVATE decoder/source) @@ -262,20 +225,20 @@ else() VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR} ) - if(WIN32) - set_target_properties(opencsd PROPERTIES - RUNTIME_OUTPUT_NAME opencsd - ARCHIVE_OUTPUT_NAME opencsd_dll - ) - endif() opencsd_set_output_dirs(opencsd "lib") add_library(opencsd_static STATIC $) add_library(OpenCSD::opencsd_static ALIAS opencsd_static) target_link_libraries(opencsd_static PUBLIC opencsd_options) - set_target_properties(opencsd_static PROPERTIES - OUTPUT_NAME opencsd - ) + if(WIN32) + set_target_properties(opencsd_static PROPERTIES + OUTPUT_NAME opencsd + ) + else() + set_target_properties(opencsd_static PROPERTIES + OUTPUT_NAME opencsd_static + ) + endif() opencsd_set_output_dirs(opencsd_static "lib") add_library(opencsd_c_api_obj_shared OBJECT ${OPENCSD_C_API_SRCS}) @@ -296,12 +259,6 @@ else() VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR} ) - if(WIN32) - set_target_properties(opencsd_c_api PROPERTIES - RUNTIME_OUTPUT_NAME opencsd_c_api - ARCHIVE_OUTPUT_NAME opencsd_c_api_dll - ) - endif() opencsd_set_output_dirs(opencsd_c_api "lib") add_library(opencsd_c_api_obj_static OBJECT ${OPENCSD_C_API_SRCS}) @@ -317,17 +274,81 @@ else() if(WIN32) target_compile_definitions(opencsd_c_api_static INTERFACE OCSD_USE_STATIC_C_API) endif() - set_target_properties(opencsd_c_api_static PROPERTIES - OUTPUT_NAME opencsd_c_api - ) + if(WIN32) + set_target_properties(opencsd_c_api_static PROPERTIES + OUTPUT_NAME opencsd_c_api + ) + else() + set_target_properties(opencsd_c_api_static PROPERTIES + OUTPUT_NAME opencsd_c_api_static + ) + endif() opencsd_set_output_dirs(opencsd_c_api_static "lib") + if(OPENCSD_FULL_PROJECT_LAYOUT) + if(WIN32) + add_custom_target(stage_shared_libs + COMMAND ${CMAKE_COMMAND} -E make_directory "${OPENCSD_BIN_OUT}" + COMMAND ${CMAKE_COMMAND} -E copy_if_different + $ + "${OPENCSD_BIN_OUT}/$" + COMMAND ${CMAKE_COMMAND} -E copy_if_different + $ + "${OPENCSD_BIN_OUT}/$" + ) + else() + add_custom_target(stage_shared_libs + COMMAND ${CMAKE_COMMAND} -E make_directory "${OPENCSD_BIN_OUT}" + COMMAND ${CMAKE_COMMAND} -E copy_if_different + $ + "${OPENCSD_BIN_OUT}/$" + COMMAND ${CMAKE_COMMAND} -E create_symlink + $ + "${OPENCSD_BIN_OUT}/$" + COMMAND ${CMAKE_COMMAND} -E create_symlink + $ + "${OPENCSD_BIN_OUT}/$" + COMMAND ${CMAKE_COMMAND} -E copy_if_different + $ + "${OPENCSD_BIN_OUT}/$" + COMMAND ${CMAKE_COMMAND} -E create_symlink + $ + "${OPENCSD_BIN_OUT}/$" + COMMAND ${CMAKE_COMMAND} -E create_symlink + $ + "${OPENCSD_BIN_OUT}/$" + ) + endif() + add_dependencies(stage_shared_libs opencsd opencsd_c_api) + endif() + add_custom_target(libs DEPENDS opencsd opencsd_static opencsd_c_api opencsd_c_api_static ) +else() + add_library(opencsd STATIC ${OPENCSD_SRCS}) + add_library(OpenCSD::opencsd ALIAS opencsd) + target_link_libraries(opencsd PUBLIC opencsd_options) + target_include_directories(opencsd PRIVATE decoder/source) + set_target_properties(opencsd PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR} + ) + + add_library(opencsd_c_api STATIC ${OPENCSD_C_API_SRCS}) + add_library(OpenCSD::opencsd_c_api ALIAS opencsd_c_api) + target_link_libraries(opencsd_c_api PUBLIC opencsd PRIVATE opencsd_options) + target_include_directories(opencsd_c_api PRIVATE decoder/source) + if(WIN32) + target_compile_definitions(opencsd_c_api PUBLIC OCSD_USE_STATIC_C_API) + endif() + set_target_properties(opencsd_c_api PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR} + ) endif() if(BUILD_TESTING) @@ -483,7 +504,7 @@ set(OPENCSD_INSTALL_TARGETS opencsd_options ) -if(NOT OPENCSD_BUILD_MIN_LIB_STATIC) +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") list(APPEND OPENCSD_INSTALL_TARGETS opencsd_static opencsd_c_api_static @@ -506,7 +527,39 @@ if(BUILD_TESTING AND NOT OPENCSD_BUILD_MIN_LIB_STATIC) install(FILES decoder/docs/man/trc_pkt_lister.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) endif() -install(DIRECTORY decoder/include/opencsd/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/opencsd) +install(FILES + decoder/include/opencsd/trc_gen_elem_types.h + decoder/include/opencsd/ocsd_if_types.h + decoder/include/opencsd/ocsd_if_version.h + decoder/include/opencsd/trc_pkt_types.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/opencsd +) +install(FILES + decoder/include/opencsd/ptm/trc_pkt_types_ptm.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/opencsd/ptm +) +install(FILES + decoder/include/opencsd/stm/trc_pkt_types_stm.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/opencsd/stm +) +install(FILES + decoder/include/opencsd/etmv3/trc_pkt_types_etmv3.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/opencsd/etmv3 +) +install(FILES + decoder/include/opencsd/etmv4/trc_pkt_types_etmv4.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/opencsd/etmv4 +) +install(FILES + decoder/include/opencsd/ete/trc_pkt_types_ete.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/opencsd/ete +) +install(FILES + decoder/include/opencsd/c_api/ocsd_c_api_types.h + decoder/include/opencsd/c_api/opencsd_c_api.h + decoder/include/opencsd/c_api/ocsd_c_api_custom.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/opencsd/c_api +) install(EXPORT OpenCSDTargets FILE OpenCSDTargets.cmake