Hello,
I would like to create a flake that creates an environment where I can cross compile simple C code to risc32 or risc64 on an aarch64-darwin machine.
I currently have this flake:
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/release-23.11";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = {
nixpkgs,
flake-utils,
...
}:
flake-utils.lib.eachDefaultSystem (system: let
pkgs = import nixpkgs {inherit system;};
riscv64Pkgs =
(import nixpkgs {
inherit system;
crossSystem.config = "riscv32-linux-gnu";
})
.buildPackages;
in {
devShells.default = pkgs.mkShell {
buildInputs = with riscv64Pkgs; [
gcc
];
};
});
}
The problem is that, gcc
seems to be getting a flag that is macOS only.
$ riscv32-linux-gnu-gcc main.c
riscv32-linux-gnu-gcc: error: unrecognized command-line option ‘-iframework’
Is there a way for me to turn this flag off ? Where is it defined ?
Thank you for your time !
Update:
I’ve done some research on where the iframework
comes from:
I cloned the nixpkgs
repo and did a quick regex search, I found that in pkgs/build-support/cc-wrapper/setup-hook.sh
, there’s this section:
Is there a way that I can turn this off with an override of some sort ? This is definitely correct in the general case, but the riscv32
gcc
doesn’t like this option.
Thank you for your time !
Hello !
you have a problem with gcc
because you have two different gcc
in your shell: the one that comes from stdenv (through mkShell, which is a rather thin wrapper around stdenv.mkDerivation
) and which is correctly setup, and the one that comes from buildInputs
, which is half-broken because buildInputs
is for libs, not compilers.
You should only keep the gcc from stdenv: instead of pkgs.mkShell { buildInputs = [ pkgs.gcc ]; }
use pkgs.stdenv.mkDerivation { /* no buildInputs */ }
. To obtain a cross gcc, then you need a cross stdenv:
let
riscv64Pkgs =
import nixpkgs {
inherit system;
crossSystem.config = "riscv32-linux-gnu";
};
in
riscv64Pkgs.stdenv.mkDerivation { name = "whatever"; }
Notice how I removed .buildPackage
: stdenv is a bit special in that pkgs.stdenv
is the stdenv
to build pkgs
, so riscv64Pkgs.buildPackages.stdenv
builds packages to build packages for riscv.
For more complex stuff, please mind that you need to use callPackage for splicing. See How do I cross compile my own package (rather than something in nix-pkgs) for another example.
2 Likes
Thanks for the explanation ! It worked perfectly.