test(cpp-e2e): add multi-context, cross-library, pipeline, stress tests (#30) (#42)

This commit is contained in:
Gabriel Cruz
2026-05-26 09:18:12 -03:00
committed by GitHub
parent 6a7e4616fd
commit 436c0d760b
16 changed files with 970 additions and 102 deletions
+25 -21
View File
@@ -61,7 +61,7 @@ add_custom_command(
COMMENT "Compiling Nim library libmy_timer"
VERBATIM
)
add_custom_target(nim_lib ALL DEPENDS "${NIM_LIB_FILE}")
add_custom_target(my_timer_nim_lib ALL DEPENDS "${NIM_LIB_FILE}")
# On Windows, an `IMPORTED SHARED` target needs IMPORTED_IMPLIB pointing at
# the `.lib` import library so MSVC's `link.exe` can resolve symbols. The
@@ -77,7 +77,7 @@ else()
add_library(my_timer SHARED IMPORTED GLOBAL)
set_target_properties(my_timer PROPERTIES IMPORTED_LOCATION "${NIM_LIB_FILE}")
endif()
add_dependencies(my_timer nim_lib)
add_dependencies(my_timer my_timer_nim_lib)
# Absolute path to the runtime library (DLL/dylib/so). Exposed via the cache
# so consumers in other directories (e.g. tests/e2e/cpp) can stage the DLL
@@ -86,34 +86,38 @@ set(my_timer_RUNTIME_LIB "${NIM_LIB_FILE}" CACHE INTERNAL
"Absolute path to the my_timer runtime library")
# ── TinyCBOR (vendored at ffi/codegen/templates/cpp/vendor/tinycbor) ─────────
# Guarded so two sibling cpp_bindings dirs in one parent project don't redefine
# the `tinycbor` target.
set(TINYCBOR_SRC_DIR "${REPO_ROOT}/ffi/codegen/templates/cpp/vendor")
add_library(tinycbor STATIC
"${TINYCBOR_SRC_DIR}/tinycbor/cborencoder.c"
"${TINYCBOR_SRC_DIR}/tinycbor/cborencoder_close_container_checked.c"
"${TINYCBOR_SRC_DIR}/tinycbor/cborparser.c"
"${TINYCBOR_SRC_DIR}/tinycbor/cborparser_dup_string.c"
"${TINYCBOR_SRC_DIR}/tinycbor/cborerrorstrings.c"
)
target_include_directories(tinycbor PUBLIC
"${TINYCBOR_SRC_DIR}" # consumer uses #include <tinycbor/cbor.h>
"${TINYCBOR_SRC_DIR}/tinycbor" # internal _p.h includes resolve here
)
set_property(TARGET tinycbor PROPERTY C_STANDARD 99)
set_property(TARGET tinycbor PROPERTY POSITION_INDEPENDENT_CODE ON)
if(NOT TARGET tinycbor)
add_library(tinycbor STATIC
"${TINYCBOR_SRC_DIR}/tinycbor/cborencoder.c"
"${TINYCBOR_SRC_DIR}/tinycbor/cborencoder_close_container_checked.c"
"${TINYCBOR_SRC_DIR}/tinycbor/cborparser.c"
"${TINYCBOR_SRC_DIR}/tinycbor/cborparser_dup_string.c"
"${TINYCBOR_SRC_DIR}/tinycbor/cborerrorstrings.c"
)
target_include_directories(tinycbor PUBLIC
"${TINYCBOR_SRC_DIR}" # consumer uses #include <tinycbor/cbor.h>
"${TINYCBOR_SRC_DIR}/tinycbor" # internal _p.h includes resolve here
)
set_property(TARGET tinycbor PROPERTY C_STANDARD 99)
set_property(TARGET tinycbor PROPERTY POSITION_INDEPENDENT_CODE ON)
endif()
add_library(my_timer_headers INTERFACE)
target_include_directories(my_timer_headers INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}")
target_link_libraries(my_timer_headers INTERFACE my_timer tinycbor)
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp")
add_executable(example main.cpp)
target_link_libraries(example PRIVATE my_timer_headers)
add_dependencies(example nim_lib)
add_executable(my_timer_example main.cpp)
target_link_libraries(my_timer_example PRIVATE my_timer_headers)
add_dependencies(my_timer_example my_timer_nim_lib)
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
add_custom_command(TARGET example POST_BUILD
add_custom_command(TARGET my_timer_example POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
"${my_timer_RUNTIME_LIB}"
"$<TARGET_FILE_DIR:example>"
COMMENT "Staging my_timer.dll next to example.exe")
"$<TARGET_FILE_DIR:my_timer_example>"
COMMENT "Staging my_timer.dll next to my_timer_example.exe")
endif()
endif()
+11 -2
View File
@@ -18,8 +18,10 @@ extern "C" {
// ── encode_cbor overloads (primitives + containers) ─────────────────────
// Per-struct encode_cbor / decode_cbor are emitted by cpp.nim next to each
// generated struct. These helpers cover the leaf types and container shapes
// the struct emitters defer into.
// generated struct; these helpers cover the leaf types they defer into.
// Guarded so two nim-ffi headers can share a translation unit.
#ifndef NIM_FFI_CBOR_HELPERS_HPP_INCLUDED
#define NIM_FFI_CBOR_HELPERS_HPP_INCLUDED
inline CborError encode_cbor(CborEncoder& e, bool v) {
return cbor_encode_boolean(&e, v);
@@ -185,6 +187,8 @@ inline T decodeCborFFI(const std::vector<std::uint8_t>& bytes) {
return out;
}
#endif // NIM_FFI_CBOR_HELPERS_HPP_INCLUDED
// ============================================================
// User-declared FFI types
// ============================================================
@@ -633,6 +637,9 @@ void my_timer_set_event_callback(void* ctx, FFICallback callback, void* user_dat
// ============================================================
// Synchronous call helper
// ============================================================
// Guarded so two nim-ffi headers can share a translation unit.
#ifndef NIM_FFI_SYNC_CALL_HELPER_HPP_INCLUDED
#define NIM_FFI_SYNC_CALL_HELPER_HPP_INCLUDED
namespace {
@@ -683,6 +690,8 @@ inline std::vector<std::uint8_t> ffi_call_(std::function<int(FFICallback, void*)
} // anonymous namespace
#endif // NIM_FFI_SYNC_CALL_HELPER_HPP_INCLUDED
// ============================================================
// High-level C++ context class
// ============================================================