Unable to get cgo compiled with bazel to work with nix

Hi!

I am trying to make all the dependencies through nix in my shell of an existing go monorepo project and I’m struggling quite a lot. The projects does not uses nix, so I have ignored the following files

/flake.nix
/flake.lock
/shell.nix
/.envrc
/.direnv/

my envrc file contains use flake path:$(pwd).
I run all the commands below by simply going into the project directory before executing them.

The go monorepo uses bazel to build and test the projects (so we use commands like bazel test, bazel build, bazel run).

First things first, I started with something easy like

{pkgs, ...}:
pkgs.mkShell {
  nativeBuildInputs = with pkgs; [
    alejandra
    bazel_6
    go
  ];
}

testing some simple projects worked like a charm.

One project require a library that requires cgo to be enabled, when trying to build the test the package that contain such library I got the following error:

bazel test //test_that_requires_cgo
INFO: Analyzed 9 targets (2 packages loaded, 1600 targets configured).
INFO: Found 5 targets and 4 test targets...
ERROR: package_that_requires_cgo/BUILD.bazel:28:12: GoLink package_that_requires_cgo_test failed: (Exit 1): builder failed: error executing command (from target //package_that_requires_cgo) bazel-out/darwin_arm64-opt-exec-2B5CBBC6-ST-be345d979f75/bin/external/go_sdk/builder_reset/builder ... (remaining 11 arguments skipped)

Use --sandbox_debug to see verbose messages from the sandbox and retain the sandbox build root for debugging
external/go_sdk/pkg/tool/darwin_arm64/link: running external/local_config_cc/cc_wrapper.sh failed: exit status 1
ld: framework not found CoreFoundation
clang-11: error: linker command failed with exit code 1 (use -v to see invocation)

link: error running subcommand external/go_sdk/pkg/tool/darwin_arm64/link: exit status 2

This is where things started to get messy. I tried quite everything I could. Imported pkgs.darwin.apple_sdk.frameworks.CoreFoundation in nativeBuildInputs, but it lead to missing .h headers, I imported libclang, now headers from the macOS sdk were missing so I imported pkgs.darwin.apple_sdk.MacOSX-SDK, … everytime I had to tell bazel where to find stuff by customizing my .bazelrc.user file.

I won’t be able to explain all the steps that lead me to this shell.nix file

{
  lib,
  pkgs,
  stdenv,
  libcxx,
}:
pkgs.mkShell {
  nativeBuildInputs = with pkgs; [
    bashInteractive
    alejandra
    bazel_6
    go
    jdk11
    libclang
    pkgs.darwin.apple_sdk.MacOSX-SDK
    pkgs.darwin.apple_sdk.frameworks.CoreServices
    pkgs.darwin.apple_sdk.frameworks.CoreFoundation
    pkgs.darwin.apple_sdk.frameworks.Security
  ];

  shellHook = ''
    export CGO_CFLAGS="$CGO_CFLAGS $(cat ${stdenv.cc}/nix-support/{cc,libc}-cflags | awk 1 ORS=' ')"
    export CGO_LDFLAGS="$CGO_LDFLAGS $(cat ${stdenv.cc}/nix-support/{cc,libc}-ldflags | awk 1 ORS=' ') -F${pkgs.darwin.apple_sdk.frameworks.CoreFoundation}/Library/Frameworks -framework CoreFoundation -F${pkgs.darwin.apple_sdk.frameworks.Security}/Library/Frameworks -framework Security"

    export BAZEL_USE_CPP_ONLY_TOOLCHAIN=1

    # add nix environment vars to .bazelrc
    cat > .bazelrc.user <<EOF
    test --test_env=PATH
    build --repo_env=JAVA_HOME
    build --copt="-isystem ${lib.getDev libcxx}/include/c++/v1" --copt="-isystem ${pkgs.darwin.apple_sdk.MacOSX-SDK}/usr/include"
    build --host_copt="-isystem ${lib.getDev libcxx}/include/c++/v1" --host_copt="-isystem ${pkgs.darwin.apple_sdk.MacOSX-SDK}/usr/include"
    build --linkopt="-Wl,-F${pkgs.darwin.apple_sdk.frameworks.CoreFoundation}/Library/Frameworks" --linkopt="-Wl,-framework CoreFoundation" --linkopt="-Wl,-F${pkgs.darwin.apple_sdk.frameworks.CoreServices}/Library/Frameworks" --linkopt="-Wl,-framework CoreServices" --linkopt="-Wl,-F${pkgs.darwin.apple_sdk.frameworks.Foundation}/Library/Frameworks" --linkopt="-Wl,-framework Foundation" --linkopt="-Wl,-F${pkgs.darwin.apple_sdk.frameworks.Security}/Library/Frameworks" --linkopt="-Wl,-framework Security"
    build --host_linkopt="-Wl,-F${pkgs.darwin.apple_sdk.frameworks.CoreFoundation}/Library/Frameworks" --host_linkopt="-Wl,-framework CoreFoundation" --host_linkopt="-Wl,-F${pkgs.darwin.apple_sdk.frameworks.CoreServices}/Library/Frameworks" --host_linkopt="-Wl,-framework CoreServices" --host_linkopt="-Wl,-F${pkgs.darwin.apple_sdk.frameworks.Foundation}/Library/Frameworks" --host_linkopt="-Wl,-framework Foundation" --host_linkopt="-Wl,-F${pkgs.darwin.apple_sdk.frameworks.Security}/Library/Frameworks" --host_linkopt="-Wl,-framework Security"
    EOF
  '';
}

Sorry by advance if part of the file is not used or for the messy generation of the bazel user file, this is the result of many tries and retries without really understanding the cause of the problem.
Whatever I try I am always missing something, my current error is

cgo-builtin-prolog:1:10: fatal error: 'stddef.h' file not found
#include <stddef.h>
         ^~~~~~~~~~
1 error generated.
compilepkg: error running subcommand external/go_sdk/pkg/tool/darwin_arm64/cgo: exit status 2

I am not done trying it, but I’m afraid that I am reinventing badly poorly and without success something that is way simpler and that I missed.

Am I going the right direction by customizing my .bazelrc.user file like this ?
If yes do you have any idea how to fix the error above ?
Otherwise, can you please point me to a resource online / documentation / any solved issue that can help me get to the right direction ?

Thank you

bazel wants to manage the entire show with their sandbox and by downloading everything from github repos. Generally bazel is a giant pain in my experience and I try to avoid it as much as possible.

So my recommendation for your problem is to not use bazel and nix together and choose either.

Thank you for your answer.

I’ll have a look at https://nix-bazel.build/ to see if it can help me with this