Skip to content

Commit c1589b5

Browse files
authored
Use emsdk as external bazel dependency (#766)
* Makes provided bazel rules look up @emsdk workspace instead of local workspace * Uses system-specific emscripten binaries instead of defaulting to linux * Provides macros for loading emsdk dependencies (nodejs and emscripten binaries) * Unhardcodes paths in bazel rules and .sh wrappers * `update_bazel_workspace.sh` now updates `revisions.bzl` * `emscripten_deps()` can be fed with specific emscripten version * Adds external usage test Addresses #650 and #696
1 parent fdda852 commit c1589b5

21 files changed

+334
-101
lines changed

.circleci/config.yml

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ jobs:
166166
docker login -u "$DOCKER_USER" -p "$DOCKER_PASS"
167167
make -C ./docker version=${CIRCLE_TAG} alias=latest push
168168
169-
test-bazel:
169+
test-bazel-linux:
170170
executor: bionic
171171
steps:
172172
- checkout
@@ -186,6 +186,21 @@ jobs:
186186
apt-get install -q -y bazel
187187
- run: test/test_bazel.sh
188188

189+
test-bazel-mac:
190+
macos:
191+
xcode: "12.2.0"
192+
environment:
193+
EMSDK_NOTTY: "1"
194+
HOMEBREW_NO_AUTO_UPDATE: "1"
195+
steps:
196+
- checkout
197+
- run: brew install grep
198+
- run:
199+
name: install bazel
200+
command: |
201+
brew install bazel
202+
- run: test/test_bazel_mac.sh
203+
189204
workflows:
190205
flake8:
191206
jobs:
@@ -208,6 +223,9 @@ workflows:
208223
ignore: /.*/
209224
tags:
210225
only: /.*/
211-
test-bazel:
226+
test-bazel-linux:
227+
jobs:
228+
- test-bazel-linux
229+
test-bazel-mac:
212230
jobs:
213-
- test-bazel
231+
- test-bazel-mac

bazel/BUILD

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package(default_visibility = ['//visibility:public'])
2+
3+
config_setting(
4+
name = "linux",
5+
constraint_values = [
6+
"@platforms//os:linux",
7+
"@platforms//cpu:x86_64",
8+
],
9+
)
10+
11+
config_setting(
12+
name = "macos",
13+
constraint_values = [
14+
"@platforms//os:macos",
15+
"@platforms//cpu:x86_64",
16+
],
17+
)
18+
19+
config_setting(
20+
name = "windows",
21+
constraint_values = [
22+
"@platforms//os:windows",
23+
"@platforms//cpu:x86_64",
24+
],
25+
)
26+
27+
alias(
28+
name = "binaries",
29+
actual = select({
30+
":linux": "@emscripten_bin_linux//:all",
31+
":macos": "@emscripten_bin_mac//:all",
32+
":windows": "@emscripten_bin_win//:all",
33+
}),
34+
)
35+
36+
alias(
37+
name = "node_modules",
38+
actual = select({
39+
":linux": "@emscripten_npm_linux//:node_modules",
40+
":macos": "@emscripten_npm_mac//:node_modules",
41+
":windows": "@emscripten_npm_win//:node_modules",
42+
}),
43+
)
44+

bazel/WORKSPACE

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,7 @@
1-
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
1+
workspace(name = "emsdk")
22

3-
http_archive(
4-
name = "build_bazel_rules_nodejs",
5-
sha256 = "0f2de53628e848c1691e5729b515022f5a77369c76a09fbe55611e12731c90e3",
6-
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/2.0.1/rules_nodejs-2.0.1.tar.gz"],
7-
)
3+
load(":deps.bzl", "deps")
4+
deps()
85

9-
load("@build_bazel_rules_nodejs//:index.bzl", "npm_install")
10-
11-
# emscripten 2.0.15
12-
http_archive(
13-
name = "emscripten",
14-
sha256 = "7ff49fc63adf29970f6e7af1df445d7f554bdbbb2606db1cb5d3567ce69df1db",
15-
strip_prefix = "install",
16-
url = "https://storage.googleapis.com/webassembly/emscripten-releases-builds/linux/89202930a98fe7f9ed59b574469a9471b0bda7dd/wasm-binaries.tbz2",
17-
build_file = "//emscripten_toolchain:emscripten.BUILD",
18-
type = "tar.bz2",
19-
)
20-
21-
npm_install(
22-
name = "npm",
23-
package_json = "@emscripten//:emscripten/package.json",
24-
package_lock_json = "@emscripten//:emscripten/package-lock.json",
25-
)
6+
load(":emscripten_deps.bzl", "emscripten_deps")
7+
emscripten_deps()

bazel/deps.bzl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
2+
3+
def deps():
4+
excludes = native.existing_rules().keys()
5+
6+
if "build_bazel_rules_nodejs" not in excludes:
7+
http_archive(
8+
name = "build_bazel_rules_nodejs",
9+
sha256 = "0f2de53628e848c1691e5729b515022f5a77369c76a09fbe55611e12731c90e3",
10+
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/2.0.1/rules_nodejs-2.0.1.tar.gz"],
11+
)

bazel/emscripten_deps.bzl

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
2+
load("@build_bazel_rules_nodejs//:index.bzl", "npm_install")
3+
load(":revisions.bzl", "EMSCRIPTEN_TAGS")
4+
5+
def _parse_version(v):
6+
return [int(u) for u in v.split(".")]
7+
8+
def emscripten_deps(emscripten_version = "latest"):
9+
version = emscripten_version
10+
11+
if version == "latest":
12+
version = reversed(sorted(EMSCRIPTEN_TAGS.keys(), key=_parse_version))[0]
13+
14+
if version not in EMSCRIPTEN_TAGS.keys():
15+
error_msg = "Emscripten version {} not found.".format(version)
16+
error_msg += " Look at @emsdk//:revisions.bzl for the list "
17+
error_msg += "of currently supported versions."
18+
fail(error_msg)
19+
20+
revision = EMSCRIPTEN_TAGS[version]
21+
22+
emscripten_url = "https://storage.googleapis.com/webassembly/emscripten-releases-builds/{}/{}/wasm-binaries.tbz2"
23+
24+
# This could potentially backfire for projects with multiple emscripten
25+
# dependencies that use different emscripten versions
26+
excludes = native.existing_rules().keys()
27+
if "emscripten_bin_linux" not in excludes:
28+
http_archive(
29+
name = "emscripten_bin_linux",
30+
strip_prefix = "install",
31+
url = emscripten_url.format("linux", revision.hash),
32+
sha256 = revision.sha_linux,
33+
build_file = "@emsdk//emscripten_toolchain:emscripten.BUILD",
34+
type = "tar.bz2",
35+
)
36+
37+
if "emscripten_bin_mac" not in excludes:
38+
http_archive(
39+
name = "emscripten_bin_mac",
40+
strip_prefix = "install",
41+
url = emscripten_url.format("mac", revision.hash),
42+
sha256 = revision.sha_mac,
43+
build_file = "@emsdk//emscripten_toolchain:emscripten.BUILD",
44+
type = "tar.bz2",
45+
)
46+
47+
if "emscripten_bin_win" not in excludes:
48+
http_archive(
49+
name = "emscripten_bin_win",
50+
strip_prefix = "install",
51+
url = emscripten_url.format("win", revision.hash),
52+
sha256 = revision.sha_win,
53+
build_file = "@emsdk//emscripten_toolchain:emscripten.BUILD",
54+
type = "tar.bz2",
55+
)
56+
57+
if "emscripten_npm_linux" not in excludes:
58+
npm_install(
59+
name = "emscripten_npm_linux",
60+
package_json = "@emscripten_bin_linux//:emscripten/package.json",
61+
package_lock_json = "@emscripten_bin_linux//:emscripten/package-lock.json",
62+
)
63+
64+
if "emscripten_npm_mac" not in excludes:
65+
npm_install(
66+
name = "emscripten_npm_mac",
67+
package_json = "@emscripten_bin_mac//:emscripten/package.json",
68+
package_lock_json = "@emscripten_bin_mac//:emscripten/package-lock.json",
69+
)
70+
71+
if "emscripten_npm_win" not in excludes:
72+
npm_install(
73+
name = "emscripten_npm_win",
74+
package_json = "@emscripten_bin_win//:emscripten/package.json",
75+
package_lock_json = "@emscripten_bin_win//:emscripten/package-lock.json",
76+
)

bazel/emscripten_toolchain/BUILD.bazel

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ filegroup(
99
"emcc.sh",
1010
"emscripten_config",
1111
"env.sh",
12-
"@emscripten//:all",
1312
"@nodejs//:node_files",
14-
"@npm//:node_modules",
13+
"@emsdk//:binaries",
14+
"@emsdk//:node_modules",
1515
],
1616
)
1717

@@ -26,7 +26,7 @@ filegroup(
2626
"emcc_link.sh",
2727
"link_wrapper.py",
2828
":common-script-includes",
29-
"@emscripten//:all",
29+
"@emsdk//:binaries",
3030
"@nodejs//:node_files",
3131
],
3232
)
@@ -36,7 +36,7 @@ filegroup(
3636
srcs = [
3737
":compile-emscripten",
3838
":link-emscripten",
39-
"@emscripten//:all",
39+
"@emsdk//:binaries",
4040
"@nodejs//:node_files",
4141
],
4242
)
@@ -49,7 +49,8 @@ cc_library(name = "malloc")
4949
emscripten_cc_toolchain_config_rule(
5050
name = "wasm",
5151
cpu = "wasm",
52-
emscripten_version = "emscripten",
52+
em_config = "emscripten_config",
53+
emscripten_binaries = "@emsdk//:binaries",
5354
)
5455

5556
cc_toolchain(

bazel/emscripten_toolchain/crosstool.bzl

Lines changed: 45 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,10 @@ def _impl(ctx):
6969
abi_libc_version = "default"
7070

7171
cc_target_os = "emscripten"
72-
emscripten_version = ctx.attr.emscripten_version
7372

74-
builtin_sysroot = "external/emscripten/emscripten/cache/sysroot"
73+
emscripten_dir = ctx.attr.emscripten_binaries.label.workspace_root
74+
75+
builtin_sysroot = emscripten_dir + "/emscripten/cache/sysroot"
7576

7677
################################################################
7778
# Tools
@@ -909,7 +910,7 @@ def _impl(ctx):
909910
"-iwithsysroot" + "/include/c++/v1",
910911
"-iwithsysroot" + "/include/compat",
911912
"-iwithsysroot" + "/include",
912-
"-isystem", "external/emscripten/lib/clang/13.0.0/include",
913+
"-isystem", emscripten_dir + "/lib/clang/13.0.0/include",
913914
],
914915
),
915916
# Inputs and outputs
@@ -1016,6 +1017,22 @@ def _impl(ctx):
10161017
]
10171018

10181019
crosstool_default_env_sets = [
1020+
# Globals
1021+
env_set(
1022+
actions = all_compile_actions +
1023+
all_link_actions +
1024+
[ACTION_NAMES.cpp_link_static_library],
1025+
env_entries = [
1026+
env_entry(
1027+
key = "EM_BIN_PATH",
1028+
value = emscripten_dir,
1029+
),
1030+
env_entry(
1031+
key = "EM_CONFIG_PATH",
1032+
value = ctx.file.em_config.path,
1033+
),
1034+
],
1035+
),
10191036
# Use llvm backend. Off by default, enabled via --features=llvm_backend
10201037
env_set(
10211038
actions = all_compile_actions +
@@ -1052,49 +1069,42 @@ def _impl(ctx):
10521069
features.append(crosstool_default_flags_feature)
10531070

10541071
cxx_builtin_include_directories = [
1055-
"external/emscripten/emscripten/cache/sysroot/include/c++/v1",
1056-
"external/emscripten/emscripten/cache/sysroot/include/compat",
1057-
"external/emscripten/emscripten/cache/sysroot/include",
1058-
"external/emscripten/lib/clang/13.0.0/include",
1072+
emscripten_dir + "/emscripten/cache/sysroot/include/c++/v1",
1073+
emscripten_dir + "/emscripten/cache/sysroot/include/compat",
1074+
emscripten_dir + "/emscripten/cache/sysroot/include",
1075+
emscripten_dir + "/lib/clang/13.0.0/include",
10591076
]
10601077

10611078
artifact_name_patterns = []
10621079

10631080
make_variables = []
10641081

1065-
out = ctx.actions.declare_file(ctx.label.name)
1066-
ctx.actions.write(out, "Fake executable")
1067-
return [
1068-
cc_common.create_cc_toolchain_config_info(
1069-
ctx = ctx,
1070-
features = features,
1071-
action_configs = action_configs,
1072-
artifact_name_patterns = artifact_name_patterns,
1073-
cxx_builtin_include_directories = cxx_builtin_include_directories,
1074-
toolchain_identifier = toolchain_identifier,
1075-
host_system_name = host_system_name,
1076-
target_system_name = target_system_name,
1077-
target_cpu = target_cpu,
1078-
target_libc = target_libc,
1079-
compiler = compiler,
1080-
abi_version = abi_version,
1081-
abi_libc_version = abi_libc_version,
1082-
tool_paths = tool_paths,
1083-
make_variables = make_variables,
1084-
builtin_sysroot = builtin_sysroot,
1085-
cc_target_os = cc_target_os,
1086-
),
1087-
DefaultInfo(
1088-
executable = out,
1089-
),
1090-
]
1082+
return cc_common.create_cc_toolchain_config_info(
1083+
ctx = ctx,
1084+
features = features,
1085+
action_configs = action_configs,
1086+
artifact_name_patterns = artifact_name_patterns,
1087+
cxx_builtin_include_directories = cxx_builtin_include_directories,
1088+
toolchain_identifier = toolchain_identifier,
1089+
host_system_name = host_system_name,
1090+
target_system_name = target_system_name,
1091+
target_cpu = target_cpu,
1092+
target_libc = target_libc,
1093+
compiler = compiler,
1094+
abi_version = abi_version,
1095+
abi_libc_version = abi_libc_version,
1096+
tool_paths = tool_paths,
1097+
make_variables = make_variables,
1098+
builtin_sysroot = builtin_sysroot,
1099+
cc_target_os = cc_target_os,
1100+
)
10911101

10921102
emscripten_cc_toolchain_config_rule = rule(
10931103
implementation = _impl,
10941104
attrs = {
10951105
"cpu": attr.string(mandatory = True, values = ["asmjs", "wasm"]),
1096-
"emscripten_version": attr.string(mandatory = True),
1106+
"em_config": attr.label(mandatory = True, allow_single_file=True),
1107+
"emscripten_binaries": attr.label(mandatory = True),
10971108
},
10981109
provides = [CcToolchainConfigInfo],
1099-
executable = True,
11001110
)

bazel/emscripten_toolchain/emar.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/bin/bash
22

3-
source emscripten_toolchain/env.sh
3+
source external/emsdk/emscripten_toolchain/env.sh
44

55
exec python3 $EMSCRIPTEN/emar.py "$@"

bazel/emscripten_toolchain/emcc.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/bin/bash
22

3-
source emscripten_toolchain/env.sh
3+
source external/emsdk/emscripten_toolchain/env.sh
44

5-
exec python3 external/emscripten/emscripten/emcc.py "$@"
5+
exec python3 $EMSCRIPTEN/emcc.py "$@"
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/bin/bash
22

3-
source emscripten_toolchain/env.sh
3+
source external/emsdk/emscripten_toolchain/env.sh
44

5-
exec python3 emscripten_toolchain/link_wrapper.py "$@"
5+
exec python3 external/emsdk/emscripten_toolchain/link_wrapper.py "$@"

0 commit comments

Comments
 (0)