pkgsStatic ffmpeg can't find HOSTCC

Hi,

I’m currently on a little project to get a statically linked ffmpeg build out of Nix. I’ve disabled most of the libraries I don’t need as well as the ones I need but don’t compile/link yet. However the current compilation fails on this:

ffmpeg-full-static-x86_64-unknown-linux-musl> /nix/store/a54wrar1jym1d8yvlijq0l2gghmy8szz-bash-5.1-p12/bin/bash: line 1: gcc: command not found

This is correct, the host platform really doesn’t have a GCC installed (this is running on a Ubuntu machine, but could equally run on NixOS).

Since I’m new to this (statically linking/cross compilation) I was wondering if the community could help me answer a few questions:

  1. I presume the reason I’m cross compiling is that statically linked packages in Nix are mostly compiled with musl, while most other things use glibc?
  2. AFAIK HOSTCC is the compiler toolchain using musl instead of glibc? I’m not sure what environment variables these should be set to in comparison to CC and LD. Surprisingly if I install a gcc in the environment (e.g. Ubuntu) and use nix develop; genericBuild I get ffmpeg properly statically linked. I wonder why that “side-effect” works (using /usr/bin/gcc and /usr/bin/ld), but setting HOSTCC to ${stdenv.cc.targetPrefix}cc errors out with undefined references.

flake.nix I use:

{
  description = "Flake to get a static ffmpeg build";

  inputs.nixpkgs.url = github:NixOS/nixpkgs?rev=7cb82ec6149236f3655bd0fb269c41b55e4892fc;
  outputs = { self, nixpkgs }: {
    overlay = final: prev:
    {
      # to avoid undefined reference
      alsa-lib = prev.alsa-lib.overrideAttrs (old: rec {
        version = "1.2.6.1";
        src = builtins.fetchurl {
          url = "https://www.alsa-project.org/files/pub/lib/${old.pname}-${version}.tar.bz2";
          sha256 = "0grk09zikmmn9pf8bpqvrjqflmxclrhapgm0b6qmznrcsn9jjn5d";
        };
      });
      soxr = prev.soxr.overrideAttrs (old: rec {
        cmakeFlags = old.cmakeFlags ++ [ "-DWITH_OPENMP:bool=off"];
      });
      ffmpeg-full = prev.callPackage ./overlays/ffmpeg-full.nix {
        svt-av1 = null;
        rav1e = null;
        rtmpdump = null;
        libjack2 = null;
        libmodplug = null;
        libmfx = null;
        libpulseaudio = null;
        samba = null;
        vid-stab = null;
        celt = null;
        gsm = null; # compile error
        ladspaH = null; # compile error
        libaom = null; # compile errror - cmake possibly enabled+disabled shared lib
        frei0r = null; # gst-plugins transitive dependency 'x86_64-unknown-linux' not recognized
        libbs2b = null; # flac -ld: attempted static link of dynamic object
        SDL2 = null; # flac -ld: attempted static link of dynamic object
        openal = null; # flac -ld: attempted static link of dynamic object
        libva = null; # relocation R_X86_64_32 against `.ctors' can not be used when making a shared object; recompile with -fPIC
        srt = null; # against `.ctors' can not be used when making a shared object; recompile with -fPIC
        x265 = null;  # against `.ctors' can not be used when making a shared object; recompile with -fPIC
        xavs = null; # same ^^ check for Unknown option --disable-shared/--enable-static
        xvidcore = null; # same ^^
        zeromq4 = null; # same but cmake
        libass = null; # same in libselinux
        ffplayProgram = false;
        gnutls = null; # p11-kit (gnutls) cannot be used as a static library
        networkBuild = false; # p11-kit (gnutls) cannot be used as a static library
        glslang = null; # compilation error in spirv-tools/spirv-headers
        libv4l = null; # /libpam.a(pam_audit.o): in function `pam_modutil_audit_write': (.text+0x541): undefined reference to `audit_close'
        vulkan-loader = null; # (.text.epoll_create1+0x0): multiple definition of `epoll_create1'; in wayland-static
        libX11 = null; # error trying to rebuild the world (e.g. glibc)
        librsvg = null; # libglvnd ../../libtool: line 2625: func__fatal_error: command not found
        libvdpau = null; # multiple undefined references - meson build
        libcaca = null; # x86_64-unknown-linux-musl-ar: `u' modifier ignored since `D' is the default (see `U')
        openjpeg = null; # (.text+0xc34): undefined reference to `libdeflate_free_compressor' libtiff
        libwebp = null; # (.text+0xc34): undefined reference to `libdeflate_free_compressor' libtiff
        libbluray = null; # libbluray not found using pkg-config
        libdc1394 = null; # libdc1394-2 not found using pkg-config
        fontconfig = null; # fontconfig not found using pkg-config
        freetype = null; # freetype2 not found using ...
        libssh = null; # ^^
        game-music-emu = null; # ^^
        libvmaf = null; # XXXXXXXXXXXXXXXXX - undefined references
        libvorbis = null; # XXXXXXXX - undefined references
        libxcb = null;
        libopus = null; # yields to undefined references when linking ffmpeg binary
        libxcbshmExtlib = false;
        libxcbxfixesExtlib = false;
        libxcbshapeExtlib = false;
        qtFaststartProgram = false;
        inherit (prev.darwin.apple_sdk.frameworks)
        Cocoa CoreServices CoreAudio AVFoundation MediaToolbox
        VideoDecodeAcceleration;
      };
    };
    defaultPackage.x86_64-linux =
      with import nixpkgs { system = "x86_64-linux"; overlays = [ self.overlay ]; };
      pkgsStatic.ffmpeg-full;
  };
}

Answering my own question.

Setting:

makeFlags = [
  "HOSTCC=$\{CC}"
  "HOSTLD=$\{LD}"
];

in the ffmpeg-full derivation made the build pass. I can only speculate as to why that works. I’ll see if that still works out if I cross compile.