Mercurial
view third_party/emsdk/bazel/emscripten_toolchain/toolchain.bzl @ 279:b3b547563ec7
Add Google connector service and agent wiki
Implement the C/Seobeo Google Drive and Gmail connector with encrypted OAuth storage, Zenbu authentication, browser testing, AI tool discovery, chunked HTTP decoding, and Bazel coverage. Consolidate repository guidance into progressive wiki documentation and enforce arena-first allocation for new first-party C code.
Co-authored-by: Copilot <[email protected]>
Copilot-Session: 84c338fd-0939-4bb3-b7f3-1062eb213e5d
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Mon, 17 Aug 2026 22:22:36 -0700 |
| parents | 8d17f6e6e290 |
| children |
line wrap: on
line source
"""This module encapsulates logic to create emscripten_cc_toolchain_config rule.""" load( "@rules_cc//cc:cc_toolchain_config_lib.bzl", "action_config", "env_entry", "env_set", "feature", "feature_set", "flag_group", "tool", "tool_path", "variable_with_value", "with_feature_set", _flag_set = "flag_set", ) load("@rules_cc//cc:action_names.bzl", "ACTION_NAMES") load("@rules_cc//cc/common:cc_common.bzl", "cc_common") def flag_set(flags = None, features = None, not_features = None, **kwargs): """Extension to flag_set which allows for a "simple" form. The simple form allows specifying flags as a simple list instead of a flag_group if enable_if or expand_if semantics are not required. Similarly, the simple form allows passing features/not_features if they are a simple list of semantically "and" features. (i.e. "asan" and "dbg", rather than "asan" or "dbg") Args: flags: list, set of flags features: list, set of features required to be enabled. not_features: list, set of features required to not be enabled. **kwargs: The rest of the args for flag_set. Returns: flag_set """ if flags: if kwargs.get("flag_groups"): fail("Cannot set flags and flag_groups") else: kwargs["flag_groups"] = [flag_group(flags = flags)] if features or not_features: if kwargs.get("with_features"): fail("Cannot set features/not_feature and with_features") kwargs["with_features"] = [with_feature_set( features = features or [], not_features = not_features or [], )] return _flag_set(**kwargs) CROSSTOOL_DEFAULT_WARNINGS = [ "-Wall", ] def _impl(ctx): target_cpu = ctx.attr.cpu toolchain_identifier = "emscripten-" + target_cpu target_system_name = target_cpu + "-unknown-emscripten" host_system_name = "i686-unknown-linux-gnu" target_libc = "musl/js" abi_version = "emscripten_syscalls" compiler = "emscripten" abi_libc_version = "default" cc_target_os = "emscripten" emscripten_dir = ctx.attr.emscripten_binaries.label.workspace_root nodejs_path = ctx.file.nodejs_bin.path builtin_sysroot = emscripten_dir + "/emscripten/cache/sysroot" emcc_script = "emcc.%s" % ctx.attr.script_extension emcc_link_script = "emcc_link.%s" % ctx.attr.script_extension emar_script = "emar.%s" % ctx.attr.script_extension ################################################################ # Tools ################################################################ clang_tool = tool(path = emcc_script) clif_match_tool = tool(path = "dummy_clif_matcher") link_tool = tool(path = emcc_link_script) archive_tool = tool(path = emar_script) strip_tool = tool(path = "NOT_USED_STRIP_TOOL") #### Legacy tool paths (much of this is redundant with action_configs, but #### these are still used for some things) tool_paths = [ tool_path(name = "ar", path = emar_script), tool_path(name = "cpp", path = "/bin/false"), tool_path(name = "gcc", path = emcc_script), tool_path(name = "gcov", path = "/bin/false"), tool_path(name = "ld", path = emcc_link_script), tool_path(name = "nm", path = "NOT_USED"), tool_path(name = "objdump", path = "/bin/false"), tool_path(name = "strip", path = "NOT_USED"), ] ################################################################ # Action Configs ################################################################ cpp_compile_action = action_config( action_name = ACTION_NAMES.cpp_compile, tools = [clang_tool], ) cpp_module_compile_action = action_config( action_name = ACTION_NAMES.cpp_module_compile, tools = [clang_tool], ) cpp_module_codegen_action = action_config( action_name = ACTION_NAMES.cpp_module_codegen, tools = [clang_tool], ) clif_match_action = action_config( action_name = ACTION_NAMES.clif_match, tools = [clif_match_tool], ) cpp_link_dynamic_library_action = action_config( action_name = ACTION_NAMES.cpp_link_dynamic_library, tools = [link_tool], ) strip_action = action_config( action_name = ACTION_NAMES.strip, tools = [strip_tool], ) preprocess_assemble_action = action_config( action_name = ACTION_NAMES.preprocess_assemble, tools = [clang_tool], ) cpp_header_parsing_action = action_config( action_name = ACTION_NAMES.cpp_header_parsing, tools = [clang_tool], ) cpp_link_static_library_action = action_config( action_name = ACTION_NAMES.cpp_link_static_library, enabled = True, flag_sets = [ flag_set( flag_groups = [ flag_group( flags = ["rcsD", "%{output_execpath}"], expand_if_available = "output_execpath", ), ], ), flag_set( flag_groups = [ flag_group( iterate_over = "libraries_to_link", flag_groups = [ flag_group( flags = ["%{libraries_to_link.name}"], expand_if_equal = variable_with_value( name = "libraries_to_link.type", value = "object_file", ), ), flag_group( flags = ["%{libraries_to_link.object_files}"], iterate_over = "libraries_to_link.object_files", expand_if_equal = variable_with_value( name = "libraries_to_link.type", value = "object_file_group", ), ), ], expand_if_available = "libraries_to_link", ), ], ), flag_set( flag_groups = [ flag_group( flags = ["@%{linker_param_file}"], expand_if_available = "linker_param_file", ), ], ), ], tools = [archive_tool], ) c_compile_action = action_config( action_name = ACTION_NAMES.c_compile, tools = [clang_tool], ) linkstamp_compile_action = action_config( action_name = ACTION_NAMES.linkstamp_compile, tools = [clang_tool], ) assemble_action = action_config( action_name = ACTION_NAMES.assemble, tools = [clang_tool], ) cpp_link_executable_action = action_config( action_name = ACTION_NAMES.cpp_link_executable, tools = [link_tool], ) cpp_link_nodeps_dynamic_library_action = action_config( action_name = ACTION_NAMES.cpp_link_nodeps_dynamic_library, tools = [link_tool], ) action_configs = [ strip_action, c_compile_action, cpp_compile_action, linkstamp_compile_action, assemble_action, preprocess_assemble_action, cpp_header_parsing_action, cpp_module_compile_action, cpp_module_codegen_action, cpp_link_executable_action, cpp_link_dynamic_library_action, cpp_link_nodeps_dynamic_library_action, cpp_link_static_library_action, clif_match_action, ] all_compile_actions = [ ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile, ACTION_NAMES.linkstamp_compile, ACTION_NAMES.assemble, ACTION_NAMES.preprocess_assemble, ACTION_NAMES.cpp_header_parsing, ACTION_NAMES.cpp_module_compile, ACTION_NAMES.cpp_module_codegen, ACTION_NAMES.clif_match, ACTION_NAMES.lto_backend, ] all_cpp_compile_actions = [ ACTION_NAMES.cpp_compile, ACTION_NAMES.linkstamp_compile, ACTION_NAMES.cpp_header_parsing, ACTION_NAMES.cpp_module_compile, ACTION_NAMES.cpp_module_codegen, ACTION_NAMES.clif_match, ] preprocessor_compile_actions = [ ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile, ACTION_NAMES.linkstamp_compile, ACTION_NAMES.preprocess_assemble, ACTION_NAMES.cpp_header_parsing, ACTION_NAMES.cpp_module_compile, ACTION_NAMES.clif_match, ] all_link_actions = [ ACTION_NAMES.cpp_link_executable, ACTION_NAMES.cpp_link_dynamic_library, ACTION_NAMES.cpp_link_nodeps_dynamic_library, ] ################################################################ # Features ################################################################ features = [ # This set of magic "feature"s are important configuration information for blaze. feature(name = "no_legacy_features", enabled = True), feature( name = "has_configured_linker_path", enabled = True, ), # Blaze requests this feature by default, but we don't care. feature(name = "dependency_file"), # Blaze requests this feature by default, but we don't care. feature(name = "random_seed"), # Formerly "needsPic" attribute feature(name = "supports_pic", enabled = False), # Blaze requests this feature by default. # Blaze also tests if this feature is supported, before setting the "pic" build-variable. feature(name = "pic"), # Blaze requests this feature by default. # Blaze also tests if this feature is supported before setting preprocessor_defines # (...but why?) feature(name = "preprocessor_defines"), # Blaze requests this feature by default. # Blaze also tests if this feature is supported before setting includes. (...but why?) feature(name = "include_paths"), # Blaze tests if this feature is enabled in order to create implicit # "nodeps" .so outputs from cc_library rules. feature(name = "supports_dynamic_linker", enabled = False), # Blaze requests this feature when linking a cc_binary which is # "dynamic" aka linked against nodeps-dynamic-library cc_library # outputs. feature(name = "dynamic_linking_mode"), #### Configuration features feature( name = "crosstool_cpu", enabled = True, implies = ["crosstool_cpu_" + target_cpu], ), feature( name = "crosstool_cpu_asmjs", provides = ["variant:crosstool_cpu"], ), feature( name = "crosstool_cpu_wasm", provides = ["variant:crosstool_cpu"], ), # These 3 features will be automatically enabled by blaze in the # corresponding build mode. feature( name = "opt", provides = ["variant:crosstool_build_mode"], ), feature( name = "dbg", provides = ["variant:crosstool_build_mode"], ), feature( name = "fastbuild", provides = ["variant:crosstool_build_mode"], ), # Feature to prevent 'command line too long' issues feature( name = "archive_param_file", enabled = True, ), feature( name = "compiler_param_file", enabled = True, ), #### User-settable features # Set if enabling exceptions. feature(name = "exceptions"), # Set if enabling wasm_exceptions. feature(name = "wasm_exceptions"), # This feature overrides the default optimization to prefer execution speed # over binary size (like clang -O3). feature( name = "optimized_for_speed", provides = ["variant:crosstool_optimization_mode"], ), # This feature overrides the default optimization to prefer binary size over # execution speed (like clang -Oz). feature( name = "optimized_for_size", provides = ["variant:crosstool_optimization_mode"], ), # Convenience aliases / alt-spellings. feature( name = "optimize_for_speed", implies = ["optimized_for_speed"], ), feature( name = "optimize_for_size", implies = ["optimized_for_size"], ), # This feature allows easier use of profiling tools by preserving mangled # C++ names. This does everything profiling_funcs does and more. feature(name = "profiling"), # This feature emits only enough debug info for function names to appear # in profiles. feature(name = "profiling_funcs"), # This feature allows source maps to be generated. feature( name = "source_maps", implies = ["full_debug_info"], ), feature( name = "dwarf_debug_info", implies = ["profiling"], ), # Turns on full debug info (-g3). feature(name = "full_debug_info"), # Enables the use of "Emscripten" Pthread implementation. # https://kripken.github.io/emscripten-site/docs/porting/pthreads.html # https://github.com/kripken/emscripten/wiki/Pthreads-with-WebAssembly feature(name = "use_pthreads"), # If enabled, the runtime will exit when main() completes. feature(name = "exit_runtime"), # Primarily for toolchain maintainers: feature(name = "emcc_debug"), feature(name = "emcc_debug_link"), feature( name = "llvm_backend", requires = [feature_set(features = ["crosstool_cpu_wasm"])], enabled = True, ), # Remove once flag is flipped. # See https://github.com/bazelbuild/bazel/issues/7687 feature( name = "do_not_split_linking_cmdline", ), # Adds simd support, only available with the llvm backend. feature( name = "wasm_simd", requires = [feature_set(features = ["llvm_backend"])], ), # Adds relaxed-simd support, only available with the llvm backend. feature( name = "wasm_relaxed_simd", requires = [feature_set(features = ["llvm_backend"])], ), feature( name = "precise_long_double_printf", enabled = True, ), feature( name = "wasm_warnings_as_errors", enabled = False, ), # ASan and UBSan. See also: # https://emscripten.org/docs/debugging/Sanitizers.html feature(name = "wasm_asan"), feature(name = "wasm_ubsan"), feature( name = "output_format_js", enabled = True, ), feature( name = "wasm_standalone", ), ] crosstool_default_flag_sets = [ # Compile, Link, and CC_FLAGS make variable flag_set( actions = [ ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile, ACTION_NAMES.linkstamp_compile, ACTION_NAMES.assemble, ACTION_NAMES.preprocess_assemble, ACTION_NAMES.cpp_header_parsing, ACTION_NAMES.cpp_module_compile, ACTION_NAMES.cpp_module_codegen, ACTION_NAMES.clif_match, ACTION_NAMES.cpp_link_executable, ACTION_NAMES.cpp_link_dynamic_library, ACTION_NAMES.cpp_link_nodeps_dynamic_library, ], flag_groups = [ flag_group( flags = ["--sysroot=%{sysroot}"], expand_if_available = "sysroot", ), ], ), # Compile + Link flag_set( actions = [ ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile, ACTION_NAMES.linkstamp_compile, ACTION_NAMES.assemble, ACTION_NAMES.preprocess_assemble, ACTION_NAMES.cpp_header_parsing, ACTION_NAMES.cpp_module_compile, ACTION_NAMES.cpp_module_codegen, ACTION_NAMES.clif_match, ACTION_NAMES.cpp_link_executable, ACTION_NAMES.cpp_link_dynamic_library, ACTION_NAMES.cpp_link_nodeps_dynamic_library, ], # This forces color diagnostics even on Forge (where we don't have an # attached terminal). flags = [ "-fdiagnostics-color", ], ), # C++ compiles (and implicitly link) flag_set( actions = all_cpp_compile_actions, flags = [ "-fno-exceptions", ], not_features = ["exceptions", "wasm_exceptions"], ), flag_set( actions = all_cpp_compile_actions, flags = [ "-fexceptions", ], features = ["exceptions"], ), flag_set( actions = all_cpp_compile_actions + all_link_actions, flags = [ "-fwasm-exceptions", ], features = ["wasm_exceptions"], ), # All compiles (and implicitly link) flag_set( actions = all_compile_actions + all_link_actions, flags = [ "-fno-strict-aliasing", "-funsigned-char", "-no-canonical-prefixes", ], ), # Language Features flag_set( actions = all_cpp_compile_actions, flags = ["-std=gnu++17", "-nostdinc", "-nostdinc++"], ), # Emscripten-specific settings: flag_set( actions = all_compile_actions + all_link_actions, flags = ["-s", "WASM=0"], features = ["crosstool_cpu_asmjs"], ), flag_set( actions = all_compile_actions + all_link_actions, flags = ["-s", "USE_PTHREADS=1"], features = ["use_pthreads"], ), flag_set( actions = all_link_actions, flags = ["-s", "EXIT_RUNTIME=1"], features = ["exit_runtime"], ), flag_set( actions = all_compile_actions + all_link_actions, flags = ["-pthread"], features = ["llvm_backend", "use_pthreads"], ), flag_set( actions = all_compile_actions + all_link_actions, flags = ["-msimd128"], features = ["wasm_simd"], ), flag_set( actions = all_compile_actions + all_link_actions, flags = ["-msimd128", "-mrelaxed-simd"], features = ["wasm_relaxed_simd"], ), flag_set( actions = all_link_actions, flags = ["-s", "PRINTF_LONG_DOUBLE=1"], features = ["precise_long_double_printf"], ), flag_set( actions = all_link_actions, flags = ["--oformat=js"], features = ["output_format_js"], ), # Opt flag_set( actions = preprocessor_compile_actions, flags = ["-DNDEBUG"], features = ["opt"], ), flag_set( actions = all_compile_actions, flags = ["-fomit-frame-pointer"], features = ["opt"], ), flag_set( actions = all_compile_actions + all_link_actions, flags = ["-O2"], features = ["opt"], ), # Users can override opt-level with semantic names... flag_set( actions = all_compile_actions + all_link_actions, flags = ["-Oz"], features = ["optimized_for_size", "opt"], ), flag_set( actions = all_compile_actions + all_link_actions, flags = ["-O3"], features = ["optimized_for_speed", "opt"], ), # Fastbuild flag_set( actions = all_compile_actions, flags = ["-fomit-frame-pointer"], features = ["fastbuild"], ), flag_set( actions = all_compile_actions + all_link_actions, flags = ["-O0"], features = ["fastbuild"], ), # Dbg flag_set( actions = all_compile_actions, flags = ["-fno-omit-frame-pointer"], features = ["dbg"], ), flag_set( actions = all_compile_actions + all_link_actions, flags = ["-g", "-O0"], features = ["dbg"], ), flag_set( actions = all_compile_actions + all_link_actions, flags = [ "-g", "-fsanitize=address", "-O1", "-DADDRESS_SANITIZER=1", "-fno-omit-frame-pointer", ], features = ["wasm_asan"], ), flag_set( actions = all_compile_actions + all_link_actions, flags = [ "-g3", "-fsanitize=undefined", "-O1", "-DUNDEFINED_BEHAVIOR_SANITIZER=1", "-fno-omit-frame-pointer", "-fno-sanitize=vptr", ], features = ["wasm_ubsan"], ), # Profiling provides full debug info and a special --profiling flag # to control name mangling flag_set( actions = all_link_actions, flags = ["--profiling"], features = ["profiling"], ), flag_set( actions = all_link_actions, flags = ["--profiling_funcs"], features = ["profiling_funcs"], ), flag_set( actions = all_compile_actions + all_link_actions, flags = ["-g3"], features = ["full_debug_info"], ), flag_set( actions = all_link_actions, flags = ["-gseparate-dwarf"], features = ["dwarf_debug_info"], ), flag_set( actions = all_compile_actions + all_link_actions, flags = ["-fdebug-compilation-dir=."], features = ["dwarf_debug_info"], ), # Generic warning flag list flag_set( actions = all_compile_actions, flags = CROSSTOOL_DEFAULT_WARNINGS, ), # Defines and Includes and Paths and such flag_set( actions = all_compile_actions, flag_groups = [ flag_group(flags = ["-fPIC"], expand_if_available = "pic"), ], ), flag_set( actions = preprocessor_compile_actions, flag_groups = [ flag_group( flags = ["-D%{preprocessor_defines}"], iterate_over = "preprocessor_defines", ), ], ), flag_set( actions = preprocessor_compile_actions, flag_groups = [ flag_group( flags = ["-include", "%{includes}"], iterate_over = "includes", expand_if_available = "includes", ), ], ), flag_set( actions = preprocessor_compile_actions, flag_groups = [ flag_group( flags = ["-iquote", "%{quote_include_paths}"], iterate_over = "quote_include_paths", ), flag_group( flags = ["-I%{include_paths}"], iterate_over = "include_paths", ), flag_group( flags = ["-isystem", "%{system_include_paths}"], iterate_over = "system_include_paths", ), ], ), ## Linking options (not libs -- those go last) # Generic link options flag_set( actions = [ ACTION_NAMES.cpp_link_dynamic_library, ACTION_NAMES.cpp_link_nodeps_dynamic_library, ], flags = ["-shared"], ), # Linker search paths and objects: flag_set( actions = all_link_actions, flag_groups = [ flag_group( iterate_over = "runtime_library_search_directories", flag_groups = [ flag_group( flags = [ "-Wl,-rpath,$EXEC_ORIGIN/%{runtime_library_search_directories}", ], expand_if_true = "is_cc_test", ), flag_group( flags = [ "-Wl,-rpath,$ORIGIN/%{runtime_library_search_directories}", ], expand_if_false = "is_cc_test", ), ], expand_if_available = "runtime_library_search_directories", ), ], ), flag_set( actions = all_link_actions, flag_groups = [ flag_group( flags = ["-L%{library_search_directories}"], iterate_over = "library_search_directories", expand_if_available = "library_search_directories", ), ], ), flag_set( actions = all_link_actions, flag_groups = [ flag_group( # This is actually a list of object files from the linkstamp steps flags = ["%{linkstamp_paths}"], iterate_over = "linkstamp_paths", expand_if_available = "linkstamp_paths", ), ], ), flag_set( actions = all_link_actions, flag_groups = [ flag_group( flags = ["@%{thinlto_param_file}"], expand_if_available = "libraries_to_link", expand_if_true = "thinlto_param_file", ), flag_group( iterate_over = "libraries_to_link", flag_groups = [ flag_group( flags = ["-Wl,--start-lib"], expand_if_equal = variable_with_value( name = "libraries_to_link.type", value = "object_file_group", ), ), flag_group( flags = ["-Wl,-whole-archive"], expand_if_true = "libraries_to_link.is_whole_archive", ), flag_group( flags = ["%{libraries_to_link.object_files}"], iterate_over = "libraries_to_link.object_files", expand_if_equal = variable_with_value( name = "libraries_to_link.type", value = "object_file_group", ), ), flag_group( flags = ["%{libraries_to_link.name}"], expand_if_equal = variable_with_value( name = "libraries_to_link.type", value = "object_file", ), ), flag_group( flags = ["%{libraries_to_link.name}"], expand_if_equal = variable_with_value( name = "libraries_to_link.type", value = "interface_library", ), ), flag_group( flags = ["%{libraries_to_link.name}"], expand_if_equal = variable_with_value( name = "libraries_to_link.type", value = "static_library", ), ), flag_group( flags = ["-l%{libraries_to_link.name}"], expand_if_equal = variable_with_value( name = "libraries_to_link.type", value = "dynamic_library", ), ), flag_group( flags = ["-l:%{libraries_to_link.name}"], expand_if_equal = variable_with_value( name = "libraries_to_link.type", value = "versioned_dynamic_library", ), ), flag_group( flags = ["-Wl,-no-whole-archive"], expand_if_true = "libraries_to_link.is_whole_archive", ), flag_group( flags = ["-Wl,--end-lib"], expand_if_equal = variable_with_value( name = "libraries_to_link.type", value = "object_file_group", ), ), ], expand_if_available = "libraries_to_link", ), ], ), # Configure the header parsing and preprocessing. flag_set( actions = [ACTION_NAMES.cpp_header_parsing], flags = ["-xc++-header", "-fsyntax-only"], features = ["parse_headers"], ), # Note: user compile flags should be nearly last -- you probably # don't want to put any more features after this! flag_set( actions = [ ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile, ACTION_NAMES.linkstamp_compile, ACTION_NAMES.assemble, ACTION_NAMES.preprocess_assemble, ACTION_NAMES.cpp_header_parsing, ACTION_NAMES.cpp_module_compile, ACTION_NAMES.cpp_module_codegen, ACTION_NAMES.clif_match, ], flag_groups = [ flag_group( flags = ["%{user_compile_flags}"], iterate_over = "user_compile_flags", expand_if_available = "user_compile_flags", ), ], ), flag_set( actions = all_link_actions, flag_groups = [ flag_group( flags = ["%{user_link_flags}"], iterate_over = "user_link_flags", expand_if_available = "user_link_flags", ), ], ), ## Options which need to go late -- after all the user options -- go here. flag_set( # One might hope that these options would only be needed for C++ # compiles. But, sadly, users compile ".c" files with custom # copts=["-x", "c++"], and expect that to be able to find C++ stdlib # headers. It might be worth pondering how blaze could support this sort # of use-case better. actions = preprocessor_compile_actions + [ACTION_NAMES.cc_flags_make_variable], flags = [ "-iwithsysroot" + "/include/c++/v1", "-iwithsysroot" + "/include/compat", "-iwithsysroot" + "/include", "-isystem", emscripten_dir + "/lib/clang/22/include", ], ), # Inputs and outputs flag_set( actions = [ ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile, ACTION_NAMES.linkstamp_compile, ACTION_NAMES.assemble, ACTION_NAMES.preprocess_assemble, ACTION_NAMES.cpp_header_parsing, ACTION_NAMES.cpp_module_compile, ACTION_NAMES.cpp_module_codegen, ACTION_NAMES.clif_match, ], flag_groups = [ flag_group( flags = ["-MD", "-MF", "%{dependency_file}"], expand_if_available = "dependency_file", ), ], ), flag_set( actions = [ ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile, ACTION_NAMES.linkstamp_compile, ACTION_NAMES.assemble, ACTION_NAMES.preprocess_assemble, ACTION_NAMES.cpp_header_parsing, ACTION_NAMES.cpp_module_compile, ACTION_NAMES.cpp_module_codegen, ACTION_NAMES.clif_match, ], flag_groups = [ flag_group( flags = ["-c", "%{source_file}"], expand_if_available = "source_file", ), ], ), flag_set( actions = [ ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile, ACTION_NAMES.linkstamp_compile, ACTION_NAMES.assemble, ACTION_NAMES.preprocess_assemble, ACTION_NAMES.cpp_header_parsing, ACTION_NAMES.cpp_module_compile, ACTION_NAMES.cpp_module_codegen, ACTION_NAMES.clif_match, ], flag_groups = [ flag_group( flags = ["-S"], expand_if_available = "output_assembly_file", ), flag_group( flags = ["-E"], expand_if_available = "output_preprocess_file", ), flag_group( flags = ["-o", "%{output_file}"], expand_if_available = "output_file", ), ], ), flag_set( actions = all_link_actions, flag_groups = [ flag_group( flags = ["-o", "%{output_execpath}"], expand_if_available = "output_execpath", ), ], ), # And finally, the params file! flag_set( actions = all_link_actions, flag_groups = [ flag_group( flags = ["@%{linker_param_file}"], expand_if_available = "linker_param_file", ), ], ), flag_set( actions = all_compile_actions, flags = [ "-Wno-builtin-macro-redefined", # Genrules may not escape quotes enough for these, so # don't put them into $(CC_FLAGS): '-D__DATE__="redacted"', '-D__TIMESTAMP__="redacted"', '-D__TIME__="redacted"', ], ), flag_set( actions = all_compile_actions, flags = ["-Werror"], features = ["wasm_warnings_as_errors"], ), flag_set( actions = all_link_actions, flags = ["-sSTANDALONE_WASM"], features = ["wasm_standalone"], ), ] 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, ), env_entry( key = "NODE_JS_PATH", value = nodejs_path, ), ], ), # Use llvm backend. Off by default, enabled via --features=llvm_backend env_set( actions = all_compile_actions + all_link_actions + [ACTION_NAMES.cpp_link_static_library], env_entries = [env_entry(key = "EMCC_WASM_BACKEND", value = "1")], with_features = [with_feature_set(features = ["llvm_backend"])], ), # Debug compile and link. Off by default, enabled via --features=emcc_debug env_set( actions = all_compile_actions, env_entries = [env_entry(key = "EMCC_DEBUG", value = "1")], with_features = [with_feature_set(features = ["emcc_debug"])], ), # Debug only link step. Off by default, enabled via --features=emcc_debug_link env_set( actions = all_link_actions, env_entries = [env_entry(key = "EMCC_DEBUG", value = "1")], with_features = [ with_feature_set(features = ["emcc_debug"]), with_feature_set(features = ["emcc_debug_link"]), ], ), ] crosstool_default_flags_feature = feature( name = "crosstool_default_flags", enabled = True, flag_sets = crosstool_default_flag_sets, env_sets = crosstool_default_env_sets, ) features.append(crosstool_default_flags_feature) cxx_builtin_include_directories = [ 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/21/include", ] artifact_name_patterns = [] make_variables = [] 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"]), "em_config": attr.label(mandatory = True, allow_single_file = True), "emscripten_binaries": attr.label(mandatory = True, cfg = "exec"), "nodejs_bin": attr.label(mandatory = True, allow_single_file = True), "script_extension": attr.string(mandatory = True, values = ["sh", "bat"]), }, )