diff --git a/crate_universe/Cargo.lock b/crate_universe/Cargo.lock index 4bebf73ab8..1c3b662e25 100644 --- a/crate_universe/Cargo.lock +++ b/crate_universe/Cargo.lock @@ -243,9 +243,9 @@ dependencies = [ [[package]] name = "cfg-expr" -version = "0.18.0" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a2b34126159980f92da2a08bdec0694fd80fb5eb9e48aff25d20a0d8dfa710d" +checksum = "9acd0bdbbf4b2612d09f52ba61da432140cb10930354079d0d53fafc12968726" dependencies = [ "smallvec", ] diff --git a/crate_universe/Cargo.toml b/crate_universe/Cargo.toml index 88fb9e6989..8286841527 100644 --- a/crate_universe/Cargo.toml +++ b/crate_universe/Cargo.toml @@ -69,7 +69,7 @@ cargo_metadata = "0.19.2" cargo_toml = "0.22.1" cargo-lock = "10.1.0" cargo-platform = "0.1.9" -cfg-expr = "0.18.0" +cfg-expr = "0.20.4" clap = { version = "4.5.37", features = ["derive", "env"] } crates-index = { version = "3.7.0", default-features = false, features = [ "git", diff --git a/crate_universe/private/crates_vendor.bzl b/crate_universe/private/crates_vendor.bzl index ca18c11cd6..b136be7756 100644 --- a/crate_universe/private/crates_vendor.bzl +++ b/crate_universe/private/crates_vendor.bzl @@ -33,6 +33,7 @@ _ENVIRON=() _ENVIRON+=(BAZEL_REAL="${{BAZEL_REAL}}") _ENVIRON+=(BUILD_WORKSPACE_DIRECTORY="${{BUILD_WORKSPACE_DIRECTORY}}") _ENVIRON+=(PATH="${{PATH}}") +_ENVIRON+=(HTTPS_PROXY="${{HTTPS_PROXY}}") {env} if [[ -n "${{CARGO_BAZEL_DEBUG:-}}" ]]; then diff --git a/rust/platform/BUILD.bazel b/rust/platform/BUILD.bazel index d5513b1e79..d1f295193f 100644 --- a/rust/platform/BUILD.bazel +++ b/rust/platform/BUILD.bazel @@ -21,6 +21,26 @@ constraint_value( constraint_setting = ":wasi_version", ) +constraint_setting( + name = "qnx_version", + default_constraint_value = ":qnx7", # For backwards compatibility +) + +constraint_value( + name = "qnx7", + constraint_setting = ":qnx_version", +) + +constraint_value( + name = "qnx7_iosock", + constraint_setting = ":qnx_version", +) + +constraint_value( + name = "qnx8", + constraint_setting = ":qnx_version", +) + package_group( name = "function_transition_allowlist", packages = [ diff --git a/rust/platform/triple_mappings.bzl b/rust/platform/triple_mappings.bzl index cd123b3c4a..ef79b91463 100644 --- a/rust/platform/triple_mappings.bzl +++ b/rust/platform/triple_mappings.bzl @@ -76,8 +76,11 @@ SUPPORTED_T2_PLATFORM_TRIPLES = { _T3_PLATFORM_TRIPLES = { "aarch64-unknown-nto-qnx710": _support(std = True, host_tools = False), + "aarch64-unknown-nto-qnx710_iosock": _support(std = True, host_tools = False), + "aarch64-unknown-nto-qnx800": _support(std = True, host_tools = False), "wasm64-unknown-unknown": _support(std = False, host_tools = False), "x86_64-pc-nto-qnx710": _support(std = True, host_tools = False), + "x86_64-pc-nto-qnx710_iosock": _support(std = True, host_tools = False), "x86_64-pc-nto-qnx800": _support(std = True, host_tools = False), } @@ -285,6 +288,12 @@ _SYSTEM_TO_STDLIB_LINKFLAGS = { "windows": ["advapi32.lib", "ws2_32.lib", "userenv.lib", "Bcrypt.lib"], } +_NTO_ABI_TO_CONSTRAINT = { + "qnx710": "@rules_rust//rust/platform:qnx7", + "qnx710_iosock": "@rules_rust//rust/platform:qnx7_iosock", + "qnx800": "@rules_rust//rust/platform:qnx8", +} + def cpu_arch_to_constraints(cpu_arch, *, system = None): """Returns a list of constraint values which represents a triple's CPU. @@ -349,6 +358,9 @@ def abi_to_constraints(abi, *, arch = None, system = None): else: all_abi_constraints.append("@build_bazel_apple_support//constraints:device") + if system == "nto": + all_abi_constraints.append(_NTO_ABI_TO_CONSTRAINT[abi]) + # TODO(bazelbuild/platforms#38): Implement when C++ toolchain is more mature and we # figure out how they're doing this return all_abi_constraints diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl index 14b02dcfe3..7f301ccc30 100644 --- a/rust/private/rustc.bzl +++ b/rust/private/rustc.bzl @@ -71,6 +71,8 @@ AliasableDepInfo = provider( _error_format_values = ["human", "json", "short"] +_OS_WITH_DYLINK_SUPPORT = ["linux", "darwin", "macos", "android", "nto"] + ErrorFormatInfo = provider( doc = "Set the --error-format flag for all rustc invocations", fields = {"error_format": "(string) [" + ", ".join(_error_format_values) + "]"}, @@ -1106,10 +1108,13 @@ def construct_arguments( _add_lto_flags(ctx, toolchain, rustc_flags, crate_info) _add_codegen_units_flags(toolchain, emit, rustc_flags) - # Use linker_type to determine whether to use direct or indirect linker invocation - # If linker_type is not explicitly set, infer from which linker is actually being used ld_is_direct_driver = False + # This lists the libs that are injected through the toolchain configuration. + # Since we might add dependent libraries after these libraries, we need to add + # these later, after all other user libraries, see below. + additional_libs_from_link_args = [] + # Link! if ("link" in emit and crate_info.type not in ["rlib", "lib"]) or add_flags_for_binary: # Rust's built-in linker can handle linking wasm files. We don't want to attempt to use the cc @@ -1134,6 +1139,8 @@ def construct_arguments( env.update(link_env) rustc_flags.add(ld, format = "--codegen=linker=%s") + rustc_flags.add_joined("--codegen", link_args, join_with = " ", format_joined = "link-args=%s") + additional_libs_from_link_args = [arg for arg in link_args if arg.startswith("-l")] # Split link args into individual "--codegen=link-arg=" flags to handle nested spaces. # Additional context: https://github.com/rust-lang/rust/pull/36574 @@ -1170,6 +1177,9 @@ def construct_arguments( if toolchain._experimental_link_std_dylib: rustc_flags.add("--codegen=prefer-dynamic") + # Now add all libraries taken from the toolchain configuration, see above. + rustc_flags.add_joined("--codegen", additional_libs_from_link_args, join_with = " ", format_joined = "link-args=%s") + # Make bin crate data deps available to tests. for data in getattr(attr, "data", []): if rust_common.crate_info in data: @@ -2094,7 +2104,7 @@ def _compute_rpaths(toolchain, output_dir, dep_info, use_pic): # without a version of Bazel that includes # https://github.com/bazelbuild/bazel/pull/13427. This is known to not be # included in Bazel 4.1 and below. - if toolchain.target_os not in ["linux", "darwin", "macos", "android"]: + if toolchain.target_os not in _OS_WITH_DYLINK_SUPPORT: fail("Runtime linking is not supported on {}, but found {}".format( toolchain.target_os, dep_info.transitive_noncrates, @@ -2260,6 +2270,7 @@ def _portable_link_flags(lib, use_pic, ambiguous_libs, get_lib_name, for_windows elif _is_dylib(lib): return [ "-ldylib=%s" % get_lib_name(artifact), + "-Clink-arg=-l{}".format(get_lib_name(artifact)), ] return [] diff --git a/test/unit/platform_triple/BUILD.bazel b/test/unit/platform_triple/BUILD.bazel index bb30c72b66..9104c647fc 100644 --- a/test/unit/platform_triple/BUILD.bazel +++ b/test/unit/platform_triple/BUILD.bazel @@ -1,4 +1,5 @@ load(":platform_triple_test.bzl", "platform_triple_test_suite") +load(":qnx_version_test.bzl", "qnx_version_constraints_test") load(":wasi_platform_test.bzl", "wasi_platform_test_suite") platform_triple_test_suite( @@ -8,3 +9,7 @@ platform_triple_test_suite( wasi_platform_test_suite( name = "wasi_platform_test_suite", ) + +qnx_version_constraints_test( + name = "qnx_version_test_suite", +) diff --git a/test/unit/platform_triple/qnx_version_test.bzl b/test/unit/platform_triple/qnx_version_test.bzl new file mode 100644 index 0000000000..2dd1fdbad2 --- /dev/null +++ b/test/unit/platform_triple/qnx_version_test.bzl @@ -0,0 +1,108 @@ +"""Tests for WASI platform constraint mappings""" + +load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest") +load("//rust/platform:triple_mappings.bzl", "triple_to_constraint_set") + +def _qnx_version_constraints_test_impl(ctx): + env = unittest.begin(ctx) + + # Test aarch64 QNX7 constraints + qnx_version_constraints = triple_to_constraint_set("aarch64-unknown-nto-qnx710") + asserts.equals( + env, + [ + "@platforms//cpu:aarch64", + "@platforms//os:qnx", + "@rules_rust//rust/platform:qnx7", + ], + qnx_version_constraints, + "aarch64-unknown-nto-qnx710 doesn't map to the appropriate constraints", + ) + + # Test aarch64 QNX7 with iopkt constraints + qnx_version_constraints = triple_to_constraint_set("aarch64-unknown-nto-qnx710_iosock") + asserts.equals( + env, + [ + "@platforms//cpu:aarch64", + "@platforms//os:qnx", + "@rules_rust//rust/platform:qnx7_iosock", + ], + qnx_version_constraints, + "aarch64-unknown-nto-qnx710_iosock doesn't map to the appropriate constraints", + ) + + # Test aarch64 QNX8 constraints + qnx_version_constraints = triple_to_constraint_set("aarch64-unknown-nto-qnx800") + asserts.equals( + env, + [ + "@platforms//cpu:aarch64", + "@platforms//os:qnx", + "@rules_rust//rust/platform:qnx8", + ], + qnx_version_constraints, + "aarch64-unknown-nto-qnx800 doesn't map to the appropriate constraints", + ) + + # Test x86_64 QNX7 constraints + qnx_version_constraints = triple_to_constraint_set("x86_64-pc-nto-qnx710") + asserts.equals( + env, + [ + "@platforms//cpu:x86_64", + "@platforms//os:qnx", + "@rules_rust//rust/platform:qnx7", + ], + qnx_version_constraints, + "x86_64-pc-nto-qnx710 doesn't map to the appropriate constraints", + ) + + # Test x86_64 QNX7 with iosock constraints + qnx_version_constraints = triple_to_constraint_set("x86_64-pc-nto-qnx710_iosock") + asserts.equals( + env, + [ + "@platforms//cpu:x86_64", + "@platforms//os:qnx", + "@rules_rust//rust/platform:qnx7_iosock", + ], + qnx_version_constraints, + "x86_64-pc-nto-qnx710_iosock doesn't map to the appropriate constraints", + ) + + # Test x86_64 QNX8 constraints + qnx_version_constraints = triple_to_constraint_set("x86_64-pc-nto-qnx800") + asserts.equals( + env, + [ + "@platforms//cpu:x86_64", + "@platforms//os:qnx", + "@rules_rust//rust/platform:qnx8", + ], + qnx_version_constraints, + "x86_64-pc-nto-qnx800 doesn't map to the appropriate constraints", + ) + + return unittest.end(env) + +_qnx_version_constraints_test = unittest.make(_qnx_version_constraints_test_impl) + +def qnx_version_constraints_test(name, **kwargs): + """Define a test suite for the QNX version to constraints mappings + + Args: + name (str): The name of the test suite. + **kwargs (dict): Additional keyword arguments for the test_suite. + """ + _qnx_version_constraints_test( + name = "qnx_version_constraints_test", + ) + + native.test_suite( + name = name, + tests = [ + ":qnx_version_constraints_test", + ], + **kwargs + )