Skip to content

Conversation

@ypujante
Copy link
Contributor

@ypujante ypujante commented May 10, 2025

This PR is implementing #24260.

The logic that this PR implements is the following:

  • the external port is loaded like the other ports and "flagged" as being external (port.is_external = hasattr(port, 'EXTERNAL_PORT')
  • if the port is never needed, then nothing else happens
  • if the port is needed (because the user wants to use it via --use-port=contrib.emdawn, or it is a dependency of another port), then the code fetches the artifact and uses the port file included in the artifact to load the actual port file as if it was a local port, and replaces it in the ports array and ports_by_name map.

=> as a result, all calls using ports_by_name have been changed to call get_port_by_name to detect whether the port is remote or not and act appropriately

An external port looks like this: it only contains info about where the port is located, the actual logic is coming from PORT_FILE

TAG = 'v20250509.171557'

EXTERNAL_PORT = f'https://github.com/google/dawn/releases/download/{TAG}/emdawnwebgpu_pkg-{TAG}.zip'
SHA512 = '4b66bf0f64b9616a6420abdad636b3ecefab892dde8f67cd941147bfddf7920f5523ff10160c9a563ef377a0f88b2dfc033527591b2d0753d531de5cbbabde59'
PORT_FILE = 'emdawnwebgpu_pkg/emdawnwebgpu.port.py'

# contrib port information (required)
URL = 'https://dawn.googlesource.com/dawn'
DESCRIPTION = 'Dawn is an open-source and cross-platform implementation of the WebGPU standard'
LICENSE = 'BSD 3-Clause License'

@ypujante ypujante marked this pull request as ready for review May 14, 2025 13:56
@ypujante
Copy link
Contributor Author

After investigating the code further, I may have found a solution for the cache issue: I added cache.ensure right before calling cache.withlock which fixes the cache issue.

Please let me know what you think of theses changes.

I don't understand why mypy is failing on something that is not changed in this PR

tools/ports/__init__.py:29: error: Need type annotation for "ports_by_name" (hint: "ports_by_name: Dict[<type>, <type>] = ...")  [var-annotated]
Found 1 error in 1 file (checked 131 source files)

@ypujante
Copy link
Contributor Author

@sbc100 Note that it is no longer a draft pull request as the implementation is working.

The test added works:

  test_remote_ports (test_other.other) ... ok (0.000s)

The test failures don't seem to be related, for example:

======================================================================
FAIL [1.000s]: test_webgl_multi_draw_elements_instanced (test_browser.browser)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/root/project/test/common.py", line 2357, in run_browser
    self.assertContained(expected, output)
  File "/root/project/test/common.py", line 1651, in assertContained
    self.fail("Expected to find '%s' in '%s', diff:\n\n%s\n%s" % (
  File "/usr/lib/python3.8/unittest/case.py", line 753, in fail
    raise self.failureException(msg)
AssertionError: Expected to find '/report_result?0
' in '/report_result?exception:Cannot read properties of undefined (reading 'GLctx') / TypeError: Cannot read properties of undefined (reading 'GLctx')
    at _emscripten_webgl_enable_WEBGL_multi_draw (http://localhost:8888/test.js:1833:107)
    at http://localhost:8888/test.wasm:wasm-function[31]:0x894
    at http://localhost:8888/test.wasm:wasm-function[32]:0xbeb
    at http://localhost:8888/test.js:896:12
    at callMain (http://localhost:8888/test.js:2687:15)
    at doRun (http://localhost:8888/test.js:2740:24)
    at http://localhost:8888/test.js:2749:7

This test passes locally.

Of course the mypy test is failing due to missing type annotation but I don't understand why since I did not change that part of the code.

So at this stage I am awaiting your feedback to see if this is the right direction and what you want me to do to move forward with this PR.

I will obviously update documentation/Changelog once you are satisfied with the changes

Copy link
Collaborator

@sbc100 sbc100 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This approach seem reasonable yes.

Can update the PR description with some more details.

@ypujante
Copy link
Contributor Author

ypujante commented May 15, 2025

@sbc100 I have made the changes you requested. Here are some comments:

I added a TODO comment for cache.ensure() as I do not know where else to put it to make it work

In regards to the "delay" feature, I implemented the change you requested but I want you to know that I do not agree with it and here is an example that demonstrates why:

> rm -rf cache

> ./embuilder build sdl2 contrib.emdawn

shared:INFO: (Emscripten: Running sanity checks)
embuilder:INFO: building sdl2
ports:INFO: retrieving port: sdl2 from https://github.com/libsdl-org/SDL/archive/release-2.32.0.zip
ports:INFO: unpacking port: sdl2
cache:INFO: generating port: sysroot/lib/wasm32-emscripten/libSDL2.a... (this will be cached in "/usr/local/emsdk/emscripten/main/cache/sysroot/lib/wasm32-emscripten/libSDL2.a" for subsequent builds)
cache:INFO: generating system headers: sysroot_install.stamp... (this will be cached in "/usr/local/emsdk/emscripten/main/cache/sysroot_install.stamp" for subsequent builds)
cache:INFO:  - ok
system_libs:INFO: compiled 118 inputs in 4.66s
cache:INFO:  - ok
embuilder:INFO: ...success. Took (7.47s)
embuilder:INFO: building contrib.emdawn
ports:INFO: retrieving port: contrib.emdawn from https://github.com/google/dawn/releases/download/v20250509.171557/emdawnwebgpu_pkg-v20250509.171557.zip
ports:INFO: unpacking port: contrib.emdawn
cache:INFO: generating port: sysroot/lib/wasm32-emscripten/lib_emdawnwebgpu-cb451621-O0.a... (this will be cached in "/usr/local/emsdk/emscripten/main/cache/sysroot/lib/wasm32-emscripten/lib_emdawnwebgpu-cb451621-O0.a" for subsequent builds)
system_libs:INFO: compiled 1 inputs in 0.82s
cache:INFO:  - ok
embuilder:INFO: ...success. Took (1.42s)
embuilder:INFO: Built 2 targets in (8.98s)

> rm -rf cache/ports

> ./embuilder build sdl2 contrib.emdawn

embuilder:INFO: building sdl2
ports:INFO: retrieving port: sdl2 from https://github.com/libsdl-org/SDL/archive/release-2.32.0.zip
ports:INFO: unpacking port: sdl2
cache:INFO: deleting cached file: /usr/local/emsdk/emscripten/main/cache/sysroot/lib/wasm32-emscripten/libSDL2.a
cache:INFO: generating port: sysroot/lib/wasm32-emscripten/libSDL2.a... (this will be cached in "/usr/local/emsdk/emscripten/main/cache/sysroot/lib/wasm32-emscripten/libSDL2.a" for subsequent builds)
system_libs:INFO: compiled 118 inputs in 4.72s
cache:INFO:  - ok
embuilder:INFO: ...success. Took (7.30s)
embuilder:INFO: building contrib.emdawn
ports:INFO: retrieving port: contrib.emdawn from https://github.com/google/dawn/releases/download/v20250509.171557/emdawnwebgpu_pkg-v20250509.171557.zip
ports:INFO: unpacking port: contrib.emdawn
embuilder:INFO: ...success. Took (0.58s)
embuilder:INFO: Built 2 targets in (7.90s)

As you can see from this example, a local port behaves differently from a remote port. After deleting the cache/portsdirectory, sdl2 gets redownloaded and rebuilt, but contrib.emdawn gets redownloaded but not rebuilt. That was the reason why I had the 2 lines and variable (need_clear_project_build) you made me remove. I just don't think this is right but this is your decision. I assume this use case is not important or valid, but then why is it implemented in the first place?

@sbc100
Copy link
Collaborator

sbc100 commented May 15, 2025

@sbc100 I have made the changes you requested. Here are some comments:

I added a TODO comment for cache.ensure() as I do not know where else to put it to make it work

In regards to the "delay" feature, I implemented the change you requested but I want you to know that I do not agree with it and here is an example that demonstrates why:

> rm -rf cache

> ./embuilder build sdl2 contrib.emdawn

shared:INFO: (Emscripten: Running sanity checks)
embuilder:INFO: building sdl2
ports:INFO: retrieving port: sdl2 from https://github.com/libsdl-org/SDL/archive/release-2.32.0.zip
ports:INFO: unpacking port: sdl2
cache:INFO: generating port: sysroot/lib/wasm32-emscripten/libSDL2.a... (this will be cached in "/usr/local/emsdk/emscripten/main/cache/sysroot/lib/wasm32-emscripten/libSDL2.a" for subsequent builds)
cache:INFO: generating system headers: sysroot_install.stamp... (this will be cached in "/usr/local/emsdk/emscripten/main/cache/sysroot_install.stamp" for subsequent builds)
cache:INFO:  - ok
system_libs:INFO: compiled 118 inputs in 4.66s
cache:INFO:  - ok
embuilder:INFO: ...success. Took (7.47s)
embuilder:INFO: building contrib.emdawn
ports:INFO: retrieving port: contrib.emdawn from https://github.com/google/dawn/releases/download/v20250509.171557/emdawnwebgpu_pkg-v20250509.171557.zip
ports:INFO: unpacking port: contrib.emdawn
cache:INFO: generating port: sysroot/lib/wasm32-emscripten/lib_emdawnwebgpu-cb451621-O0.a... (this will be cached in "/usr/local/emsdk/emscripten/main/cache/sysroot/lib/wasm32-emscripten/lib_emdawnwebgpu-cb451621-O0.a" for subsequent builds)
system_libs:INFO: compiled 1 inputs in 0.82s
cache:INFO:  - ok
embuilder:INFO: ...success. Took (1.42s)
embuilder:INFO: Built 2 targets in (8.98s)

> rm -rf cache/ports

> ./embuilder build sdl2 contrib.emdawn

embuilder:INFO: building sdl2
ports:INFO: retrieving port: sdl2 from https://github.com/libsdl-org/SDL/archive/release-2.32.0.zip
ports:INFO: unpacking port: sdl2
cache:INFO: deleting cached file: /usr/local/emsdk/emscripten/main/cache/sysroot/lib/wasm32-emscripten/libSDL2.a
cache:INFO: generating port: sysroot/lib/wasm32-emscripten/libSDL2.a... (this will be cached in "/usr/local/emsdk/emscripten/main/cache/sysroot/lib/wasm32-emscripten/libSDL2.a" for subsequent builds)
system_libs:INFO: compiled 118 inputs in 4.72s
cache:INFO:  - ok
embuilder:INFO: ...success. Took (7.30s)
embuilder:INFO: building contrib.emdawn
ports:INFO: retrieving port: contrib.emdawn from https://github.com/google/dawn/releases/download/v20250509.171557/emdawnwebgpu_pkg-v20250509.171557.zip
ports:INFO: unpacking port: contrib.emdawn
embuilder:INFO: ...success. Took (0.58s)
embuilder:INFO: Built 2 targets in (7.90s)

As you can see from this example, a local port behaves differently from a remote port. After deleting the cache/portsdirectory, sdl2 gets redownloaded and rebuilt, but contrib.emdawn gets redownloaded but not rebuilt. That was the reason why I had the 2 lines and variable (need_clear_project_build) you made me remove. I just don't think this is right but this is your decision. I assume this use case is not important or valid, but then why is it implemented in the first place?

Yup, looks like you are correct. I was assuming that the build directory for the remote port was not even a thing.

I don't love the way we need to modify fetch_project like that have here, or even the fact that we are using Ports.fetch_project in the first place. Hopefully we we can improve on this at some point.

@ypujante
Copy link
Contributor Author

@sbc100

I don't love the way we need to modify fetch_project like that have here, or even the fact that we are using Ports.fetch_project in the first place. Hopefully we we can improve on this at some point.

So I reintroduced the behavior but I did it differently taking into account your comment about not loving the way it was done: I refactored fetch_project so that it calls a (new) function called fetch_port_artifact which does what fetch_project used to do but does not clear the build anymore. Instead it returns True if the port is up to date and False if not.

This way the new code calls fetch_port_artifact directly and can "delay" until the end of the call to clear the build. The old code simply calls fetch_port_artifact and clears the build right away if not up to date.

I think it is lot cleaner (and from my manual testing, replaying the scenario I described earlier, it works great).

If you agree with these changes, I can then update the ChangeLog and Documentation about the new concept of remote ports. I can also update the emdawn contrib port to a more recent version.

@kainino0x is there a version of Dawn/emdawn that is more "stable" than others or should I just pick the latest (nightly) version?

Copy link
Collaborator

@sbc100 sbc100 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! I like this better. LGTM % docs, although TBH we could land this now as an internal-only experiment (without public docs)

@ypujante
Copy link
Contributor Author

@sbc100 I am good with landing this internal-only. Once this is released, I can then also turn contrib.glfw as a remote port for another real-life test case and release it publicly with this change.

@kainino0x
Copy link
Collaborator

@kainino0x is there a version of Dawn/emdawn that is more "stable" than others or should I just pick the latest (nightly) version?

Latest nightly v20250514.194204 should be the best one we have. It has the most bugfixes.

@ypujante
Copy link
Contributor Author

@sbc100 @kainino0x Alright, so I just updated the PR with the recommended emdawn version (v20250514.194204) and LICENSE string.

As per our prior conversation, let's move forward with pushing this PR as-is (no docs / internal-only). Once this is merged, @kainino0x can deprecate -sUSE_WEBGPU and recommend switching to --use-port=contrib.emdawn.

Once the next version of Emscripten is released with these changes, I can then work on making contrib.glfw3 a remote port as well so that we have another test case and then make another PR to update it and make these changes more official (docs , etc..)

@sbc100
Copy link
Collaborator

sbc100 commented May 15, 2025

@sbc100 @kainino0x Alright, so I just updated the PR with the recommended emdawn version (v20250514.194204) and LICENSE string.

As per our prior conversation, let's move forward with pushing this PR as-is (no docs / internal-only). Once this is merged, @kainino0x can deprecate -sUSE_WEBGPU and recommend switching to --use-port=contrib.emdawn.

Once the next version of Emscripten is released with these changes, I can then work on making contrib.glfw3 a remote port as well so that we have another test case and then make another PR to update it and make these changes more official (docs , etc..)

I wonder if we can avoid asking folks to make actual releases for repos that just contains a single port (like contrib.glfw3)? Perhaps we can just use the archive URL for a given GIT commit?

@ypujante
Copy link
Contributor Author

I merged main and the tests reran. There are 2 failures (which were not present before the merge) which don't seem to be related to this PR. So I believe this is ready to be merged.

======================================================================
ERROR [0.003s]: test_pthread_dlopen_many (test_core.core0)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.8/unittest/case.py", line 60, in testPartExecutor
    yield
  File "/usr/lib/python3.8/unittest/case.py", line 676, in run
    self._callTestMethod(testMethod)
  File "/usr/lib/python3.8/unittest/case.py", line 633, in _callTestMethod
    method()
  File "/root/project/test/test_core.py", line 121, in decorated
    return func(self, *args, **kwargs)
  File "/root/project/test/common.py", line 349, in decorated
    f(self, *args, **kwargs)
  File "/root/project/test/test_core.py", line 9296, in test_pthread_dlopen_many
    self.do_runf('core/pthread/test_pthread_dlopen_many.c',
  File "/root/project/test/common.py", line 1926, in do_runf
    return self._build_and_run(filename, expected_output, **kwargs)
  File "/root/project/test/common.py", line 1971, in _build_and_run
    js_output = self.run_js(js_file, engine, args,
  File "/root/project/test/common.py", line 1555, in run_js
    raise timeout_error
  File "/root/project/test/common.py", line 1527, in run_js
    jsrun.run_js(filename, engine, args,
  File "/root/project/test/jsrun.py", line 103, in run_js
    proc = subprocess.run(
  File "/usr/lib/python3.8/subprocess.py", line 495, in run
    stdout, stderr = process.communicate(input, timeout=timeout)
  File "/usr/lib/python3.8/subprocess.py", line 1028, in communicate
    stdout, stderr = self._communicate(input, endtime, timeout)
  File "/usr/lib/python3.8/subprocess.py", line 1894, in _communicate
    self.wait(timeout=self._remaining_time(endtime))
  File "/usr/lib/python3.8/subprocess.py", line 1083, in wait
    return self._wait(timeout=timeout)
  File "/usr/lib/python3.8/subprocess.py", line 1798, in _wait
    raise TimeoutExpired(self.args, timeout)
subprocess.TimeoutExpired: Command '['/root/emsdk/node/20.18.0_64bit/bin/node', '--stack-trace-limit=50', '--trace-uncaught', '/tmp/emtest_h9ywpgy3/emscripten_test_core0_bcxwcaqa/test_pthread_dlopen_many.js']' timed out after 299.9999436500002 seconds

======================================================================
FAIL [0.002s]: test_async_hello_v8 (test_core.instance)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.8/unittest/case.py", line 60, in testPartExecutor
    yield
  File "/usr/lib/python3.8/unittest/case.py", line 676, in run
    self._callTestMethod(testMethod)
  File "/usr/lib/python3.8/unittest/case.py", line 633, in _callTestMethod
    method()
  File "/root/project/test/common.py", line 316, in decorated
    return func(self, *args, **kwargs)
  File "/root/project/test/test_core.py", line 8073, in test_async_hello_v8
    self.test_async_hello()
  File "/root/project/test/common.py", line 895, in resulting_test
    return func(self, *args)
  File "/root/project/test/test_core.py", line 197, in metafunc
    f(self, *args, **kwargs)
  File "/root/project/test/test_core.py", line 8054, in test_async_hello
    self.do_runf('main.c', 'HelloWorld!99')
  File "/root/project/test/common.py", line 1926, in do_runf
    return self._build_and_run(filename, expected_output, **kwargs)
  File "/root/project/test/common.py", line 1955, in _build_and_run
    js_file = self.build(filename, **kwargs)
  File "/root/project/test/common.py", line 1414, in build
    self.run_process(cmd, stderr=self.stderr_redirect if not DEBUG else None)
  File "/root/project/test/common.py", line 1757, in run_process
    self.fail(f'subprocess exited with non-zero return code({e.returncode}): `{shlex.join(cmd)}`')
  File "/usr/lib/python3.8/unittest/case.py", line 753, in fail
    raise self.failureException(msg)
AssertionError: subprocess exited with non-zero return code(1): `/root/project/emcc main.c -o main.mjs -sNO_DEFAULT_TO_CXX -sMODULARIZE=instance -sASYNCIFY -sEXIT_RUNTIME -Wclosure -Werror -Wno-limited-postlink-optimizations -Wno-experimental -Wno-unused-command-line-argument -sENVIRONMENT=shell````

@ypujante
Copy link
Contributor Author

@kainino0x I don't think it is a showstopper for releasing these changes, but version v20250514.194204 generates an issue with the closure compiler:

// rebuilding my example: see https://github.com/pongasoft/emscripten-ports/tree/master/examples/Dawn
// /usr/local/emsdk/emscripten/main/emcc -sASYNCIFY=1 --closure=1 -O2 --use-port=contrib.emdawn main.cpp -o /tmp/dawn/index.html

building:ERROR: Closure compiler run failed:

building:ERROR: /var/folders/wz/zqhny4ks031bqlr6r27bfkzm0000gn/T/emscripten_temp_48uj9d0y/index.jso1.js:1152:17: ERROR - [JSC_UNDEFINED_VARIABLE] variable stringToNewUTF8 is undeclared
  1152|     var strPtr = stringToNewUTF8(strs);
                         ^^^^^^^^^^^^^^^

1 error(s), 0 warning(s)

@sbc100
Copy link
Collaborator

sbc100 commented May 16, 2025

@kainino0x I don't think it is a showstopper for releasing these changes, but version v20250514.194204 generates an issue with the closure compiler:

// rebuilding my example: see https://github.com/pongasoft/emscripten-ports/tree/master/examples/Dawn
// /usr/local/emsdk/emscripten/main/emcc -sASYNCIFY=1 --closure=1 -O2 --use-port=contrib.emdawn main.cpp -o /tmp/dawn/index.html

building:ERROR: Closure compiler run failed:

building:ERROR: /var/folders/wz/zqhny4ks031bqlr6r27bfkzm0000gn/T/emscripten_temp_48uj9d0y/index.jso1.js:1152:17: ERROR - [JSC_UNDEFINED_VARIABLE] variable stringToNewUTF8 is undeclared
  1152|     var strPtr = stringToNewUTF8(strs);
                         ^^^^^^^^^^^^^^^

1 error(s), 0 warning(s)

Looks like a call to an undefined function. Likely a missing dependency.

@ypujante
Copy link
Contributor Author

This is the snippet of code that triggers the error:

// line 579 | library_webgpu.js
...
      }
    },

    fillAdapterInfoStruct: (info, infoStruct) => {
      {{{ gpu.makeCheckDescriptor('infoStruct') }}}

      // Populate subgroup limits.
      {{{ makeSetValue('infoStruct', C_STRUCTS.WGPUAdapterInfo.subgroupMinSize, 'info.subgroupMinSize', 'i32') }}};
      {{{ makeSetValue('infoStruct', C_STRUCTS.WGPUAdapterInfo.subgroupMaxSize, 'info.subgroupMaxSize', 'i32') }}};

      // Append all the strings together to condense into a single malloc.
      var strs = info.vendor + info.architecture + info.device + info.description;
      var strPtr = stringToNewUTF8(strs);
...

it is definitely missing the fillAdapterInfoStruct__deps section

@kainino0x
Copy link
Collaborator

Oops, that was a recent regression (from here). We haven't quite got automated testing up and running yet. Will fix.

@ypujante
Copy link
Contributor Author

@kainino0x it's funny because it is my own CI that caught the problem :)

@kainino0x
Copy link
Collaborator

kainino0x commented May 16, 2025

Heh, any build is better than none! I just added a basic compile test but it's not running anywhere, I should add that to the github release so it does a last check before releasing.

Should be fixed today with https://dawn-review.googlesource.com/c/dawn/+/242734. Thanks for the report.

copybara-service bot pushed a commit to google/dawn that referenced this pull request May 16, 2025
The deps need to be on the fillAdapterInfoStruct helper rather than the
functions that use it, I think because it's positioned like a public API
so Emscripten assumes it can't eliminate it (but still assumes it can
eliminate stringToNewUTF8). It's not an immediate code size problem
because Closure still eliminates it if it's unused, but Closure needs
the code to be valid to do that.

Tested this fixes a local release+closure build.

Also updated the externs for these; I have not verified that change (but
it's safe, it can't break anything).

No-Try: true
Bug: emscripten-core/emscripten#24303 (comment)
Change-Id: Ib718f37c2dccf18374a115c9f12192685da55e46
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/242734
Commit-Queue: Loko Kung <lokokung@google.com>
Auto-Submit: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Loko Kung <lokokung@google.com>
@kainino0x
Copy link
Collaborator

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to call this emdawnwebgpu for consistency with the project name (the reason it has that weird name is to make it very easily keyword searchable)

@ypujante
Copy link
Contributor Author

  • I bumped the version to v20250516.124039 which fixes the closure compiler issue I had noticed
  • I renamed the port per @kainino0x request

The tests are passing minus one which seems to be irrelevant ERROR: could not find the following tests: esm-integration

@ypujante
Copy link
Contributor Author

I merged with main yesterday and there was no test failures.

I merged again this morning and there are 2 test failures which are unrelated to these changes:

======================================================================
FAIL [0.005s]: test_dyncall_pointers_legacy (test_core.core3)
----------------------------------------------------------------------

======================================================================
ERROR [0.005s]: test_fcntl_open_rawfs (test_core.esm_integration)
----------------------------------------------------------------------

@sbc100 Is there anything else that I need to do for this PR? Just as an FYI, I will be traveling in a couple of days so I will be less available for changes. So please let me know if there is anything that need to be changed.

@sbc100
Copy link
Collaborator

sbc100 commented May 20, 2025

Both of those failures are known issues. The former has now been fixed and the later is just a flake.


@requires_network
def test_remote_ports(self):
self.emcc(test_file('hello_world.c'), ['--use-port=contrib.emdawnwebgpu'])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kainino0x the name emdawnwebgpu seems rather long and redundant to me.

How about simple emdawn or even just dawn. The em prefix and the webgpu suffix both seem redundant in this context but maybe I'm missing something?

In any case we can land this and bikeshed later.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, I agree 100% with @sbc100. I had named it originally dawn because it is the name of the project and it is following the pattern of all the other ports (sdl2, glfw3, etc... which are not named emsdl2, emglfw3). I only renamed it because @kainino0x asked me to.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Emdawnwebgpu is the name of the project, it's used for the package releases and in the Dawn source tree. I chose it to be easily searchable and unambiguous (from USE_WEBGPU, any other potential/future ways of using Dawn in Wasm, Tint in Wasm, etc.)

Copy link
Collaborator

@sbc100 sbc100 May 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough!

Also, we could drip the contrib. here if you like since we do care internally about maintain this port if good working order. When we could just have --use-port=emdawnwebgpu

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the distinction is how much we maintain it, then making it a non-contrib port makes sense to me. Will probably roll that change into #24220.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, kind of. Its not super well defined. Basically I wanted to allow folks to create new ports in emscripten without adding more work for emscripten developers to make sure they keep working in all out different build configurations. I think we webgpu is key enough that we should consider it core and make sure it works over time.

That said, we should at some point add a few more emscripten-side tests to ensure we don't break things on our end.

@sbc100 sbc100 changed the title Allow for fully external contrib ports Allow externally hosted contrib ports May 20, 2025
@sbc100 sbc100 merged commit 26b4bce into emscripten-core:main May 20, 2025
27 of 30 checks passed
@kainino0x
Copy link
Collaborator

🎉

kainino0x added a commit to kainino0x/dawn that referenced this pull request May 21, 2025
Thanks to emscripten-core/emscripten#24303
(which should be in the next Emscription release, 4.0.10(?)), users
can use this new port format which just includes a pointer to a zip
containing a port file.

Generate and release a port file like the one used in Emscripten, which
can (1) be used instead of extracting the zip and (2) be copied directly
into Emscripten whenever we want to update its version of
`tools/ports/emdawnwebgpu.py`.

Bug: 371024051
Change-Id: I12ee39d68454d7e7dba56798864b39ade51862b0
kainino0x added a commit to kainino0x/dawn that referenced this pull request May 21, 2025
Thanks to emscripten-core/emscripten#24303
(which should be in the next Emscription release, 4.0.10), users can use
this new port format which just includes a pointer to a zip containing a
port file.

This change generates and releases a port file like the one used in
Emscripten, which can (1) be used instead of extracting the zip and (2)
be copied directly into Emscripten whenever we want to update its
version of `tools/ports/emdawnwebgpu.py`.

Bug: 371024051
Change-Id: I12ee39d68454d7e7dba56798864b39ade51862b0
kainino0x added a commit to kainino0x/dawn that referenced this pull request May 21, 2025
Thanks to emscripten-core/emscripten#24303
(which should be in the next Emscription release, 4.0.10), users can use
this new port format which just includes a pointer to a zip containing a
port file.

This change generates and releases a port file like the one used in
Emscripten, which can (1) be used instead of extracting the zip and (2)
be copied directly into Emscripten whenever we want to update its
version of `tools/ports/emdawnwebgpu.py`.

Bug: 371024051
Change-Id: I12ee39d68454d7e7dba56798864b39ade51862b0
kainino0x added a commit to kainino0x/dawn that referenced this pull request May 21, 2025
Thanks to emscripten-core/emscripten#24303
(which should be in the next Emscription release, 4.0.10), users can use
this new port format which just includes a pointer to a zip containing a
port file.

This change generates and releases a port file like the one used in
Emscripten, which can (1) be used instead of extracting the zip and (2)
be copied directly into Emscripten whenever we want to update its
version of `tools/ports/emdawnwebgpu.py`.

Our version of Emscripten is still 4.0.8, but people can still use this
with 4.0.10+.

No-Try: true
Bug: 371024051
Bug: 415224043
Change-Id: I12ee39d68454d7e7dba56798864b39ade51862b0
kainino0x added a commit to kainino0x/dawn that referenced this pull request May 21, 2025
Thanks to emscripten-core/emscripten#24303
(which should be in the next Emscription release, 4.0.10), users can use
this new port format which just includes a pointer to a zip containing a
port file.

This change generates and releases a port file like the one used in
Emscripten, which can (1) be used instead of extracting the zip and (2)
be copied directly into Emscripten whenever we want to update its
version of `tools/ports/emdawnwebgpu.py`. It includes a full copy of the
package README as a docstring to make the port self-documenting.

Our version of Emscripten is still 4.0.8, but people can use this with
4.0.10+.

No-Try: true
Bug: 371024051
Bug: 415224043
Change-Id: I12ee39d68454d7e7dba56798864b39ade51862b0
copybara-service bot pushed a commit to google/dawn that referenced this pull request May 21, 2025
Thanks to emscripten-core/emscripten#24303
(which should be in the next Emscription release, 4.0.10), users can use
this new port format which just includes a pointer to a zip containing a
port file.

This change generates and releases a port file like the one used in
Emscripten, which can (1) be used instead of extracting the zip and (2)
be copied directly into Emscripten whenever we want to update its
version of `tools/ports/emdawnwebgpu.py`. It includes a full copy of the
package README as a docstring to make the port self-documenting.

Our version of Emscripten is still 4.0.8, but people can use this with
4.0.10+.

No-Try: true
Bug: 371024051
Bug: 415224043
Change-Id: I12ee39d68454d7e7dba56798864b39ade51862b0
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/243214
Auto-Submit: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Loko Kung <lokokung@google.com>
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
@ypujante ypujante deleted the ticket-24260 branch May 23, 2025 16:50
Lukasdoe pushed a commit to Lukasdoe/emscripten that referenced this pull request Jun 19, 2025
The logic that this PR implements is the following:

* the external port is loaded like the other ports and "flagged" as
being external (`port.is_external = hasattr(port, 'EXTERNAL_PORT'`)
* if the port is never needed, then nothing else happens
* if the port is needed (because the user wants to use it via
`--use-port=contrib.emdawn`, or it is a dependency of another port),
then the code fetches the artifact and uses the port file included in
the artifact to load the actual port file as if it was a local port, and
replaces it in the ports array and `ports_by_name` map.

=> as a result, all calls using `ports_by_name` have been changed to
call `get_port_by_name` to detect whether the port is remote or not and
act appropriately

An external port looks like this: it only contains info about where the
port is located, the actual logic is coming from `PORT_FILE`

```
TAG = 'v20250509.171557'

EXTERNAL_PORT = f'https://github.com/google/dawn/releases/download/{TAG}/emdawnwebgpu_pkg-{TAG}.zip'
SHA512 = '4b66bf0f64b9616a6420abdad636b3ecefab892dde8f67cd941147bfddf7920f5523ff10160c9a563ef377a0f88b2dfc033527591b2d0753d531de5cbbabde59'
PORT_FILE = 'emdawnwebgpu_pkg/emdawnwebgpu.port.py'

# contrib port information (required)
URL = 'https://dawn.googlesource.com/dawn'
DESCRIPTION = 'Dawn is an open-source and cross-platform implementation of the WebGPU standard'
LICENSE = 'BSD 3-Clause License'
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants