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
This commit is contained in:
44
bazel/BUILD
Normal file
44
bazel/BUILD
Normal file
@@ -0,0 +1,44 @@
|
||||
package(default_visibility = ['//visibility:public'])
|
||||
|
||||
config_setting(
|
||||
name = "linux",
|
||||
constraint_values = [
|
||||
"@platforms//os:linux",
|
||||
"@platforms//cpu:x86_64",
|
||||
],
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name = "macos",
|
||||
constraint_values = [
|
||||
"@platforms//os:macos",
|
||||
"@platforms//cpu:x86_64",
|
||||
],
|
||||
)
|
||||
|
||||
config_setting(
|
||||
name = "windows",
|
||||
constraint_values = [
|
||||
"@platforms//os:windows",
|
||||
"@platforms//cpu:x86_64",
|
||||
],
|
||||
)
|
||||
|
||||
alias(
|
||||
name = "binaries",
|
||||
actual = select({
|
||||
":linux": "@emscripten_bin_linux//:all",
|
||||
":macos": "@emscripten_bin_mac//:all",
|
||||
":windows": "@emscripten_bin_win//:all",
|
||||
}),
|
||||
)
|
||||
|
||||
alias(
|
||||
name = "node_modules",
|
||||
actual = select({
|
||||
":linux": "@emscripten_npm_linux//:node_modules",
|
||||
":macos": "@emscripten_npm_mac//:node_modules",
|
||||
":windows": "@emscripten_npm_win//:node_modules",
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -1,25 +1,7 @@
|
||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
workspace(name = "emsdk")
|
||||
|
||||
http_archive(
|
||||
name = "build_bazel_rules_nodejs",
|
||||
sha256 = "0f2de53628e848c1691e5729b515022f5a77369c76a09fbe55611e12731c90e3",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/2.0.1/rules_nodejs-2.0.1.tar.gz"],
|
||||
)
|
||||
load(":deps.bzl", "deps")
|
||||
deps()
|
||||
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "npm_install")
|
||||
|
||||
# emscripten 2.0.15
|
||||
http_archive(
|
||||
name = "emscripten",
|
||||
sha256 = "7ff49fc63adf29970f6e7af1df445d7f554bdbbb2606db1cb5d3567ce69df1db",
|
||||
strip_prefix = "install",
|
||||
url = "https://storage.googleapis.com/webassembly/emscripten-releases-builds/linux/89202930a98fe7f9ed59b574469a9471b0bda7dd/wasm-binaries.tbz2",
|
||||
build_file = "//emscripten_toolchain:emscripten.BUILD",
|
||||
type = "tar.bz2",
|
||||
)
|
||||
|
||||
npm_install(
|
||||
name = "npm",
|
||||
package_json = "@emscripten//:emscripten/package.json",
|
||||
package_lock_json = "@emscripten//:emscripten/package-lock.json",
|
||||
)
|
||||
load(":emscripten_deps.bzl", "emscripten_deps")
|
||||
emscripten_deps()
|
||||
|
||||
11
bazel/deps.bzl
Normal file
11
bazel/deps.bzl
Normal file
@@ -0,0 +1,11 @@
|
||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
|
||||
def deps():
|
||||
excludes = native.existing_rules().keys()
|
||||
|
||||
if "build_bazel_rules_nodejs" not in excludes:
|
||||
http_archive(
|
||||
name = "build_bazel_rules_nodejs",
|
||||
sha256 = "0f2de53628e848c1691e5729b515022f5a77369c76a09fbe55611e12731c90e3",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/2.0.1/rules_nodejs-2.0.1.tar.gz"],
|
||||
)
|
||||
76
bazel/emscripten_deps.bzl
Normal file
76
bazel/emscripten_deps.bzl
Normal file
@@ -0,0 +1,76 @@
|
||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
load("@build_bazel_rules_nodejs//:index.bzl", "npm_install")
|
||||
load(":revisions.bzl", "EMSCRIPTEN_TAGS")
|
||||
|
||||
def _parse_version(v):
|
||||
return [int(u) for u in v.split(".")]
|
||||
|
||||
def emscripten_deps(emscripten_version = "latest"):
|
||||
version = emscripten_version
|
||||
|
||||
if version == "latest":
|
||||
version = reversed(sorted(EMSCRIPTEN_TAGS.keys(), key=_parse_version))[0]
|
||||
|
||||
if version not in EMSCRIPTEN_TAGS.keys():
|
||||
error_msg = "Emscripten version {} not found.".format(version)
|
||||
error_msg += " Look at @emsdk//:revisions.bzl for the list "
|
||||
error_msg += "of currently supported versions."
|
||||
fail(error_msg)
|
||||
|
||||
revision = EMSCRIPTEN_TAGS[version]
|
||||
|
||||
emscripten_url = "https://storage.googleapis.com/webassembly/emscripten-releases-builds/{}/{}/wasm-binaries.tbz2"
|
||||
|
||||
# This could potentially backfire for projects with multiple emscripten
|
||||
# dependencies that use different emscripten versions
|
||||
excludes = native.existing_rules().keys()
|
||||
if "emscripten_bin_linux" not in excludes:
|
||||
http_archive(
|
||||
name = "emscripten_bin_linux",
|
||||
strip_prefix = "install",
|
||||
url = emscripten_url.format("linux", revision.hash),
|
||||
sha256 = revision.sha_linux,
|
||||
build_file = "@emsdk//emscripten_toolchain:emscripten.BUILD",
|
||||
type = "tar.bz2",
|
||||
)
|
||||
|
||||
if "emscripten_bin_mac" not in excludes:
|
||||
http_archive(
|
||||
name = "emscripten_bin_mac",
|
||||
strip_prefix = "install",
|
||||
url = emscripten_url.format("mac", revision.hash),
|
||||
sha256 = revision.sha_mac,
|
||||
build_file = "@emsdk//emscripten_toolchain:emscripten.BUILD",
|
||||
type = "tar.bz2",
|
||||
)
|
||||
|
||||
if "emscripten_bin_win" not in excludes:
|
||||
http_archive(
|
||||
name = "emscripten_bin_win",
|
||||
strip_prefix = "install",
|
||||
url = emscripten_url.format("win", revision.hash),
|
||||
sha256 = revision.sha_win,
|
||||
build_file = "@emsdk//emscripten_toolchain:emscripten.BUILD",
|
||||
type = "tar.bz2",
|
||||
)
|
||||
|
||||
if "emscripten_npm_linux" not in excludes:
|
||||
npm_install(
|
||||
name = "emscripten_npm_linux",
|
||||
package_json = "@emscripten_bin_linux//:emscripten/package.json",
|
||||
package_lock_json = "@emscripten_bin_linux//:emscripten/package-lock.json",
|
||||
)
|
||||
|
||||
if "emscripten_npm_mac" not in excludes:
|
||||
npm_install(
|
||||
name = "emscripten_npm_mac",
|
||||
package_json = "@emscripten_bin_mac//:emscripten/package.json",
|
||||
package_lock_json = "@emscripten_bin_mac//:emscripten/package-lock.json",
|
||||
)
|
||||
|
||||
if "emscripten_npm_win" not in excludes:
|
||||
npm_install(
|
||||
name = "emscripten_npm_win",
|
||||
package_json = "@emscripten_bin_win//:emscripten/package.json",
|
||||
package_lock_json = "@emscripten_bin_win//:emscripten/package-lock.json",
|
||||
)
|
||||
@@ -9,9 +9,9 @@ filegroup(
|
||||
"emcc.sh",
|
||||
"emscripten_config",
|
||||
"env.sh",
|
||||
"@emscripten//:all",
|
||||
"@nodejs//:node_files",
|
||||
"@npm//:node_modules",
|
||||
"@emsdk//:binaries",
|
||||
"@emsdk//:node_modules",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -26,7 +26,7 @@ filegroup(
|
||||
"emcc_link.sh",
|
||||
"link_wrapper.py",
|
||||
":common-script-includes",
|
||||
"@emscripten//:all",
|
||||
"@emsdk//:binaries",
|
||||
"@nodejs//:node_files",
|
||||
],
|
||||
)
|
||||
@@ -36,7 +36,7 @@ filegroup(
|
||||
srcs = [
|
||||
":compile-emscripten",
|
||||
":link-emscripten",
|
||||
"@emscripten//:all",
|
||||
"@emsdk//:binaries",
|
||||
"@nodejs//:node_files",
|
||||
],
|
||||
)
|
||||
@@ -49,7 +49,8 @@ cc_library(name = "malloc")
|
||||
emscripten_cc_toolchain_config_rule(
|
||||
name = "wasm",
|
||||
cpu = "wasm",
|
||||
emscripten_version = "emscripten",
|
||||
em_config = "emscripten_config",
|
||||
emscripten_binaries = "@emsdk//:binaries",
|
||||
)
|
||||
|
||||
cc_toolchain(
|
||||
|
||||
@@ -69,9 +69,10 @@ def _impl(ctx):
|
||||
abi_libc_version = "default"
|
||||
|
||||
cc_target_os = "emscripten"
|
||||
emscripten_version = ctx.attr.emscripten_version
|
||||
|
||||
builtin_sysroot = "external/emscripten/emscripten/cache/sysroot"
|
||||
emscripten_dir = ctx.attr.emscripten_binaries.label.workspace_root
|
||||
|
||||
builtin_sysroot = emscripten_dir + "/emscripten/cache/sysroot"
|
||||
|
||||
################################################################
|
||||
# Tools
|
||||
@@ -909,7 +910,7 @@ def _impl(ctx):
|
||||
"-iwithsysroot" + "/include/c++/v1",
|
||||
"-iwithsysroot" + "/include/compat",
|
||||
"-iwithsysroot" + "/include",
|
||||
"-isystem", "external/emscripten/lib/clang/13.0.0/include",
|
||||
"-isystem", emscripten_dir + "/lib/clang/13.0.0/include",
|
||||
],
|
||||
),
|
||||
# Inputs and outputs
|
||||
@@ -1016,6 +1017,22 @@ def _impl(ctx):
|
||||
]
|
||||
|
||||
crosstool_default_env_sets = [
|
||||
# Globals
|
||||
env_set(
|
||||
actions = all_compile_actions +
|
||||
all_link_actions +
|
||||
[ACTION_NAMES.cpp_link_static_library],
|
||||
env_entries = [
|
||||
env_entry(
|
||||
key = "EM_BIN_PATH",
|
||||
value = emscripten_dir,
|
||||
),
|
||||
env_entry(
|
||||
key = "EM_CONFIG_PATH",
|
||||
value = ctx.file.em_config.path,
|
||||
),
|
||||
],
|
||||
),
|
||||
# Use llvm backend. Off by default, enabled via --features=llvm_backend
|
||||
env_set(
|
||||
actions = all_compile_actions +
|
||||
@@ -1052,49 +1069,42 @@ def _impl(ctx):
|
||||
features.append(crosstool_default_flags_feature)
|
||||
|
||||
cxx_builtin_include_directories = [
|
||||
"external/emscripten/emscripten/cache/sysroot/include/c++/v1",
|
||||
"external/emscripten/emscripten/cache/sysroot/include/compat",
|
||||
"external/emscripten/emscripten/cache/sysroot/include",
|
||||
"external/emscripten/lib/clang/13.0.0/include",
|
||||
emscripten_dir + "/emscripten/cache/sysroot/include/c++/v1",
|
||||
emscripten_dir + "/emscripten/cache/sysroot/include/compat",
|
||||
emscripten_dir + "/emscripten/cache/sysroot/include",
|
||||
emscripten_dir + "/lib/clang/13.0.0/include",
|
||||
]
|
||||
|
||||
artifact_name_patterns = []
|
||||
|
||||
make_variables = []
|
||||
|
||||
out = ctx.actions.declare_file(ctx.label.name)
|
||||
ctx.actions.write(out, "Fake executable")
|
||||
return [
|
||||
cc_common.create_cc_toolchain_config_info(
|
||||
ctx = ctx,
|
||||
features = features,
|
||||
action_configs = action_configs,
|
||||
artifact_name_patterns = artifact_name_patterns,
|
||||
cxx_builtin_include_directories = cxx_builtin_include_directories,
|
||||
toolchain_identifier = toolchain_identifier,
|
||||
host_system_name = host_system_name,
|
||||
target_system_name = target_system_name,
|
||||
target_cpu = target_cpu,
|
||||
target_libc = target_libc,
|
||||
compiler = compiler,
|
||||
abi_version = abi_version,
|
||||
abi_libc_version = abi_libc_version,
|
||||
tool_paths = tool_paths,
|
||||
make_variables = make_variables,
|
||||
builtin_sysroot = builtin_sysroot,
|
||||
cc_target_os = cc_target_os,
|
||||
),
|
||||
DefaultInfo(
|
||||
executable = out,
|
||||
),
|
||||
]
|
||||
return cc_common.create_cc_toolchain_config_info(
|
||||
ctx = ctx,
|
||||
features = features,
|
||||
action_configs = action_configs,
|
||||
artifact_name_patterns = artifact_name_patterns,
|
||||
cxx_builtin_include_directories = cxx_builtin_include_directories,
|
||||
toolchain_identifier = toolchain_identifier,
|
||||
host_system_name = host_system_name,
|
||||
target_system_name = target_system_name,
|
||||
target_cpu = target_cpu,
|
||||
target_libc = target_libc,
|
||||
compiler = compiler,
|
||||
abi_version = abi_version,
|
||||
abi_libc_version = abi_libc_version,
|
||||
tool_paths = tool_paths,
|
||||
make_variables = make_variables,
|
||||
builtin_sysroot = builtin_sysroot,
|
||||
cc_target_os = cc_target_os,
|
||||
)
|
||||
|
||||
emscripten_cc_toolchain_config_rule = rule(
|
||||
implementation = _impl,
|
||||
attrs = {
|
||||
"cpu": attr.string(mandatory = True, values = ["asmjs", "wasm"]),
|
||||
"emscripten_version": attr.string(mandatory = True),
|
||||
"em_config": attr.label(mandatory = True, allow_single_file=True),
|
||||
"emscripten_binaries": attr.label(mandatory = True),
|
||||
},
|
||||
provides = [CcToolchainConfigInfo],
|
||||
executable = True,
|
||||
)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
source emscripten_toolchain/env.sh
|
||||
source external/emsdk/emscripten_toolchain/env.sh
|
||||
|
||||
exec python3 $EMSCRIPTEN/emar.py "$@"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
source emscripten_toolchain/env.sh
|
||||
source external/emsdk/emscripten_toolchain/env.sh
|
||||
|
||||
exec python3 external/emscripten/emscripten/emcc.py "$@"
|
||||
exec python3 $EMSCRIPTEN/emcc.py "$@"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
source emscripten_toolchain/env.sh
|
||||
source external/emsdk/emscripten_toolchain/env.sh
|
||||
|
||||
exec python3 emscripten_toolchain/link_wrapper.py "$@"
|
||||
exec python3 external/emsdk/emscripten_toolchain/link_wrapper.py "$@"
|
||||
|
||||
@@ -3,8 +3,8 @@ import platform
|
||||
|
||||
ROOT_DIR = os.environ["ROOT_DIR"]
|
||||
EMSCRIPTEN_ROOT = os.environ["EMSCRIPTEN"]
|
||||
LLVM_ROOT = ROOT_DIR + "/external/emscripten/bin"
|
||||
BINARYEN_ROOT = ROOT_DIR + "/external/emscripten"
|
||||
BINARYEN_ROOT = ROOT_DIR + "/" + os.environ["EM_BIN_PATH"]
|
||||
LLVM_ROOT = BINARYEN_ROOT + "/bin"
|
||||
FROZEN_CACHE = True
|
||||
|
||||
system = platform.system()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
export ROOT_DIR=`(pwd -P)`
|
||||
export EMSCRIPTEN=${ROOT_DIR}/external/emscripten/emscripten
|
||||
export EM_CONFIG=${ROOT_DIR}/emscripten_toolchain/emscripten_config
|
||||
export EMSCRIPTEN=$ROOT_DIR/$EM_BIN_PATH/emscripten
|
||||
export EM_CONFIG=$ROOT_DIR/$EM_CONFIG_PATH
|
||||
|
||||
@@ -27,13 +27,13 @@ def _wasm_transition_impl(settings, attr):
|
||||
|
||||
return {
|
||||
"//command_line_option:compiler": "emscripten",
|
||||
"//command_line_option:crosstool_top": "//emscripten_toolchain:everything",
|
||||
"//command_line_option:crosstool_top": "@emsdk//emscripten_toolchain:everything",
|
||||
"//command_line_option:cpu": "wasm",
|
||||
"//command_line_option:features": features,
|
||||
"//command_line_option:dynamic_mode": "off",
|
||||
"//command_line_option:linkopt": linkopts,
|
||||
"//command_line_option:platforms": [],
|
||||
"//command_line_option:custom_malloc": "//emscripten_toolchain:malloc",
|
||||
"//command_line_option:custom_malloc": "@emsdk//emscripten_toolchain:malloc",
|
||||
}
|
||||
|
||||
_wasm_transition = transition(
|
||||
@@ -145,7 +145,7 @@ wasm_cc_binary = rule(
|
||||
executable = True,
|
||||
allow_files = True,
|
||||
cfg = "exec",
|
||||
default = Label("//emscripten_toolchain:wasm_binary"),
|
||||
default = Label("@emsdk//emscripten_toolchain:wasm_binary"),
|
||||
),
|
||||
},
|
||||
outputs = _wasm_binary_outputs,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Rules related to C++ and WebAssembly.
|
||||
"""
|
||||
|
||||
load("//emscripten_toolchain:wasm_cc_binary.bzl", _wasm_cc_binary = "wasm_cc_binary")
|
||||
load(":wasm_cc_binary.bzl", _wasm_cc_binary = "wasm_cc_binary")
|
||||
|
||||
wasm_cc_binary = _wasm_cc_binary
|
||||
|
||||
23
bazel/revisions.bzl
Normal file
23
bazel/revisions.bzl
Normal file
@@ -0,0 +1,23 @@
|
||||
# This file is automatically updated by emsdk/scripts/update_bazel_workspace.sh
|
||||
# DO NOT MODIFY
|
||||
|
||||
EMSCRIPTEN_TAGS = {
|
||||
"2.0.15": struct(
|
||||
hash = "89202930a98fe7f9ed59b574469a9471b0bda7dd",
|
||||
sha_linux = "7ff49fc63adf29970f6e7af1df445d7f554bdbbb2606db1cb5d3567ce69df1db",
|
||||
sha_mac = "e35cced1514ad0da40584f8dd6f76aabf847ce0fa82c6dc8dd9442fb74ed6d0d",
|
||||
sha_win = "31d5f8107c87833cea57edc57613bba4b36b16152772f744c5ad204594b4e666",
|
||||
),
|
||||
"2.0.14": struct(
|
||||
hash = "fc5562126762ab26c4757147a3b4c24e85a7289e",
|
||||
sha_linux = "e466cd47ddd4bf0acd645412fdf08eda6d232484e48e5a2643e08062a7a4cf56",
|
||||
sha_mac = "1c554c08459b7025638ca4eddba0d35babe8c26b202a70a74e9442d577896211",
|
||||
sha_win = "428bc6094671937af96f26d803871fc5cd83d4d2b1c1df45fa6873a9bc5cac51",
|
||||
),
|
||||
"2.0.13": struct(
|
||||
hash = "ce0e4a4d1cab395ee5082a60ebb4f3891a94b256",
|
||||
sha_linux = "8986ed886e111c661099c5147126b8a379a4040aab6a1f572fe01f0f9b99a343",
|
||||
sha_mac = "88c91332c8c76fed14ebf0edc9a08f586012f54f04ad61e5b1b6d02bf96bdeab",
|
||||
sha_win = "9fb3b945b7bd56e34d17ec04de4cce475f26c49d161aee9d9c0b8b1434591f88",
|
||||
),
|
||||
}
|
||||
12
bazel/test_external/BUILD
Normal file
12
bazel/test_external/BUILD
Normal file
@@ -0,0 +1,12 @@
|
||||
load("@emsdk//emscripten_toolchain:wasm_rules.bzl", "wasm_cc_binary")
|
||||
|
||||
cc_binary(
|
||||
name = "hello-world",
|
||||
srcs = ["hello-world.cc"],
|
||||
)
|
||||
|
||||
wasm_cc_binary(
|
||||
name = "hello-world-wasm",
|
||||
cc_target = ":hello-world",
|
||||
)
|
||||
|
||||
10
bazel/test_external/WORKSPACE
Normal file
10
bazel/test_external/WORKSPACE
Normal file
@@ -0,0 +1,10 @@
|
||||
local_repository(
|
||||
name = "emsdk",
|
||||
path = "..",
|
||||
)
|
||||
|
||||
load("@emsdk//:deps.bzl", "deps")
|
||||
deps()
|
||||
|
||||
load("@emsdk//:emscripten_deps.bzl", "emscripten_deps")
|
||||
emscripten_deps()
|
||||
6
bazel/test_external/hello-world.cc
Normal file
6
bazel/test_external/hello-world.cc
Normal file
@@ -0,0 +1,6 @@
|
||||
#include <iostream>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
std::cout << "hello world!" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user