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

Using msvc and crt-static #929

Closed
dtolnay opened this issue Sep 2, 2021 · 9 comments
Closed

Using msvc and crt-static #929

dtolnay opened this issue Sep 2, 2021 · 9 comments

Comments

@dtolnay
Copy link
Owner

dtolnay commented Sep 2, 2021

Moved from #927 (comment).

It looks like the target-features don't flow from the top crate down to the crates it consumes, at least not if it's scoped to the package's own .cargo/config.toml. If I only set this in my project's .cargo/config.toml, when it builds cxx, the flag is missing and it's not listed in the CARGO_CFG_TARGET_FEATURE output for cxx, but it is used in my project.

It turns out cc also has support for this already by default 😄, but because it's not flowing from the top-level package config.toml down to its dependencies and their dependencies, it doesn't kick in. It does work if you set the RUSTFLAGS environment variable before running cargo, and it works for user-wide ~/.cargo/config.toml as well, but this would let a consumer handle it automatically with feature flags in the Cargo.toml.

@dtolnay
Copy link
Owner Author

dtolnay commented Sep 2, 2021

If I only set this in my project's .cargo/config.toml, when it builds cxx, the flag is missing and it's not listed in the CARGO_CFG_TARGET_FEATURE output for cxx

@wravery this sounds wrong to me, it does not match what I understand about cargo config. Can you double check the behavior you observed on your end? Can you provide a more detailed reproducible description of what you are doing to observe that behavior?

Here is what I did to confirm that this is not the behavior I get. Add a dependency on https://docs.rs/crate/print-target-feature/0.1.0/source/build.rs which just prints out the value of CARGO_CFG_TARGET_FEATURE from its build.rs:

[package]
name = "repro"
version = "0.0.0"

[dependencies]
print-target-feature = "*"

Building repro without rust flags in .cargo/config.toml, for me it prints:

CARGO_CFG_TARGET_FEATURE="fxsr,sse,sse2"

Then adding .cargo/config.toml:

[target.x86_64-unknown-linux-gnu]
rustflags = ["-C", "target-feature=+crt-static"]

building repro now prints:

CARGO_CFG_TARGET_FEATURE="crt-static,fxsr,sse,sse2"

@dtolnay
Copy link
Owner Author

dtolnay commented Sep 2, 2021

Assuming we do find that .cargo/config.toml's crt-static setting is not observable to certain dependencies (in a way that does not apply to the print-target-feature crate), I still don't know why we would address this in a cxx-specific way, as opposed to in the cc crate (or in a Cargo fix?). From what you wrote in #927, you definitely want crt-static globally applied to all uses of cc in your dependency graph, not specifically to ones mediated by cxx. Your only use of cc today might be through cxx but I don't feel that this makes cxx the appropriate place to place a workaround.

@wravery
Copy link
Contributor

wravery commented Sep 2, 2021

OK, let me try to isolate a project structure that reproduces this behavior.

@wravery
Copy link
Contributor

wravery commented Sep 2, 2021

I was wrong about the cause, my .cargo/config.toml file tested for the feature, and the feature didn't exist in the dependencies so when they found and interpreted it locally, they didn't apply the rustflags. I switched my config.toml to check for cfg(target_env = "msvc") instead, and that shows -C target-feature=+crt-static getting appended to all of the dependencies as they are built.

However, it still isn't getting picked up by cxx specifically when it executes cxx_build::bridge in the build script. I am also using the cmake crate to build my dependencies in the same script just before I invoke cxx_build::bridge, and I noticed it seems to be directing cargo to change the cargo:root=... to its output directory, deep in the target. This may be a bug in cmake rather than cxx.

@wravery
Copy link
Contributor

wravery commented Sep 2, 2021

Actually, that's just setting metadata. I don't think it should change the behavior of cargo.

@wravery
Copy link
Contributor

wravery commented Sep 2, 2021

The verbose output I'm looking at seems to come from the link_cplusplus crate:

rustc --crate-name link_cplusplus --edition=2018 C:\Users\wrave\.cargo\registry\src\github.com-1ecc6299db9ec823\link-cplusplus-1.0.5\src\lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts --crate-type lib --emit=dep-info,metadata,link -C embed-bitcode=no -C debuginfo=2 --cfg "feature=\"default\"" -C metadata=dc6c59aa8605f6cb -C extra-filename=-dc6c59aa8605f6cb --out-dir C:\repos\wravery\gqlmapi-rs\target\debug\deps -L dependency=C:\repos\wravery\gqlmapi-rs\target\debug\deps --cap-lints warn -C target-feature=+crt-static -L native=C:\repos\wravery\gqlmapi-rs\target\debug\build\link-cplusplus-e9557bea2241d2b1\out -l static=link-cplusplus`
[cxx 1.0.54] TARGET = Some("x86_64-pc-windows-msvc")
[cxx 1.0.54] OPT_LEVEL = Some("0")
[cxx 1.0.54] HOST = Some("x86_64-pc-windows-msvc")
[cxx 1.0.54] CXX_x86_64-pc-windows-msvc = None
[cxx 1.0.54] CXX_x86_64_pc_windows_msvc = None
[cxx 1.0.54] HOST_CXX = None
[cxx 1.0.54] CXX = None
[cxx 1.0.54] CXXFLAGS_x86_64-pc-windows-msvc = None
[cxx 1.0.54] CXXFLAGS_x86_64_pc_windows_msvc = None
[cxx 1.0.54] HOST_CXXFLAGS = None
[cxx 1.0.54] CXXFLAGS = None
[cxx 1.0.54] CRATE_CC_NO_DEFAULTS = None
[cxx 1.0.54] CARGO_CFG_TARGET_FEATURE = Some("fxsr,sse,sse2")
[cxx 1.0.54] DEBUG = Some("true")
[cxx 1.0.54] CXX_x86_64-pc-windows-msvc = None
[cxx 1.0.54] CXX_x86_64_pc_windows_msvc = None
[cxx 1.0.54] HOST_CXX = None
[cxx 1.0.54] CXX = None
[cxx 1.0.54] CXXFLAGS_x86_64-pc-windows-msvc = None
[cxx 1.0.54] CXXFLAGS_x86_64_pc_windows_msvc = None
[cxx 1.0.54] HOST_CXXFLAGS = None
[cxx 1.0.54] CXXFLAGS = None
[cxx 1.0.54] CRATE_CC_NO_DEFAULTS = None
[cxx 1.0.54] CARGO_CFG_TARGET_FEATURE = Some("fxsr,sse,sse2")
[cxx 1.0.54] running: "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\VC\\Tools\\MSVC\\14.29.30133\\bin\\HostX64\\x64\\cl.exe" "-nologo" "-MD" "-Z7" "-Brepro" "-W4" "-FoC:\\repos\\wravery\\gqlmapi-rs\\target\\debug\\build\\cxx-f4ba972b791f1822\\out\\src/cxx.o" "-c" "src/cxx.cc"

It's passing -C target-feature=+crt-static to rustc, but by the time it actually invokes the compiler for cxx.cc, it's losing the feature in CARGO_CFG_TARGET_FEATURE and it invokes cl.exe with -MD which uses the dynamic CRT.

@dtolnay
Copy link
Owner Author

dtolnay commented Sep 2, 2021

Good catch — link-cplusplus is kind of sketchy and I would be prepared to believe that whatever it does doesn't do the right thing in the presence of crt-static. If you track down what is going on, I would accept a fix in the link-cplusplus crate (code or documentation).

@wravery
Copy link
Contributor

wravery commented Sep 2, 2021

Looks like the bug is in cargo itself, or both cc and I misunderstand CARGO_CFG_TARGET_FEATURE. I added some debug output to the build.rs file in link-cplusplus:

    println!("target_feature:crt-static: {:?}", cfg!(target_feature = "crt-static"));
    println!("env:CARGO_CFG_TARGET_FEATURE: {:?}", env::var("CARGO_CFG_TARGET_FEATURE"));

and here's the ouput:

target_feature:crt-static: true
env:CARGO_CFG_TARGET_FEATURE: Ok("fxsr,sse,sse2")

The cc crate relies on CARGO_CFG_TARGET_FEATURE. I'll try a fix there which uses cfg!(target_feature, "crt-static") instead.

@wravery
Copy link
Contributor

wravery commented Sep 2, 2021

That's from a standalone build of link-cplusplus, BTW, with a .cargo/config.toml file in the project to simulate consuming it from a project that uses that to set rustflags.

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

No branches or pull requests

2 participants