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

Support crate_type file extensions more fully #38

Merged
merged 9 commits into from
Feb 26, 2018
Merged
Show file tree
Hide file tree
Changes from 6 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
21 changes: 19 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,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)
```

<table class="table table-condensed table-bordered table-params">
Expand Down Expand Up @@ -112,7 +112,24 @@ rust_library(name, srcs, crate_root, deps, data, crate_features, rustc_flags)
if <code>srcs</code> contains only one file.
</p>
</td>
</td>
</tr>
<tr>
<td><code>crate_type</code></td>
<td>
<code>String, optional</code>
<p>
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".
Copy link
Collaborator Author

@acmcarther acmcarther Feb 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'proc-macro' isn't tested in this PR as the required crate dependencies are impractical to import without cargo-raze.

For the record, the required crates are

extern crate proc_macro;
extern crate syn;
extern crate quote;

EDIT: oops, github doesn't support comments to selected text.

</p>
<p>
The exact output depends on the selected toolchain but generally will
match what Cargo would do. If binary compilation is desired, use
<code>rust_binary</code> instead of the "bin" crate type.
</p>
</td>
</tr>
<tr>
<td><code>deps</code></td>
<td>
Expand Down
27 changes: 27 additions & 0 deletions examples/hello_lib/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -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"],
Expand Down
4 changes: 4 additions & 0 deletions rust/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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"],
)

Expand All @@ -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"],
)
"""
Expand Down
58 changes: 34 additions & 24 deletions rust/rust.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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"):
extension = toolchain.dylib_ext
elif crate_type == "staticlib":
extension = toolchain.staticlib_ext
elif crate_type in ("rlib", "lib", "proc-macro"):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

proc-macro should be a dylib (though I don't know if rustc actually cares)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah this is important. We're relying on rustc to "produce the right thing" without us telling it what to make. Indeed, it is producing a dylib in this case, so we need to expect a dylib. Not sure how I became under the impression that this was an rlib -- my local code pre-osx fix used dylib here.

Fixed.

# 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)
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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,
Expand Down Expand Up @@ -535,17 +544,14 @@ _rust_common_attrs = {
}

_rust_library_attrs = {
"crate_type": attr.string(),
"crate_type": attr.string(default = "rlib"),
}

rust_library = rule(
_rust_library_impl,
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"],
)

Expand All @@ -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
Expand Down
4 changes: 4 additions & 0 deletions rust/toolchain.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -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]

Expand All @@ -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"),
),
Expand Down