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

Add cargo:rustc-link-arg to pass custom linker arguments #6298

Merged
merged 5 commits into from
Mar 27, 2019
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
7 changes: 7 additions & 0 deletions src/cargo/core/compiler/build_context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ impl TargetConfig {
let mut output = BuildOutput {
library_paths: Vec::new(),
library_links: Vec::new(),
linker_args: Vec::new(),
cfgs: Vec::new(),
env: Vec::new(),
metadata: Vec::new(),
Expand Down Expand Up @@ -258,6 +259,12 @@ impl TargetConfig {
.library_paths
.extend(list.iter().map(|v| PathBuf::from(&v.0)));
}
"rustc-cdylib-link-arg" => {
let args = value.list(k)?;
output
.linker_args
.extend(args.iter().map(|v| v.0.clone()));
}
"rustc-cfg" => {
let list = value.list(k)?;
output.cfgs.extend(list.iter().map(|v| v.0.clone()));
Expand Down
5 changes: 5 additions & 0 deletions src/cargo/core/compiler/custom_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ pub struct BuildOutput {
pub library_paths: Vec<PathBuf>,
/// Names and link kinds of libraries, suitable for the `-l` flag.
pub library_links: Vec<String>,
/// Linker arguments suitable to be passed to `-C link-arg=<args>`
pub linker_args: Vec<String>,
/// Various `--cfg` flags to pass to the compiler.
pub cfgs: Vec<String>,
/// Additional environment variables to run the compiler with.
Expand Down Expand Up @@ -437,6 +439,7 @@ impl BuildOutput {
) -> CargoResult<BuildOutput> {
let mut library_paths = Vec::new();
let mut library_links = Vec::new();
let mut linker_args = Vec::new();
let mut cfgs = Vec::new();
let mut env = Vec::new();
let mut metadata = Vec::new();
Expand Down Expand Up @@ -484,6 +487,7 @@ impl BuildOutput {
}
"rustc-link-lib" => library_links.push(value.to_string()),
"rustc-link-search" => library_paths.push(PathBuf::from(value)),
"rustc-cdylib-link-arg" => linker_args.push(value.to_string()),
"rustc-cfg" => cfgs.push(value.to_string()),
"rustc-env" => env.push(BuildOutput::parse_rustc_env(&value, &whence)?),
"warning" => warnings.push(value.to_string()),
Expand All @@ -496,6 +500,7 @@ impl BuildOutput {
Ok(BuildOutput {
library_paths,
library_links,
linker_args,
cfgs,
env,
metadata,
Expand Down
9 changes: 9 additions & 0 deletions src/cargo/core/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ fn rustc<'a, 'cfg>(
// If we are a binary and the package also contains a library, then we
// don't pass the `-l` flags.
let pass_l_flag = unit.target.is_lib() || !unit.pkg.targets().iter().any(|t| t.is_lib());
let pass_cdylib_link_args = unit.target.is_cdylib();
let do_rename = unit.target.allows_underscores() && !unit.mode.is_any_test();
let real_name = unit.target.name().to_string();
let crate_name = unit.target.crate_name();
Expand Down Expand Up @@ -257,6 +258,7 @@ fn rustc<'a, 'cfg>(
&build_state,
&build_deps,
pass_l_flag,
pass_cdylib_link_args,
current_id,
)?;
add_plugin_deps(&mut rustc, &build_state, &build_deps, &root_output)?;
Expand Down Expand Up @@ -346,6 +348,7 @@ fn rustc<'a, 'cfg>(
build_state: &BuildMap,
build_scripts: &BuildScripts,
pass_l_flag: bool,
pass_cdylib_link_args: bool,
current_id: PackageId,
) -> CargoResult<()> {
for key in build_scripts.to_link.iter() {
Expand All @@ -367,6 +370,12 @@ fn rustc<'a, 'cfg>(
rustc.arg("-l").arg(name);
}
}
if pass_cdylib_link_args {
for arg in output.linker_args.iter() {
let link_arg = format!("link-arg={}", arg);
rustc.arg("-C").arg(link_arg);
}
}
}
}
Ok(())
Expand Down
4 changes: 4 additions & 0 deletions src/doc/src/reference/build-scripts.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ cargo:rustc-link-lib=static=foo
cargo:rustc-link-search=native=/path/to/foo
cargo:rustc-cfg=foo
cargo:rustc-env=FOO=bar
cargo:rustc-cdylib-link-arg=-Wl,-soname,libfoo.so.1.2.3
# arbitrary user-defined metadata
cargo:root=/path/to/foo
cargo:libdir=/path/to/foo/lib
Expand Down Expand Up @@ -93,6 +94,9 @@ crate is built:
This is useful for embedding additional metadata in crate's code,
such as the hash of Git HEAD or the unique identifier of a continuous
integration server.
* `rustc-cdylib-link-arg=FLAG` is a flag passed to the compiler as
`-C link-arg=FLAG` when building a `cdylib`. Its usage is highly platform
specific. It is useful to set the shared library version or the runtime-path.
* `rerun-if-changed=PATH` is a path to a file or directory which indicates that
the build script should be re-run if it changes (detected by a more-recent
last-modified timestamp on the file). Normally build scripts are re-run if
Expand Down