Skip to content

Commit

Permalink
Create cmake-multi-platform.yml
Browse files Browse the repository at this point in the history
  • Loading branch information
jspanchu committed Jun 10, 2024
1 parent 8d4e205 commit 182c59f
Show file tree
Hide file tree
Showing 5 changed files with 209 additions and 53 deletions.
127 changes: 127 additions & 0 deletions .github/workflows/cmake-multi-platform.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
name: CMake on multiple platforms

on:
workflow_dispatch:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
build:
runs-on: ${{ matrix.os }}

strategy:
# Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable.
fail-fast: false

# Set up a matrix to run the following 3 configurations:
# 1. <Windows, Release, latest MSVC compiler toolchain on the default runner image, default generator>
# 2. <Linux, Release, latest Clang compiler toolchain on the default runner image, default generator>
# 3. <MacOS, Release, latest Clang compiler toolchain on the default runner image, default generator>
matrix:
os: [macos-14, ubuntu-22.04, windows-2022]
build_type: [Release]
toolchain: [clang, msvc]
include:
- os: macos-14
toolchain: clang
c_compiler: $(brew --prefix llvm@15)/bin/clang
cpp_compiler: $(brew --prefix llvm@15)/bin/clang++
artifact_name: dawn-macos-arm64
- os: windows-2022
toolchain: msvc
c_compiler: cl
cpp_compiler: cl
artifact_name: dawn-win-x86_64
- os: ubuntu-22.04
toolchain: clang
c_compiler: clang-18
cpp_compiler: clang++-18
artifact_name: dawn-linux-x86_64
exclude:
- os: macos-14
toolchain: msvc
- os: ubuntu-22.04
toolchain: msvc
- os: windows-2022
toolchain: clang

steps:
- uses: actions/checkout@v4

- name: Set reusable strings
# Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file.
id: strings
shell: bash
run: |
echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT"
- name: Set up dependencies on linux
if: matrix.os == 'ubuntu-22.04'
run: |
sudo apt-get update
sudo apt-get install -y xcb libxcb-xkb-dev x11-xkb-utils libx11-xcb-dev libxkbcommon-x11-dev
wget https://apt.llvm.org/llvm.sh
chmod +x ./llvm.sh
sudo ./llvm.sh 18
clang-18 --version
- name: Configure CMake
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
run: >
cmake -B ${{ steps.strings.outputs.build-output-dir }}
-DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }}
-DCMAKE_C_COMPILER=${{ matrix.c_compiler }}
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
-S ${{ github.workspace }}
- name: Build
run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }}

- name: Install
run: cmake --install ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }} --prefix install

- name: Artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact_name }}
path: install

- name: Aniticipate crash dumps on windows
if: matrix.os == 'windows-2022'
working-directory: ${{ steps.strings.outputs.build-output-dir }}
run: |
mkdir CrashDumps
reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" /v DumpFolder /d ${{ github.workspace }}\build\CrashDumps /t REG_EXPAND_SZ /f
- name: Aniticipate crash dumps on Linux
if: matrix.os == 'ubuntu-22.04'
working-directory: ${{ steps.strings.outputs.build-output-dir }}
run: |
ulimit -c unlimited
mkdir CrashDumps
sudo chmod 777 $PWD/CrashDumps
# Core filenames will be of the form executable.pid.timestamp:
sudo bash -c 'echo "$PWD/CrashDumps/%e.%p.%t" > /proc/sys/kernel/core_pattern'
cat /proc/sys/kernel/core_pattern
- name: Aniticipate crash dumps on macOS
if: matrix.os == 'macos-14'
working-directory: ${{ steps.strings.outputs.build-output-dir }}
run: mkdir CrashDumps # TODO

- name: Test
working-directory: ${{ steps.strings.outputs.build-output-dir }}
run: |
ctest --output-on-failure -C ${{ matrix.build_type }}
ls CrashDumps
- name: Crash dump
if: ${{ failure() }}
uses: actions/upload-artifact@v4
with:
name: dawn_test_crash_dump
path: |
${{ github.workspace }}\build\CrashDumps\*.dmp
123 changes: 71 additions & 52 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
cmake_minimum_required(VERSION 3.18 FATAL_ERROR)
project(DynDawn)

cmake_minimum_required(VERSION 3.23 FATAL_ERROR)
project(dawn_bundled
VERSION 127.0.6526.1
LANGUAGES C CXX)
# D_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR is a temporary workaround for a Visual Studio 2022 and github actions mess
# check if resolved here: https://github.com/actions/runner-images/issues/10004
if (MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR")
endif ()
include(FetchContent)

# speed up subsequent configures by not updating git repo
# and therefore avoiding the need to run gclient sync.
# speed up subsequent configure triggers by not updating git repo
# and therefore avoiding the need to run `gclient sync` during reconfigure
# See https://cmake.org/cmake/help/latest/module/ExternalProject.html#update-step-options
set(dawn_disconnect_subsequent_updates ON)

FetchContent_Declare(dawn
GIT_REPOSITORY https://dawn.googlesource.com/dawn
GIT_TAG chromium/6526
GIT_SUBMODULES ""
GIT_SHALLOW ON
GIT_REPOSITORY https://dawn.googlesource.com/dawn
GIT_TAG chromium/6526
GIT_SUBMODULES ""
GIT_SHALLOW ON
UPDATE_DISCONNECTED ${dawn_disconnect_subsequent_updates}
PATCH_COMMAND
"${CMAKE_COMMAND}"
Expand All @@ -22,14 +26,15 @@ FetchContent_Declare(dawn
-P
"${CMAKE_CURRENT_LIST_DIR}/GclientSync.cmake"
"-DGCLIENT_SYNC_TARGET_SOURCE_DIR=${FETCHCONTENT_BASE_DIR}/dawn-src")

# Dawn outputs various library files in a directory structure that mirrors
# it's source tree. While this is convenient to understand provenance,
# having all of them under one roof is quite convenient for packaging.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib")
set(CMAKE_PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")

# Forces dawn to generate static libraries and bundle them all into one giant shared library.
set(BUILD_SHARED_LIBS OFF)
# Disable unneeded parts
set(DAWN_BUILD_SAMPLES OFF)
set(DAWN_USE_GLFW OFF)
Expand All @@ -38,44 +43,56 @@ set(TINT_BUILD_CMD_TOOLS OFF)
set(TINT_BUILD_SAMPLES OFF)
set(TINT_BUILD_DOCS OFF)
set(TINT_BUILD_TESTS OFF)

# add dawn source directory to build system
FetchContent_MakeAvailable(dawn)

# Until dawn is able to build shared libraries successfully, we build it by hand.
# Ask dawn to generate static libraries and bundle them all into one giant shared library.
set(BUILD_SHARED_LIBS OFF)
list(APPEND CMAKE_MODULE_PATH "${dawn_SOURCE_DIR}/tools/android/webgpu/src/main/cpp")
include(BundleLibraries)
# So that wgpuXXX symbols are exported from webgpu.h
target_compile_definitions(webgpu_dawn
PRIVATE "WGPU_IMPLEMENTATION"
PUBLIC "WGPU_SHARED_LIBRARY")
bundle_libraries(webgpu_dyndawn webgpu_dawn dawn_native absl::raw_hash_set)
# Handle platform specific link libraries. This was done in dawn/native/CMakeLists.txt,
# however, they're lost since all libraries were shredded down to individial objects in bundle_libraries.
if (DAWN_ENABLE_METAL)
if (DAWN_TARGET_MACOS)
target_link_libraries(webgpu_dyndawn PRIVATE "-framework Cocoa")
endif()
target_link_libraries(webgpu_dyndawn PRIVATE
"-framework IOKit"
"-framework IOSurface"
"-framework QuartzCore"
"-framework Metal")
endif ()
if (WIN32 AND NOT WINDOWS_STORE)
target_link_libraries(webgpu_dyndawn PRIVATE user32.lib)
endif()
if (WINDOWS_STORE)
target_link_libraries(webgpu_dyndawn PRIVATE debug dxgi.lib)
endif()
if (DAWN_ENABLE_D3D12)
target_link_libraries(webgpu_dyndawn PRIVATE dxguid.lib)
if (DAWN_USE_BUILT_DXC)
target_link_libraries(webgpu_dyndawn PRIVATE dxcompiler)
endif()
endif ()

# This is all of necessary dawn libraries bundled up.
add_library(dawn SHARED "${dawn_BINARY_DIR}/gen/src/dawn/native/webgpu_dawn_native_proc.cpp")
add_library(dawn::dawn ALIAS dawn)
# 'nested-namespace-definition' requires compiler flag '/std:c++17'
target_compile_features(dawn PRIVATE cxx_std_17)
target_link_libraries(dawn
PRIVATE dawn_native)
# associate the header with the target so that it gets installed.
target_sources(dawn INTERFACE
FILE_SET dawn_webgpu_header
TYPE HEADERS
BASE_DIRS "${dawn_BINARY_DIR}/gen/include"
FILES "${dawn_BINARY_DIR}/gen/include/dawn/webgpu.h")
target_compile_definitions(dawn
PUBLIC "WGPU_SHARED_LIBRARY")
target_compile_definitions(dawn
PRIVATE "WGPU_IMPLEMENTATION")
# installs header `dawn/webgpu.h` and the shared library `dawn`
include(GNUInstallDirs)
install(TARGETS dawn
EXPORT dawn-targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
FILE_SET dawn_webgpu_header)
install(
DIRECTORY "${dawn_BINARY_DIR}/gen/emscripten-bits"
TYPE LIB)
# installs helpful package info so that folks can locate us via cmake find_package or pkg-config.
install(EXPORT dawn-targets
FILE dawnTargets.cmake
NAMESPACE dawn::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/dawn)
# Create a ConfigVersion.cmake file:
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/dawnConfigVersion.cmake
COMPATIBILITY AnyNewerVersion)
# Configure config file
configure_package_config_file(${CMAKE_CURRENT_LIST_DIR}/cmake/dawnConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/dawnConfig.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/dawn)
# Install the fully generated config and configVersion files
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/dawnConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/dawnConfigVersion.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/dawn)
# Run simple unit tests to ensure wgpu symbols were exported.
include(CTest)
set(BUILD_TESTING ON)
if (BUILD_TESTING)
Expand All @@ -93,8 +110,10 @@ if (BUILD_TESTING)
add_executable(simple_cpp tests/simple.cpp)
target_compile_features(simple_cpp PRIVATE cxx_std_17)
target_link_libraries(simple_cpp PRIVATE webgpu_headers)
add_test(NAME test-simple-cpp COMMAND simple_cpp "$<TARGET_FILE:webgpu_dyndawn>")
add_test(NAME test-simple-cpp COMMAND simple_cpp "$<TARGET_FILE:dawn>")
add_executable(simple_c tests/simple.c)
target_link_libraries(simple_c PRIVATE webgpu_headers)
add_test(NAME test-simple-c COMMAND simple_c "$<TARGET_FILE:webgpu_dyndawn>")
add_test(NAME test-simple-c COMMAND simple_c "$<TARGET_FILE:dawn>")
endif ()
# Packaging
include(CPack)
5 changes: 5 additions & 0 deletions cmake/dawnConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
get_filename_component(dawn_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)

if(NOT TARGET dawn::dawn)
include("${dawn_CMAKE_DIR}/dawnTargets.cmake")
endif()
3 changes: 3 additions & 0 deletions tests/simple.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,12 @@ void onAdapterReceived(WGPURequestAdapterStatus status, WGPUAdapter adapter,
}

int main(int argc, char **argv) {
fprintf(stderr, "argc: %d\n", argc);
if (argc < 2) {
fprintf(stderr, "Usage: simple_c /path/to/<webgpu_implementation_lib>\n");
return EXIT_FAILURE;
}
fprintf(stderr, "argv: %s %s\n", argv[0], argv[1]);
LIBRARY_HANDLE_TYPE webgpuImpl = NULL;
webgpuImpl = LOAD_LIBRARY(argv[1]);
if (webgpuImpl == NULL) {
Expand Down Expand Up @@ -94,4 +96,5 @@ int main(int argc, char **argv) {
fprintf(stderr, "wgpuInstanceRequestAdapter failed!\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
4 changes: 3 additions & 1 deletion tests/simple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@

int main(int argc, char **argv) {
if (argc < 2) {
fprintf(stderr, "Usage: simple_cpp /path/to/<webgpu_implementation_lib>\n");
std::cerr << "Usage: simple_cpp /path/to/<webgpu_implementation_lib>\n";
return EXIT_FAILURE;
}
LIBRARY_HANDLE_TYPE webgpuImpl = LOAD_LIBRARY(argv[1]);
Expand All @@ -50,6 +50,7 @@ int main(int argc, char **argv) {
}
WGPUProcCreateInstance wgpuCreateInstance = nullptr;
LOAD_WGPU_SYMBOL(CreateInstance);
std::cerr << wgpuCreateInstance << '\n';

WGPUInstance instance = wgpuCreateInstance(nullptr);
if (instance == nullptr) {
Expand Down Expand Up @@ -95,4 +96,5 @@ int main(int argc, char **argv) {
std::cerr << "wgpuInstanceRequestAdapter failed!\n";
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

0 comments on commit 182c59f

Please sign in to comment.