NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
18.08k stars 14.13k forks source link

avr-gcc crashes because of -iframework option on macos #248206

Closed peacememories closed 1 year ago

peacememories commented 1 year ago

Describe the bug

I am trying to set up an AVR build toolchain. After reading this comment I tried to create a shell using

nix-shell -p pkgs.pkgsCross.avr.buildPackages.gcc

but the resulting avr-gcc command fails with

[nix-shell:~]$ avr-gcc
avr-gcc: error: unrecognized command-line option ‘-iframework’
avr-gcc: error: unrecognized command-line option ‘-iframework’
avr-gcc: error: unrecognized command-line option ‘-iframework’
avr-gcc: error: unrecognized command-line option ‘-iframework’
avr-gcc: error: unrecognized command-line option ‘-iframework’
avr-gcc: error: unrecognized command-line option ‘-iframework’
avr-gcc: error: unrecognized command-line option ‘-iframework’

Steps To Reproduce

Steps to reproduce the behavior:

  1. Install nix with nixpkgs channel 23.05-darwin or unstable
  2. Create a shell containing pkgs.pkgsCross.avr.buildPackages.gcc
  3. Try to run avr-gcc

Expected behavior

The command should still crash, but with "no input files" as an error. The raw command avr-gcc-12.2.0 does this, but trying to build with this results in an error similar to https://github.com/NixOS/nixpkgs/issues/48205, which I assume would be fixed by the wrapper (since the solution in the issue was also to add a wrapper).

Additional context

I found some similar issues by doing a Github search

It seems that this is a common problem with a Darwin shim interfering with cross compiler toolchains that don't need the shim since they don't use the host gcc? I found this solution in the derivation for simavr

Notify maintainers

@Synthetica9 @vcunat @Ericson2314

Metadata

[user@system:~]$ nix-shell -p nix-info --run "nix-info -m"
 - system: `"aarch64-darwin"`
 - host os: `Darwin 22.4.0, macOS 13.3`
 - multi-user?: `yes`
 - sandbox: `no`
 - version: `nix-env (Nix) 2.13.5`
 - channels(root): `"nixpkgs-23.05-darwin"`
 - nixpkgs: `/nix/var/nix/profiles/per-user/root/channels/nixpkgs`
peacememories commented 1 year ago

For additional context, I ran into this while trying to create an arduino rust project. I am using the following shell.nix:

{pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
  nativeBuildInputs = with pkgs; [
    rustup
    pkgsCross.avr.buildPackages.gcc
  ];
}
Artturin commented 1 year ago

https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/tools/simavr/setup-hook-darwin.sh

Because it’s getting called from a Darwin stdenv, avr-gcc will pick up on Darwin-specific flags, and it will barf and die on -iframework in particular. Strip them out, so simavr can compile its test firmware.

flag possibly coming from https://github.com/NixOS/nixpkgs/blob/191539342a8ea9c3dba5b66972b3907abd099d28/pkgs/build-support/cc-wrapper/setup-hook.sh#L75-L77

maybe should be behind a stdenv.targetPlatform.isDarwin

Artturin commented 1 year ago

There's this comment https://github.com/NixOS/nixpkgs/blob/191539342a8ea9c3dba5b66972b3907abd099d28/pkgs/build-support/cc-wrapper/setup-hook.sh#L63C1-L65

# It's fine that any other cc-wrapper will redefine this. Bash functions close
# over no state, and there's no @-substitutions within, so any redefined
# function is guaranteed to be exactly the same.

so it would be more appropriate to put a filtering fix in https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/cc-wrapper/cc-wrapper.sh

like https://github.com/NixOS/nixpkgs/blob/fac6214d8417547b0e514746c43cde327fd3e55c/pkgs/build-support/wrapper-common/utils.bash#L151-L171

peacememories commented 1 year ago

I've tried digging into the problem a bit and found the following:

The wrapper itself is not the problem here, at least not directly. The avr-gcc wrapper reads the NIX_FLAGS_COMPILE environment variable, which is set when enting a nix-shell. Manually deleting all the -iframework arguments from this variable (which is just the same framework path repeated, probably a result of some layering) makes the build work.

Now I assume these -iframework arguments are important when actually spawning a non-cross-compile shell. Would it somehow be possible to ignore them in the avr-gcc wrapper? Or is there perhaps a more elegant solution?

Artturin commented 1 year ago

For additional context, I ran into this while trying to create an arduino rust project. I am using the following shell.nix:

{pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
  nativeBuildInputs = with pkgs; [
    rustup
    pkgsCross.avr.buildPackages.gcc
  ];
}
{ pkgs ? (import <nixpkgs> {}).__splicedPackages }:
pkgs.pkgsCross.avr.mkShell {
  nativeBuildInputs = with pkgs; [
    rustup
  ];
}

try this, it's more correct

peacememories commented 1 year ago

For now I've added a modified version of https://github.com/NixOS/nixpkgs/blob/fa1d4611cc2ce41d7b93c4a8e8db0efaaf286475/pkgs/development/tools/simavr/setup-hook-darwin.sh#L2-L34 to my shell.nix, but I think this could be improved. Especially since it's entirely feasible that one might build for the host system as well as an avr-target from the same development shell, just removing the -iframework arguments does not seem wise.

peacememories commented 1 year ago

For additional context, I ran into this while trying to create an arduino rust project. I am using the following shell.nix:

{pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
  nativeBuildInputs = with pkgs; [
    rustup
    pkgsCross.avr.buildPackages.gcc
  ];
}
{ pkgs ? (import <nixpkgs> {}).__splicedPackages }:
pkgs.pkgsCross.avr.mkShell {
  nativeBuildInputs = with pkgs; [
    rustup
  ];
}

try this, it's more correct

Ah, thanks, I missed that answer.

If I may ask - what does the __splicedPackages contain? I'm not sure if this means the issue can be closed as everything's working as intended, or if we should change something here to create a "pit of success", steering people towards the right configuration. I'll leave that decision up to you if that is okay, since you have far more experience.

Artturin commented 1 year ago

splicedPackages contains spliced packages splicing adds the `splicedattribute set to the package mkDerivation then picks__spliced.buildHostfornativeBuildInputs` https://github.com/NixOS/nixpkgs/blob/86c83ab79d71084b4b107adf4c3838b7cbcc6446/pkgs/stdenv/generic/make-derivation.nix#L212

and __spliced.hostTarget for buildInputs https://github.com/NixOS/nixpkgs/blob/86c83ab79d71084b4b107adf4c3838b7cbcc6446/pkgs/stdenv/generic/make-derivation.nix#L212

danwdart commented 1 year ago

Came across this whilst trying to make a cross-platform shell.nix for multiple output architectures. Am I to import a different nixpkgs when compiling under darwin?

Artturin commented 1 year ago

IDK if we support a multiple output system builds. There are all kinds of hooks that need to be run for build host target

Artturin commented 1 year ago

Create a new issue if there has not already been one, check the open and closed cross-compilation issues.