diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000000..28bec79d45ca --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,600 @@ +################################################################### +# CMake build script for OpenCSD +# 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) + +set(CMAKE_CXX_STANDARD 11) +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) + +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) + 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") + 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 + ) + if(APPLE) + set(OPENCSD_LINK_FLAGS) + else() + set(OPENCSD_LINK_FLAGS + -Wl,-z,defs + ) + endif() + 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_C_FLAGS}> + $<$:${OPENCSD_CXX_FLAGS}> +) +target_link_options(opencsd_options INTERFACE ${OPENCSD_LINK_FLAGS}) +target_include_directories(opencsd_options INTERFACE + $ + $ +) + +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() + + if(TARGET stage_shared_libs) + add_dependencies(${target} stage_shared_libs) + endif() +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 + 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 +) + +set(OPENCSD_C_API_SRCS + decoder/source/c_api/ocsd_c_api.cpp + decoder/source/c_api/ocsd_c_api_custom_obj.cpp +) + +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 +) + +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) + + 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} + ) + 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) + 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}) + 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} + ) + 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() + 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) + 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 +) + +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + list(APPEND OPENCSD_INSTALL_TARGETS + opencsd_static + opencsd_c_api_static + ) +endif() + +install(TARGETS ${OPENCSD_INSTALL_TARGETS} + EXPORT OpenCSDTargets + COMPONENT development + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) + +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(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 + NAMESPACE OpenCSD:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/OpenCSD +) + +include(CMakePackageConfigHelpers) + +configure_package_config_file( + ${CMAKE_CURRENT_SOURCE_DIR}/decoder/build/cmake/OpenCSDConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/OpenCSDConfig.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/OpenCSD +) + +write_basic_package_version_file( + ${CMAKE_CURRENT_BINARY_DIR}/OpenCSDConfigVersion.cmake + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion +) + +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/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/build/cmake/OpenCSDConfig.cmake.in b/decoder/build/cmake/OpenCSDConfig.cmake.in new file mode 100644 index 000000000000..6665c69c7859 --- /dev/null +++ b/decoder/build/cmake/OpenCSDConfig.cmake.in @@ -0,0 +1,5 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/OpenCSDTargets.cmake") + +check_required_components(OpenCSD) 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`. 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/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/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 */ /** @}*/ 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: