Skip to content

Commit

Permalink
Pass C++ runtime lib when C++ toolchain declares it
Browse files Browse the repository at this point in the history
Currently `rules_rust` won't link against the C++ standard library in case
C++ toolchain is the `static_link_cpp_runtimes` feature (therefore when
it uses `cc_toolchain.static_runtime_lib` and `cc_toolchain.dynamic_runtime_lib`
attributes to declare which version of C++ static library should be
linked into the final binary).

This PR modifies `get_libs_for_static_executable` to also look into the
C++ toolchain and depend on C++ standard library from there.

Once we implement the support for dynamically linked rust binaries we
will likely have an equivalend `get_libs_for_dynamic_executable`, which
would then look into `cc_toolchain.dynamic_runtime_lib`.

While there, I moved the `get_cc_toolchain` function to the `utils.rs`,
to be consistent with the handling of the Rust toolchain.
  • Loading branch information
hlopko committed Jan 28, 2021
1 parent 1092a78 commit 6408822
Show file tree
Hide file tree
Showing 13 changed files with 225 additions and 44 deletions.
2 changes: 2 additions & 0 deletions .bazelci/presubmit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ tasks:
# Skip tests for dylib support on osx, since we don't support it yet.
- "-@examples//ffi/rust_calling_c:matrix_dylib_test"
- "-@examples//ffi/rust_calling_c:matrix_dynamically_linked"
- "-@examples//ffi/rust_calling_cc:matrix_dynamically_linked"
- "-@examples//ffi/rust_calling_c/simple/..."
build_targets: *osx_targets
test_targets: *osx_targets
Expand All @@ -56,6 +57,7 @@ tasks:
- "@examples//..."
- "-@examples//ffi/rust_calling_c:matrix_dylib_test"
- "-@examples//ffi/rust_calling_c:matrix_dynamically_linked"
- "-@examples//ffi/rust_calling_cc:matrix_dynamically_linked"
- "-@examples//ffi/rust_calling_c/simple/..."
- "-@examples//hello_sys/..."
- "-@examples//complex_sys/..."
Expand Down
16 changes: 11 additions & 5 deletions bindgen/bindgen.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# limitations under the License.

# buildifier: disable=module-docstring
load("//rust:private/utils.bzl", "find_toolchain", "get_libs_for_static_executable")
load("//rust:private/utils.bzl", "find_cc_toolchain", "find_toolchain", "get_libs_for_static_executable")
load("//rust:rust.bzl", "rust_library")

def rust_bindgen_library(
Expand Down Expand Up @@ -53,6 +53,7 @@ def rust_bindgen_library(

def _rust_bindgen_impl(ctx):
rust_toolchain = find_toolchain(ctx)
cc_toolchain, feature_configuration = find_cc_toolchain(ctx)

# nb. We can't grab the cc_library`s direct headers, so a header must be provided.
cc_lib = ctx.attr.cc_lib
Expand Down Expand Up @@ -82,7 +83,7 @@ def _rust_bindgen_impl(ctx):
output = ctx.outputs.out

# libclang should only have 1 output file
libclang_dir = get_libs_for_static_executable(libclang).to_list()[0].dirname
libclang_dir = get_libs_for_static_executable(libclang, cc_toolchain, feature_configuration).to_list()[0].dirname
include_directories = cc_lib[CcInfo].compilation_context.includes.to_list()
quote_include_directories = cc_lib[CcInfo].compilation_context.quote_includes.to_list()
system_include_directories = cc_lib[CcInfo].compilation_context.system_includes.to_list()
Expand Down Expand Up @@ -110,17 +111,17 @@ def _rust_bindgen_impl(ctx):
}

if libstdcxx:
env["LD_LIBRARY_PATH"] = ":".join([f.dirname for f in get_libs_for_static_executable(libstdcxx).to_list()])
env["LD_LIBRARY_PATH"] = ":".join([f.dirname for f in get_libs_for_static_executable(libstdcxx, cc_toolchain, feature_configuration).to_list()])

ctx.actions.run(
executable = bindgen_bin,
inputs = depset(
[header],
transitive = [
cc_lib[CcInfo].compilation_context.headers,
get_libs_for_static_executable(libclang),
get_libs_for_static_executable(libclang, cc_toolchain, feature_configuration),
] + [
get_libs_for_static_executable(libstdcxx),
get_libs_for_static_executable(libstdcxx, cc_toolchain, feature_configuration),
] if libstdcxx else [],
),
outputs = [unformatted_output],
Expand Down Expand Up @@ -173,11 +174,16 @@ rust_bindgen = rule(
allow_single_file = True,
cfg = "exec",
),
"_cc_toolchain": attr.label(
default = Label("@bazel_tools//tools/cpp:current_cc_toolchain"),
),
},
outputs = {"out": "%{name}.rs"},
fragments = ["cpp"],
toolchains = [
str(Label("//bindgen:bindgen_toolchain")),
str(Label("//rust:toolchain")),
"@bazel_tools//tools/cpp:toolchain_type",
],
)

Expand Down
9 changes: 4 additions & 5 deletions cargo/cargo_build_script.bzl
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# buildifier: disable=module-docstring
load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "C_COMPILE_ACTION_NAME")
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
load("//rust:private/rust.bzl", "name_to_crate_name")
load("//rust:private/rustc.bzl", "BuildInfo", "DepInfo", "get_cc_toolchain", "get_compilation_mode_opts", "get_linker_and_args")
load("//rust:private/utils.bzl", "expand_locations", "find_toolchain")
load("//rust:private/rustc.bzl", "BuildInfo", "DepInfo", "get_compilation_mode_opts", "get_linker_and_args")
load("//rust:private/utils.bzl", "expand_locations", "find_toolchain", "find_cc_toolchain")
load("//rust:rust.bzl", "rust_binary")

def get_cc_compile_env(cc_toolchain, feature_configuration):
Expand Down Expand Up @@ -65,7 +64,7 @@ def _build_script_impl(ctx):
toolchain.rust_lib.files,
]

cc_toolchain = find_cpp_toolchain(ctx)
cc_toolchain, feature_configuration = find_cc_toolchain(ctx)

# Start with the default shell env, which contains any --action_env
# settings passed in on the command line.
Expand All @@ -92,7 +91,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
26 changes: 26 additions & 0 deletions examples/ffi/rust_calling_cc/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
load("@rules_rust//rust:rust.bzl", "rust_binary")

package(default_visibility = ["//ffi/rust_calling_cc:__subpackages__"])

rust_binary(
name = "matrix",
srcs = [
"src/ffi.rs",
"src/matrix.rs",
],
deps = [
"//ffi/rust_calling_cc/cc:native_matrix",
],
)

rust_binary(
name = "matrix_dynamically_linked",
srcs = [
"src/ffi.rs",
"src/matrix.rs",
],
crate_root = "src/matrix.rs",
deps = [
"//ffi/rust_calling_cc/cc:native_matrix_so",
],
)
31 changes: 31 additions & 0 deletions examples/ffi/rust_calling_cc/cc/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_import", "cc_library", "cc_test")

package(default_visibility = ["//ffi/rust_calling_cc:__subpackages__"])

cc_library(
name = "native_matrix",
srcs = ["matrix.cc"],
hdrs = ["matrix.h"],
)

cc_test(
name = "native_matrix_test",
srcs = ["matrix_test.cc"],
deps = [
":native_matrix",
],
)

## Do the same as above, but with a dynamic c library.

cc_import(
name = "native_matrix_so",
hdrs = ["matrix.h"],
shared_library = ":libnative_matrix_so.so",
)

cc_binary(
name = "libnative_matrix_so.so",
srcs = ["matrix.cc", "matrix.h"],
linkshared = True,
)
23 changes: 23 additions & 0 deletions examples/ffi/rust_calling_cc/cc/matrix.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2017 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "ffi/rust_calling_cc/cc/matrix.h"

#include <iostream>

extern "C" void print_matrix() {
std::cout << "1 2 3" << std::endl;
std::cout << "4 5 6" << std::endl;
std::cout << "7 8 9" << std::endl;
}
20 changes: 20 additions & 0 deletions examples/ffi/rust_calling_cc/cc/matrix.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright 2017 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef MATRIX_SRC_MATRIX_H_
#define MATRIX_SRC_MATRIX_H_

extern "C" void print_matrix();

#endif // MATRIX_SRC_MATRIX_H_
23 changes: 23 additions & 0 deletions examples/ffi/rust_calling_cc/cc/matrix_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2017 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "ffi/rust_calling_cc/cc/matrix.h"

#include <stdlib.h>


int main(int argc, char** argv) {
print_matrix();
return EXIT_SUCCESS;
}
17 changes: 17 additions & 0 deletions examples/ffi/rust_calling_cc/src/ffi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2017 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern "C" {
pub fn print_matrix();
}
18 changes: 18 additions & 0 deletions examples/ffi/rust_calling_cc/src/matrix.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2017 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

mod ffi;
fn main() {
unsafe { ffi::print_matrix(); }
}
10 changes: 6 additions & 4 deletions rust/private/clippy.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,12 @@ load(
"collect_deps",
"collect_inputs",
"construct_arguments",
"get_cc_toolchain",
)
load(
"//rust:private/rust.bzl",
"crate_root_src",
)
load("//rust:private/utils.bzl", "determine_output_hash", "find_toolchain")
load("//rust:private/utils.bzl", "determine_output_hash", "find_toolchain", "find_cc_toolchain")

_rust_extensions = [
"rs",
Expand All @@ -48,6 +47,8 @@ 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[CrateInfo]

if crate_info.is_test:
Expand All @@ -64,13 +65,16 @@ def _clippy_aspect_impl(target, ctx):
crate_info.proc_macro_deps,
crate_info.aliases,
toolchain,
cc_toolchain,
feature_configuration,
)

compile_inputs, out_dir, build_env_file, build_flags_files = collect_inputs(
ctx,
ctx.rule.file,
ctx.rule.files,
toolchain,
cc_toolchain,
crate_info,
dep_info,
build_info,
Expand All @@ -80,8 +84,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
Loading

0 comments on commit 6408822

Please sign in to comment.