diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..27d72d4 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,99 @@ +name: release + +on: + push: + branches: [main] + pull_request: # build and package only; the release job is main-only + +permissions: + contents: write + +jobs: + build: + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + name: linux + - os: macos-latest + name: macos + - os: windows-latest + name: windows-msvc + - os: windows-latest + name: windows-mingw + mingw: true + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: configure + shell: bash + run: | + if [ "${{ matrix.mingw }}" = "true" ]; then + cmake -B build -S . -G Ninja -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc \ + -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++ \ + -DWEYVELENGTH_BUILD_TESTS=OFF + else + cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DWEYVELENGTH_BUILD_TESTS=OFF + fi + + - name: build + run: cmake --build build --config Release --target weyvelength_client weyvelength_client_shared Server -j + + - name: package + shell: bash + run: | + set -eu + pkg="weyvelength-${{ matrix.name }}" + mkdir -p "$pkg"/{bin,lib,include} + if [ "${{ runner.os }}" = "Windows" ]; then + find build -type f -name Server.exe -exec cp {} "$pkg/bin/" \; + else + find build -type f -name Server -exec cp {} "$pkg/bin/" \; + fi + # the SDK only: juice is already linked into both, so its own lib is not shipped + find build/Client -maxdepth 2 -type f \ + \( -name "*weyvelength*.a" -o -name "*weyvelength*.lib" \ + -o -name "*weyvelength*.dll" -o -name "*weyvelength*.so" -o -name "*weyvelength*.dylib" \) \ + -exec cp {} "$pkg/lib/" \; + cp Client/include/weyvelength.h "$pkg/include/" + cp LICENSE "$pkg/" + ls -R "$pkg" + + - uses: actions/upload-artifact@v4 + with: + name: weyvelength-${{ matrix.name }} + path: weyvelength-${{ matrix.name }}/ + + release: + if: github.ref == 'refs/heads/main' + needs: build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: download artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: generate release tag + run: echo "TAG=v$(date +'%Y%m%d%H%M%S')-$(git rev-parse --short HEAD)" >> $GITHUB_ENV + + - name: create packages + run: | + set -eu + for dir in artifacts/*/; do + name=$(basename "$dir") + tar -czf "$name.tar.gz" -C "$dir" . + done + ls -l *.tar.gz + + - uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ env.TAG }} + files: weyvelength-*.tar.gz diff --git a/Client/CMakeLists.txt b/Client/CMakeLists.txt index 5418ea7..43a51ea 100644 --- a/Client/CMakeLists.txt +++ b/Client/CMakeLists.txt @@ -3,16 +3,38 @@ set(NO_TESTS ON CACHE BOOL "" FORCE) set(NO_SERVER ON CACHE BOOL "" FORCE) # ICE-only; the STUN/TURN server bundled in libjuice is unused here add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/libjuice) set_target_properties(juice PROPERTIES EXCLUDE_FROM_ALL ON) # only juice-static is used here +set_property(TARGET juice-static PROPERTY POSITION_INDEPENDENT_CODE ON) # linked into the shared SDK below -# The client SDK: everything behind weyvelength.h. A static lib so other -# projects (e.g. game clients) can link it without vendoring the sources. -add_library( - weyvelength_client STATIC +set(WEYVELENGTH_CLIENT_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/client.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/p2p_mesh.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/weyvelength.cpp) + +# The client SDK: everything behind weyvelength.h. A static lib so other +# projects (e.g. game clients) can link it without vendoring the sources. +add_library(weyvelength_client STATIC ${WEYVELENGTH_CLIENT_SOURCES}) target_include_directories( weyvelength_client PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include/private) target_link_libraries(weyvelength_client PRIVATE weyvelength_shared juice-static) + +# Same SDK as a shared library, for FFI consumers that can't link C++ objects. +# juice is still linked in statically, so the result has no extra runtime deps. +option(WEYVELENGTH_BUILD_SHARED "Build the client SDK as a shared library too" ON) +if(WEYVELENGTH_BUILD_SHARED) + add_library(weyvelength_client_shared SHARED ${WEYVELENGTH_CLIENT_SOURCES}) + set_target_properties( + weyvelength_client_shared + PROPERTIES OUTPUT_NAME weyvelength + WINDOWS_EXPORT_ALL_SYMBOLS OFF) # WEYVE_API marks the C ABI; nothing else is public + target_include_directories( + weyvelength_client_shared + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include/private) + target_compile_definitions( + weyvelength_client_shared + PUBLIC WEYVE_DLL + PRIVATE WEYVE_DLL_EXPORT) + target_link_libraries(weyvelength_client_shared PRIVATE weyvelength_shared juice-static) +endif()