Skip to content

Commit

Permalink
Auto merge of #6298 - lu-zero:rustc-link-args, r=alexcrichton
Browse files Browse the repository at this point in the history
Add cargo:rustc-link-arg to pass custom linker arguments

It is useful to produce correct `cdylibs` on platforms such as Linux and
MacOS.

Groundwork to address #5045 in the future.
  • Loading branch information
bors committed Mar 27, 2019
2 parents a57b96d + f608ed6 commit 5f3f281
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 0 deletions.
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 @@ -438,6 +440,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 @@ -485,6 +488,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 @@ -497,6 +501,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

0 comments on commit 5f3f281

Please sign in to comment.