doesn’t work (though the overlay works (tested with hellox))
It says: error: attribute 'xcode_15_2' missing.
Did I do something wrong in the override of the darwin attribute in the overlay?
I tried to take a shortcut and directly do the derivation inline in buildInputs with the requireFile expression etc. from xcode.nix for my specific xcode version, but couldn’t get it to work, probably due to making mistakes in the chaining of expressions.
As a workaround I can get xcode working in a devShell flake without overlay by just doing the appleSDK thing in the below flake.
{
description = "flutter shell";
inputs = {
# nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, flake-utils, nixpkgs }:
flake-utils.lib.eachDefaultSystem (system: {
devShell =
let
pkgs = import nixpkgs {
inherit system;
config.allowUnfree = true;
overlays =
[ (import ./.nix/overlay) ]; # somehow doesn't work as expected?
};
inherit (pkgs) lib;
appleSDK =
if pkgs.stdenv.isDarwin then
(pkgs.darwin.callPackage ./.nix/overlay/xcode.nix { }).xcode_15_2
else
{ };
myllvm = pkgs.llvmPackages_15;
libs = with pkgs;
if stdenv.isLinux then [
atk
at-spi2-core.dev
dbus.dev
gtk3
pango
cairo
harfbuzz
gdk-pixbuf
glib # these are transitive but explicit here for the LD_LIBRARY_PATH
fontconfig
libdatrie
libselinux
libsepol
pcre
libthai
libxkbcommon
pcre2
util-linux.dev
xorg.libX11.dev
xorg.libXdmcp
xorg.libXtst
libappindicator.dev
libepoxy
libdeflate
gnome.zenity
] else if stdenv.isDarwin then
[
# libs needed for darwin
]
else
builtins.throw "Unsupported system (not Linux or Darwin)";
in
(pkgs.mkShell.override {
stdenv =
if pkgs.stdenv.isDarwin then
pkgs.stdenv
else
myllvm.stdenv;
}) {
nativeBuildInputs = with pkgs;
[ pkg-config ninja cmake dart flutter319 go envsubst ]
++ lib.optionals stdenv.isLinux [
myllvm.bintools # https://matklad.github.io/2022/03/14/rpath-or-why-lld-doesnt-work-on-nixos.html
];
buildInputs = libs ++ lib.optionals pkgs.stdenv.isLinux
(with myllvm; [ libcxxClang libunwind ])
++ lib.optionals pkgs.stdenv.isDarwin (with pkgs;
[
# this whole stuff is prepared as follows:
# https://github.com/NixOS/nixpkgs/blob/032324fd20e3be4124ffefd00da5bd66b0550e8c/pkgs/os-specific/darwin/xcode/default.nix#L23-L32
appleSDK
]);
shellHook =
if pkgs.stdenv.isDarwin then ''
# PATH=${appleSDK}/Contents/Developer/usr/bin:${appleSDK}/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin:$PATH
PATH=${appleSDK}/Contents/Developer/usr/bin:$PATH
SDKROOT=${appleSDK}/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
'' else
"";
};
});
}
That even makes the flutter part of my project work.
BUT: depending on which PATH I set in the shellHook a go library I link into the flutter app won’t compile.
If I don’t set clang to the env’s Xcode (from Toolchain), I get
clang-16: error: cannot use 'cpp-output' output with multiple -arch options
and if I set the path I get
# runtime/cgo
_cgo_export.c:3:10: fatal error: 'stdlib.h' file not found
Anyway it seems that setting the paths for the stdenv by setting PATH in a shellHook is very hacky, is there a “natural” way to force the actually installed apple SDK?
(If I don’t set any paths I get the ancient SDK version 11). I guess that would more naturally solve library resolution?
If I recall correctly I gave up and just manually installed flutter for the gitlab-runner user on the mac, to compile my flutter code for mac in gitlab-ci. I haven’t touched it for some time now, but it appears to be working reliably enough.
TBH I’m not really satisfied with the state of stdenv on darwin, the fact that SDK version 11 is still the (hardcoded) default with no documented way to override has become a PITA, so I have all but given up on doing serious stuff with nix on darwin. (It’s still ok for occasional devshells and a partial nix-darwin and HM user config, but even for the latter I still have to use some packages from brew (via the nix-darwin module, which makes it better)
24.11 changed the way SDKs work on Darwin. The SDK used in the stdenv can be overridden by adding the appropriate apple-sdk package to buildInputs. This is documented extensively in the manual in the Darwin section.
The announcement from last fall when these changes landed goes into detail about what changed as well as what the changes enable. (I think the Flutter situation probably still sucks, but someone motivated to do so should be able to fix it.)
I ended up using stdenvNoCc for stdenv package and instead of using xcrun and the Xcode SDK from Nix, I ended up using the ones from the XCode installation by setting this:
Darwin had been stuck in a bad state for a long time, so I don’t fault people for assuming it hadn’t gotten better. There have been some growing pains (particularly with dev shells that mix Nix-built and native dependencies), but it’s generally in a better state now and should be able to keep up with updates in the future.
to the shellHook = the Flutter command isn’t found anymore.
My flake.nix works - but I would like to setup Xcode more idiomatic, if there is a recommended way. Currently I am using this workaround in shellHook = :
# installs or checks for the right xcode version
echo "installing xcode ${xcode_version}"
xcodes install ${xcode_version} --experimental-unxip # --directory "$PWD/.xcode"
xcodes select ${xcode_version}
This is my complete flake.nix file
{
description = "Flutter toolchain. Installs all tools needed for flutter, with versions pinned for this project. Rust's own tooling handles the rust toolchain.";
# nix flutter doesn't work: https://github.com/NixOS/nixpkgs/issues/243448
# thus using a local installation
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
android-nixpkgs = {
url = "github:tadfisher/android-nixpkgs";
inputs = {
flake-utils.follows = "flake-utils";
nixpkgs.follows = "nixpkgs";
devshell.follows = "devshell";
};
};
devshell = {
url = "github:numtide/devshell";
inputs = {
nixpkgs.follows = "nixpkgs";
};
};
# share rust configuration with nix ... not really needed!
# rust-overlay = {
# url = "github:oxalica/rust-overlay";
# inputs = {
# nixpkgs.follows = "nixpkgs";
# flake-utils.follows = "flake-utils";
# };
# };
};
# Use this to create an android emulator
# however, this is not needed, as VSCode's Flutter Plugin can create emulators as well
# AVD_package = "system-images;android-34;aosp_atd;arm64-v8a";
# local_toolchain_path = "$PWD/.toolchain";
# local_SDK_path = "${local_toolchain_path}/android";
# local_AVD_path = "${local_SDK_path}/AVD";
# avdmanager create avd --name android-34-pixel_8 --package '${AVD_package}' --device "pixel_8"
shellHook = ''
# export PATH=$(echo $PATH | sd "${pkgs.xcbuild.xcrun}/bin" "")
# unset DEVELOPER_DIR
# uncomment to enable flutter-rust-bridge-codegen logging
# export RUST_BACKTRACE=1
# export RUST_LOG="debug"
# installs or checks for the right xcode version
echo "installing xcode ${xcode_version}"
xcodes install ${xcode_version} --experimental-unxip # --directory "$PWD/.xcode"
xcodes select ${xcode_version}
echo
# GRADLE_USER_HOME=$HOME/gradle-user-home
# GRADLE_HOME=$HOME/gradle-home
'';
# GRADLE_USER_HOME = " /home/admin0101/.gradle ";
# GRADLE_OPTS = " - Dorg.gradle.project.android.aapt2FromMavenOverride=${androidCustomPackage}/share/android-sdk/build-tools/34.0.0/aapt2";
};
}
);
}
Note that I am using nix only on my Mac - thus I don’t have any if Darwin (which I should …). I am using it system wide as well, with flake and home-manager. But that should not really matter here …