Skip to content

Commit 5f3f281

Browse files
committed
Auto merge of #6298 - lu-zero:rustc-link-args, r=alexcrichton
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.
2 parents a57b96d + f608ed6 commit 5f3f281

File tree

4 files changed

+25
-0
lines changed

4 files changed

+25
-0
lines changed

src/cargo/core/compiler/build_context/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ impl TargetConfig {
223223
let mut output = BuildOutput {
224224
library_paths: Vec::new(),
225225
library_links: Vec::new(),
226+
linker_args: Vec::new(),
226227
cfgs: Vec::new(),
227228
env: Vec::new(),
228229
metadata: Vec::new(),
@@ -258,6 +259,12 @@ impl TargetConfig {
258259
.library_paths
259260
.extend(list.iter().map(|v| PathBuf::from(&v.0)));
260261
}
262+
"rustc-cdylib-link-arg" => {
263+
let args = value.list(k)?;
264+
output
265+
.linker_args
266+
.extend(args.iter().map(|v| v.0.clone()));
267+
}
261268
"rustc-cfg" => {
262269
let list = value.list(k)?;
263270
output.cfgs.extend(list.iter().map(|v| v.0.clone()));

src/cargo/core/compiler/custom_build.rs

+5
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ pub struct BuildOutput {
2121
pub library_paths: Vec<PathBuf>,
2222
/// Names and link kinds of libraries, suitable for the `-l` flag.
2323
pub library_links: Vec<String>,
24+
/// Linker arguments suitable to be passed to `-C link-arg=<args>`
25+
pub linker_args: Vec<String>,
2426
/// Various `--cfg` flags to pass to the compiler.
2527
pub cfgs: Vec<String>,
2628
/// Additional environment variables to run the compiler with.
@@ -438,6 +440,7 @@ impl BuildOutput {
438440
) -> CargoResult<BuildOutput> {
439441
let mut library_paths = Vec::new();
440442
let mut library_links = Vec::new();
443+
let mut linker_args = Vec::new();
441444
let mut cfgs = Vec::new();
442445
let mut env = Vec::new();
443446
let mut metadata = Vec::new();
@@ -485,6 +488,7 @@ impl BuildOutput {
485488
}
486489
"rustc-link-lib" => library_links.push(value.to_string()),
487490
"rustc-link-search" => library_paths.push(PathBuf::from(value)),
491+
"rustc-cdylib-link-arg" => linker_args.push(value.to_string()),
488492
"rustc-cfg" => cfgs.push(value.to_string()),
489493
"rustc-env" => env.push(BuildOutput::parse_rustc_env(&value, &whence)?),
490494
"warning" => warnings.push(value.to_string()),
@@ -497,6 +501,7 @@ impl BuildOutput {
497501
Ok(BuildOutput {
498502
library_paths,
499503
library_links,
504+
linker_args,
500505
cfgs,
501506
env,
502507
metadata,

src/cargo/core/compiler/mod.rs

+9
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ fn rustc<'a, 'cfg>(
211211
// If we are a binary and the package also contains a library, then we
212212
// don't pass the `-l` flags.
213213
let pass_l_flag = unit.target.is_lib() || !unit.pkg.targets().iter().any(|t| t.is_lib());
214+
let pass_cdylib_link_args = unit.target.is_cdylib();
214215
let do_rename = unit.target.allows_underscores() && !unit.mode.is_any_test();
215216
let real_name = unit.target.name().to_string();
216217
let crate_name = unit.target.crate_name();
@@ -257,6 +258,7 @@ fn rustc<'a, 'cfg>(
257258
&build_state,
258259
&build_deps,
259260
pass_l_flag,
261+
pass_cdylib_link_args,
260262
current_id,
261263
)?;
262264
add_plugin_deps(&mut rustc, &build_state, &build_deps, &root_output)?;
@@ -346,6 +348,7 @@ fn rustc<'a, 'cfg>(
346348
build_state: &BuildMap,
347349
build_scripts: &BuildScripts,
348350
pass_l_flag: bool,
351+
pass_cdylib_link_args: bool,
349352
current_id: PackageId,
350353
) -> CargoResult<()> {
351354
for key in build_scripts.to_link.iter() {
@@ -367,6 +370,12 @@ fn rustc<'a, 'cfg>(
367370
rustc.arg("-l").arg(name);
368371
}
369372
}
373+
if pass_cdylib_link_args {
374+
for arg in output.linker_args.iter() {
375+
let link_arg = format!("link-arg={}", arg);
376+
rustc.arg("-C").arg(link_arg);
377+
}
378+
}
370379
}
371380
}
372381
Ok(())

src/doc/src/reference/build-scripts.md

+4
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ cargo:rustc-link-lib=static=foo
6262
cargo:rustc-link-search=native=/path/to/foo
6363
cargo:rustc-cfg=foo
6464
cargo:rustc-env=FOO=bar
65+
cargo:rustc-cdylib-link-arg=-Wl,-soname,libfoo.so.1.2.3
6566
# arbitrary user-defined metadata
6667
cargo:root=/path/to/foo
6768
cargo:libdir=/path/to/foo/lib
@@ -93,6 +94,9 @@ crate is built:
9394
This is useful for embedding additional metadata in crate's code,
9495
such as the hash of Git HEAD or the unique identifier of a continuous
9596
integration server.
97+
* `rustc-cdylib-link-arg=FLAG` is a flag passed to the compiler as
98+
`-C link-arg=FLAG` when building a `cdylib`. Its usage is highly platform
99+
specific. It is useful to set the shared library version or the runtime-path.
96100
* `rerun-if-changed=PATH` is a path to a file or directory which indicates that
97101
the build script should be re-run if it changes (detected by a more-recent
98102
last-modified timestamp on the file). Normally build scripts are re-run if

0 commit comments

Comments
 (0)