Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
cdd3b1a
chore: remove dead intrinsic surface and unify the ABI version default
heifner Aug 28, 2026
705b29f
chore: address review — prune staged headers, finish the version parser
heifner Aug 28, 2026
2377cb5
chore: address second review — one capability predicate, unconditiona…
heifner Aug 31, 2026
ccdfe55
test: resolve magic_enum include from CMake, not a find(1) guess
heifner Aug 31, 2026
55e77c0
test: use ERE alternation in abidiff_tests
heifner Aug 31, 2026
7a10f46
chore: address third review — version parsing, mixed-version merge, O…
heifner Aug 31, 2026
dd9ccdf
chore: address fourth review — required sections, variant matching, p…
heifner Aug 31, 2026
8d94682
chore: address fifth review — versionless descriptors, gated sections…
heifner Sep 1, 2026
9f9473b
chore: address sixth review — crash artifacts, test rigor, dead state
heifner Sep 1, 2026
b5394ff
chore: narrow core-dump ignore patterns to real dump shapes
heifner Sep 1, 2026
b82df2f
chore: fix the remaining ABI matchers and finish the staging rework
heifner Sep 1, 2026
d0c406f
chore: fix regressions from the previous round and finish the matcher…
heifner Sep 1, 2026
c28fe9a
chore: fix the merger's absent-key tolerance and guard whole-section …
heifner Sep 1, 2026
995de04
chore: merge table metadata per key, and correct a false claim about …
heifner Sep 1, 2026
edabb09
chore: stop pruning libsf.a, and diff sections the version gate was h…
heifner Sep 2, 2026
9c35d1d
chore: build the wasm softfloat archive in every configuration
heifner Sep 2, 2026
ec3b84d
chore: normalise protobuf_types, and pin the fixes nothing was pinning
heifner Sep 2, 2026
c3be9d7
chore: build the OFF configuration in the probe, and restrict protobu…
heifner Sep 2, 2026
fc675ed
chore: refuse ABIs whose duplicate members would be silently dropped
heifner Sep 3, 2026
5578e17
chore: check duplicates inside the string spelling, and assert what O…
heifner Sep 3, 2026
482e2ed
chore: refuse a nested duplicate only where the value is actually ado…
heifner Sep 3, 2026
511b1ad
chore: parse ABIs strictly, and count only the non-native sysiolib he…
heifner Sep 4, 2026
97756f9
chore: state strictness as this tool's policy, not as a claim about t…
heifner Sep 4, 2026
5f7d0c6
chore: correct comments that describe superseded implementations
heifner Sep 4, 2026
3cc7752
chore: correct the optional-field schema note in the source as well
heifner Sep 4, 2026
0729b54
chore: put the retired zero-major sentinel in past tense
heifner Sep 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ $BUILD_DIR/tests/unit/kv_cached_tests

Adding a unit test needs **two** registrations: `add_cdt_unit_test(<name>)` in `tests/unit/CMakeLists.txt` (builds it) and `add_unit_test(<name>)` in `tests/CMakeLists.txt` (registers it with ctest). Miss the second and the test still compiles but `ctest` never executes it — a silent gap, not a failure. `basic_name_tests` sat that way until it was registered; when adding a test, check both lists match.

A few unit tests are shell scripts registered directly in `tests/CMakeLists.txt`: `version_tests`, `abi_version_tests`, `multidir_contract_tests`, `postpass_tests`.
A few unit tests are shell scripts registered directly in `tests/CMakeLists.txt`: `version_tests`, `abi_version_tests`, `abidiff_tests`, `multidir_contract_tests`, `postpass_tests`, `staged_headers_tests`.

### Toolchain tests

Expand Down
2 changes: 1 addition & 1 deletion cmake/CDTMacros.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ endmacro()
# )
#
# The resulting module exports an `apply(uint64_t, uint64_t, uint64_t)`
# function. Intrinsic symbols (db_store_i64, etc.) are left undefined and
# function. Intrinsic symbols (kv_set, kv_get, etc.) are left undefined and
# resolved at dlopen time against symbols exported by the host executable.
function(add_native_contract)
cmake_parse_arguments(ARG "" "TARGET;CONTRACT_CLASS;ABI_FILE"
Expand Down
11 changes: 8 additions & 3 deletions cmake/InstallCDT.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,14 @@ macro( cdt_libraries_install)
install(DIRECTORY ${CMAKE_BINARY_DIR}/lib/ DESTINATION lib COMPONENT base
PATTERN "libnative*" EXCLUDE
PATTERN "cmake" EXCLUDE)
install(DIRECTORY ${CMAKE_BINARY_DIR}/lib/ DESTINATION lib COMPONENT dev
FILES_MATCHING PATTERN "libnative*"
PATTERN "cmake" EXCLUDE)
# Guarded on the option, not merely on what happens to be sitting in lib/: a tree
# reconfigured from native ON to OFF can still hold archives from the previous build.
# stage_cdt_tree prunes those, and this makes packaging one impossible regardless.
if(ENABLE_NATIVE_COMPILER)
install(DIRECTORY ${CMAKE_BINARY_DIR}/lib/ DESTINATION lib COMPONENT dev
FILES_MATCHING PATTERN "libnative*"
PATTERN "cmake" EXCLUDE)
endif()
install(DIRECTORY ${CMAKE_BINARY_DIR}/include/ DESTINATION include COMPONENT base)
endmacro( cdt_libraries_install )

Expand Down
6 changes: 6 additions & 0 deletions cmake/package.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,17 @@ set(CPACK_WIRE_PUBLIC_ENTRY_POINTS "${CDT_PUBLIC_ENTRY_POINTS}")
# versioned name on its own (see the archive-name/root decoupling in
# cmake/cpack-project-config.cmake), so this no longer renames anything -- it is
# a plain alias, kept because CI and the docs invoke it by name.
# Depends on CDTWasmLibraries because header staging (and its pruning) happens in that
# nested build -- see cmake/stage_cdt_tree.cmake. The generated `package` and `install`
# targets are ordered after `all` and so pick it up for free, but this convenience
# target is standalone: without the dependency, `cmake --build . --target package-tgz`
# on a reused tree could run CPack over a stale staged header a prior build deleted.
add_custom_target(package-tgz
COMMAND "${CMAKE_CPACK_COMMAND}" -G TGZ
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
COMMENT "Packaging ${CPACK_PACKAGE_FILE_NAME}.tar.gz (portable toolchain)"
VERBATIM)
add_dependencies(package-tgz CDTWasmLibraries)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Remove stale native archives before packaging an OFF rebuild

This dependency runs the nested build, but reconfiguring a reused tree from native ON to OFF only removes the native targets; it does not delete the archives they previously copied into ${CMAKE_BINARY_DIR}/lib. InstallCDT.cmake still picks up stale libnative*.a for dev/TGZ and stale libsf.a for base/TGZ. In an existing tree, libnative.a still contains all four security-group symbols removed by this PR, so the documented upgrade/package path can ship the old implementation even after this dependency runs. Please prune those outputs when native mode is off (or make installation configuration-aware) and cover the ON→OFF package payload.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed and fixed in 7a10f46, and I agree this one mattered most — it meant the documented upgrade path could ship the very API this PR deletes.

Two layers:

  • stage_cdt_tree (renamed from stage_headers, since it no longer stages only headers) prunes lib/libnative* and lib/libsf.a when native mode is off. That target already runs at build time and already prunes the header trees for exactly this reason, so it is the same mechanism rather than a new one.
  • The libnative* install in InstallCDT.cmake is now guarded on ENABLE_NATIVE_COMPILER, so a stale file cannot be packaged even if something reintroduces one.

Verified the prune against a scratch tree seeded the way an earlier ON build leaves one:

before: libc.a libnative.a libnative_sysio.a libsf.a
after:  libc.a
native header trees: 0

libsf.a was the easy one to miss — it goes to the base component, not dev, so it would have shipped in the plain package too.

staged_headers_tests.sh now asserts those archives are absent when native is off, alongside the header trees.


set(CPACK_SET_DESTDIR OFF)
set(CPACK_PACKAGE_RELOCATABLE OFF)
Expand Down
99 changes: 99 additions & 0 deletions cmake/stage_cdt_tree.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Stage the CDT-owned parts of the build tree -- headers into <build>/include and the
# native archives in <build>/lib -- pruning first.
#
# Run in script mode (`cmake -P`) from the `stage_cdt_tree` build target, not at
# configure time. Configure-time `file(COPY)` is additive: it never removes a staged
# copy whose source has been deleted, so a removed header stayed in <build>/include
# forever -- shipped by install/CPack, and visible to native consumers whose compiled
# view could then disagree with the rebuilt library. Reusing a build tree across such
# a deletion is the case this exists to handle, and a configure-time copy cannot,
# because the ExternalProject's configure step is stamped and does not re-run.
#
# The two destinations OVERLAP: sysiolib owns include/sysiolib, and native's second
# copy lands in include/sysiolib/native, a subdirectory of it. Pruning and copying
# from one ordered script is what makes that safe -- two independent steps would race
# to delete each other's output.
#
# `file(COPY)` preserves source timestamps, so re-running every build neither churns
# mtimes nor triggers downstream rebuilds. (It also skips files already current at the
# destination, but that never applies here: both destinations are REMOVE_RECURSE'd
# below before either is repopulated.)
#
# EVERY tree staged into <build>/include is handled here. The four vendored ones -- libc,
# libcxx, boost/preprocessor and bluegrass -- were left as configure-time copies in an
# earlier revision, which meant deleting a header from the cdt-musl or cdt-libcxx submodule
# left the staged copy shipping forever, exactly the bug this script exists to fix. They are
# pruned and recopied on the same schedule now.
#
# Inputs (via -D):
# STAGE_SOURCE_DIR - the repo's libraries/ directory
# STAGE_BINARY_DIR - BASE_BINARY_DIR, whose include/ subtree is staged into
# STAGE_NATIVE - truthy when ENABLE_NATIVE_COMPILER is on

foreach(var STAGE_SOURCE_DIR STAGE_BINARY_DIR)
if(NOT DEFINED ${var})
message(FATAL_ERROR "stage_cdt_tree.cmake: ${var} is required")
endif()
endforeach()

set(header_patterns FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp")

# Prune BOTH trees before either is repopulated, and prune the native tree whether or
# not native mode is on. Pruning it inside the STAGE_NATIVE branch left the previous
# build's native headers staged when a reused tree flipped ENABLE_NATIVE_COMPILER from
# ON to OFF -- and since InstallCDT.cmake installs the whole include tree, an OFF build
# then packaged an API it was configured not to build. (include/sysiolib/native happens
# to vanish with its parent; include/sysio/native has no such parent.)
file(REMOVE_RECURSE "${STAGE_BINARY_DIR}/include/sysiolib")
file(REMOVE_RECURSE "${STAGE_BINARY_DIR}/include/sysio/native")
file(REMOVE_RECURSE "${STAGE_BINARY_DIR}/include/libc")
file(REMOVE_RECURSE "${STAGE_BINARY_DIR}/include/libcxx")
file(REMOVE_RECURSE "${STAGE_BINARY_DIR}/include/boost/preprocessor")
file(REMOVE_RECURSE "${STAGE_BINARY_DIR}/include/bluegrass")

# sysiolib -> include/sysiolib
file(COPY "${STAGE_SOURCE_DIR}/sysiolib"
DESTINATION "${STAGE_BINARY_DIR}/include"
${header_patterns})

# The native-host archives are copied into lib/ by POST_BUILD commands that exist only while
# ENABLE_NATIVE_COMPILER is on. Reconfiguring a reused tree to OFF removes those targets but
# not the files they already copied, and InstallCDT.cmake installs lib/ wholesale -- so an OFF
# build packaged archives its own configuration never produced, still carrying whatever symbols
# the last ON build put in them.
#
# libnative* ONLY. libsf.a is a WebAssembly archive, not a native-host one: cdt-ld links it
# with -lsf for --use-rt and every --fquery mode (compiler_options.hpp.in), and the base
# install ships it. It is declared in libraries/native/CMakeLists.txt but OUTSIDE that file's
# native-only guard, so every configuration builds and stages it -- deleting it here would
# strip the copy an OFF package needs to link those modes.
if(NOT STAGE_NATIVE)
file(GLOB stale_native "${STAGE_BINARY_DIR}/lib/libnative*")
if(stale_native)
file(REMOVE ${stale_native})
endif()
endif()

if(STAGE_NATIVE)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Prune the native tree when native mode is disabled

Because include/sysio/native is removed only inside this truthy branch, reusing a build directory and switching the supported ENABLE_NATIVE_COMPILER option from ON to OFF leaves the old native headers behind. include/sysiolib/native happens to disappear when its parent is pruned, but InstallCDT.cmake installs the entire include tree, so an OFF build/package can still ship include/sysio/native. I reproduced the ON-to-OFF transition at this head, and the new staging test still passes because those files have source counterparts. Move the removal before the conditional and add transition/absence coverage.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed and fixed in 2377cb5. Both trees are now pruned unconditionally, before either is repopulated — include/sysio/native no longer depends on STAGE_NATIVE being on to be cleaned.

You were also right that the staging test could not catch it: its invariant is "no staged file without a source counterpart", and these files have counterparts — they simply should not be staged in that configuration. Those are orthogonal properties, so it needed a separate assertion rather than a stronger version of the same one. staged_headers_tests.sh now takes ENABLE_NATIVE_COMPILER and asserts the native trees are absent when it is off (and present when on).

# native -> include/sysio/native
file(COPY "${STAGE_SOURCE_DIR}/native"
DESTINATION "${STAGE_BINARY_DIR}/include/sysio"
${header_patterns} PATTERN "softfloat" EXCLUDE)

# native/native -> include/sysiolib/native (inside the tree pruned above)
file(COPY "${STAGE_SOURCE_DIR}/native/native"
DESTINATION "${STAGE_BINARY_DIR}/include/sysiolib"
${header_patterns} PATTERN "softfloat" EXCLUDE)
endif()

# The vendored trees. libc and libcxx copy whole directories rather than header-matching,
# because musl and libc++ both ship extensionless headers (<cstdint>, <vector>, ...) that a
# "*.h;*.hpp" filter would drop.
file(COPY "${STAGE_SOURCE_DIR}/libc/cdt-musl/include/" DESTINATION "${STAGE_BINARY_DIR}/include/libc/")
file(COPY "${STAGE_SOURCE_DIR}/libc/cdt-musl/src/internal/" DESTINATION "${STAGE_BINARY_DIR}/include/libc/")
file(COPY "${STAGE_SOURCE_DIR}/libc/cdt-musl/arch/eos/" DESTINATION "${STAGE_BINARY_DIR}/include/libc/")
file(COPY "${STAGE_SOURCE_DIR}/libc++/cdt-libcxx/include/" DESTINATION "${STAGE_BINARY_DIR}/include/libcxx")
file(COPY "${STAGE_SOURCE_DIR}/boost/include/boost/preprocessor"
DESTINATION "${STAGE_BINARY_DIR}/include/boost")
file(COPY "${STAGE_SOURCE_DIR}/meta_refl/include/bluegrass"
DESTINATION "${STAGE_BINARY_DIR}/include")
65 changes: 0 additions & 65 deletions imports/cdt.imports.in
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ memcmp
memset
abort
action_data_size
add_security_group_participants
alt_bn128_add
alt_bn128_mul
alt_bn128_pair
Expand All @@ -29,70 +28,9 @@ check_permission_authorization
check_transaction_authorization
current_receiver
current_time
db_end_i64
db_find_i64
db_get_i64
db_idx128_end
db_idx128_find_primary
db_idx128_find_secondary
db_idx128_lowerbound
db_idx128_next
db_idx128_previous
db_idx128_remove
db_idx128_store
db_idx128_update
db_idx128_upperbound
db_idx256_end
db_idx256_find_primary
db_idx256_find_secondary
db_idx256_lowerbound
db_idx256_next
db_idx256_previous
db_idx256_remove
db_idx256_store
db_idx256_update
db_idx256_upperbound
db_idx64_end
db_idx64_find_primary
db_idx64_find_secondary
db_idx64_lowerbound
db_idx64_next
db_idx64_previous
db_idx64_remove
db_idx64_store
db_idx64_update
db_idx64_upperbound
db_idx_double_end
db_idx_double_find_primary
db_idx_double_find_secondary
db_idx_double_lowerbound
db_idx_double_next
db_idx_double_previous
db_idx_double_remove
db_idx_double_store
db_idx_double_update
db_idx_double_upperbound
db_idx_long_double_end
db_idx_long_double_find_primary
db_idx_long_double_find_secondary
db_idx_long_double_lowerbound
db_idx_long_double_next
db_idx_long_double_previous
db_idx_long_double_remove
db_idx_long_double_store
db_idx_long_double_update
db_idx_long_double_upperbound
db_lowerbound_i64
db_next_i64
db_previous_i64
db_remove_i64
db_store_i64
db_update_i64
db_upperbound_i64
expiration
get_action
get_active_producers
get_active_security_group
get_block_num
get_blockchain_parameters_packed
get_code_hash
Expand All @@ -102,7 +40,6 @@ get_ram_usage
get_resource_limits
get_sender
has_auth
in_active_security_group
is_account
is_feature_activated
k1_recover
Expand All @@ -124,7 +61,6 @@ publication_time
read_action_data
read_transaction
recover_key
remove_security_group_participants
require_auth
require_auth2
require_recipient
Expand All @@ -134,7 +70,6 @@ send_inline
set_action_return_value
set_blockchain_parameters_packed
set_finalizers
set_kv_parameters_packed
set_privileged
set_proposed_producers
set_proposed_producers_ex
Expand Down
47 changes: 42 additions & 5 deletions libraries/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,51 @@ endif()
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_EXTENSIONS ON)

# Stage the CDT-owned headers into ${BASE_BINARY_DIR}/include at BUILD time, pruning
# any whose source has been deleted. See cmake/stage_cdt_tree.cmake for why this cannot
# be a configure-time file(COPY).
add_custom_target(stage_cdt_tree ALL
COMMAND ${CMAKE_COMMAND}
-DSTAGE_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
-DSTAGE_BINARY_DIR=${BASE_BINARY_DIR}
-DSTAGE_NATIVE=$<BOOL:${ENABLE_NATIVE_COMPILER}>
-P ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/stage_cdt_tree.cmake
COMMENT "Staging CDT build tree into ${BASE_BINARY_DIR}/include"
VERBATIM)

add_subdirectory(libc)
add_subdirectory(libc++)
add_subdirectory(sysiolib)
add_subdirectory(rt)

if (ENABLE_NATIVE_COMPILER)
add_subdirectory(native)
endif()
# Added unconditionally. The directory defines the WebAssembly softfloat archive `sf`, which
# cdt-ld links with -lsf for --use-rt and every --fquery mode, alongside the native-host
# targets -- and only the latter depend on ENABLE_NATIVE_COMPILER. Skipping the whole
# directory meant a clean OFF build produced no libsf.a at all, so an OFF package could not
# link those Wasm modes. The native-host targets are gated inside the file instead.
add_subdirectory(native)

# Anything compiled against the staged tree must see the pruned copy, not a leftover.
#
# Enumerated, not listed by hand. The staging step REMOVE_RECURSE's its destinations and every
# compile in this tree carries -I<build>/include/... baked in by the driver, so a target that
# is not ordered after it can race the deletion. A three-name allowlist covered `sysio`,
# `native` and `native_sysio` and silently missed sysio_malloc, sysio_dsm, sysio_cmem, c, c++,
# rt, sf and the native_* variants -- and would miss the next one added.
function(cdt_order_after_staging dir)
get_property(dir_targets DIRECTORY "${dir}" PROPERTY BUILDSYSTEM_TARGETS)
foreach(tgt IN LISTS dir_targets)
if(NOT tgt STREQUAL "stage_cdt_tree")
get_target_property(tgt_type ${tgt} TYPE)
if(NOT tgt_type STREQUAL "INTERFACE_LIBRARY")
add_dependencies(${tgt} stage_cdt_tree)
endif()
endif()
endforeach()
get_property(subdirs DIRECTORY "${dir}" PROPERTY SUBDIRECTORIES)
foreach(subdir IN LISTS subdirs)
cdt_order_after_staging("${subdir}")
endforeach()
endfunction()
cdt_order_after_staging("${CMAKE_CURRENT_SOURCE_DIR}")

file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/boost/include/boost/preprocessor DESTINATION ${BASE_BINARY_DIR}/include/boost)
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/meta_refl/include/bluegrass DESTINATION ${BASE_BINARY_DIR}/include)
1 change: 0 additions & 1 deletion libraries/libc++/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,3 @@ if (ENABLE_NATIVE_COMPILER)
add_custom_command( TARGET native_c++ POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:native_c++> ${BASE_BINARY_DIR}/lib )
endif()

file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/cdt-libcxx/include/ DESTINATION ${BASE_BINARY_DIR}/include/libcxx)
3 changes: 0 additions & 3 deletions libraries/libc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,3 @@ if (ENABLE_NATIVE_COMPILER)
add_custom_command( TARGET native_c POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:native_c> ${BASE_BINARY_DIR}/lib )
endif()

file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/cdt-musl/include/ DESTINATION ${BASE_BINARY_DIR}/include/libc/)
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/cdt-musl/src/internal/ DESTINATION ${BASE_BINARY_DIR}/include/libc/)
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/cdt-musl/arch/eos/ DESTINATION ${BASE_BINARY_DIR}/include/libc/)
17 changes: 10 additions & 7 deletions libraries/native/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -355,15 +355,18 @@ list( APPEND native_softfloat_sources ${native_softfloat_headers} )
add_library ( sf STATIC ${softfloat_sources} )
target_include_directories( sf PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/softfloat/source/include" "${CMAKE_CURRENT_SOURCE_DIR}/${SOFTFLOAT_SPECIALIZE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/${SOFTFLOAT_PLATFORM_DIR}" ${CMAKE_SOURCE_DIR})

add_native_library ( native STATIC ${native_softfloat_sources} intrinsics.cpp crt.cpp ${CRT_ASM} )
target_include_directories( native PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/softfloat/source/include" "${CMAKE_CURRENT_SOURCE_DIR}/${NATIVE_SOFTFLOAT_SPECIALIZE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/${NATIVE_SOFTFLOAT_PLATFORM_DIR}" ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/sysiolib/capi ${CMAKE_SOURCE_DIR}/sysiolib/contracts ${CMAKE_SOURCE_DIR}/sysiolib/core)
# The native-HOST library. Everything above this point -- including the `sf` archive -- is
# WebAssembly and is built in every configuration, because cdt-ld links -lsf for --use-rt and
# the --fquery modes regardless of whether the native tester is enabled.
if (ENABLE_NATIVE_COMPILER)
add_native_library ( native STATIC ${native_softfloat_sources} intrinsics.cpp crt.cpp ${CRT_ASM} )
target_include_directories( native PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/softfloat/source/include" "${CMAKE_CURRENT_SOURCE_DIR}/${NATIVE_SOFTFLOAT_SPECIALIZE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/${NATIVE_SOFTFLOAT_PLATFORM_DIR}" ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/sysiolib/capi ${CMAKE_SOURCE_DIR}/sysiolib/contracts ${CMAKE_SOURCE_DIR}/sysiolib/core)

add_dependencies(native native_sysio)
add_dependencies(native native_sysio)

add_custom_command( TARGET native POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:native> ${BASE_BINARY_DIR}/lib )
add_custom_command( TARGET native POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:native> ${BASE_BINARY_DIR}/lib )
endif()

add_custom_command( TARGET sf POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:sf> ${BASE_BINARY_DIR}/lib )

file(COPY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION ${BASE_BINARY_DIR}/include/sysio FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp" PATTERN "softfloat" EXCLUDE)

file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/native DESTINATION ${BASE_BINARY_DIR}/include/sysiolib FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp" PATTERN "softfloat" EXCLUDE)
# Header staging lives in the stage_cdt_tree target (cmake/stage_cdt_tree.cmake).
16 changes: 0 additions & 16 deletions libraries/native/intrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -704,22 +704,6 @@ extern "C" {
}
#pragma clang diagnostic pop

int64_t add_security_group_participants(const char* data, uint32_t datalen) {
return intrinsics::get().call<intrinsics::add_security_group_participants>(data, datalen);
}

int64_t remove_security_group_participants(const char* data, uint32_t datalen){
return intrinsics::get().call<intrinsics::remove_security_group_participants>(data, datalen);
}

bool in_active_security_group(const char* data, uint32_t datalen){
return intrinsics::get().call<intrinsics::in_active_security_group>(data, datalen);
}

uint32_t get_active_security_group(char* data, uint32_t datalen){
return intrinsics::get().call<intrinsics::get_active_security_group>(data, datalen);
}

void set_finalizers(uint64_t packed_finalizer_format, const char* data, uint32_t len) {
intrinsics::get().call<intrinsics::set_finalizers>(packed_finalizer_format, data, len);
}
Expand Down
5 changes: 0 additions & 5 deletions libraries/native/native/sysio/intrinsics_def.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#include <sysio/system.h>
#include <sysio/transaction.h>
#include <sysio/types.h>
#include <sysio/security_group.h>

#include <type_traits>
#include <functional>
Expand Down Expand Up @@ -102,10 +101,6 @@ intrinsic_macro(send_context_free_inline) \
intrinsic_macro(get_context_free_data) \
intrinsic_macro(get_sender) \
intrinsic_macro(set_action_return_value) \
intrinsic_macro(add_security_group_participants) \
intrinsic_macro(remove_security_group_participants) \
intrinsic_macro(in_active_security_group) \
intrinsic_macro(get_active_security_group) \
intrinsic_macro(blake2_f) \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Refresh the staged headers when removing these entries. libraries/native/CMakeLists.txt:367-369 and libraries/sysiolib/CMakeLists.txt:51 copy headers into build/include only during the stamped CDTWasmLibraries configure step; the inner reconfigure dependencies do not include these headers. Reusing a pre-PR build tree therefore rebuilds libnative.a from this shorter tuple and refreshes cdt.imports, but leaves the old four-entry-longer intrinsic table and both deleted security-group headers staged. Native consumers then compile against a tuple/enum layout that disagrees with the rebuilt library, and install/CPack still ships the removed API. Please make staging/cleanup a build dependency and cover upgrading an existing build tree.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed, and fixed here in 705b29f.

You were right about more than the mechanism: the two deleted headers were still staged in my own build tree after the rebuild that produced the "29/29 green" in the PR body. So the green run was against a partially stale staging area — thanks for catching it.

Staging moves out of the three configure-time file(COPY) calls into cmake/stage_headers.cmake, run from a stage_cdt_headers build target that prunes before it copies.

One thing worth flagging from doing it: the destinations overlap. sysiolib owns include/sysiolib, and native's second copy lands in include/sysiolib/native, inside it. Two independent prune+copy steps would race to delete each other's output, so it is one ordered script rather than a step per source dir. file(COPY) preserves source timestamps and skips files already current, so re-running it every build causes no downstream rebuild churn.

Verified the upgrade case specifically, since a green ctest does not demonstrate it — I planted both removed headers back into the existing tree and rebuilt without reconfiguring:

[3/17] Performing build step for 'CDTWasmLibraries'
[1/1] Staging CDT headers into .../cmake-build-debug-vcpkg/include
...
pruned: include/sysiolib/capi/sysio/security_group.h
pruned: include/sysiolib/contracts/sysio/security_group.hpp

CDTWasmLibraries-stamp/CDTWasmLibraries-configure was untouched throughout (dated 11 days earlier), so the configure step never re-ran — which is the case you described.

New tests/unit/staged_headers_tests.sh pins the invariant that every staged header has a source counterpart, so this catches any future stale staging, not just this deletion. It fails on the pre-fix tree and passes after.

intrinsic_macro(blake2b_256) \
intrinsic_macro(sha3) \
Expand Down
2 changes: 1 addition & 1 deletion libraries/sysiolib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@ if (ENABLE_NATIVE_COMPILER)
add_custom_command( TARGET native_sysio POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:native_sysio> ${BASE_BINARY_DIR}/lib )
endif()

file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/../sysiolib DESTINATION ${BASE_BINARY_DIR}/include FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp")
# Header staging lives in the stage_cdt_tree target (cmake/stage_cdt_tree.cmake).
Loading