Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate CMake distribution in CD #251

Open
wants to merge 11 commits into
base: trunk
Choose a base branch
from
72 changes: 71 additions & 1 deletion .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -217,16 +217,86 @@ jobs:
path: dist
name: dist

distribution-release:
name: Create easy-to-integrate distributions (release)
needs: [linux-x86_64, windows-x86_64, windows-i686, macos-x86_64, macos-arm64]
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v3
- name: Download assets
uses: actions/download-artifact@v3
with:
name: dist
- name: Create commit-sha file
env:
GITHUB_SHA: ${{ github.sha }}
run: |
echo $GITHUB_SHA > dist/commit-sha
- name: Prepare distribution
run: |
cp dist/commit-sha distribution
cp ffi/webgpu-headers/webgpu.h distribution/include/webgpu
cp ffi/wgpu.h distribution/include/webgpu
for zipfile in wgpu-*-release.zip
arch=$(echo $zipfile | cut -d- -f2-3)
mkdir -p distribution/bin/$arch
unzip dist/wgpu-*-release.zip distribution/bin/
unzip -d distribution/bin $zipfile *.so *.dylib *.dll
done
mv distribution webgpu
zip -r wgpu-distribution-release.zip webgpu
- name: Upload
uses: actions/upload-artifact@v3
with:
path: wgpu-distribution-release.zip
name: dist

distribution-debug:
name: Create easy-to-integrate distributions (debug)
needs: [linux-x86_64, windows-x86_64, windows-i686, macos-x86_64, macos-arm64]
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v3
- name: Download assets
uses: actions/download-artifact@v3
with:
name: dist
- name: Create commit-sha file
env:
GITHUB_SHA: ${{ github.sha }}
run: |
echo $GITHUB_SHA > dist/commit-sha
- name: Prepare distribution
run: |
cp dist/commit-sha distribution
cp ffi/webgpu-headers/webgpu.h distribution/include/webgpu
cp ffi/wgpu.h distribution/include/webgpu
for zipfile in wgpu-*-debug.zip
arch=$(echo $zipfile | cut -d- -f2-3)
mkdir -p distribution/bin/$arch
unzip dist/wgpu-*-debug.zip distribution/bin/
unzip -d distribution/bin $zipfile *.so *.dylib *.dll
done
mv distribution webgpu
zip -r wgpu-distribution-debug.zip webgpu
- name: Upload
uses: actions/upload-artifact@v3
with:
path: wgpu-distribution-debug.zip
name: dist

# Create a Github release and upload the binary libs that we just built.
# There should be a release and debug build for each platform (win32, win64, MacOS64, Linux64),
# plus a file containing the commit sha.
publish:
name: Publish Github release
needs: [linux-x86_64, windows-x86_64, windows-i686, macos-x86_64, macos-arm64]
needs: [linux-x86_64, windows-x86_64, windows-i686, macos-x86_64, macos-arm64, distribution-release, distribution-debug]
runs-on: ubuntu-latest
if: success() && contains(github.ref, 'tags/v')
steps:
- uses: actions/checkout@v3
with:
submodules: 'true'
- name: set version (which gets used as release name)
run: |
echo "WGPU_NATIVE_VERSION=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV
Expand Down
114 changes: 114 additions & 0 deletions distribution/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
cmake_minimum_required(VERSION 3.0.0...3.24 FATAL_ERROR)
project(webgpu-backend-wgpu VERSION 1.0.0)

message(STATUS "Using wgpu-native backend for WebGPU")

if (EMSCRIPTEN)

add_library(webgpu INTERFACE)

target_include_directories(webgpu INTERFACE
"${CMAKE_CURRENT_SOURCE_DIR}/include-emscripten"
)

# This is used to advertise the flavor of WebGPU that this zip provides
target_compile_definitions(webgpu INTERFACE WEBGPU_BACKEND_EMSCRIPTEN)

function(target_copy_webgpu_binaries Target)
endfunction()

else (EMSCRIPTEN)

set(WGPU ${CMAKE_CURRENT_SOURCE_DIR})
if (NOT ARCH)
set(ARCH ${CMAKE_SYSTEM_PROCESSOR})
if (ARCH STREQUAL "AMD64")
set(ARCH "x86_64")
endif()
endif()

# A pre-compiled target (IMPORTED) that is a dynamically
# linked library (SHARED, meaning .dll, .so or .dylib).
add_library(webgpu SHARED IMPORTED GLOBAL)

# This is used to advertise the flavor of WebGPU that this zip provides
target_compile_definitions(webgpu INTERFACE WEBGPU_BACKEND_WGPU)

if(CMAKE_SYSTEM_NAME STREQUAL "Windows")

set(WGPU_RUNTIME_LIB ${WGPU}/bin/windows-${ARCH}/wgpu_native.dll)
set_target_properties(
webgpu
PROPERTIES
IMPORTED_LOCATION "${WGPU_RUNTIME_LIB}"
IMPORTED_IMPLIB "${WGPU}/bin/windows-${ARCH}/wgpu_native.lib"
INTERFACE_INCLUDE_DIRECTORIES "${WGPU}/include"
)

elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")

set(WGPU_RUNTIME_LIB ${WGPU}/bin/linux-${ARCH}/libwgpu_native.so)
set_target_properties(
webgpu
PROPERTIES
IMPORTED_LOCATION "${WGPU_RUNTIME_LIB}"
INTERFACE_INCLUDE_DIRECTORIES "${WGPU}/include"
)

elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")

set(WGPU_RUNTIME_LIB ${WGPU}/bin/macos-${ARCH}/libwgpu_native.dylib)
set_target_properties(
webgpu
PROPERTIES
IMPORTED_LOCATION "${WGPU_RUNTIME_LIB}"
INTERFACE_INCLUDE_DIRECTORIES "${WGPU}/include"
)

else()

message(FATAL_ERROR "Plateform not supported by this release of WebGPU. You may consider building it yourself from its source (see https://github.com/gfx-rs/wgpu-native)")

endif()

message(STATUS "Using WebGPU runtime from '${WGPU_RUNTIME_LIB}'")
set(WGPU_RUNTIME_LIB ${WGPU_RUNTIME_LIB} PARENT_SCOPE)
set(WGPU_RUNTIME_LIB ${WGPU_RUNTIME_LIB} CACHE INTERNAL "Path to the WebGPU library binary")

# The application's binary must find wgpu.dll or libwgpu.so at runtime,
# so we automatically copy it (it's called WGPU_RUNTIME_LIB in general)
# next to the binary.
# Also make sure that the binarie's RPATH is set to find this shared library.
function(target_copy_webgpu_binaries Target)
add_custom_command(
TARGET ${Target} POST_BUILD
COMMAND
${CMAKE_COMMAND} -E copy_if_different
${WGPU_RUNTIME_LIB}
$<TARGET_FILE_DIR:${Target}>
COMMENT
"Copying '${WGPU_RUNTIME_LIB}' to '$<TARGET_FILE_DIR:${Target}>'..."
)
set_target_properties(${Target} PROPERTIES INSTALL_RPATH "./")

if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
# Bug fix, there might be a cleaner way to do this but no INSTALL_RPATH
# or related target properties seem to be a solution.
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
set(ARCH_DIR aarch64)
else()
set(ARCH_DIR ${CMAKE_SYSTEM_PROCESSOR})
endif()
add_custom_command(
TARGET ${Target} POST_BUILD
COMMAND
${CMAKE_INSTALL_NAME_TOOL} "-change"
"/Users/runner/work/wgpu-native/wgpu-native/target/${ARCH_DIR}-apple-darwin/release/deps/libwgpu_native.dylib"
"@executable_path/libwgpu_native.dylib"
"$<TARGET_FILE:${Target}>"
VERBATIM
)
endif()
endfunction()

endif (EMSCRIPTEN)
69 changes: 69 additions & 0 deletions distribution/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
WebGPU distribution
===================

This is a pre-compiled distribution of [WebGPU native](https://github.com/webgpu-native/webgpu-headers) based on [`wgpu-native`](https://github.com/gfx-rs/wgpu-native) and ready to be used in a [CMake](https://cmake.org/) project.

Suggested usage
---------------

1. Unzip the content of this archive into your source tree in a directory called `webgpu/`

2. Edit you source tree's `CMakeLists.txt`:

```CMake
# [...] Define your application target, called for instance `App`

# Include this archive as a subdirectory
add_subdirectory(webgpu)

# You now have a target `webgpu` against which you can link your application:
target_link_library(App PRIVATE webgpu)

# The application's binary must find wgpu.dll or libwgpu.so at runtime,
# so we automatically copy it next to the binary.
target_copy_webgpu_binaries(App)

# (Alternatively you can use the ${WGPU_RUNTIME_LIB} variable to get the
# binary that must be copied and handle it yourselves.)
```

Notes
-----

### Preprocessor variable

In order to statically distinguish this distribution of WebGPU from other possible backends, it defines the following preprocessor variable:

```C
#define WEBGPU_BACKEND_WGPU
```

### Emscripten support

The CMakeLists provided with this distribution is designed to transparently work with emscripten's `emcmake`:

```bash
# Activate your emscripten installation
source /path/to/emsdk_env.sh
# Configure the project by prefixing with "emcmake"
emcmake cmake -B build-wasm
# Build the project as usual
cmake --build build-wasm
```

Reference
---------

When adding this distribution as a subdirectory in your CMake project, you get:

- `webgpu`: A CMake target that provides the standard `webgpu.h` header and non-standard extensions `wgpu.h` as well as their implementation as a runtime library.
- `${WGPU_RUNTIME_LIB}`: A CMake variable containing the path to the runtime library that your program needs to locate (.dll on Windows, .so on linux, .dylib on macOS).
- `target_copy_webgpu_binaries(Target)`: A helper CMake function to automatically copy the runtime library next to the compiled application produced by target `Target`, so that it finds it out of the box.
- `#define WEBGPU_BACKEND_WGPU`: A preprocessor variable defined in any target linking agains `webgpu` that can be used to detect that this distribution is based on a `wgpu-native` backend.

The `webgpu` target provides the following headers:

```C
#include <webgpu/webgpu.h> // standard webgpu-native header
#include <webgpu/wgpu.h> // non-standard extensions
```
Empty file added distribution/bin/.gitkeep
Empty file.
Empty file.