diff --git a/README.md b/README.md index e91474f9ac..977be671e7 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ The master branch should always be current with the latest bazel, as such you ca ## rust_library ```python -rust_library(name, srcs, crate_root, deps, data, crate_features, rustc_flags) +rust_library(name, srcs, crate_root, crate_type, deps, data, crate_features, rustc_flags) ```
crate_type |
+
+ String, optional
+ + The type of crate to be produced during library compilation. This + list closely matches Cargo's own notion of crate-type, and the + available options are "lib", "rlib", "dylib", "cdylib", "staticlib", + and "proc-macro". + +
+ The exact output depends on the selected toolchain but generally will
+ match what Cargo would do. If binary compilation is desired, use
+ |
+
deps |
diff --git a/examples/hello_lib/BUILD b/examples/hello_lib/BUILD index 31a6943dcf..d67a76556e 100644 --- a/examples/hello_lib/BUILD +++ b/examples/hello_lib/BUILD @@ -16,6 +16,33 @@ rust_library( ], ) +rust_library( + name = "hello_dylib", + srcs = [ + "src/greeter.rs", + "src/lib.rs", + ], + crate_type = "dylib", +) + +rust_library( + name = "hello_cdylib", + srcs = [ + "src/greeter.rs", + "src/lib.rs", + ], + crate_type = "cdylib", +) + +rust_library( + name = "hello_staticlib", + srcs = [ + "src/greeter.rs", + "src/lib.rs", + ], + crate_type = "staticlib", +) + rust_test( name = "hello_lib_test", deps = [":hello_lib"], diff --git a/rust/repositories.bzl b/rust/repositories.bzl index 336c0a20b1..ebffb5dc12 100644 --- a/rust/repositories.bzl +++ b/rust/repositories.bzl @@ -89,6 +89,8 @@ rust_toolchain( rust_lib = ["@rust_linux_x86_64//:rust_lib"], rustc = "@rust_linux_x86_64//:rustc", rustc_lib = ["@rust_linux_x86_64//:rustc_lib"], + staticlib_ext = ".a", + dylib_ext = ".so", visibility = ["//visibility:public"], ) @@ -112,6 +114,8 @@ rust_toolchain( rust_lib = ["@rust_darwin_x86_64//:rust_lib"], rustc = "@rust_darwin_x86_64//:rustc", rustc_lib = ["@rust_darwin_x86_64//:rustc_lib"], + staticlib_ext = ".a", + dylib_ext = ".dylib", visibility = ["//visibility:public"], ) """ diff --git a/rust/rust.bzl b/rust/rust.bzl index f10da0fffe..3f32b5d4ce 100644 --- a/rust/rust.bzl +++ b/rust/rust.bzl @@ -55,13 +55,6 @@ RUST_FILETYPE = FileType([".rs"]) A_FILETYPE = FileType([".a"]) -LIBRARY_CRATE_TYPES = [ - "lib", - "rlib", - "dylib", - "staticlib", -] - # Used by rust_doc HTML_MD_FILETYPE = FileType([ ".html", @@ -205,6 +198,27 @@ def _find_crate_root_src(srcs, file_names=["lib.rs"]): return src fail("No %s source file found." % " or ".join(file_names), "srcs") +def _determine_lib_name(name, crate_type, toolchain): + extension = None + if crate_type in ("dylib", "cdylib", "proc-macro"): + extension = toolchain.dylib_ext + elif crate_type == "staticlib": + extension = toolchain.staticlib_ext + elif crate_type in ("lib", "rlib"): + # All platforms produce 'rlib' here + extension = ".rlib" + elif crate_type == "bin": + fail("crate_type of 'bin' was detected in a rust_library. Please compile " + + "this crate as a rust_binary instead.") + + if not extension: + fail(("Unknown crate_type: %s. If this is a cargo-supported crate type, " + + "please file an issue!") % crate_type) + + + return "lib{name}{extension}".format(name=name, + extension=extension) + def _crate_root_src(ctx, file_names=["lib.rs"]): if ctx.file.crate_root == None: return _find_crate_root_src(ctx.files.srcs, file_names) @@ -219,18 +233,14 @@ def _rust_library_impl(ctx): # Find lib.rs lib_rs = _crate_root_src(ctx) - # Validate crate_type - crate_type = "" - if ctx.attr.crate_type != "": - if ctx.attr.crate_type not in LIBRARY_CRATE_TYPES: - fail("Invalid crate_type for rust_library. Allowed crate types are: %s" - % " ".join(LIBRARY_CRATE_TYPES), "crate_type") - crate_type += ctx.attr.crate_type - else: - crate_type += "lib" + # Find toolchain + toolchain = _find_toolchain(ctx) # Output library - rust_lib = ctx.outputs.rust_lib + rust_lib_name = _determine_lib_name(ctx.attr.name, + ctx.attr.crate_type, + toolchain); + rust_lib = ctx.actions.declare_file(rust_lib_name) output_dir = rust_lib.dirname # Dependencies @@ -240,12 +250,11 @@ def _rust_library_impl(ctx): allow_cc_deps=True) # Build rustc command - toolchain = _find_toolchain(ctx) cmd = build_rustc_command( ctx = ctx, toolchain = toolchain, crate_name = ctx.label.name, - crate_type = crate_type, + crate_type = ctx.attr.crate_type, src = lib_rs, output_dir = output_dir, depinfo = depinfo) @@ -272,7 +281,7 @@ def _rust_library_impl(ctx): return struct( files = depset([rust_lib]), - crate_type = crate_type, + crate_type = ctx.attr.crate_type, crate_root = lib_rs, rust_srcs = ctx.files.srcs, rust_deps = ctx.attr.deps, @@ -535,7 +544,7 @@ _rust_common_attrs = { } _rust_library_attrs = { - "crate_type": attr.string(), + "crate_type": attr.string(default = "rlib"), } rust_library = rule( @@ -543,9 +552,6 @@ rust_library = rule( attrs = dict(_rust_common_attrs.items() + _rust_library_attrs.items()), host_fragments = ["cpp"], - outputs = { - "rust_lib": "lib%{name}.rlib", - }, toolchains = ["@io_bazel_rules_rust//rust:toolchain"], ) @@ -564,6 +570,10 @@ Args: If `crate_root` is not set, then this rule will look for a `lib.rs` file or the single file in `srcs` if `srcs` contains only one file. + crate_type: The type of linkage to use for building this library. Options + include "lib", "rlib", "dylib", "cdylib", "staticlib", and "proc-macro" + + The exact output file will depend on the toolchain used. deps: List of other libraries to be linked to this library target. These can be either other `rust_library` targets or `cc_library` targets if diff --git a/rust/toolchain.bzl b/rust/toolchain.bzl index db15802a99..889524e080 100644 --- a/rust/toolchain.bzl +++ b/rust/toolchain.bzl @@ -141,6 +141,8 @@ def _rust_toolchain_impl(ctx): rust_doc = _get_first_file(ctx.attr.rust_doc), rustc_lib = _get_files(ctx.attr.rustc_lib), rust_lib = _get_files(ctx.attr.rust_lib), + staticlib_ext = ctx.attr.staticlib_ext, + dylib_ext = ctx.attr.dylib_ext, crosstool_files = ctx.files._crosstool) return [toolchain] @@ -151,6 +153,8 @@ rust_toolchain = rule( "rust_doc": attr.label(allow_files = True), "rustc_lib": attr.label_list(allow_files = True), "rust_lib": attr.label_list(allow_files = True), + "staticlib_ext": attr.string(mandatory = True), + "dylib_ext": attr.string(mandatory = True), "_crosstool": attr.label( default = Label("//tools/defaults:crosstool"), ), |