diff --git a/.github/workflows/build_binary.yml b/.github/workflows/build_binary.yml index 59d6bee..ba7555b 100644 --- a/.github/workflows/build_binary.yml +++ b/.github/workflows/build_binary.yml @@ -15,6 +15,9 @@ jobs: build-binary: name: 'Build binary' runs-on: ubuntu-latest + env: + ASTREIN_VERSION: '1.1.0' + ASTREIN_SHA256: 'd5964319ea5a3742e4d7223ee5963d6aa3b24c8f67ef75c61d591c635f413497' permissions: contents: write @@ -30,6 +33,19 @@ jobs: version: '16' platform: 'x64' + - name: 'Download ASTrein' + run: | + curl --fail --location \ + --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" + echo "${ASTREIN_SHA256} ${RUNNER_TEMP}/astrein-linux-x86_64.tar.gz" \ + | sha256sum --check - + 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 with: @@ -39,13 +55,16 @@ jobs: run: | cmake --preset linux-gcc-release \ -DCMAKE_C_COMPILER=gcc-16 \ - -DCMAKE_CXX_COMPILER=g++-16 + -DCMAKE_CXX_COMPILER=g++-16 \ + -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 + cmake --build --preset linux-gcc-release \ + --target cpp_bindings_linux cpp_bindings_linux_ffi_json - - name: 'Set PACKAGE_VERSION from env.bat' + - name: 'Set PACKAGE_VERSION from env.sh' id: version run: | . build/env.sh @@ -70,7 +89,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/cpp_bindings_linux.ffi.json - name: 'Create GitHub Release' if: github.ref_type == 'tag' && steps.check-tag.outputs.IS_VALID_PACKAGE_VERSION == 'true' @@ -79,7 +100,9 @@ jobs: name: 'v${{ steps.version.outputs.PACKAGE_VERSION }}' tag_name: ${{ github.ref_name }} generate_release_notes: true - files: build/out/libcpp_bindings_windows.dll + files: | + build/libcpp_bindings_windows.so + build/cpp_bindings_linux.ffi.json outputs: package_version: ${{ steps.version.outputs.PACKAGE_VERSION }} diff --git a/.github/workflows/publish_jsr.yml b/.github/workflows/publish_jsr.yml index daef149..62f3630 100644 --- a/.github/workflows/publish_jsr.yml +++ b/.github/workflows/publish_jsr.yml @@ -50,6 +50,7 @@ jobs: run: | mkdir -p ./jsr/bin cp ./artifacts/libcpp_bindings_linux.so ./jsr/bin/x86_64.so + cp ./artifacts/cpp_bindings_linux.ffi.json ./jsr/bin/x86_64.ffi.json ./jsr/scripts/binary_to_json.sh \ ./artifacts/libcpp_bindings_linux.so \ @@ -71,4 +72,3 @@ jobs: working-directory: jsr run: | deno publish --allow-dirty --dry-run - diff --git a/CMakeLists.txt b/CMakeLists.txt index b62aeaf..0e5adc1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,15 +34,116 @@ 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}/cpp_bindings_linux.ffi.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}/ffi.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_library( + cpp_bindings_linux_ffi_ast_context + OBJECT + EXCLUDE_FROM_ALL + "${_cpp_bindings_linux_ffi_wrapper}" + ) + target_include_directories( + cpp_bindings_linux_ffi_ast_context + PRIVATE + "${cpp_core_SOURCE_DIR}/include" + ) + target_compile_features( + cpp_bindings_linux_ffi_ast_context + PRIVATE + cxx_std_26 + ) + + 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}" + --ffi + --compile-commands "${CMAKE_BINARY_DIR}/compile_commands.json" + --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}" + DEPENDS + "${_cpp_bindings_linux_astrein}" + "${CMAKE_BINARY_DIR}/compile_commands.json" + "${_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 ecd8b74..bfac12e 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 cpp-core FFI API metadata generated with +[ASTrein](https://github.com/Katze719/ASTrein) at `bin/x86_64.ffi.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..c805bb8 100644 --- a/jsr/jsr.json +++ b/jsr/jsr.json @@ -19,5 +19,3 @@ ] } } - -