[emscripten] Fix CMake dependencies for generated files
Follow-up to https://dawn-review.googlesource.com/c/dawn/+/227196
The specific issue I had was that modifying dawn.json would rebuild
webgpu_generated_struct_info*.json but not
library_webgpu_generated_struct_info.js. While looking at this I noticed
a lot of other missing dependencies as well:
- Generators on generator scripts
- Generators on their input files (the dependency was on a separate
target that _also_ depended on the generator, which wouldn't actually
rerun the generator).
- Link flags on all the other linked files
The comments try to explain my understanding of the setup. I don't fully
understand why it needs to be this way, though. Tested locally:
- rm -rf gen
- touch .../library_webgpu_struct_info_part1.txt
- touch .../library_webgpu_enum_tables.js
- touch .../library_webgpu.js
Additionally, runs the link test during GitHub release.
Bug: 419062310
Fixed: 418173488
Change-Id: I59a20eba9ea3f081a1cb170b2029fc9364aa95ef
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/242954
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Loko Kung <lokokung@google.com>
diff --git a/.github/workflows/package-emdawnwebgpu.sh b/.github/workflows/package-emdawnwebgpu.sh
index 40d9a0c..f4869f6 100755
--- a/.github/workflows/package-emdawnwebgpu.sh
+++ b/.github/workflows/package-emdawnwebgpu.sh
@@ -22,10 +22,10 @@
git submodule update --init --depth=1 third_party/emsdk
python3 tools/activate-emsdk
-# Build
+# Build the package, and also test that the bindings can link.
mkdir -p out/wasm
third_party/emsdk/upstream/emscripten/emcmake cmake -S=. -B=out/wasm
-make -j4 -C out/wasm emdawnwebgpu_pkg
+make -j4 -C out/wasm emdawnwebgpu_pkg emdawnwebgpu_link_test
# Create zip
cat << EOF > out/wasm/emdawnwebgpu_pkg/VERSION.txt
diff --git a/src/emdawnwebgpu/CMakeLists.txt b/src/emdawnwebgpu/CMakeLists.txt
index 4e7380f..0eee3bc 100644
--- a/src/emdawnwebgpu/CMakeLists.txt
+++ b/src/emdawnwebgpu/CMakeLists.txt
@@ -102,6 +102,10 @@
COMMAND ${ARGS}
OUTPUT ${OUTPUT}
COMMENT "Dawn Emscripten: Generating ${PRINT_NAME}."
+ DEPENDS
+ "${EMSCRIPTEN_ROOT_PATH}/tools/gen_struct_info.py"
+ ${EMDAWNWEBGPU_HEADERS_GEN_HEADERS} # for webgpu.h
+ ${EMDAWNWEBGPU_STRUCT_INFO_JSON_GEN_SOURCES} # for struct_info_webgpu.json
)
# Prior to CMake 3.20 the GENERATED property is local to a directory which means that putting
@@ -124,16 +128,10 @@
OUTPUT_JSON WEBGPU_STRUCT_INFO_GEN32
WASM64 OFF
)
- add_custom_target(webgpu_generated_struct_info32
- DEPENDS emdawnwebgpu_headers_gen ${EMDAWNWEBGPU_STRUCT_INFO_JSON_GEN_SOURCES} ${WEBGPU_STRUCT_INFO_GEN32}
- )
webgpu_gen_struct_info(
OUTPUT_JSON WEBGPU_STRUCT_INFO_GEN64
WASM64 ON
)
- add_custom_target(webgpu_generated_struct_info64
- DEPENDS emdawnwebgpu_headers_gen ${EMDAWNWEBGPU_STRUCT_INFO_JSON_GEN_SOURCES} ${WEBGPU_STRUCT_INFO_GEN64}
- )
# TODO(crbug.com/346806934): Consider using CMake builtin `cat` as per https://stackoverflow.com/a/62362885,
# especially if we are to remove the GN build where concat.py is needed.
@@ -151,15 +149,18 @@
set(PRINT_NAME library_webgpu_generated_struct_info.js)
set(OUTPUT "${EM_BUILD_GEN_DIR}/${PRINT_NAME}")
+ set(SRCS
+ "${EM_SRC_DIR}/snippets/library_webgpu_struct_info_part1.txt"
+ "${WEBGPU_STRUCT_INFO_GEN32}"
+ "${EM_SRC_DIR}/snippets/library_webgpu_struct_info_part2.txt"
+ "${WEBGPU_STRUCT_INFO_GEN64}"
+ "${EM_SRC_DIR}/snippets/library_webgpu_struct_info_part3.txt"
+ )
set(ARGS
${Python3_EXECUTABLE}
"${EM_SRC_DIR}/concat.py"
"${OUTPUT}"
- "${EM_SRC_DIR}/snippets/library_webgpu_struct_info_part1.txt"
- "${EM_BUILD_GEN_DIR}/webgpu_generated_struct_info32.json"
- "${EM_SRC_DIR}/snippets/library_webgpu_struct_info_part2.txt"
- "${EM_BUILD_GEN_DIR}/webgpu_generated_struct_info64.json"
- "${EM_SRC_DIR}/snippets/library_webgpu_struct_info_part3.txt"
+ ${SRCS}
)
set(${arg_OUTPUT_JS} "${OUTPUT}" PARENT_SCOPE)
@@ -167,6 +168,9 @@
COMMAND ${ARGS}
OUTPUT ${OUTPUT}
COMMENT "Dawn Emscripten: Generating ${PRINT_NAME}."
+ DEPENDS
+ "${EM_SRC_DIR}/concat.py"
+ ${SRCS}
)
# Prior to CMake 3.20 the GENERATED property is local to a directory which means that putting
@@ -186,37 +190,13 @@
webgpu_gen_struct_info_js(
OUTPUT_JS EMDAWNWEBGPU_STRUCT_INFO_JS
)
- add_custom_target(webgpu_generated_struct_info_js
- DEPENDS
- webgpu_generated_struct_info32
- webgpu_generated_struct_info64
- ${EMDAWNWEBGPU_STRUCT_INFO_JS}
- )
- add_library(emdawnwebgpu_config INTERFACE)
- target_include_directories(emdawnwebgpu_config BEFORE INTERFACE
+ # Include dir, and dependency on the generated files in the include dir.
+ add_library(emdawnwebgpu_c_include INTERFACE)
+ target_include_directories(emdawnwebgpu_c_include BEFORE INTERFACE
"${EM_BUILD_GEN_DIR}/include"
)
- add_dependencies(emdawnwebgpu_config
- webgpu_generated_struct_info_js
- emdawnwebgpu_js_gen
- emdawnwebgpu_headers_gen
- )
- target_link_options(emdawnwebgpu_config INTERFACE
- # We are using Dawn-generated bindings, not built-in ones
- "-sUSE_WEBGPU=0"
- # The JS libraries needed for bindings
- "--js-library=${EM_BUILD_GEN_DIR}/library_webgpu_enum_tables.js"
- "--js-library=${EM_BUILD_GEN_DIR}/library_webgpu_generated_struct_info.js"
- "--js-library=${EM_BUILD_GEN_DIR}/library_webgpu_generated_sig_info.js"
- "--js-library=${DAWN_EMDAWNWEBGPU_DIR}/pkg/webgpu/src/library_webgpu.js"
- # Closure externs to avoid minifying WebGPU API symbols
- "--closure-args=--externs=${DAWN_EMDAWNWEBGPU_DIR}/pkg/webgpu/src/webgpu-externs.js"
- )
- # Relink when library_webgpu.js file changes.
- set_target_properties(emdawnwebgpu_config PROPERTIES
- INTERFACE_LINK_DEPENDS "${DAWN_EMDAWNWEBGPU_DIR}/pkg/webgpu/src/library_webgpu.js"
- )
+ add_dependencies(emdawnwebgpu_c_include emdawnwebgpu_headers_gen)
dawn_add_library(
emdawnwebgpu_c
@@ -226,7 +206,37 @@
SOURCES
"${DAWN_EMDAWNWEBGPU_DIR}/pkg/webgpu/src/webgpu.cpp"
DEPENDS
- emdawnwebgpu_config
+ emdawnwebgpu_c_include
+ )
+ target_link_options(emdawnwebgpu_c INTERFACE
+ # IMPORTANT: If changing these dependencies, update EMDAWNWEBGPU_C_ALL_FILE_DEPS too.
+ "--js-library=${EM_BUILD_GEN_DIR}/library_webgpu_enum_tables.js"
+ "--js-library=${EM_BUILD_GEN_DIR}/library_webgpu_generated_sig_info.js"
+ "--js-library=${EM_BUILD_GEN_DIR}/library_webgpu_generated_struct_info.js"
+ "--js-library=${DAWN_EMDAWNWEBGPU_DIR}/pkg/webgpu/src/library_webgpu.js"
+ "--closure-args=--externs=${DAWN_EMDAWNWEBGPU_DIR}/pkg/webgpu/src/webgpu-externs.js"
+ )
+
+ # Dependencies from emdawnwebgpu_c to the files referenced in the linker flags.
+ # - These are used as both file-level dependencies (defining *when* to rebuild) and
+ # target-level dependencies (defining *how* to rebuild).
+ set(EMDAWNWEBGPU_C_GENERATED_FILE_DEPS
+ "${EMDAWNWEBGPU_JS_GEN_SOURCES}"
+ "${EMDAWNWEBGPU_STRUCT_INFO_JS}"
+ )
+ # - There are also source files, which are used only as file-level dependencies.
+ set(EMDAWNWEBGPU_C_ALL_FILE_DEPS
+ "${EMDAWNWEBGPU_C_GENERATED_FILE_DEPS}"
+ "${DAWN_EMDAWNWEBGPU_DIR}/pkg/webgpu/src/library_webgpu.js"
+ "${DAWN_EMDAWNWEBGPU_DIR}/pkg/webgpu/src/webgpu-externs.js"
+ )
+ add_custom_target(emdawnwebgpu_config_generated_deps
+ DEPENDS "${EMDAWNWEBGPU_C_GENERATED_FILE_DEPS}"
+ )
+ add_dependencies(emdawnwebgpu_c emdawnwebgpu_config_generated_deps)
+ set_target_properties(emdawnwebgpu_c PROPERTIES
+ # This defines file-level dependencies of the linker (intended for "linker scripts").
+ INTERFACE_LINK_DEPENDS "${EMDAWNWEBGPU_C_ALL_FILE_DEPS}"
)
dawn_add_library(
@@ -244,10 +254,9 @@
add_custom_target(emdawnwebgpu_pkg
DEPENDS
- # Note emdawnwebgpu_headers_gen generates all the files we need. We don't want
- # emdawnwebgpu_c because that will actually compile webgpu.cpp. We want to
- # package webgpu.cpp as a source file, instead.
- emdawnwebgpu_config
+ # This will compile webgpu.cpp, which is unnecessary because we package webgpu.cpp as a
+ # source file, but it's simpler than specifying all the generator dependencies again.
+ emdawnwebgpu_c
)
add_custom_command(TARGET emdawnwebgpu_pkg POST_BUILD