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

pkgsCross.mingw32.stdenv.cc provides slightly incomplete linking environment: cannot find -lmcfgthread #156343

Open
trofi opened this issue Jan 23, 2022 · 8 comments
Labels
0.kind: bug 6.topic: cross-compilation Building packages on a different sort platform than than they will be run on

Comments

@trofi
Copy link
Contributor

trofi commented Jan 23, 2022

I was trying to install a few cross-compilers to be available in parallel in a single environment as ${target}-gcc. Looks like mingw one are slightly broken currently. Here is a minimal reproducer:

// $ cat a.c
int main(){}

Porblematic attempt mingw32:

$ nix build -f ~/nm pkgsCross.mingw32.stdenv.cc
$ ./result/bin/i686-w64-mingw32-gcc a.c -o a
/nix/store/wlcxwq9ll6jprhjfn5iwv6mk5ip9g8d1-i686-w64-mingw32-binutils-2.35.2/bin/i686-w64-mingw32-ld: cannot find -lmcfgthread
collect2: error: ld returned 1 exit status

Working gnu32 attempt:

$ nix build -f ~/nm pkgsCross.gnu32.stdenv.cc
$ ./result/bin/i686-unknown-linux-gnu-gcc a.c -o a

Expected behavior

I expect both cases of compiler to be able to link minimal int main(){} example without extra environment settings.

Metadata

$ nix-shell -p nix-info --run "nix-info -m"
 - system: `"x86_64-linux"`
 - host os: `Linux 5.16.0, NixOS, 22.05 (Quokka)`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.6.0pre20211217_6e6e998`
 - channels(root): `"nixos"`
 - nixpkgs: `/nix/var/nix/profiles/per-user/root/channels/nixos`
@trofi
Copy link
Contributor Author

trofi commented Jan 23, 2022

The following workaround seems to be enough to get working cc:

pkgsCross.mingw32.stdenv.cc.override ({
  extraBuildCommands = ''printf '%s' '-L${pkgsCross.mingw32.windows.mcfgthreads}/lib' >> $out/nix-support/cc-ldflags'';
})

@Mindavi Mindavi added the 6.topic: cross-compilation Building packages on a different sort platform than than they will be run on label Jan 23, 2022
@skvadrik
Copy link

A slightly fixed workaround by @trofi that also patches include flags (fixed system-wide Mingw):

pkgsCross.mingw32.stdenv.cc.override ({
    extraBuildCommands = ''
        printf '%s' '-L${pkgsCross.mingw32.windows.mcfgthreads}/lib' >> $out/nix-support/cc-ldflags
        printf '%s' '-I${pkgsCross.mingw32.windows.mcfgthreads.dev}/include' >> $out/nix-support/cc-cflags
    '';
})

@yihuang
Copy link
Contributor

yihuang commented May 26, 2022

I have the same issue when trying to cross-build golang applications, how do you think we should patch the nixpkgs? it seems not easy to override gcc locally.

@alexshpilkin
Copy link
Member

alexshpilkin commented Jun 17, 2022

Note that this does not happen if you use the compiler (ostensibly the same one) from a stdenv derivation:

$ nix build --impure --expr '
let pkgs = (builtins.getFlake "nixpkgs").legacyPackages.${builtins.currentSystem};
in pkgs.pkgsCross.mingw32.stdenv.mkDerivation {
name = "a"; src = ./.;
buildPhase = "$CC -o a a.c";
installPhase = "cp a.exe $out";
}'
$ file -L result
result: PE32 executable (console) Intel 80386, for MS Windows

or via a development shell (damn these commands are unpleasant):

$ nix develop --impure --expr '
let pkgs = (builtins.getFlake "nixpkgs").legacyPackages.${builtins.currentSystem};
in pkgs.mkShell.override { stdenv = pkgs.pkgsCross.mingw32.stdenv; } { }'
$ $CC -o a a.c
$ file a.exe
a.exe: PE32 executable (console) Intel 80386, for MS Windows
$ which $CC
/nix/store/pl1qhrxnf33s0my900pnnpbp08xhfdyz-i686-w64-mingw32-stage-final-gcc-debug-wrapper-10.3.0/bin/i686-w64-mingw32-gcc
$ ^D

even though that same (wrapped) compiler outside such a shell is nonfunctional:

$ /nix/store/pl1qhrxnf33s0my900pnnpbp08xhfdyz-i686-w64-mingw32-stage-final-gcc-debug-wrapper-10.3.0/bin/i686-w64-mingw32-gcc -o a a.c
/nix/store/mv3bssklr1g1zwby7bkr62njdh70413s-i686-w64-mingw32-binutils-2.38/bin/i686-w64-mingw32-ld: cannot find -lmcfgthread: No such file or directory
collect2: error: ld returned 1 exit status

Are cross compilers even supposed to be usable that way?

@trofi
Copy link
Contributor Author

trofi commented Jun 17, 2022

Why not? There might be no other alternative if one wants 5 cross-compilers simultaneously in a single derivation (or more realistically two: 32-bit and 64-bit mingw at the same time).

I personally like to install native compiler and a bunch of cross-compilers system-wide so my ./configure --build=... --host=... && make just works without nix shells on simple projects. I install native compiler as gcc_latest. I'd say pkgsCross.mingw32.stdenv.cc should do exactly the same thing.

@milahu
Copy link
Contributor

milahu commented Oct 16, 2022

printf '%s' '-L${pkgsCross.mingw32.windows.mcfgthreads}/lib' >> $out/nix-support/cc-ldflags

should add whitespace → printf '%s\n' or printf '%s ' or echo

@nixos-discourse
Copy link

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/statically-linked-mingw-binaries/38395/1

@W1M0R
Copy link

W1M0R commented Jun 3, 2024

This comment of mine should probably belong to this issue instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
0.kind: bug 6.topic: cross-compilation Building packages on a different sort platform than than they will be run on
Projects
None yet
Development

No branches or pull requests

8 participants