From ec7fd020fbed888de65491c47caf65e5485464b6 Mon Sep 17 00:00:00 2001 From: JP Hutchins Date: Fri, 21 Aug 2026 16:30:12 -0700 Subject: [PATCH] fix: ic_bundle list arguments (closes #10) EXTRA_FILES and EXTRA_POSTFIXES are documented as lists but were declared in the one_value_keywords slot, so the docstring's own EXTRA_POSTFIXES example failed: CMake Error at src/ic_bundle.cmake:80 (message): Unparsed arguments: -app-signed.hex;-app-update-s-e.gbl They move to multi_value_keywords. The previous workaround -- quoting a semicolon-joined string -- keeps working, since the foreach still expands it. EXTRA_FILES was also never read after set_default(), so passing it bundled nothing at all. It now copies each path into the bundle as "${FULL_NAME}_". Naming rather than preserving the source name keeps every file in the bundle identifiable once it is pulled back out of the zip, which is the reason the other artifacts are renamed; the docstring now says so explicitly, since the argument takes arbitrary paths and the destination was previously unspecified. Both are exercised by a new test project rather than by extending the existing one, because ic_bundle() creates a target literally named `bundle` and so cannot be called twice within one CMake project. Reverting src/ic_bundle.cmake alone fails 8 of the 9 new asserts, so the test covers the defect rather than the fix. Found while bundling signed MCUboot artifacts from a Zephyr sysbuild project, where the application image emits zephyr.signed.bin and zephyr.signed.hex beside its unsigned output and the bootloader hex comes from a sibling build domain. Co-Authored-By: claude-opus-5[1m] --- src/ic_bundle.cmake | 24 ++++++++++++++-- tests/CMakeLists.txt | 1 + tests/fixtures/ic_bundle/bootloader.hex | 0 tests/fixtures/ic_bundle/project.signed.bin | 0 tests/fixtures/ic_bundle/project.signed.hex | 0 tests/script.cmake | 4 +++ .../test_ic_bundle_extra_args/CMakeLists.txt | 21 ++++++++++++++ .../extra_args.cmake | 28 +++++++++++++++++++ 8 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 tests/fixtures/ic_bundle/bootloader.hex create mode 100644 tests/fixtures/ic_bundle/project.signed.bin create mode 100644 tests/fixtures/ic_bundle/project.signed.hex create mode 100644 tests/test_ic_bundle_extra_args/CMakeLists.txt create mode 100644 tests/test_ic_bundle_extra_args/extra_args.cmake diff --git a/src/ic_bundle.cmake b/src/ic_bundle.cmake index 96edd94..dec0605 100644 --- a/src/ic_bundle.cmake +++ b/src/ic_bundle.cmake @@ -49,6 +49,8 @@ FULL_NAME [EXTRA_FILES ] default: [empty cmake list] A list of paths to extra build artifacts that should be bundled, example: EXTRA_FILES "${CMAKE_BINARY_DIR}/bootloader/zephyr/zephyr.hex" + Each file is copied as "${FULL_NAME}_", so the example above + would be bundled as "${FULL_NAME}_zephyr.hex". [DEPENDS ] default: ${PROJECT_NAME} The target to depend on for the bundle target. For Zephyr projects, this @@ -65,16 +67,20 @@ function(ic_bundle) ) set(optional_keyword_args PREFIX - EXTRA_FILES - EXTRA_POSTFIXES DEPENDS BUNDLE_DIR ) + set(multi_value_keyword_args + EXTRA_FILES + EXTRA_POSTFIXES + ) list(APPEND keyword_args ${required_keyword_args} ${optional_keyword_args} ) - cmake_parse_arguments(PARSE_ARGV 0 "" "" "${keyword_args}" "") + cmake_parse_arguments( + PARSE_ARGV 0 "" "" "${keyword_args}" "${multi_value_keyword_args}" + ) if(_UNPARSED_ARGUMENTS) message(FATAL_ERROR "Unparsed arguments: ${_UNPARSED_ARGUMENTS}") @@ -105,6 +111,18 @@ function(ic_bundle) foreach(extra_postfix ${_EXTRA_POSTFIXES}) add_artifact("${extra_postfix}") endforeach() + + foreach(extra_file ${_EXTRA_FILES}) + cmake_path(GET extra_file FILENAME extra_file_name) + _add_artifact(artifact_list + bundle + "${_BUNDLE_DIR}" + "${extra_file}" + "" + "${_FULL_NAME}_${extra_file_name}" + "${_DEPENDS}" + ) + endforeach() add_custom_command( OUTPUT "${_FULL_NAME}.zip" diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b3f7f59..2268e1b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -12,5 +12,6 @@ test_cmake_begin() include(test_ic_project.cmake) include(test_ic_bundle/minimal_args.cmake) +include(test_ic_bundle_extra_args/extra_args.cmake) test_cmake_end() diff --git a/tests/fixtures/ic_bundle/bootloader.hex b/tests/fixtures/ic_bundle/bootloader.hex new file mode 100644 index 0000000..e69de29 diff --git a/tests/fixtures/ic_bundle/project.signed.bin b/tests/fixtures/ic_bundle/project.signed.bin new file mode 100644 index 0000000..e69de29 diff --git a/tests/fixtures/ic_bundle/project.signed.hex b/tests/fixtures/ic_bundle/project.signed.hex new file mode 100644 index 0000000..e69de29 diff --git a/tests/script.cmake b/tests/script.cmake index 827e4a4..4a2c6d9 100644 --- a/tests/script.cmake +++ b/tests/script.cmake @@ -6,6 +6,10 @@ # Build the examples since the tests check for build artifacts execute_process(COMMAND cmake "-B" "tests/test_ic_bundle/build" "-S" "tests/test_ic_bundle") execute_process(COMMAND cmake "--build" "tests/test_ic_bundle/build") +execute_process( + COMMAND cmake "-B" "tests/test_ic_bundle_extra_args/build" "-S" "tests/test_ic_bundle_extra_args" +) +execute_process(COMMAND cmake "--build" "tests/test_ic_bundle_extra_args/build") # Run the tests execute_process( diff --git a/tests/test_ic_bundle_extra_args/CMakeLists.txt b/tests/test_ic_bundle_extra_args/CMakeLists.txt new file mode 100644 index 0000000..cd2aa2b --- /dev/null +++ b/tests/test_ic_bundle_extra_args/CMakeLists.txt @@ -0,0 +1,21 @@ +# Copyright (c) 2026 Intercreate, Inc. +# SPDX-License-Identifier: Apache-2.0 +# +# Authors: J.P. Hutchins + +cmake_minimum_required(VERSION 3.20.0) +project(create_the_ic_bundle_extra_args_build) + +include(${CMAKE_SOURCE_DIR}/../../ic.cmake) + +add_custom_target(test_ic_bundle_extra_args ALL) + +set(FULL_NAME "client_project_board@rev_1.0.0_123456") + +ic_bundle( + FULL_NAME "${FULL_NAME}" + PREFIX ${CMAKE_SOURCE_DIR}/../fixtures/ic_bundle/project + EXTRA_POSTFIXES .signed.bin .signed.hex + EXTRA_FILES ${CMAKE_SOURCE_DIR}/../fixtures/ic_bundle/bootloader.hex + DEPENDS test_ic_bundle_extra_args +) diff --git a/tests/test_ic_bundle_extra_args/extra_args.cmake b/tests/test_ic_bundle_extra_args/extra_args.cmake new file mode 100644 index 0000000..fa4b548 --- /dev/null +++ b/tests/test_ic_bundle_extra_args/extra_args.cmake @@ -0,0 +1,28 @@ +# Copyright (c) 2026 Intercreate, Inc. +# SPDX-License-Identifier: Apache-2.0 +# +# Authors: J.P. Hutchins + +test_cmake_group_begin("ic_bundle() EXTRA_POSTFIXES and EXTRA_FILES") + +set(FULL_NAME "client_project_board@rev_1.0.0_123456") + +set(BUNDLE_DIR "${CMAKE_CURRENT_LIST_DIR}/build/${FULL_NAME}") + +# More than one postfix, which a one-value keyword could not accept +assert(EXISTS "${BUNDLE_DIR}/${FULL_NAME}.signed.bin") +assert(EXISTS "${BUNDLE_DIR}/${FULL_NAME}.signed.hex") + +# A file from outside PREFIX, named after the bundle rather than its source +assert(EXISTS "${BUNDLE_DIR}/${FULL_NAME}_bootloader.hex") +assert(NOT EXISTS "${BUNDLE_DIR}/bootloader.hex") + +# The default artifacts are still bundled alongside them +assert(EXISTS "${BUNDLE_DIR}/${FULL_NAME}.elf") +assert(EXISTS "${BUNDLE_DIR}/${FULL_NAME}.bin") +assert(EXISTS "${BUNDLE_DIR}/${FULL_NAME}.hex") +assert(EXISTS "${BUNDLE_DIR}/${FULL_NAME}.map") + +assert(EXISTS "${BUNDLE_DIR}.zip") + +test_cmake_group_end()