From 5930fb468627e041999793faf9078d632f96a1e0 Mon Sep 17 00:00:00 2001 From: Katze719 Date: Sun, 23 Aug 2026 22:09:21 +0200 Subject: [PATCH 1/5] feat: ship cpp-core FFI metadata in JSR package --- .github/workflows/build_binary.yml | 7 +++++-- .github/workflows/publish_jsr.yml | 3 ++- jsr/.gitignore | 1 + jsr/README.md | 5 +++++ jsr/jsr.json | 8 ++++---- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build_binary.yml b/.github/workflows/build_binary.yml index 59d6bee..1d5d494 100644 --- a/.github/workflows/build_binary.yml +++ b/.github/workflows/build_binary.yml @@ -43,7 +43,8 @@ jobs: - name: 'Build' run: | - cmake --build --preset linux-gcc-release --target cpp_bindings_linux + cmake --build --preset linux-gcc-release \ + --target cpp_bindings_linux cpp_core_ast_slim_json - name: 'Set PACKAGE_VERSION from env.bat' id: version @@ -70,7 +71,9 @@ jobs: with: if-no-files-found: error name: libcpp_bindings_linux - path: build/libcpp_bindings_linux.so + path: | + build/libcpp_bindings_linux.so + build/ast/cpp_core_ffi_api.json - name: 'Create GitHub Release' if: github.ref_type == 'tag' && steps.check-tag.outputs.IS_VALID_PACKAGE_VERSION == 'true' diff --git a/.github/workflows/publish_jsr.yml b/.github/workflows/publish_jsr.yml index daef149..b47aaa6 100644 --- a/.github/workflows/publish_jsr.yml +++ b/.github/workflows/publish_jsr.yml @@ -49,7 +49,9 @@ jobs: - name: 'Prepare files for JSR' run: | mkdir -p ./jsr/bin + mkdir -p ./jsr/ffi cp ./artifacts/libcpp_bindings_linux.so ./jsr/bin/x86_64.so + cp ./artifacts/ast/cpp_core_ffi_api.json ./jsr/ffi/cpp_core_ffi_api.json ./jsr/scripts/binary_to_json.sh \ ./artifacts/libcpp_bindings_linux.so \ @@ -71,4 +73,3 @@ jobs: working-directory: jsr run: | deno publish --allow-dirty --dry-run - diff --git a/jsr/.gitignore b/jsr/.gitignore index 0e547b0..a6eb0e0 100644 --- a/jsr/.gitignore +++ b/jsr/.gitignore @@ -1,2 +1,3 @@ bin/ +ffi/ !src/bin/ diff --git a/jsr/README.md b/jsr/README.md index ecd8b74..c29e06d 100644 --- a/jsr/README.md +++ b/jsr/README.md @@ -5,6 +5,11 @@ Binaries are provided as a [package on JSR](https://jsr.io/@serial/cpp-bindings-linux). They are serialized as a base64 string inside the JSON file. +The package also includes the generated cpp-core FFI API metadata at +`ffi/cpp_core_ffi_api.json`. It describes the exported C symbols, parameter and +return types, callbacks, default values, and API documentation used by downstream +FFI adapter generators. + This package is primarily intended as a dependency for [`@serial/serial`](https://jsr.io/@serial/serial). However, it can also be used independently. diff --git a/jsr/jsr.json b/jsr/jsr.json index e26d409..6c558c6 100644 --- a/jsr/jsr.json +++ b/jsr/jsr.json @@ -12,12 +12,12 @@ "LICENSE", "jsr.json", "src/**", - "bin/**" + "bin/**", + "ffi/**" ], "exclude": [ - "!bin/" + "!bin/", + "!ffi/" ] } } - - From 9cc9b37375ba985c266601a0babf2d582b1827f3 Mon Sep 17 00:00:00 2001 From: Katze719 Date: Sun, 23 Aug 2026 22:12:51 +0200 Subject: [PATCH 2/5] ci: install clang 22 for FFI metadata --- .github/workflows/build_binary.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build_binary.yml b/.github/workflows/build_binary.yml index 1d5d494..439d098 100644 --- a/.github/workflows/build_binary.yml +++ b/.github/workflows/build_binary.yml @@ -30,6 +30,13 @@ jobs: version: '16' platform: 'x64' + - name: 'Setup Clang for FFI metadata' + uses: KyleMayes/install-llvm-action@v2 + with: + version: '22.1.0' + force-url: 'https://github.com/llvm/llvm-project/releases/download/llvmorg-22.1.0/LLVM-22.1.0-Linux-X64.tar.xz' + env: false + - name: 'Setup CMake' uses: jwlawson/actions-setup-cmake@v2 with: @@ -39,7 +46,8 @@ jobs: run: | cmake --preset linux-gcc-release \ -DCMAKE_C_COMPILER=gcc-16 \ - -DCMAKE_CXX_COMPILER=g++-16 + -DCMAKE_CXX_COMPILER=g++-16 \ + -DCPP_CORE_AST_CLANGXX="${LLVM_PATH}/bin/clang++" - name: 'Build' run: | From 2272fc69ad76de61a9c835a2b67a462aa1a3ac00 Mon Sep 17 00:00:00 2001 From: Katze719 <38188106+Katze719@users.noreply.github.com> Date: Mon, 24 Aug 2026 08:15:22 +0200 Subject: [PATCH 3/5] Update .github/workflows/build_binary.yml Co-authored-by: Mqx <62719703+Mqxx@users.noreply.github.com> --- .github/workflows/build_binary.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_binary.yml b/.github/workflows/build_binary.yml index 439d098..a563c73 100644 --- a/.github/workflows/build_binary.yml +++ b/.github/workflows/build_binary.yml @@ -54,7 +54,7 @@ jobs: cmake --build --preset linux-gcc-release \ --target cpp_bindings_linux cpp_core_ast_slim_json - - name: 'Set PACKAGE_VERSION from env.bat' + - name: 'Set PACKAGE_VERSION from env.sh' id: version run: | . build/env.sh From ec321fcdb43333b39ca86dabd111336b85fa294f Mon Sep 17 00:00:00 2001 From: Katze719 <38188106+Katze719@users.noreply.github.com> Date: Mon, 24 Aug 2026 08:32:35 +0200 Subject: [PATCH 4/5] Apply suggestions from code review Co-authored-by: Mqx <62719703+Mqxx@users.noreply.github.com> --- .github/workflows/publish_jsr.yml | 3 +-- jsr/.gitignore | 1 - jsr/README.md | 2 +- jsr/jsr.json | 2 -- 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish_jsr.yml b/.github/workflows/publish_jsr.yml index b47aaa6..00c83dd 100644 --- a/.github/workflows/publish_jsr.yml +++ b/.github/workflows/publish_jsr.yml @@ -49,9 +49,8 @@ jobs: - name: 'Prepare files for JSR' run: | mkdir -p ./jsr/bin - mkdir -p ./jsr/ffi cp ./artifacts/libcpp_bindings_linux.so ./jsr/bin/x86_64.so - cp ./artifacts/ast/cpp_core_ffi_api.json ./jsr/ffi/cpp_core_ffi_api.json + cp ./artifacts/ast/cpp_core_ffi_api.json ./jsr/bin/x86_64.ast.json ./jsr/scripts/binary_to_json.sh \ ./artifacts/libcpp_bindings_linux.so \ diff --git a/jsr/.gitignore b/jsr/.gitignore index a6eb0e0..0e547b0 100644 --- a/jsr/.gitignore +++ b/jsr/.gitignore @@ -1,3 +1,2 @@ bin/ -ffi/ !src/bin/ diff --git a/jsr/README.md b/jsr/README.md index c29e06d..59d7b1d 100644 --- a/jsr/README.md +++ b/jsr/README.md @@ -6,7 +6,7 @@ Binaries are provided as a [package on JSR](https://jsr.io/@serial/cpp-bindings-linux). They are serialized as a base64 string inside the JSON file. The package also includes the generated cpp-core FFI API metadata at -`ffi/cpp_core_ffi_api.json`. It describes the exported C symbols, parameter and +`bin/x86_64.ast.json`. It describes the exported C symbols, parameter and return types, callbacks, default values, and API documentation used by downstream FFI adapter generators. diff --git a/jsr/jsr.json b/jsr/jsr.json index 6c558c6..d8b7d64 100644 --- a/jsr/jsr.json +++ b/jsr/jsr.json @@ -13,11 +13,9 @@ "jsr.json", "src/**", "bin/**", - "ffi/**" ], "exclude": [ "!bin/", - "!ffi/" ] } } From 8e7de2b35ac265e27cd9a6316d255a1fddb64296 Mon Sep 17 00:00:00 2001 From: Katze719 Date: Mon, 24 Aug 2026 22:06:06 +0200 Subject: [PATCH 5/5] ci: generate FFI metadata with ASTrein --- .github/workflows/build_binary.yml | 27 ++++++--- CMakeLists.txt | 89 +++++++++++++++++++++++++++++- jsr/README.md | 8 +-- 3 files changed, 110 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build_binary.yml b/.github/workflows/build_binary.yml index a563c73..d948073 100644 --- a/.github/workflows/build_binary.yml +++ b/.github/workflows/build_binary.yml @@ -15,6 +15,8 @@ jobs: build-binary: name: 'Build binary' runs-on: ubuntu-latest + env: + ASTREIN_VERSION: '1.0.0' permissions: contents: write @@ -30,12 +32,20 @@ jobs: version: '16' platform: 'x64' - - name: 'Setup Clang for FFI metadata' - uses: KyleMayes/install-llvm-action@v2 - with: - version: '22.1.0' - force-url: 'https://github.com/llvm/llvm-project/releases/download/llvmorg-22.1.0/LLVM-22.1.0-Linux-X64.tar.xz' - env: false + - name: 'Download ASTrein' + run: | + curl --fail --location \ + --retry 100 \ + --retry-all-errors \ + --retry-delay 30 \ + --retry-max-time 3000 \ + --output "${RUNNER_TEMP}/astrein-linux-x86_64.tar.gz" \ + "https://github.com/Katze719/ASTrein/releases/download/v${ASTREIN_VERSION}/astrein-linux-x86_64.tar.gz" + mkdir -p "${RUNNER_TEMP}/astrein" + tar -xzf "${RUNNER_TEMP}/astrein-linux-x86_64.tar.gz" \ + -C "${RUNNER_TEMP}/astrein" \ + --strip-components=1 + "${RUNNER_TEMP}/astrein/bin/astrein" --version - name: 'Setup CMake' uses: jwlawson/actions-setup-cmake@v2 @@ -47,12 +57,13 @@ jobs: cmake --preset linux-gcc-release \ -DCMAKE_C_COMPILER=gcc-16 \ -DCMAKE_CXX_COMPILER=g++-16 \ - -DCPP_CORE_AST_CLANGXX="${LLVM_PATH}/bin/clang++" + -DCPP_BINDINGS_LINUX_ENABLE_FFI_JSON_EXPORT=ON \ + -DCPP_BINDINGS_LINUX_ASTREIN_EXECUTABLE="${RUNNER_TEMP}/astrein/bin/astrein" - name: 'Build' run: | cmake --build --preset linux-gcc-release \ - --target cpp_bindings_linux cpp_core_ast_slim_json + --target cpp_bindings_linux cpp_bindings_linux_ffi_json - name: 'Set PACKAGE_VERSION from env.sh' id: version diff --git a/CMakeLists.txt b/CMakeLists.txt index b62aeaf..c38f6fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,15 +34,100 @@ set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_MODULE_STD 26) set(CMAKE_CXX_MODULE_EXTENSIONS OFF) +option( + CPP_BINDINGS_LINUX_ENABLE_FFI_JSON_EXPORT + "Enable ASTrein JSON export for the cpp-core FFI headers" + OFF +) +set( + CPP_BINDINGS_LINUX_ASTREIN_EXECUTABLE + "" + CACHE FILEPATH + "Path to the ASTrein executable used for FFI JSON export" +) +set( + CPP_BINDINGS_LINUX_FFI_JSON_OUTPUT + "${CMAKE_BINARY_DIR}/ast/cpp_core_ffi_api.json" + CACHE FILEPATH + "Output path for the generated cpp-core FFI API metadata" +) + CPMAddPackage( NAME cpp_core GITHUB_REPOSITORY Serial-IO/cpp-core - GIT_TAG v2.0.0 + GIT_TAG v2.0.1 OPTIONS "CMAKE_EXPORT_COMPILE_COMMANDS OFF" - "CPP_CORE_ENABLE_AST_EXPORT ON" ) +if(CPP_BINDINGS_LINUX_ENABLE_FFI_JSON_EXPORT) + if(CPP_BINDINGS_LINUX_ASTREIN_EXECUTABLE) + set(_cpp_bindings_linux_astrein "${CPP_BINDINGS_LINUX_ASTREIN_EXECUTABLE}") + else() + find_program(_cpp_bindings_linux_astrein NAMES astrein) + endif() + + if(NOT _cpp_bindings_linux_astrein) + message( + FATAL_ERROR + "CPP_BINDINGS_LINUX_ENABLE_FFI_JSON_EXPORT=ON requires ASTrein. " + "Install astrein or set CPP_BINDINGS_LINUX_ASTREIN_EXECUTABLE." + ) + endif() + + file( + GLOB_RECURSE _cpp_bindings_linux_ffi_headers + CONFIGURE_DEPENDS + "${cpp_core_SOURCE_DIR}/include/*.h" + "${cpp_core_SOURCE_DIR}/include/*.hpp" + ) + set( + _cpp_bindings_linux_ffi_wrapper + "${CMAKE_BINARY_DIR}/ast/cpp_core_ffi_api.cpp" + ) + get_filename_component( + _cpp_bindings_linux_ffi_output_dir + "${CPP_BINDINGS_LINUX_FFI_JSON_OUTPUT}" + DIRECTORY + ) + + file( + GENERATE + OUTPUT "${_cpp_bindings_linux_ffi_wrapper}" + CONTENT "#include \n" + ) + + add_custom_command( + OUTPUT "${CPP_BINDINGS_LINUX_FFI_JSON_OUTPUT}" + COMMAND + ${CMAKE_COMMAND} -E make_directory + "${_cpp_bindings_linux_ffi_output_dir}" + COMMAND + "${_cpp_bindings_linux_astrein}" + --mode=reduced + --require-c-linkage + --require-default-visibility + --public-header "cpp_core/serial.h" + --api-root "${cpp_core_SOURCE_DIR}/include" + --output "${CPP_BINDINGS_LINUX_FFI_JSON_OUTPUT}" + "${_cpp_bindings_linux_ffi_wrapper}" + -- + "-std=c++${CMAKE_CXX_STANDARD}" + "-I${cpp_core_SOURCE_DIR}/include" + DEPENDS + "${_cpp_bindings_linux_astrein}" + "${_cpp_bindings_linux_ffi_wrapper}" + ${_cpp_bindings_linux_ffi_headers} + COMMENT "Exporting cpp-core FFI API metadata with ASTrein" + VERBATIM + ) + + add_custom_target( + cpp_bindings_linux_ffi_json + DEPENDS "${CPP_BINDINGS_LINUX_FFI_JSON_OUTPUT}" + ) +endif() + CPMAddPackage( NAME GTest GITHUB_REPOSITORY google/googletest diff --git a/jsr/README.md b/jsr/README.md index 59d7b1d..5005392 100644 --- a/jsr/README.md +++ b/jsr/README.md @@ -5,10 +5,10 @@ Binaries are provided as a [package on JSR](https://jsr.io/@serial/cpp-bindings-linux). They are serialized as a base64 string inside the JSON file. -The package also includes the generated cpp-core FFI API metadata at -`bin/x86_64.ast.json`. It describes the exported C symbols, parameter and -return types, callbacks, default values, and API documentation used by downstream -FFI adapter generators. +The package also includes cpp-core FFI API metadata generated with +[ASTrein](https://github.com/Katze719/ASTrein) at `bin/x86_64.ast.json`. +It describes the exported C symbols, parameter and return types, callbacks, +default values, and API documentation used by downstream FFI adapter generators. This package is primarily intended as a dependency for [`@serial/serial`](https://jsr.io/@serial/serial). However, it can also be used independently.