-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
under latest MinGW, cannot link with C code using stdout #47048
Comments
Mingw-w64 seen some huge changes lately, if recompiling Rust with latest mingw-w64 doesn't work or still gives errors like that then it's probably a regression they introduced. |
Got anyone else arriving here across the web w/ new MinGW breaks, in addition to:
You might also need to downgrade winpthreads (granted your version numbers may be different):
Had to do both at once due to codeps. I ran into this Rust+MinGW issue when statically building latest Tor and deps w/ latest MinGW. |
The old packages are also available at http://repo.msys2.org/mingw/x86_64/, where you can download the latest versions of the packages in question that include |
Reached here by googling. @cretz thanks for the tip, it works |
Should be fixed with |
I upgraded to version 6.0.0.5114 and reproduced the issue. Downgrading to 5.0.0.5002 still works. (Keep in mind that if the library is built using 5.0.0.5002, linking will work using 6.0.0.*.) |
Similar issue was fixed recently https://github.com/Alexpux/MINGW-packages/issues/3469. Maybe rust internals have to be recompiled. |
Still happens for with |
Yeah, I just forgot that Rust is using |
The build instructions for for windows-gnu specifically suggest using MSYS2 :( . Could you please elaborate a bit about that |
Bundling
|
I looked around the link, and it seems that master already has |
I built current Rust master using MSYS2, as described in README, and now I am able to build |
What MSYS2 exactly? It may make sense to bump the version used by Rust from 6.3.0 to something up-to-date though. |
Some reasonably stable reasonably recent version :) I know this is self-contradictory.
I totally see the point, the issue is the build environment is not very well documented. Updating README with proper setup instructions for Windows GNU will help a lot. |
Using |
This build script can work around the issue. It is a bit hacky; basically it tests for the bug using this issue's test case, and if it detects the bug it creates and links libworkaround_47048.a which contains the use std::env;
use std::fs::{self, File};
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::Command;
fn main() {
let target = env::var_os("TARGET")
.expect("TARGET")
.into_string()
.expect("TARGET");
if target.contains("-windows-gnu") {
mingw_check_47048();
}
}
fn mingw_check_47048() {
let rustc = env::var_os("RUSTC").expect("RUSTC");
let out_dir = PathBuf::from(env::var_os("OUT_DIR").expect("OUT_DIR"));
let try_dir = out_dir.join("try_47048");
let mut cmd;
fs::create_dir_all(&try_dir).expect("create directory");
create_file(&try_dir.join("say_hi.c"), SAY_HI_C);
create_file(&try_dir.join("c_main.c"), C_MAIN_C);
create_file(&try_dir.join("r_main.rs"), R_MAIN_RS);
create_file(&try_dir.join("workaround.c"), WORKAROUND_C);
cmd = Command::new("gcc");
cmd.current_dir(&try_dir).args(&["-fPIC", "-c", "say_hi.c"]);
execute(cmd);
cmd = Command::new("ar");
cmd.current_dir(&try_dir)
.args(&["cr", "libsay_hi.a", "say_hi.o"]);
execute(cmd);
cmd = Command::new("gcc");
cmd.current_dir(&try_dir)
.args(&["c_main.c", "-L.", "-lsay_hi", "-o", "c_main.exe"]);
execute(cmd);
// try simple rustc command that should work, so that failure
// really is the bug being checked for
cmd = Command::new(&rustc);
cmd.arg("--version");
execute(cmd);
cmd = Command::new(&rustc);
cmd.current_dir(&try_dir)
.args(&["r_main.rs", "-L.", "-lsay_hi", "-o", "r_main.exe"]);
let status = cmd
.status()
.unwrap_or_else(|_| panic!("Unable to execute: {:?}", cmd));
let need_workaround = !status.success();
// build and test libworkaround_47048.a
if need_workaround {
cmd = Command::new("gcc");
cmd.current_dir(&try_dir).args(&["-fPIC", "-O2", "-c", "workaround.c"]);
execute(cmd);
cmd = Command::new("ar");
cmd.current_dir(&try_dir)
.args(&["cr", "libworkaround_47048.a", "workaround.o"]);
execute(cmd);
cmd = Command::new(&rustc);
cmd.current_dir(&try_dir).args(&[
"r_main.rs",
"-L.",
"-lsay_hi",
"-lworkaround_47048",
"-o",
"r_main.exe",
]);
execute(cmd);
let src = try_dir.join("libworkaround_47048.a");
let lib_dir = out_dir.join("lib");
fs::create_dir_all(&lib_dir).expect("create directory");
let dst = lib_dir.join("libworkaround_47048.a");
fs::rename(src, dst).expect("move file");
let lib_dir_str = lib_dir.to_str().expect("unsupported characters");
println!("cargo:rustc-link-search=native={}", lib_dir_str);
println!("cargo:rustc-link-lib=static=workaround_47048");
}
fs::remove_dir_all(try_dir).expect("remove directory");
}
fn create_file(filename: &Path, contents: &str) {
let mut file = File::create(filename)
.unwrap_or_else(|_| panic!("Unable to create file: {:?}", filename));
file.write_all(contents.as_bytes())
.unwrap_or_else(|_| panic!("Unable to write to file: {:?}", filename));
}
fn execute(mut command: Command) {
let status = command
.status()
.unwrap_or_else(|_| panic!("Unable to execute: {:?}", command));
if !status.success() {
if let Some(code) = status.code() {
panic!("Program failed with code {}: {:?}", code, command);
} else {
panic!("Program failed: {:?}", command);
}
}
}
const SAY_HI_C: &'static str = r#"/* say_hi.c */
#include <stdio.h>
void say_hi(void) {
fprintf(stdout, "hi!\n");
}
"#;
const C_MAIN_C: &'static str = r#"/* c_main.c */
void say_hi(void);
int main(void) {
say_hi();
return 0;
}
"#;
const R_MAIN_RS: &'static str = r#"// r_main.rs
extern "C" {
fn say_hi();
}
fn main() {
unsafe {
say_hi();
}
}
"#;
const WORKAROUND_C: &'static str = r#"/* workaround.c */
#define _CRTBLD
#include <stdio.h>
FILE *__cdecl __acrt_iob_func(unsigned index)
{
return &(__iob_func()[index]);
}
typedef FILE *__cdecl (*_f__acrt_iob_func)(unsigned index);
_f__acrt_iob_func __MINGW_IMP_SYMBOL(__acrt_iob_func) = __acrt_iob_func;
"#; |
Recent mingw-w64 GCC 8.1.0 build contains |
windows-gnu: prefer system crt libraries if they are available This is my proposal (based on `Amanieu`'s idea) on how to fix #47048 and related issues. The origin of the issue is the fact Rust ships mingw-w64 libraries but no headers and prefers own libraries over the system ones. This leads to situation when headers aren't compatible with libraries (mingw-w64 doesn't provide any forward compatibility and AFAIK backwards compatibility is guaranteed only within major release series). It's easier to understand how this PR works when looking at the linker invocation before and with this PR: https://www.diffchecker.com/GEuYFmzo It adds system libraries path before Rust libraries so the linker will prefer them. It has potential issue when system has files with the same names as Rust but that could be avoided by moving Rust shipped mingw-w64 libraries from `lib/rustlib/x86_64-pc-windows-gnu/lib` to say `lib/rustlib/x86_64-pc-windows-gnu/lib/mingw`. Then adding linker paths in this order: Rust libraries, system libraries, Rust shipped mingw-w64 libraries. I don't know if it's worth to cache system libraries path. You can look for `cache: ` string during build Rust: https://pastebin.com/kGEQZGWP I think there are enough calls to justify caching. Fixes #47048 Fixes #49078 Fixes #53454 Fixes #60912
The Travis default of windows-gnu suffers from rust-lang/rust#47048, I think. I don't see an easy way to address this right now, but switching our Windows builds to windows-msvc will avoid this and is more realistic target anyway.
The Travis default of windows-gnu suffers from rust-lang/rust#47048, I think. I don't see an easy way to address this right now, but switching our Windows builds to windows-msvc will avoid this and is more realistic target anyway.
The Travis default of windows-gnu suffers from rust-lang/rust#47048, I think. I don't see an easy way to address this right now, but switching our Windows builds to windows-msvc will avoid this and is more realistic target anyway.
The Travis default of windows-gnu suffers from rust-lang/rust#47048, I think. I don't see an easy way to address this right now, but switching our Windows builds to windows-msvc will avoid this and is more realistic target anyway.
The Travis default of windows-gnu suffers from rust-lang/rust#47048, I think. I don't see an easy way to address this right now, but switching our Windows builds to windows-msvc will avoid this and is more realistic target anyway.
The Travis default of windows-gnu suffers from rust-lang/rust#47048, I think. I don't see an easy way to address this right now, but switching our Windows builds to windows-msvc will avoid this and is more realistic target anyway.
The Travis default of windows-gnu suffers from rust-lang/rust#47048, I think. I don't see an easy way to address this right now, but switching our Windows builds to windows-msvc will avoid this and is more realistic target anyway.
The Travis default of windows-gnu suffers from rust-lang/rust#47048, I think. I don't see an easy way to address this right now, but switching our Windows builds to windows-msvc will avoid this and is more realistic target anyway.
The Travis default of windows-gnu suffers from rust-lang/rust#47048, I think. I don't see an easy way to address this right now, but switching our Windows builds to windows-msvc will avoid this and is more realistic target anyway.
The Travis default of windows-gnu suffers from rust-lang/rust#47048, I think. I don't see an easy way to address this right now, but switching our Windows builds to windows-msvc will avoid this and is more realistic target anyway.
The Travis default of windows-gnu suffers from rust-lang/rust#47048, I think. I don't see an easy way to address this right now, but switching our Windows builds to windows-msvc will avoid this and is more realistic target anyway.
The Travis default of windows-gnu suffers from rust-lang/rust#47048, I think. I don't see an easy way to address this right now, but switching our Windows builds to windows-msvc will avoid this and is more realistic target anyway.
I solved this issue by running pacman -U https://archive.org/download/archlinux_pkg_mingw-w64-crt/mingw-w64-crt-5.0.0-1-any.pkg.tar.xz https://archive.org/download/archlinux_pkg_mingw-w64-headers/mingw-w64-headers-5.0.0-1-any.pkg.tar.xz https://archive.org/download/archlinux_pkg_mingw-w64-winpthreads/mingw-w64-winpthreads-5.0.0-1-any.pkg.tar.xz to downgrade those 3 packages on archlinux. |
All the referenced issues have been closed: rust-lang/rust#47048 rust-lang/rust#53454 rust-lang/cargo#6754 Since we can (and should) use 'stable' on these targets too, we don't need the TOOLCHAIN logic any longer, so remove it.
All the referenced issues [1] have been Closed, so use "stable" for everything. Now `i686-w64-mingw32-gcc` fails with this instead error: linker `i686-w64-mingw32-gcc` not found so keep it disabled. There is probably a simple solution for this that is obvious to someone used to cross-compiling Rust programs on Windows... [1] rust-lang/rust#47048 rust-lang/rust#53454 rust-lang/cargo#6754
All the referenced issues [1] have been Closed, so use "stable" for everything. Now `i686-w64-mingw32-gcc` fails with this instead error: linker `i686-w64-mingw32-gcc` not found so keep it disabled. There is probably a simple solution for this that is obvious to someone used to cross-compiling Rust programs on Windows... [1] rust-lang/rust#47048 rust-lang/rust#53454 rust-lang/cargo#6754
I was running into this same issue on rust 1.54 while attempting to build @tspiteri's gmp-mpfr-sys crate. I was able to build within the windows-latest Github actions environment on 2021-8-3 thanks to this comment. The build was failing again when I cut the next release on 2021-8-31. I resolved it by adjusting the command to:
This raises two questions:
|
This is the first report I see since this issue was closed. There should be no change required as long as the compiler is available in |
I'm having an issue under MinGW and I'm not sure if it's a MinGW issue or a rustc issue. On the one hand the bug crops up after an update to two MinGW packages, but on the other hand I cannot reproduce with only C, and I don't know if rustc is using MinGW in some undocumented unsupported way.
say_hi.c:
c_main.c
r_main.rs:
Under the latest MinGW, specifically with packages
mingw-w64-x86_64-crt-git-6.0.0.5066.61efe559-1
andmingw-w64-x86_64-headers-git-6.0.0.5066.61efe559-1
,using only gcc like this works:
But it doesn't work with rustc:
If I downgrade those two packages to
mingw-w64-x86_64-crt-git-5.0.0.5002.34a7c1c0-1
andmingw-w64-x86_64-headers-git-5.0.0.5002.34a7c1c0-1
,it works with rustc too:
One last thing, if I compile the library using the old packages, and then upgrade the packages, both
gcc c_main.c ...
andrustc r_main.rs ...
work. If I compile the library using the new packages, and then downgrade the packages, bothgcc c_main.c ...
andrustc r_main.rs ...
fail.The text was updated successfully, but these errors were encountered: