mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-12-02 03:43:06 +00:00
ce80359d9f
When using a custom `hardware.deviceTree.dtbSource`, we cannot assume that all DTBs in this directory are regular files. This change allows for file symlinks to be present as well, which fixes the issue where only file (a symlink) is present in `dtbSource` and the copy fails with `cp: missing file operand`.
67 lines
2.1 KiB
Nix
67 lines
2.1 KiB
Nix
{ lib, stdenv, stdenvNoCC, dtc }:
|
|
|
|
with lib; {
|
|
# Compile single Device Tree overlay source
|
|
# file (.dts) into its compiled variant (.dtb)
|
|
compileDTS = ({
|
|
name,
|
|
dtsFile,
|
|
includePaths ? [],
|
|
extraPreprocessorFlags ? []
|
|
}: stdenv.mkDerivation {
|
|
inherit name;
|
|
|
|
nativeBuildInputs = [ dtc ];
|
|
|
|
buildCommand =
|
|
let
|
|
includeFlagsStr = lib.concatMapStringsSep " " (includePath: "-I${includePath}") includePaths;
|
|
extraPreprocessorFlagsStr = lib.concatStringsSep " " extraPreprocessorFlags;
|
|
in
|
|
''
|
|
$CC -E -nostdinc ${includeFlagsStr} -undef -D__DTS__ -x assembler-with-cpp ${extraPreprocessorFlagsStr} ${dtsFile} | \
|
|
dtc -I dts -O dtb -@ -o $out
|
|
'';
|
|
});
|
|
|
|
applyOverlays = (base: overlays': stdenvNoCC.mkDerivation {
|
|
name = "device-tree-overlays";
|
|
nativeBuildInputs = [ dtc ];
|
|
buildCommand = let
|
|
overlays = toList overlays';
|
|
in ''
|
|
mkdir -p $out
|
|
cd "${base}"
|
|
find -L . -type f -name '*.dtb' -print0 \
|
|
| xargs -0 cp -v --no-preserve=mode --target-directory "$out" --parents
|
|
|
|
for dtb in $(find "$out" -type f -name '*.dtb'); do
|
|
dtbCompat=$(fdtget -t s "$dtb" / compatible 2>/dev/null || true)
|
|
# skip files without `compatible` string
|
|
test -z "$dtbCompat" && continue
|
|
|
|
${flip (concatMapStringsSep "\n") overlays (o: ''
|
|
overlayCompat="$(fdtget -t s "${o.dtboFile}" / compatible)"
|
|
|
|
# skip incompatible and non-matching overlays
|
|
if [[ ! "$dtbCompat" =~ "$overlayCompat" ]]; then
|
|
echo "Skipping overlay ${o.name}: incompatible with $(basename "$dtb")"
|
|
elif ${if (o.filter == null) then "false" else ''
|
|
[[ "''${dtb//${o.filter}/}" == "$dtb" ]]
|
|
''}
|
|
then
|
|
echo "Skipping overlay ${o.name}: filter does not match $(basename "$dtb")"
|
|
else
|
|
echo -n "Applying overlay ${o.name} to $(basename "$dtb")... "
|
|
mv "$dtb"{,.in}
|
|
fdtoverlay -o "$dtb" -i "$dtb.in" "${o.dtboFile}"
|
|
echo "ok"
|
|
rm "$dtb.in"
|
|
fi
|
|
'')}
|
|
|
|
done
|
|
'';
|
|
});
|
|
}
|