Using propogated dependencies

Let’s say I have a build script such as this:

        ${toolchain.gcc}/bin/avr-gcc -mmcu=${MCU} ${CFLAGS} -c ${src}/main.c
        ${toolchain.gcc}/bin/avr-gcc -mmcu=${MCU} ${CFLAGS} -c ${uart}/include/uart.c
        ${toolchain.gcc}/bin/avr-gcc ${CFLAGS} -o main.elf uart.o main.o
        ${toolchain.binutils}/bin/avr-objcopy -O ihex -R .eeprom main.elf main.hex

And my buildDependenices looks like this:

    avr = with pkgs.pkgsCross.avr.buildPackages; [
        binutils
        gcc
        avrdude
    ];
    buildDependencies = [
        uart
    ] ++ avr;

My build script runs just fine until that last avr-objcopy command. Now, avr-objcopy is part of binutils, but pkgs.pkgsCross.avr.buildPackages.binutils produces a binutils-wrapper, not binputils proper. It does depend on the real binutils, which does contain the avr-objcopy executable.

I can see that the wrapper derivation has a nix-support directory that looks like this:

[avr-projects] savanni@garnet:/n/store $ exa -l /nix/store/li13acnmw5yd428572lzlznd4jslg4ms-avr-binutils-wrapper-2.31.1/nix-support/
.r--r--r-- 1.1k root 31 Dec  1969 add-flags.sh
.r--r--r-- 1.7k root 31 Dec  1969 add-hardening.sh
.r--r--r-- 1.1k root 31 Dec  1969 libc-cflags
.r--r--r--   69 root 31 Dec  1969 libc-ldflags
.r--r--r--    0 root 31 Dec  1969 libc-ldflags-before
.r--r--r--   64 root 31 Dec  1969 orig-bintools
.r--r--r--   63 root 31 Dec  1969 orig-libc
.r--r--r--   63 root 31 Dec  1969 orig-libc-dev
.r--r--r--  127 root 31 Dec  1969 propagated-user-env-packages
.r--r--r-- 4.9k root 31 Dec  1969 setup-hook
.r--r--r-- 2.9k root 31 Dec  1969 utils.bash

And propogated-user-env-packages and orig-binutils both have paths to the original binutils package. I just don’t know what the right way of using the nix-support directory is, and kinda feel like there is already infrastructure in nix-build that will address those things, and I’m just missing it.

So, the question is, how can I modify my build script, or my derivation, to bring the executables from the original binutils into my path, in addition to the wrapper binutils, and maybe even the gcc derivation?

Welp, I don’t know what the general answer is…

And setup-hook basically gets referred to once in all of nixpkgs

But in this case, avr-objcopy is being assigned to the $OBJCOPY environment variable, and I’m getting an AVR executable with this derivation:

{ pkgs ? import <pkgs-20.03> {},
  mkDerivation ? pkgs.stdenv.mkDerivation,
  fetchFromGitHub ? pkgs.fetchFromGitHub,
  uart ? import ../uart.nix { inherit fetchFromGitHub mkDerivation; },
  toolchain ? pkgs.pkgsCross.avr.buildPackages,
}:
let
    avr = with toolchain; [
        binutils
        gcc
        avrdude
    ];
in mkDerivation rec {
    name = "radio-listener";

    src = ./src;

    avr = with pkgs.pkgsCross.avr.buildPackages; [
        binutils
        gcc
        avrdude
    ];
    buildDependencies = [
        uart
    ] ++ avr;

    dontUnpack = true;
    dontPatchELF = true;
    dontFixup = true;

    INC = ''-I ${uart}/include'';
    MCU = "atmega32u4";
    F_CPU = "8000000";
    CFLAGS = ''-O -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -DF_CPU=${F_CPU} -DUSART1_ENABLED -DUART_RX1_BUFFER_SIZE=128 -DUART_TX1_BUFFER_SIZE=128 -std=gnu99 -I${uart}/include -D__AVR_ATmega32U4__'';

    buildPhase = ''
        ${toolchain.gcc}/bin/avr-gcc -mmcu=${MCU} ${CFLAGS} -c ${src}/main.c
        ${toolchain.gcc}/bin/avr-gcc -mmcu=${MCU} ${CFLAGS} -c ${uart}/include/uart.c
        ${toolchain.gcc}/bin/avr-gcc ${CFLAGS} -o main.elf uart.o main.o
        $OBJCOPY -O ihex -R .eeprom main.elf main.hex

    '';

    installPhase = ''
        mkdir $out
        cp main.elf main.hex $out
    '';
}

Wat I really like about this derivation is that, without any of the shenanigans of a Makefile (in fact, this is infinitely simpler), I can specify a build script, plus I can specify a dependency on a source-only library that I cannot precompile. The details of the environment have to be selected through compile-time flags, so I have to compile the uart.c file in my project, not in advance.

Though maybe I could get more advanced and turn the required parameters into parameters to be provided to the uart derivation. :smiley:

Nevertheless, this is cool.