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

Parse settings from Cargo metadata #302

Merged
merged 6 commits into from
Dec 15, 2020
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion .bazelversion
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.7.0
3.7.1
209 changes: 129 additions & 80 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,37 +46,25 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
name = "io_bazel_rules_rust",
sha256 = "b5d4d1c7609714dfef821355f40353c58aa1afb3803401b3442ed2355db9b0c7",
strip_prefix = "rules_rust-8d2b4eeeff9dce24f5cbb36018f2d60ecd676639",
sha256 = "0e2e633bf0f7f25392ffb477d677c88eb34fe70ffae05e3ad92fdd9f8d6579db",
strip_prefix = "rules_rust-bc0578798f50d018ca4278ad5610598c400992c9",
urls = [
# Master branch as of 2020-11-10
"https://github.com/bazelbuild/rules_rust/archive/8d2b4eeeff9dce24f5cbb36018f2d60ecd676639.tar.gz",
# Master branch as of 2020-12-05
"https://github.com/bazelbuild/rules_rust/archive/bc0578798f50d018ca4278ad5610598c400992c9.tar.gz",
],
)

load("@io_bazel_rules_rust//rust:repositories.bzl", "rust_repositories")

rust_repositories()

load("@io_bazel_rules_rust//:workspace.bzl", "rust_workspace")

rust_workspace()
```

### Vendoring Mode

In Vendoring mode, a root directly is selected that will house the vendored
dependencies and become the gateway to those build rules. "//cargo" is
conventional, but "//third_party/cargo" may be desirable to satisfy
organizational needs. Vendoring directly into root isn't well supported due to
implementation-specific idiosyncracies, but it may be supported in the future.
From here forward, "//cargo" will be the assumed directory.
### Generate a Cargo.toml

#### Generate a Cargo.toml

First, generate a standard Cargo.toml with the dependencies of interest. Take
care to include a `[lib]` directive so that Cargo does not complain about
missing source files for this mock crate. Here is an example:
For Bazel only projects, users should first generate a standard Cargo.toml
with the dependencies of interest. Take care to include a `[lib]` directive
so that Cargo does not complain about missing source files for this mock
crate. Here is an example:

```toml
[package]
Expand All @@ -90,7 +78,7 @@ path = "fake_lib.rs"
[dependencies]
log = "=0.3.6"

[package.metadata.raze]
[workspace.metadata.raze]
# The path relative path to the Bazel workspace root (location of
# WORKSPACE.bazel/WORKSPACE file). If no workspace file is found,
# the current working directory is used.
Expand All @@ -100,48 +88,29 @@ workspace_path = "//cargo"
# file located next to this `Cargo.toml` file.
package_aliases_dir = "."

# The target to generate BUILD rules for.
target = "x86_64-unknown-linux-gnu"
```

#### Generate buildable targets

First, install the required tools for vendoring and generating BUILDable
targets.

```bash
$ cargo install cargo-raze
```

Following that, vendor your dependencies from within the cargo/ directory. This
will also update your `Cargo.lock` file.

```bash
$ cargo vendor --versioned-dirs
```

Finally, generate your BUILD files, again from within the `cargo/` directory
# The set of targets to generate BUILD rules for.
targets = [
"x86_64-apple-darwin",
"x86_64-pc-windows-msvc",
"x86_64-unknown-linux-gnu",
]

```bash
$ cargo raze
# The two acceptable options are "Remote" and "Vendored" which
# is used to idnicate whether the user is using a non-vendored or
# vendored set of dependencies.
genmode = "Remote"
```

You can now depend on any _explicit_ dependencies in any Rust rule by depending on
`//cargo:your_dependency_name`.

### Remote Dependency Mode

In Remote mode, a directory similar to the vendoring mode is selected. In this
case, though, it contains only BUILD files, a vendoring instruction for the
WORKSPACE, and aliases to the explicit dependencies. Slightly different plumbing
is required.

#### Generate a Cargo.toml
### Using existing Cargo.toml

Generate a Cargo.toml, similar to Vendoring mode but add a new `genmode` directive in the
`[package.metadata.raze]` section
Almost all canonical cargo setups should be able to function inplace with
`cargo-raze`. Assuming the Cargo workspace is now nested under a Bazel workspace,
Users can simply add [RazeSettings](./impl/src/settings.rs) to their Cargo.toml
files to be used for generating Bazel files

```toml
# Above this line should be the contents of your Cargo.toml file

[package.metadata.raze]
# The path relative path to the Bazel workspace root (location of
# WORKSPACE.bazel/WORKSPACE file). If no workspace file is found,
Expand All @@ -152,12 +121,58 @@ workspace_path = "//cargo"
# file located next to this `Cargo.toml` file.
package_aliases_dir = "."

# The target to generate BUILD rules for.
target = "x86_64-unknown-linux-gnu"
# The set of targets to generate BUILD rules for.
targets = [
"x86_64-apple-darwin",
"x86_64-pc-windows-msvc",
"x86_64-unknown-linux-gnu",
]

# The two acceptable options are "Remote" and "Vendored" which
# is used to idnicate whether the user is using a non-vendored or
# vendored set of dependencies.
genmode = "Remote"
```

#### Cargo workspace projects

In projects that use [cargo workspaces](cargo_workspaces) uses should organize
all of their `raze` settings into the `[workspace.metadata.raze]` field in the
top level `Cargo.toml` file which contains the `[workspace]` definition. These
settings should be identical to the ones seen in `[package.metadata.raze]` in
[the previous section](#Using existing Cargo.toml). However, crate settings may still
be placed in the `Cargo.toml` files of the workspace memebers:
acmcarther marked this conversation as resolved.
Show resolved Hide resolved

```toml
# Above this line should be the contents of your package's Cargo.toml file

# Note that `some-dependency` is the name of an example dependency and
# `<0.3.0` is a semver version for the dependency crate's version. This
# should always be compaitble in some way with the dependency version
# specified in the `[dependencies]` section of the package defined in
# this file
[package.metadata.raze.crates.some-dependency.'<0.3.0']
additional_flags = [
"--cfg=optional_feature_a",
"--cfg=optional_feature_b",
]

# This demonstrates that multiple crate settings may be defined.
[package.metadata.raze.crates.some-other-dependency.'*']
additional_flags = [
"--cfg=special_feature",
]
```

[cargo_workspaces]: https://doc.rust-lang.org/book/ch14-03-cargo-workspaces.html)

### Remote Dependency Mode

In Remote mode, a directory similar to the vendoring mode is selected. In this
case, though, it contains only BUILD files, a vendoring instruction for the
WORKSPACE, and aliases to the explicit dependencies. Slightly different plumbing
is required.

This tells Raze not to expect the dependencies to be vendored and to generate
different files.

Expand All @@ -184,13 +199,47 @@ raze_fetch_remote_crates()
```

This tells Bazel where to get the dependencies from, and how to build them:
using the files generated into //cargo.
using the files generated into `//cargo`.

_Note that this method's name depends on your `gen_workspace_prefix` setting_.

You can depend on any _explicit_ dependencies in any Rust rule by depending on
`//cargo:your_dependency_name`.

### Vendoring Mode

In Vendoring mode, a root directly is selected that will house the vendored
dependencies and become the gateway to those build rules. `//cargo` is
conventional, but `//third_party/cargo` may be desirable to satisfy
organizational needs. Vendoring directly into root isn't well supported due to
implementation-specific idiosyncracies, but it may be supported in the future.
From here forward, `//cargo` will be the assumed directory.

#### Generate buildable targets (vendored)

First, install the required tools for vendoring and generating BUILDable
targets.

```bash
$ cargo install cargo-raze
```

Following that, vendor your dependencies from within the cargo/ directory. This
will also update your `Cargo.lock` file.

```bash
$ cargo vendor --versioned-dirs
```

Finally, generate your BUILD files, again from within the `cargo/` directory

```bash
$ cargo raze
```

You can now depend on any _explicit_ dependencies in any Rust rule by depending on
`//cargo:your_dependency_name`.

### Handling Unconventional Crates

Some crates execute a "build script", which, while technically unrestricted in
Expand Down Expand Up @@ -224,9 +273,9 @@ Cargo.toml, in the following manner
```toml
[package.metadata.raze.crates.unicase.'2.1.0']
additional_flags = [
# Rustc is 1.15, enable all optional settings
"--cfg=__unicase__iter_cmp",
"--cfg=__unicase__defauler_hasher",
# Rustc is 1.15, enable all optional settings
"--cfg=__unicase__iter_cmp",
"--cfg=__unicase__defauler_hasher",
]
```

Expand All @@ -245,21 +294,21 @@ openssl, this may in part look like:
```toml
[package.metadata.raze.crates.openssl-sys.'0.9.24']
additional_flags = [
# Vendored openssl is 1.0.2m
"--cfg=ossl102",
"--cfg=version=102",
# Vendored openssl is 1.0.2m
"--cfg=ossl102",
"--cfg=version=102",
]
additional_deps = [
"@//third_party/openssl:crypto",
"@//third_party/openssl:ssl",
"@//third_party/openssl:crypto",
"@//third_party/openssl:ssl",
]

[package.metadata.raze.crates.openssl.'0.10.2']
additional_flags = [
# Vendored openssl is 1.0.2m
"--cfg=ossl102",
"--cfg=version=102",
"--cfg=ossl10x",
# Vendored openssl is 1.0.2m
"--cfg=ossl102",
"--cfg=version=102",
"--cfg=ossl10x",
]
```

Expand All @@ -271,7 +320,7 @@ something like:
```python
new_local_repository(
name = "llvm",
build_file = "llvm.BUILD",
build_file = "BUILD.llvm.bazel",
path = "/usr/lib/llvm-3.9",
)
```
Expand All @@ -283,10 +332,10 @@ pre-generation:
```toml
[package.metadata.raze.crates.sdl2.'0.31.0']
skipped_deps = [
"sdl2-sys-0.31.0"
"sdl2-sys-0.31.0"
]
additional_deps = [
"@//cargo/overrides/sdl2-sys:sdl2_sys"
"@//cargo/overrides/sdl2-sys:sdl2_sys"
]
```

Expand All @@ -301,7 +350,7 @@ to tell Bazel to expose such binaries for you:
[package.metadata.raze.crates.bindgen.'0.32.2']
gen_buildrs = true # needed to build bindgen
extra_aliased_targets = [
"cargo_bin_bindgen"
"cargo_bin_bindgen"
]
```

Expand Down Expand Up @@ -331,7 +380,7 @@ specified by `workspace_path`.
Setting default_gen_buildrs to true will cause cargo-raze to generate build scripts
for all crates that require them:

```
```toml
[package.metadata.raze]
workspace_path = "//cargo"
genmode = "Remote"
Expand All @@ -348,15 +397,15 @@ Even with this setting enabled, you may still need to provide extra settings for
a few crates. For example, the ring crate needs access to the source tree at build
time:

```
```toml
[package.metadata.raze.crates.ring.'*']
data_attr = "glob([\"src/**\"])"
```

If you wish to disable the build script on an individual crate, you can do so
as follows:

```
```toml
[package.metadata.raze.crates.some_dependency.'*']
gen_buildrs = false
```
Expand Down
12 changes: 4 additions & 8 deletions examples/WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,18 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
name = "io_bazel_rules_rust",
sha256 = "b5d4d1c7609714dfef821355f40353c58aa1afb3803401b3442ed2355db9b0c7",
strip_prefix = "rules_rust-8d2b4eeeff9dce24f5cbb36018f2d60ecd676639",
sha256 = "0e2e633bf0f7f25392ffb477d677c88eb34fe70ffae05e3ad92fdd9f8d6579db",
strip_prefix = "rules_rust-bc0578798f50d018ca4278ad5610598c400992c9",
urls = [
# Master branch as of 2020-11-10
"https://github.com/bazelbuild/rules_rust/archive/8d2b4eeeff9dce24f5cbb36018f2d60ecd676639.tar.gz",
# Master branch as of 2020-12-05
"https://github.com/bazelbuild/rules_rust/archive/bc0578798f50d018ca4278ad5610598c400992c9.tar.gz",
],
)

load("@io_bazel_rules_rust//rust:repositories.bzl", "rust_repositories")

rust_repositories()

load("@io_bazel_rules_rust//:workspace.bzl", "rust_workspace")

rust_workspace()

load("//remote/binary_dependencies/cargo:crates.bzl", "remote_binary_dependencies_fetch_remote_crates")

remote_binary_dependencies_fetch_remote_crates()
Expand Down
2 changes: 1 addition & 1 deletion impl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ rustc-serialize = "0.3.24"
semver = { version = "0.11.0", features = ["serde"] }
serde = "1.0.118"
serde_derive = "1.0.118"
serde_json = "1.0.60"
slug = "0.1.4"
spdx = "0.3.4"
tempfile = "3.1.0"
Expand All @@ -53,5 +54,4 @@ hamcrest2 = "0.3.0"
httpmock = "0.5.2"
indoc = "1.0.3"
lazy_static = "1.4.0"
serde_json = "1.0.60"
tar = "0.4.30"
11 changes: 4 additions & 7 deletions impl/src/bin/cargo-raze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,10 @@ fn main() -> Result<()> {
.unwrap_or_else(|e| e.exit());

// Load settings
let manifest_path = PathBuf::from(
options
.flag_manifest_path
.unwrap_or("./Cargo.toml".to_owned()),
)
.canonicalize()?;
let settings = load_settings(&manifest_path)?;
let manifest_path = PathBuf::from(options
.flag_manifest_path
.unwrap_or("./Cargo.toml".to_owned())).canonicalize()?;
let settings = load_settings(&manifest_path, options.flag_cargo_bin_path.clone())?;
if options.flag_verbose.unwrap_or(false) {
println!("Loaded override settings: {:#?}", settings);
}
Expand Down
Loading