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

Setting rustflags does not work with --target #9743

Closed
nmattia opened this issue Jul 29, 2021 · 12 comments
Closed

Setting rustflags does not work with --target #9743

nmattia opened this issue Jul 29, 2021 · 12 comments
Labels
C-bug Category: bug

Comments

@nmattia
Copy link
Contributor

nmattia commented Jul 29, 2021

Problem

It looks like cargo ignores the rustflags set by environment variables (RUSTFLAGS and CARGO_TARGET_X86_64_APPLE_DARWIN_RUSTFLAGS and CARGO_BUILD_RUSTFLAGS) when given --target. For instance, in a build linked against -liconv, cargo build succeeds when given the proper linker arguments, whereas cargo build --target <my actual target> doesn't:

$ printenv CARGO_TARGET_X86_64_APPLE_DARWIN_RUSTFLAGS
-C link-arg=-L/path/to/iconv/lib
$ cargo build
    Finished dev [unoptimized + debuginfo] target(s) in 0.08s
$ cargo build --target x86_64-apple-darwin
   Compiling unicode-xid v0.2.1
   Compiling proc-macro2 v1.0.26
   Compiling syn v1.0.69
   Compiling autocfg v1.0.1
   Compiling serde v1.0.125
   Compiling serde_derive v1.0.125
   Compiling typenum v1.13.0
   Compiling version_check v0.9.3
   Compiling memchr v2.3.4
error: linking with `cc` failed: exit status: 1
  |
  = note: "cc" "-m64" "-arch" "x86_64" <thousands of args that do NOT include -L/path/to/iconv/lib> "-lSystem" "-lresolv" "-lc" "-lm" "-liconv"
  = note: ld: library not found for -liconv
          clang-7: error: linker command failed with exit code 1 (use -v to see invocation)

If this is the expected behavior, how do I set the linker flags?

Notes

From the Compilation Options page, I understand that this "makes Cargo run in a different mode where the target artifacts are placed in a separate directory". However, as I understand it, this should only impact where the target artifacts are placed, not how the configuration is read.

Output of cargo version:

$ cargo version
cargo 1.53.0 (4369396ce 2021-04-27)
@nmattia nmattia added the C-bug Category: bug label Jul 29, 2021
@ehuss
Copy link
Contributor

ehuss commented Jul 29, 2021

Thanks for the report! Can you provide some more information, such as the project, or a minimal reproduction? Can you run with the -v flag to print which commands are being run?

Just FYI, there are various ways flags will be ignored. When passing --target, the rustflags are ignored for build scripts and proc macros.

@nmattia
Copy link
Contributor Author

nmattia commented Jul 30, 2021

Sure, and thanks for the quick reply!

I can trigger this by adding a dependency on serde, for instance:


Cargo.toml:

[package]
name = "foo"
version = "0.1.0"
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
serde = "1"

Cargo.lock:

# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3

[[package]]
name = "foo"
version = "0.1.0"
dependencies = [
 "serde",
]

[[package]]
name = "serde"
version = "1.0.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03"

src/main.rs:

fn main() {
    println!("Hello, world!");
}

Running cargo build succeeds, but cargo build --target x86_64-apple-darwin fails with the error above.

@nmattia
Copy link
Contributor Author

nmattia commented Jul 30, 2021

I'm actually a little confused. I can't find a single mention of iconv in the serde codebase. Do you have any idea why it gets linked in?


EDIT: maybe it comes from libc?

@nmattia
Copy link
Contributor Author

nmattia commented Jul 30, 2021

Note: not only cargo doesn't add a -L/path/to/lib flag, but it looks like it overwrites DYLD_FALLBACK_LIBRARY_PATH. When running with -v, I see that it unsets DYLD_FALLBACK_LIBRARY_PATH and replaces it with an (apparently) cargo-crafted one that does not include the original value of DYLD_FALLBACK_LIBRARY_PATH.

@ehuss
Copy link
Contributor

ehuss commented Jul 30, 2021

Ah, yea, iconv is required for all apple targets due to libc. macOS should include a global copy in /usr/lib/libiconv.dylib, do you not have that?

Cargo should only extend DYLD_FALLBACK_LIBRARY_PATH if it is already set, it should preserve any paths passed in. That shouldn't be relevant for linking, though. How are you calling it? What is the value of DYLD_FALLBACK_LIBRARY_PATH and why are you overriding the default?

@nmattia
Copy link
Contributor Author

nmattia commented Aug 3, 2021

No, I don't have that it seems:

$ ls /usr/lib/libiconv.dylib
ls: /usr/lib/libiconv.dylib: No such file or directory

I worked around the problem by setting CFLAGS. I'm fairly new to macOS and assumed DYLD_FALLBACK_LIBRARY_PATH worked like a mix between LIBRARY_PATH and LD_LIBRARY_PATH, but obviously I'm wrong :)

How can I tell cargo (as opposed to telling the linker directly with CFLAGS) where to look for libiconv.dylib, if it's not in /usr/lib?

@ehuss
Copy link
Contributor

ehuss commented Aug 4, 2021

I'm a little curious, do you happen to know why libiconv is missing? Which version of macOS are you using, and which platform (is it an m1/arm mac)?

@nmattia
Copy link
Contributor Author

nmattia commented Aug 5, 2021

Sure! It's a Big Sur, Intel Mac. Is libiconv expected to be shipped with macOS? Or does that get installed by Xcode? I don't have Xcode.

Screenshot 2021-08-05 at 10 14 35

@ehuss
Copy link
Contributor

ehuss commented Aug 5, 2021

Yea, I looked it up, and in macOS 11, they switched to having a hidden cache of shared libraries (62986286).

Another thing that looks fishy is that your error message says clang-7. Do you maybe have the wrong cc in your PATH? Normal cc from Apple should just say clang: and the cc version should be at least 12.

@nmattia
Copy link
Contributor Author

nmattia commented Aug 6, 2021

Ok as mentioned I did not install the Xcode suite. I have a custom clang build, that's probably why it displays clang-7.

Is cargo expecting clang to install libiconv in /usr/lib?

By the way, thanks a lot for taking the time here!

@ehuss
Copy link
Contributor

ehuss commented Aug 6, 2021

Cargo doesn't deal with linking; rustc controls that process. It assumes that -liconv can be found somewhere in the default linker paths.

@ehuss
Copy link
Contributor

ehuss commented Sep 11, 2021

I'm going to close, at it sounds like the issue here is using a custom clang that does not know about the hidden library cache in macOS 11. You'll probably need to provide iconv somehow in the search page so that it can be found, or use the xcode clang.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: bug
Projects
None yet
Development

No branches or pull requests

2 participants