Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass C++ runtime lib when C++ toolchain declares it #562

Merged
merged 2 commits into from
Feb 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions cargo/cargo_build_script.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ load("//rust:rust.bzl", "rust_binary")
load("//rust/private:rust.bzl", "name_to_crate_name")

# buildifier: disable=bzl-visibility
load("//rust/private:rustc.bzl", "BuildInfo", "DepInfo", "get_cc_toolchain", "get_compilation_mode_opts", "get_linker_and_args")
load("//rust/private:rustc.bzl", "BuildInfo", "DepInfo", "get_compilation_mode_opts", "get_linker_and_args")

# buildifier: disable=bzl-visibility
load("//rust/private:utils.bzl", "expand_locations", "find_toolchain")
load("//rust/private:utils.bzl", "expand_locations", "find_cc_toolchain", "find_toolchain")

def get_cc_compile_env(cc_toolchain, feature_configuration):
"""Gather cc environment variables from the given `cc_toolchain`
Expand Down Expand Up @@ -98,7 +98,7 @@ def _build_script_impl(ctx):

# Pull in env vars which may be required for the cc_toolchain to work (e.g. on OSX, the SDK version).
# We hope that the linker env is sufficient for the whole cc_toolchain.
cc_toolchain, feature_configuration = get_cc_toolchain(ctx)
cc_toolchain, feature_configuration = find_cc_toolchain(ctx)
_, _, linker_env = get_linker_and_args(ctx, cc_toolchain, feature_configuration, None)
env.update(**linker_env)

Expand Down
7 changes: 3 additions & 4 deletions rust/private/clippy.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@ load(
"collect_deps",
"collect_inputs",
"construct_arguments",
"get_cc_toolchain",
)
load("//rust/private:utils.bzl", "determine_output_hash", "find_toolchain")
load("//rust/private:utils.bzl", "determine_output_hash", "find_cc_toolchain", "find_toolchain")

_rust_extensions = [
"rs",
Expand All @@ -48,6 +47,7 @@ def _clippy_aspect_impl(target, ctx):
rust_srcs = _rust_sources(target, ctx.rule)

toolchain = find_toolchain(ctx)
cc_toolchain, feature_configuration = find_cc_toolchain(ctx)
crate_info = target[rust_common.crate_info]
crate_type = crate_info.type

Expand All @@ -72,6 +72,7 @@ def _clippy_aspect_impl(target, ctx):
ctx.rule.file,
ctx.rule.files,
toolchain,
cc_toolchain,
crate_info,
dep_info,
build_info,
Expand All @@ -81,8 +82,6 @@ def _clippy_aspect_impl(target, ctx):
# This file is necessary because "ctx.actions.run" mandates an output.
clippy_marker = ctx.actions.declare_file(ctx.label.name + "_clippy.ok")

cc_toolchain, feature_configuration = get_cc_toolchain(ctx)

args, env = construct_arguments(
ctx,
ctx.file,
Expand Down
63 changes: 33 additions & 30 deletions rust/private/rustc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ load(
"@bazel_tools//tools/build_defs/cc:action_names.bzl",
"CPP_LINK_EXECUTABLE_ACTION_NAME",
)
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
load("//rust/private:common.bzl", "rust_common")
load(
"//rust/private:utils.bzl",
"expand_locations",
"find_cc_toolchain",
"get_lib_name",
"get_libs_for_static_executable",
"relativize",
Expand Down Expand Up @@ -215,25 +215,6 @@ def collect_deps(label, deps, proc_macro_deps, aliases, toolchain):
build_info,
)

def get_cc_toolchain(ctx):
"""Extracts a CcToolchain from the current target's context

Args:
ctx (ctx): The current target's rule context object

Returns:
tuple: A tuple of (CcToolchain, FeatureConfiguration)
"""
cc_toolchain = find_cpp_toolchain(ctx)

feature_configuration = cc_common.configure_features(
ctx = ctx,
cc_toolchain = cc_toolchain,
requested_features = ctx.features,
unsupported_features = ctx.disabled_features,
)
return cc_toolchain, feature_configuration

def get_cc_user_link_flags(ctx):
"""Get the current target's linkopt flags

Expand Down Expand Up @@ -319,16 +300,18 @@ def collect_inputs(
file,
files,
toolchain,
cc_toolchain,
crate_info,
dep_info,
build_info):
"""Gather's the inputs and required input information for a rustc action

Args:
ctx (ctx): The rule's context object
ctx (ctx): The rule's context object.
file (struct): A struct containing files defined in label type attributes marked as `allow_single_file`.
files (list): A list of all inputs
toolchain (rust_toolchain): The current `rust_toolchain`
files (list): A list of all inputs.
toolchain (rust_toolchain): The current `rust_toolchain`.
cc_toolchain (CcToolchainInfo): The current `cc_toolchain`.
crate_info (CrateInfo): The Crate information of the crate to process build scripts for.
dep_info (DepInfo): The target Crate's dependency information.
build_info (BuildInfo): The target Crate's build settings.
Expand All @@ -338,7 +321,7 @@ def collect_inputs(
"""
linker_script = getattr(file, "linker_script") if hasattr(file, "linker_script") else None

linker_depset = find_cpp_toolchain(ctx).all_files
linker_depset = cc_toolchain.all_files

compile_inputs = depset(
crate_info.srcs +
Expand Down Expand Up @@ -510,7 +493,7 @@ def construct_arguments(
args.add("--codegen=linker=" + ld)
args.add_joined("--codegen", link_args, join_with = " ", format_joined = "link-args=%s")

add_native_link_flags(args, dep_info, crate_type)
_add_native_link_flags(args, dep_info, crate_type, cc_toolchain, feature_configuration)

# These always need to be added, even if not linking this crate.
add_crate_link_flags(args, dep_info)
Expand Down Expand Up @@ -565,6 +548,8 @@ def rustc_compile_action(
- (DepInfo): The transitive dependencies of this crate.
- (DefaultInfo): The output file for this crate, and its runfiles.
"""
cc_toolchain, feature_configuration = find_cc_toolchain(ctx)

dep_info, build_info = collect_deps(
ctx.label,
crate_info.deps,
Expand All @@ -578,13 +563,12 @@ def rustc_compile_action(
ctx.file,
ctx.files,
toolchain,
cc_toolchain,
crate_info,
dep_info,
build_info,
)

cc_toolchain, feature_configuration = get_cc_toolchain(ctx)

args, env = construct_arguments(
ctx,
ctx.file,
Expand Down Expand Up @@ -656,7 +640,7 @@ def establish_cc_info(ctx, crate_info, toolchain, cc_toolchain, feature_configur
ctx (ctx): The rule's context object
crate_info (CrateInfo): The CrateInfo provider of the target crate
toolchain (rust_toolchain): The current `rust_toolchain`
cc_toolchain (CcToolchainInfo): The current CcToolchainInfo
cc_toolchain (CcToolchainInfo): The current `CcToolchainInfo`
feature_configuration (FeatureConfiguration): Feature configuration to be queried.

Returns:
Expand Down Expand Up @@ -821,13 +805,15 @@ def _get_crate_dirname(crate):
"""
return crate.output.dirname

def add_native_link_flags(args, dep_info, crate_type):
def _add_native_link_flags(args, dep_info, crate_type, cc_toolchain, feature_configuration):
"""Adds linker flags for all dependencies of the current target.

Args:
args (Args): The Args struct for a ctx.action
dep_info (DepInfo): Dependency Info provider
crate_type: Crate type of the current target
cc_toolchain (CcToolchainInfo): The current `cc_toolchain`
feature_configuration (FeatureConfiguration): feature configuration to use with cc_toolchain

"""
if crate_type in ["lib", "rlib"]:
Expand All @@ -838,8 +824,25 @@ def add_native_link_flags(args, dep_info, crate_type):
args.add_all(dep_info.transitive_dylibs, map_each = get_lib_name, format_each = "-ldylib=%s")
args.add_all(dep_info.transitive_staticlibs, map_each = get_lib_name, format_each = "-lstatic=%s")

if crate_type in ["dylib", "cdylib"]:
# For shared libraries we want to link C++ runtime library dynamically
# (for example libstdc++.so or libc++.so).
args.add_all(
cc_toolchain.dynamic_runtime_lib(feature_configuration = feature_configuration),
map_each = get_lib_name,
format_each = "-ldylib=%s",
)
else:
# For all other crate types we want to link C++ runtime library statically
# (for example libstdc++.a or libc++.a).
args.add_all(
cc_toolchain.static_runtime_lib(feature_configuration = feature_configuration),
map_each = get_lib_name,
format_each = "-lstatic=%s",
)

def _get_dirname(file):
"""A helper function for `add_native_link_flags`.
"""A helper function for `_add_native_link_flags`.

Args:
file (File): The target file
Expand Down
21 changes: 21 additions & 0 deletions rust/private/utils.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

"""Utility functions not specific to the rust toolchain."""

load("@bazel_tools//tools/cpp:toolchain_utils.bzl", find_rules_cc_toolchain = "find_cpp_toolchain")

def find_toolchain(ctx):
"""Finds the first rust toolchain that is configured.

Expand All @@ -25,6 +27,25 @@ def find_toolchain(ctx):
"""
return ctx.toolchains[Label("//rust:toolchain")]

def find_cc_toolchain(ctx):
"""Extracts a CcToolchain from the current target's context

Args:
ctx (ctx): The current target's rule context object

Returns:
tuple: A tuple of (CcToolchain, FeatureConfiguration)
"""
cc_toolchain = find_rules_cc_toolchain(ctx)

feature_configuration = cc_common.configure_features(
ctx = ctx,
cc_toolchain = cc_toolchain,
requested_features = ctx.features,
unsupported_features = ctx.disabled_features,
)
return cc_toolchain, feature_configuration

# TODO: Replace with bazel-skylib's `path.dirname`. This requires addressing some
# dependency issues or generating docs will break.
def relativize(path, start):
Expand Down