lint: reformat everything

This commit is contained in:
tcmal 2024-05-13 22:24:10 +01:00
parent 79813f3f0f
commit d9b1d23b5e
1236 changed files with 136987 additions and 115858 deletions

View file

@ -1,6 +1,7 @@
let requiredVersion = import ./minver.nix; in let requiredVersion = import ./minver.nix;
if ! builtins ? nixVersion || builtins.compareVersions requiredVersion builtins.nixVersion == 1 then in if !builtins ? nixVersion
|| builtins.compareVersions requiredVersion builtins.nixVersion == 1 then
abort '' abort ''

View file

@ -1,44 +1,42 @@
{ {
inputs = { inputs = { auxlib.url = "github:auxolotl/lib"; };
auxlib.url = "github:auxolotl/lib";
};
outputs = outputs = { self, auxlib, ... }:
{ self, auxlib, ... }:
let let
inherit (auxlib) lib; inherit (auxlib) lib;
forAllSystems = self.lib.genAttrs self.lib.systems.flakeExposed; forAllSystems = self.lib.genAttrs self.lib.systems.flakeExposed;
in in {
{
inherit lib; inherit lib;
auxPackages = forAllSystems (system: auxPackages = forAllSystems (system:
( (let requiredVersion = import ./minver.nix;
let requiredVersion = import ./minver.nix; in
if ! builtins ? nixVersion || builtins.compareVersions requiredVersion builtins.nixVersion == 1 then in if !builtins ? nixVersion
abort '' || builtins.compareVersions requiredVersion builtins.nixVersion
This version of Nixpkgs requires Nix >= ${requiredVersion}, please upgrade: == 1 then
abort ''
This version of Nixpkgs requires Nix >= ${requiredVersion}, please upgrade:
- If you are running NixOS, `nixos-rebuild' can be used to upgrade your system. - If you are running NixOS, `nixos-rebuild' can be used to upgrade your system.
- Alternatively, with Nix > 2.0 `nix upgrade-nix' can be used to imperatively - Alternatively, with Nix > 2.0 `nix upgrade-nix' can be used to imperatively
upgrade Nix. You may use `nix-env --version' to check which version you have. upgrade Nix. You may use `nix-env --version' to check which version you have.
- If you installed Nix using the install script (https://nixos.org/nix/install), - If you installed Nix using the install script (https://nixos.org/nix/install),
it is safe to upgrade by running it again: it is safe to upgrade by running it again:
curl -L https://nixos.org/nix/install | sh curl -L https://nixos.org/nix/install | sh
For more information, please see the NixOS release notes at For more information, please see the NixOS release notes at
https://nixos.org/nixos/manual or locally at https://nixos.org/nixos/manual or locally at
${toString ./nixos/doc/manual/release-notes}. ${toString ./nixos/doc/manual/release-notes}.
If you need further help, see https://nixos.org/nixos/support.html If you need further help, see https://nixos.org/nixos/support.html
'' ''
else else
import ./pkgs/top-level/default.nix { inherit lib; localSystem = system; } import ./pkgs/top-level/default.nix {
) inherit lib;
); localSystem = system;
}));
}; };
} }

View file

@ -1,48 +1,42 @@
/* List of maintainer teams. /* List of maintainer teams.
name = { name = {
# Required # Required
members = [ maintainer1 maintainer2 ]; members = [ maintainer1 maintainer2 ];
scope = "Maintain foo packages."; scope = "Maintain foo packages.";
shortName = "foo"; shortName = "foo";
# Optional # Optional
enableFeatureFreezePing = true; enableFeatureFreezePing = true;
githubTeams = [ "my-subsystem" ]; githubTeams = [ "my-subsystem" ];
}; };
where where
- `members` is the list of maintainers belonging to the group, - `members` is the list of maintainers belonging to the group,
- `scope` describes the scope of the group. - `scope` describes the scope of the group.
- `shortName` short human-readable name - `shortName` short human-readable name
- `enableFeatureFreezePing` will ping this team during the Feature Freeze announcements on releases - `enableFeatureFreezePing` will ping this team during the Feature Freeze announcements on releases
- There is limited mention capacity in a single post, so this should be reserved for critical components - There is limited mention capacity in a single post, so this should be reserved for critical components
or larger ecosystems within nixpkgs. or larger ecosystems within nixpkgs.
- `githubTeams` will ping specified GitHub teams as well - `githubTeams` will ping specified GitHub teams as well
More fields may be added in the future. More fields may be added in the future.
When editing this file: When editing this file:
* keep the list alphabetically sorted * keep the list alphabetically sorted
* test the validity of the format with: * test the validity of the format with:
nix-build lib/tests/teams.nix nix-build lib/tests/teams.nix
*/ */
{ lib }: { lib }:
with lib.maintainers; { with lib.maintainers; {
llvm = { llvm = {
members = []; members = [ ];
scope = "Maintain LLVM package sets and related packages"; scope = "Maintain LLVM package sets and related packages";
shortName = "LLVM"; shortName = "LLVM";
enableFeatureFreezePing = true; enableFeatureFreezePing = true;
}; };
lix = { lix = { members = [ ]; };
members = []; python = { members = [ ]; };
}; rust = { members = [ ]; };
python = {
members = [];
};
rust = {
members = [];
};
} }

View file

@ -1,56 +1,45 @@
# Builder for Agda packages. # Builder for Agda packages.
{ stdenv, lib, self, Agda, runCommand, makeWrapper, writeText, ghcWithPackages, nixosTests }: { stdenv, lib, self, Agda, runCommand, makeWrapper, writeText, ghcWithPackages
, nixosTests }:
let let
inherit (lib) inherit (lib) attrValues elem filter filterAttrs isAttrs isList platforms;
attrValues
elem
filter
filterAttrs
isAttrs
isList
platforms
;
inherit (lib.strings) inherit (lib.strings) concatMapStrings concatMapStringsSep optionalString;
concatMapStrings
concatMapStringsSep
optionalString
;
withPackages' = { withPackages' = { pkgs, ghc ? ghcWithPackages (p: with p; [ ieee754 ]) }:
pkgs, let
ghc ? ghcWithPackages (p: with p; [ ieee754 ]) pkgs' = if isList pkgs then pkgs else pkgs self;
}: let library-file = writeText "libraries" ''
pkgs' = if isList pkgs then pkgs else pkgs self; ${(concatMapStringsSep "\n" (p: "${p}/${p.libraryFile}") pkgs')}
library-file = writeText "libraries" '' '';
${(concatMapStringsSep "\n" (p: "${p}/${p.libraryFile}") pkgs')} pname = "agdaWithPackages";
''; version = Agda.version;
pname = "agdaWithPackages"; in runCommand "${pname}-${version}" {
version = Agda.version; inherit pname version;
in runCommand "${pname}-${version}" { nativeBuildInputs = [ makeWrapper ];
inherit pname version; passthru = {
nativeBuildInputs = [ makeWrapper ]; unwrapped = Agda;
passthru = { inherit withPackages;
unwrapped = Agda; tests = {
inherit withPackages; inherit (nixosTests) agda;
tests = { allPackages = withPackages
inherit (nixosTests) agda; (filter self.lib.isUnbrokenAgdaPackage (attrValues self));
allPackages = withPackages (filter self.lib.isUnbrokenAgdaPackage (attrValues self)); };
}; };
}; # Agda is a split package with multiple outputs; do not inherit them here.
# Agda is a split package with multiple outputs; do not inherit them here. meta = removeAttrs Agda.meta [ "outputsToInstall" ];
meta = removeAttrs Agda.meta [ "outputsToInstall" ]; } ''
} '' mkdir -p $out/bin
mkdir -p $out/bin makeWrapper ${Agda.bin}/bin/agda $out/bin/agda \
makeWrapper ${Agda.bin}/bin/agda $out/bin/agda \ --add-flags "--with-compiler=${ghc}/bin/ghc" \
--add-flags "--with-compiler=${ghc}/bin/ghc" \ --add-flags "--library-file=${library-file}"
--add-flags "--library-file=${library-file}" ln -s ${Agda.bin}/bin/agda-mode $out/bin/agda-mode
ln -s ${Agda.bin}/bin/agda-mode $out/bin/agda-mode
''; '';
withPackages = arg: if isAttrs arg then withPackages' arg else withPackages' { pkgs = arg; }; withPackages = arg:
if isAttrs arg then withPackages' arg else withPackages' { pkgs = arg; };
extensions = [ extensions = [
"agda" "agda"
@ -64,58 +53,61 @@ let
"lagda.typ" "lagda.typ"
]; ];
defaults = defaults = { pname, meta, buildInputs ? [ ]
{ pname , everythingFile ? "./Everything.agda", includePaths ? [ ]
, meta , libraryName ? pname, libraryFile ? "${libraryName}.agda-lib"
, buildInputs ? [] , buildPhase ? null, installPhase ? null, extraExtensions ? [ ], ... }:
, everythingFile ? "./Everything.agda" let
, includePaths ? [] agdaWithArgs =
, libraryName ? pname withPackages (filter (p: p ? isAgdaDerivation) buildInputs);
, libraryFile ? "${libraryName}.agda-lib" includePathArgs = concatMapStrings (path: "-i" + path + " ")
, buildPhase ? null (includePaths ++ [ (dirOf everythingFile) ]);
, installPhase ? null in {
, extraExtensions ? [] inherit libraryName libraryFile;
, ...
}: let
agdaWithArgs = withPackages (filter (p: p ? isAgdaDerivation) buildInputs);
includePathArgs = concatMapStrings (path: "-i" + path + " ") (includePaths ++ [(dirOf everythingFile)]);
in
{
inherit libraryName libraryFile;
isAgdaDerivation = true; isAgdaDerivation = true;
buildInputs = buildInputs ++ [ agdaWithArgs ]; buildInputs = buildInputs ++ [ agdaWithArgs ];
buildPhase = if buildPhase != null then buildPhase else '' buildPhase = if buildPhase != null then
runHook preBuild buildPhase
agda ${includePathArgs} ${everythingFile} else ''
rm ${everythingFile} ${lib.interfaceFile Agda.version everythingFile} runHook preBuild
runHook postBuild agda ${includePathArgs} ${everythingFile}
''; rm ${everythingFile} ${lib.interfaceFile Agda.version everythingFile}
runHook postBuild
'';
installPhase = if installPhase != null then installPhase else '' installPhase = if installPhase != null then
runHook preInstall installPhase
mkdir -p $out else ''
find \( ${concatMapStringsSep " -or " (p: "-name '*.${p}'") (extensions ++ extraExtensions)} \) -exec cp -p --parents -t "$out" {} + runHook preInstall
runHook postInstall mkdir -p $out
''; find \( ${
concatMapStringsSep " -or " (p: "-name '*.${p}'")
(extensions ++ extraExtensions)
} \) -exec cp -p --parents -t "$out" {} +
runHook postInstall
'';
# As documented at https://github.com/NixOS/nixpkgs/issues/172752, # As documented at https://github.com/NixOS/nixpkgs/issues/172752,
# we need to set LC_ALL to an UTF-8-supporting locale. However, on # we need to set LC_ALL to an UTF-8-supporting locale. However, on
# darwin, it seems that there is no standard such locale; luckily, # darwin, it seems that there is no standard such locale; luckily,
# the referenced issue doesn't seem to surface on darwin. Hence let's # the referenced issue doesn't seem to surface on darwin. Hence let's
# set this only on non-darwin. # set this only on non-darwin.
LC_ALL = optionalString (!stdenv.isDarwin) "C.UTF-8"; LC_ALL = optionalString (!stdenv.isDarwin) "C.UTF-8";
meta = if meta.broken or false then meta // { hydraPlatforms = platforms.none; } else meta; meta = if meta.broken or false then
meta // { hydraPlatforms = platforms.none; }
else
meta;
# Retrieve all packages from the finished package set that have the current package as a dependency and build them # Retrieve all packages from the finished package set that have the current package as a dependency and build them
passthru.tests = passthru.tests = filterAttrs (name: pkg:
filterAttrs (name: pkg: self.lib.isUnbrokenAgdaPackage pkg && elem pname (map (pkg: pkg.pname) pkg.buildInputs)) self; self.lib.isUnbrokenAgdaPackage pkg
}; && elem pname (map (pkg: pkg.pname) pkg.buildInputs)) self;
in };
{ in {
mkDerivation = args: stdenv.mkDerivation (args // defaults args); mkDerivation = args: stdenv.mkDerivation (args // defaults args);
inherit withPackages withPackages'; inherit withPackages withPackages';

View file

@ -1,17 +1,18 @@
{ lib }: { lib }: {
{ # Returns the Agda interface file to a given Agda file.
/* Returns the Agda interface file to a given Agda file. #
* # The resulting path may not be normalized.
* The resulting path may not be normalized. #
* # Examples:
* Examples: # interfaceFile pkgs.agda.version "./Everything.agda" == "_build/2.6.4.3/agda/./Everything.agdai"
* interfaceFile pkgs.agda.version "./Everything.agda" == "_build/2.6.4.3/agda/./Everything.agdai" # interfaceFile pkgs.agda.version "src/Everything.lagda.tex" == "_build/2.6.4.3/agda/src/Everything.agdai"
* interfaceFile pkgs.agda.version "src/Everything.lagda.tex" == "_build/2.6.4.3/agda/src/Everything.agdai" interfaceFile = agdaVersion: agdaFile:
*/ "_build/" + agdaVersion + "/agda/" + lib.head
interfaceFile = agdaVersion: agdaFile: "_build/" + agdaVersion + "/agda/" + lib.head (builtins.match ''(.*\.)l?agda(\.(md|org|rst|tex|typ))?'' agdaFile) + "agdai"; (builtins.match "(.*\\.)l?agda(\\.(md|org|rst|tex|typ))?" agdaFile)
+ "agdai";
/* Takes an arbitrary derivation and says whether it is an agda library package # Takes an arbitrary derivation and says whether it is an agda library package
* that is not marked as broken. # that is not marked as broken.
*/ isUnbrokenAgdaPackage = pkg:
isUnbrokenAgdaPackage = pkg: pkg.isAgdaDerivation or false && !pkg.meta.broken; pkg.isAgdaDerivation or false && !pkg.meta.broken;
} }

View file

@ -1,44 +1,174 @@
{ lib, stdenv { lib, stdenv, lapack-reference, openblas, isILP64 ? false
, lapack-reference, openblas
, isILP64 ? false
, blasProvider ? openblas }: , blasProvider ? openblas }:
let let
blasFortranSymbols = [ blasFortranSymbols = [
"caxpy" "ccopy" "cdotc" "cdotu" "cgbmv" "cgemm" "cgemv" "cgerc" "cgeru" "caxpy"
"chbmv" "chemm" "chemv" "cher" "cher2" "cher2k" "cherk" "chpmv" "chpr" "ccopy"
"chpr2" "crotg" "cscal" "csrot" "csscal" "cswap" "csymm" "csyr2k" "csyrk" "cdotc"
"ctbmv" "ctbsv" "ctpmv" "ctpsv" "ctrmm" "ctrmv" "ctrsm" "ctrsv" "dasum" "cdotu"
"daxpy" "dcabs1" "dcopy" "ddot" "dgbmv" "dgemm" "dgemv" "dger" "dnrm2" "cgbmv"
"drot" "drotg" "drotm" "drotmg" "dsbmv" "dscal" "dsdot" "dspmv" "dspr" "cgemm"
"dspr2" "dswap" "dsymm" "dsymv" "dsyr" "dsyr2" "dsyr2k" "dsyrk" "dtbmv" "cgemv"
"dtbsv" "dtpmv" "dtpsv" "dtrmm" "dtrmv" "dtrsm" "dtrsv" "dzasum" "dznrm2" "cgerc"
"icamax" "idamax" "isamax" "izamax" "lsame" "sasum" "saxpy" "scabs1" "cgeru"
"scasum" "scnrm2" "scopy" "sdot" "sdsdot" "sgbmv" "sgemm" "sgemv" "chbmv"
"sger" "snrm2" "srot" "srotg" "srotm" "srotmg" "ssbmv" "sscal" "sspmv" "chemm"
"sspr" "sspr2" "sswap" "ssymm" "ssymv" "ssyr" "ssyr2" "ssyr2k" "ssyrk" "chemv"
"stbmv" "stbsv" "stpmv" "stpsv" "strmm" "strmv" "strsm" "strsv" "xerbla" "cher"
"xerbla_array" "zaxpy" "zcopy" "zdotc" "zdotu" "zdrot" "zdscal" "zgbmv" "cher2"
"zgemm" "zgemv" "zgerc" "zgeru" "zhbmv" "zhemm" "zhemv" "zher" "zher2" "cher2k"
"zher2k" "zherk" "zhpmv" "zhpr" "zhpr2" "zrotg" "zscal" "zswap" "zsymm" "cherk"
"zsyr2k" "zsyrk" "ztbmv" "ztbsv" "ztpmv" "ztpsv" "ztrmm" "ztrmv" "ztrsm" "chpmv"
"chpr"
"chpr2"
"crotg"
"cscal"
"csrot"
"csscal"
"cswap"
"csymm"
"csyr2k"
"csyrk"
"ctbmv"
"ctbsv"
"ctpmv"
"ctpsv"
"ctrmm"
"ctrmv"
"ctrsm"
"ctrsv"
"dasum"
"daxpy"
"dcabs1"
"dcopy"
"ddot"
"dgbmv"
"dgemm"
"dgemv"
"dger"
"dnrm2"
"drot"
"drotg"
"drotm"
"drotmg"
"dsbmv"
"dscal"
"dsdot"
"dspmv"
"dspr"
"dspr2"
"dswap"
"dsymm"
"dsymv"
"dsyr"
"dsyr2"
"dsyr2k"
"dsyrk"
"dtbmv"
"dtbsv"
"dtpmv"
"dtpsv"
"dtrmm"
"dtrmv"
"dtrsm"
"dtrsv"
"dzasum"
"dznrm2"
"icamax"
"idamax"
"isamax"
"izamax"
"lsame"
"sasum"
"saxpy"
"scabs1"
"scasum"
"scnrm2"
"scopy"
"sdot"
"sdsdot"
"sgbmv"
"sgemm"
"sgemv"
"sger"
"snrm2"
"srot"
"srotg"
"srotm"
"srotmg"
"ssbmv"
"sscal"
"sspmv"
"sspr"
"sspr2"
"sswap"
"ssymm"
"ssymv"
"ssyr"
"ssyr2"
"ssyr2k"
"ssyrk"
"stbmv"
"stbsv"
"stpmv"
"stpsv"
"strmm"
"strmv"
"strsm"
"strsv"
"xerbla"
"xerbla_array"
"zaxpy"
"zcopy"
"zdotc"
"zdotu"
"zdrot"
"zdscal"
"zgbmv"
"zgemm"
"zgemv"
"zgerc"
"zgeru"
"zhbmv"
"zhemm"
"zhemv"
"zher"
"zher2"
"zher2k"
"zherk"
"zhpmv"
"zhpr"
"zhpr2"
"zrotg"
"zscal"
"zswap"
"zsymm"
"zsyr2k"
"zsyrk"
"ztbmv"
"ztbsv"
"ztpmv"
"ztpsv"
"ztrmm"
"ztrmv"
"ztrsm"
"ztrsv" "ztrsv"
]; ];
version = "3"; version = "3";
canonicalExtension = if stdenv.hostPlatform.isLinux canonicalExtension = if stdenv.hostPlatform.isLinux then
then "${stdenv.hostPlatform.extensions.sharedLibrary}.${version}" "${stdenv.hostPlatform.extensions.sharedLibrary}.${version}"
else stdenv.hostPlatform.extensions.sharedLibrary; else
stdenv.hostPlatform.extensions.sharedLibrary;
blasImplementation = lib.getName blasProvider; blasImplementation = lib.getName blasProvider;
blasProvider' = if blasImplementation == "mkl" blasProvider' = if blasImplementation == "mkl" then
then blasProvider blasProvider
else blasProvider.override { blas64 = isILP64; }; else
blasProvider.override { blas64 = isILP64; };
in in assert isILP64 -> blasImplementation == "mkl" || blasProvider'.blas64;
assert isILP64 -> blasImplementation == "mkl" || blasProvider'.blas64;
stdenv.mkDerivation { stdenv.mkDerivation {
pname = "blas"; pname = "blas";
@ -46,8 +176,9 @@ stdenv.mkDerivation {
outputs = [ "out" "dev" ]; outputs = [ "out" "dev" ];
meta = (blasProvider'.meta or {}) // { meta = (blasProvider'.meta or { }) // {
description = "${lib.getName blasProvider} with just the BLAS C and FORTRAN ABI"; description =
"${lib.getName blasProvider} with just the BLAS C and FORTRAN ABI";
}; };
passthru = { passthru = {
@ -63,81 +194,91 @@ stdenv.mkDerivation {
dontPatchELF = true; dontPatchELF = true;
installPhase = ('' installPhase = (''
mkdir -p $out/lib $dev/include $dev/lib/pkgconfig mkdir -p $out/lib $dev/include $dev/lib/pkgconfig
libblas="${lib.getLib blasProvider'}/lib/libblas${canonicalExtension}" libblas="${lib.getLib blasProvider'}/lib/libblas${canonicalExtension}"
if ! [ -e "$libblas" ]; then if ! [ -e "$libblas" ]; then
echo "$libblas does not exist, ${blasProvider'.name} does not provide libblas." echo "$libblas does not exist, ${blasProvider'.name} does not provide libblas."
exit 1 exit 1
fi fi
$NM -an "$libblas" | cut -f3 -d' ' > symbols $NM -an "$libblas" | cut -f3 -d' ' > symbols
for symbol in ${toString blasFortranSymbols}; do for symbol in ${toString blasFortranSymbols}; do
grep -q "^$symbol_$" symbols || { echo "$symbol" was not found in "$libblas"; exit 1; } grep -q "^$symbol_$" symbols || { echo "$symbol" was not found in "$libblas"; exit 1; }
done done
cp -L "$libblas" $out/lib/libblas${canonicalExtension} cp -L "$libblas" $out/lib/libblas${canonicalExtension}
chmod +w $out/lib/libblas${canonicalExtension} chmod +w $out/lib/libblas${canonicalExtension}
'' + (if stdenv.hostPlatform.isElf then '' '' + (if stdenv.hostPlatform.isElf then ''
patchelf --set-soname libblas${canonicalExtension} $out/lib/libblas${canonicalExtension} patchelf --set-soname libblas${canonicalExtension} $out/lib/libblas${canonicalExtension}
patchelf --set-rpath "$(patchelf --print-rpath $out/lib/libblas${canonicalExtension}):${lib.getLib blasProvider'}/lib" $out/lib/libblas${canonicalExtension} patchelf --set-rpath "$(patchelf --print-rpath $out/lib/libblas${canonicalExtension}):${
'' else lib.optionalString (stdenv.hostPlatform.isDarwin) '' lib.getLib blasProvider'
install_name_tool \ }/lib" $out/lib/libblas${canonicalExtension}
-id $out/lib/libblas${canonicalExtension} \ '' else
-add_rpath ${lib.getLib blasProvider'}/lib \ lib.optionalString (stdenv.hostPlatform.isDarwin) ''
$out/lib/libblas${canonicalExtension} install_name_tool \
'') + '' -id $out/lib/libblas${canonicalExtension} \
-add_rpath ${lib.getLib blasProvider'}/lib \
$out/lib/libblas${canonicalExtension}
'') + ''
if [ "$out/lib/libblas${canonicalExtension}" != "$out/lib/libblas${stdenv.hostPlatform.extensions.sharedLibrary}" ]; then if [ "$out/lib/libblas${canonicalExtension}" != "$out/lib/libblas${stdenv.hostPlatform.extensions.sharedLibrary}" ]; then
ln -s $out/lib/libblas${canonicalExtension} "$out/lib/libblas${stdenv.hostPlatform.extensions.sharedLibrary}" ln -s $out/lib/libblas${canonicalExtension} "$out/lib/libblas${stdenv.hostPlatform.extensions.sharedLibrary}"
fi fi
cat <<EOF > $dev/lib/pkgconfig/blas.pc cat <<EOF > $dev/lib/pkgconfig/blas.pc
Name: blas Name: blas
Version: ${version} Version: ${version}
Description: BLAS FORTRAN implementation Description: BLAS FORTRAN implementation
Libs: -L$out/lib -lblas Libs: -L$out/lib -lblas
Cflags: -I$dev/include Cflags: -I$dev/include
EOF EOF
libcblas="${lib.getLib blasProvider'}/lib/libcblas${canonicalExtension}" libcblas="${lib.getLib blasProvider'}/lib/libcblas${canonicalExtension}"
if ! [ -e "$libcblas" ]; then if ! [ -e "$libcblas" ]; then
echo "$libcblas does not exist, ${blasProvider'.name} does not provide libcblas." echo "$libcblas does not exist, ${blasProvider'.name} does not provide libcblas."
exit 1 exit 1
fi fi
cp -L "$libcblas" $out/lib/libcblas${canonicalExtension} cp -L "$libcblas" $out/lib/libcblas${canonicalExtension}
chmod +w $out/lib/libcblas${canonicalExtension} chmod +w $out/lib/libcblas${canonicalExtension}
'' + (if stdenv.hostPlatform.isElf then '' '' + (if stdenv.hostPlatform.isElf then ''
patchelf --set-soname libcblas${canonicalExtension} $out/lib/libcblas${canonicalExtension} patchelf --set-soname libcblas${canonicalExtension} $out/lib/libcblas${canonicalExtension}
patchelf --set-rpath "$(patchelf --print-rpath $out/lib/libcblas${canonicalExtension}):${lib.getLib blasProvider'}/lib" $out/lib/libcblas${canonicalExtension} patchelf --set-rpath "$(patchelf --print-rpath $out/lib/libcblas${canonicalExtension}):${
'' else lib.optionalString stdenv.hostPlatform.isDarwin '' lib.getLib blasProvider'
install_name_tool \ }/lib" $out/lib/libcblas${canonicalExtension}
-id $out/lib/libcblas${canonicalExtension} \ '' else
-add_rpath ${lib.getLib blasProvider'}/lib \ lib.optionalString stdenv.hostPlatform.isDarwin ''
$out/lib/libcblas${canonicalExtension} install_name_tool \
'') + '' -id $out/lib/libcblas${canonicalExtension} \
if [ "$out/lib/libcblas${canonicalExtension}" != "$out/lib/libcblas${stdenv.hostPlatform.extensions.sharedLibrary}" ]; then -add_rpath ${lib.getLib blasProvider'}/lib \
ln -s $out/lib/libcblas${canonicalExtension} "$out/lib/libcblas${stdenv.hostPlatform.extensions.sharedLibrary}" $out/lib/libcblas${canonicalExtension}
fi '') + ''
if [ "$out/lib/libcblas${canonicalExtension}" != "$out/lib/libcblas${stdenv.hostPlatform.extensions.sharedLibrary}" ]; then
ln -s $out/lib/libcblas${canonicalExtension} "$out/lib/libcblas${stdenv.hostPlatform.extensions.sharedLibrary}"
fi
cp ${lib.getDev lapack-reference}/include/cblas{,_mangling}.h $dev/include cp ${
lib.getDev lapack-reference
}/include/cblas{,_mangling}.h $dev/include
cat <<EOF > $dev/lib/pkgconfig/cblas.pc cat <<EOF > $dev/lib/pkgconfig/cblas.pc
Name: cblas Name: cblas
Version: ${version} Version: ${version}
Description: BLAS C implementation Description: BLAS C implementation
Cflags: -I$dev/include Cflags: -I$dev/include
Libs: -L$out/lib -lcblas Libs: -L$out/lib -lcblas
EOF EOF
'' + lib.optionalString (blasImplementation == "mkl") '' '' + lib.optionalString (blasImplementation == "mkl") ''
mkdir -p $out/nix-support mkdir -p $out/nix-support
echo 'export MKL_INTERFACE_LAYER=${lib.optionalString isILP64 "I"}LP64,GNU' > $out/nix-support/setup-hook echo 'export MKL_INTERFACE_LAYER=${
ln -s $out/lib/libblas${canonicalExtension} $out/lib/libmkl_rt${stdenv.hostPlatform.extensions.sharedLibrary} lib.optionalString isILP64 "I"
ln -sf ${blasProvider'}/include/* $dev/include }LP64,GNU' > $out/nix-support/setup-hook
''); ln -s $out/lib/libblas${canonicalExtension} $out/lib/libmkl_rt${stdenv.hostPlatform.extensions.sharedLibrary}
ln -sf ${blasProvider'}/include/* $dev/include
'');
} }

View file

@ -1,23 +1,21 @@
{ lib, stdenv { lib, stdenv, lapack-reference, openblas, isILP64 ? false
, lapack-reference, openblas
, isILP64 ? false
, lapackProvider ? openblas }: , lapackProvider ? openblas }:
let let
version = "3"; version = "3";
canonicalExtension = if stdenv.hostPlatform.isLinux canonicalExtension = if stdenv.hostPlatform.isLinux then
then "${stdenv.hostPlatform.extensions.sharedLibrary}.${version}" "${stdenv.hostPlatform.extensions.sharedLibrary}.${version}"
else stdenv.hostPlatform.extensions.sharedLibrary; else
stdenv.hostPlatform.extensions.sharedLibrary;
lapackImplementation = lib.getName lapackProvider; lapackImplementation = lib.getName lapackProvider;
lapackProvider' = if lapackImplementation == "mkl" lapackProvider' = if lapackImplementation == "mkl" then
then lapackProvider lapackProvider
else lapackProvider.override { blas64 = isILP64; }; else
lapackProvider.override { blas64 = isILP64; };
in in assert isILP64 -> lapackImplementation == "mkl" || lapackProvider'.blas64;
assert isILP64 -> lapackImplementation == "mkl" || lapackProvider'.blas64;
stdenv.mkDerivation { stdenv.mkDerivation {
pname = "lapack"; pname = "lapack";
@ -25,8 +23,9 @@ stdenv.mkDerivation {
outputs = [ "out" "dev" ]; outputs = [ "out" "dev" ];
meta = (lapackProvider'.meta or {}) // { meta = (lapackProvider'.meta or { }) // {
description = "${lib.getName lapackProvider'} with just the LAPACK C and FORTRAN ABI"; description =
"${lib.getName lapackProvider'} with just the LAPACK C and FORTRAN ABI";
}; };
passthru = { passthru = {
@ -45,69 +44,79 @@ stdenv.mkDerivation {
dontPatchELF = true; dontPatchELF = true;
installPhase = ('' installPhase = (''
mkdir -p $out/lib $dev/include $dev/lib/pkgconfig mkdir -p $out/lib $dev/include $dev/lib/pkgconfig
liblapack="${lib.getLib lapackProvider'}/lib/liblapack${canonicalExtension}" liblapack="${lib.getLib lapackProvider'}/lib/liblapack${canonicalExtension}"
if ! [ -e "$liblapack" ]; then if ! [ -e "$liblapack" ]; then
echo "$liblapack does not exist, ${lapackProvider'.name} does not provide liblapack." echo "$liblapack does not exist, ${lapackProvider'.name} does not provide liblapack."
exit 1 exit 1
fi fi
cp -L "$liblapack" $out/lib/liblapack${canonicalExtension} cp -L "$liblapack" $out/lib/liblapack${canonicalExtension}
chmod +w $out/lib/liblapack${canonicalExtension} chmod +w $out/lib/liblapack${canonicalExtension}
'' + (lib.optionalString stdenv.hostPlatform.isElf '' '' + (lib.optionalString stdenv.hostPlatform.isElf ''
patchelf --set-soname liblapack${canonicalExtension} $out/lib/liblapack${canonicalExtension} patchelf --set-soname liblapack${canonicalExtension} $out/lib/liblapack${canonicalExtension}
patchelf --set-rpath "$(patchelf --print-rpath $out/lib/liblapack${canonicalExtension}):${lapackProvider'}/lib" $out/lib/liblapack${canonicalExtension} patchelf --set-rpath "$(patchelf --print-rpath $out/lib/liblapack${canonicalExtension}):${lapackProvider'}/lib" $out/lib/liblapack${canonicalExtension}
'') + '' '') + ''
if [ "$out/lib/liblapack${canonicalExtension}" != "$out/lib/liblapack${stdenv.hostPlatform.extensions.sharedLibrary}" ]; then if [ "$out/lib/liblapack${canonicalExtension}" != "$out/lib/liblapack${stdenv.hostPlatform.extensions.sharedLibrary}" ]; then
ln -s $out/lib/liblapack${canonicalExtension} "$out/lib/liblapack${stdenv.hostPlatform.extensions.sharedLibrary}" ln -s $out/lib/liblapack${canonicalExtension} "$out/lib/liblapack${stdenv.hostPlatform.extensions.sharedLibrary}"
fi fi
install -D ${lib.getDev lapack-reference}/include/lapack.h $dev/include/lapack.h install -D ${
lib.getDev lapack-reference
}/include/lapack.h $dev/include/lapack.h
cat <<EOF > $dev/lib/pkgconfig/lapack.pc cat <<EOF > $dev/lib/pkgconfig/lapack.pc
Name: lapack Name: lapack
Version: ${version} Version: ${version}
Description: LAPACK FORTRAN implementation Description: LAPACK FORTRAN implementation
Cflags: -I$dev/include Cflags: -I$dev/include
Libs: -L$out/lib -llapack Libs: -L$out/lib -llapack
EOF EOF
liblapacke="${lib.getLib lapackProvider'}/lib/liblapacke${canonicalExtension}" liblapacke="${
lib.getLib lapackProvider'
}/lib/liblapacke${canonicalExtension}"
if ! [ -e "$liblapacke" ]; then if ! [ -e "$liblapacke" ]; then
echo "$liblapacke does not exist, ${lapackProvider'.name} does not provide liblapacke." echo "$liblapacke does not exist, ${lapackProvider'.name} does not provide liblapacke."
exit 1 exit 1
fi fi
cp -L "$liblapacke" $out/lib/liblapacke${canonicalExtension} cp -L "$liblapacke" $out/lib/liblapacke${canonicalExtension}
chmod +w $out/lib/liblapacke${canonicalExtension} chmod +w $out/lib/liblapacke${canonicalExtension}
'' + (lib.optionalString stdenv.hostPlatform.isElf '' '' + (lib.optionalString stdenv.hostPlatform.isElf ''
patchelf --set-soname liblapacke${canonicalExtension} $out/lib/liblapacke${canonicalExtension} patchelf --set-soname liblapacke${canonicalExtension} $out/lib/liblapacke${canonicalExtension}
patchelf --set-rpath "$(patchelf --print-rpath $out/lib/liblapacke${canonicalExtension}):${lib.getLib lapackProvider'}/lib" $out/lib/liblapacke${canonicalExtension} patchelf --set-rpath "$(patchelf --print-rpath $out/lib/liblapacke${canonicalExtension}):${
'') + '' lib.getLib lapackProvider'
}/lib" $out/lib/liblapacke${canonicalExtension}
'') + ''
if [ -f "$out/lib/liblapacke.so.3" ]; then if [ -f "$out/lib/liblapacke.so.3" ]; then
ln -s $out/lib/liblapacke.so.3 $out/lib/liblapacke.so ln -s $out/lib/liblapacke.so.3 $out/lib/liblapacke.so
fi fi
cp ${lib.getDev lapack-reference}/include/lapacke{,_mangling,_config,_utils}.h $dev/include cp ${
lib.getDev lapack-reference
}/include/lapacke{,_mangling,_config,_utils}.h $dev/include
cat <<EOF > $dev/lib/pkgconfig/lapacke.pc cat <<EOF > $dev/lib/pkgconfig/lapacke.pc
Name: lapacke Name: lapacke
Version: ${version} Version: ${version}
Description: LAPACK C implementation Description: LAPACK C implementation
Cflags: -I$dev/include Cflags: -I$dev/include
Libs: -L$out/lib -llapacke Libs: -L$out/lib -llapacke
EOF EOF
'' + lib.optionalString (lapackImplementation == "mkl") '' '' + lib.optionalString (lapackImplementation == "mkl") ''
mkdir -p $out/nix-support mkdir -p $out/nix-support
echo 'export MKL_INTERFACE_LAYER=${lib.optionalString isILP64 "I"}LP64,GNU' > $out/nix-support/setup-hook echo 'export MKL_INTERFACE_LAYER=${
ln -s $out/lib/liblapack${canonicalExtension} $out/lib/libmkl_rt${stdenv.hostPlatform.extensions.sharedLibrary} lib.optionalString isILP64 "I"
ln -sf ${lapackProvider'}/include/* $dev/include }LP64,GNU' > $out/nix-support/setup-hook
''); ln -s $out/lib/liblapack${canonicalExtension} $out/lib/libmkl_rt${stdenv.hostPlatform.extensions.sharedLibrary}
ln -sf ${lapackProvider'}/include/* $dev/include
'');
} }

View file

@ -1,14 +1,5 @@
{ lib { lib, bash, binutils-unwrapped, coreutils, gawk, libarchive, pv, squashfsTools
, bash , buildFHSEnv, pkgs }:
, binutils-unwrapped
, coreutils
, gawk
, libarchive
, pv
, squashfsTools
, buildFHSEnv
, pkgs
}:
rec { rec {
appimage-exec = pkgs.substituteAll { appimage-exec = pkgs.substituteAll {
@ -26,9 +17,9 @@ rec {
]; ];
}; };
extract = args@{ name ? "${args.pname}-${args.version}", postExtract ? "", src, ... }: pkgs.runCommand "${name}-extracted" { extract =
buildInputs = [ appimage-exec ]; args@{ name ? "${args.pname}-${args.version}", postExtract ? "", src, ... }:
} '' pkgs.runCommand "${name}-extracted" { buildInputs = [ appimage-exec ]; } ''
appimage-exec.sh -x $out ${src} appimage-exec.sh -x $out ${src}
${postExtract} ${postExtract}
''; '';
@ -38,173 +29,172 @@ rec {
extractType2 = extract; extractType2 = extract;
wrapType1 = wrapType2; wrapType1 = wrapType2;
wrapAppImage = args@{ wrapAppImage = args@{ src, extraPkgs, meta ? { }, ... }:
src, buildFHSEnv (defaultFhsEnvArgs // {
extraPkgs, targetPkgs = pkgs:
meta ? {}, [ appimage-exec ] ++ defaultFhsEnvArgs.targetPkgs pkgs
... ++ extraPkgs pkgs;
}: buildFHSEnv
(defaultFhsEnvArgs // {
targetPkgs = pkgs: [ appimage-exec ]
++ defaultFhsEnvArgs.targetPkgs pkgs ++ extraPkgs pkgs;
runScript = "appimage-exec.sh -w ${src} --"; runScript = "appimage-exec.sh -w ${src} --";
meta = { meta = {
sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ]; sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ];
} // meta; } // meta;
} // (removeAttrs args (builtins.attrNames (builtins.functionArgs wrapAppImage)))); } // (removeAttrs args
(builtins.attrNames (builtins.functionArgs wrapAppImage))));
wrapType2 = args@{ src, extraPkgs ? pkgs: [ ], ... }: wrapAppImage wrapType2 = args@{ src, extraPkgs ? pkgs: [ ], ... }:
(args // { wrapAppImage (args // {
inherit extraPkgs; inherit extraPkgs;
src = extract (lib.filterAttrs (key: value: builtins.elem key [ "name" "pname" "version" "src" ]) args); src = extract (lib.filterAttrs
(key: value: builtins.elem key [ "name" "pname" "version" "src" ])
args);
# passthru src to make nix-update work # passthru src to make nix-update work
# hack to keep the origin position (unsafeGetAttrPos) # hack to keep the origin position (unsafeGetAttrPos)
passthru = lib.pipe args [ passthru =
lib.attrNames lib.pipe args [ lib.attrNames (lib.remove "src") (removeAttrs args) ]
(lib.remove "src") // args.passthru or { };
(removeAttrs args)
] // args.passthru or { };
}); });
defaultFhsEnvArgs = { defaultFhsEnvArgs = {
# Most of the packages were taken from the Steam chroot # Most of the packages were taken from the Steam chroot
targetPkgs = pkgs: with pkgs; [ targetPkgs = pkgs:
gtk3 with pkgs; [
bashInteractive gtk3
gnome.zenity bashInteractive
xorg.xrandr gnome.zenity
which xorg.xrandr
perl which
xdg-utils perl
iana-etc xdg-utils
krb5 iana-etc
gsettings-desktop-schemas krb5
hicolor-icon-theme # dont show a gtk warning about hicolor not being installed gsettings-desktop-schemas
]; hicolor-icon-theme # dont show a gtk warning about hicolor not being installed
];
# list of libraries expected in an appimage environment: # list of libraries expected in an appimage environment:
# https://github.com/AppImage/pkg2appimage/blob/master/excludelist # https://github.com/AppImage/pkg2appimage/blob/master/excludelist
multiPkgs = pkgs: with pkgs; [ multiPkgs = pkgs:
desktop-file-utils with pkgs; [
xorg.libXcomposite desktop-file-utils
xorg.libXtst xorg.libXcomposite
xorg.libXrandr xorg.libXtst
xorg.libXext xorg.libXrandr
xorg.libX11 xorg.libXext
xorg.libXfixes xorg.libX11
libGL xorg.libXfixes
libGL
gst_all_1.gstreamer gst_all_1.gstreamer
gst_all_1.gst-plugins-ugly gst_all_1.gst-plugins-ugly
gst_all_1.gst-plugins-base gst_all_1.gst-plugins-base
libdrm libdrm
xorg.xkeyboardconfig xorg.xkeyboardconfig
xorg.libpciaccess xorg.libpciaccess
glib glib
gtk2 gtk2
bzip2 bzip2
zlib zlib
gdk-pixbuf gdk-pixbuf
xorg.libXinerama xorg.libXinerama
xorg.libXdamage xorg.libXdamage
xorg.libXcursor xorg.libXcursor
xorg.libXrender xorg.libXrender
xorg.libXScrnSaver xorg.libXScrnSaver
xorg.libXxf86vm xorg.libXxf86vm
xorg.libXi xorg.libXi
xorg.libSM xorg.libSM
xorg.libICE xorg.libICE
freetype freetype
curlWithGnuTls curlWithGnuTls
nspr nspr
nss nss
fontconfig fontconfig
cairo cairo
pango pango
expat expat
dbus dbus
cups cups
libcap libcap
SDL2 SDL2
libusb1 libusb1
udev udev
dbus-glib dbus-glib
atk atk
at-spi2-atk at-spi2-atk
libudev0-shim libudev0-shim
xorg.libXt xorg.libXt
xorg.libXmu xorg.libXmu
xorg.libxcb xorg.libxcb
xorg.xcbutil xorg.xcbutil
xorg.xcbutilwm xorg.xcbutilwm
xorg.xcbutilimage xorg.xcbutilimage
xorg.xcbutilkeysyms xorg.xcbutilkeysyms
xorg.xcbutilrenderutil xorg.xcbutilrenderutil
libGLU libGLU
libuuid libuuid
libogg libogg
libvorbis libvorbis
SDL SDL
SDL2_image SDL2_image
glew110 glew110
openssl openssl
libidn libidn
tbb tbb
wayland wayland
mesa mesa
libxkbcommon libxkbcommon
vulkan-loader vulkan-loader
flac flac
freeglut freeglut
libjpeg libjpeg
libpng12 libpng12
libpulseaudio libpulseaudio
libsamplerate libsamplerate
libmikmod libmikmod
libthai libthai
libtheora libtheora
libtiff libtiff
pixman pixman
speex speex
SDL_image SDL_image
SDL_ttf SDL_ttf
SDL_mixer SDL_mixer
SDL2_ttf SDL2_ttf
SDL2_mixer SDL2_mixer
libappindicator-gtk2 libappindicator-gtk2
libcaca libcaca
libcanberra libcanberra
libgcrypt libgcrypt
libvpx libvpx
librsvg librsvg
xorg.libXft xorg.libXft
libvdpau libvdpau
alsa-lib alsa-lib
harfbuzz harfbuzz
e2fsprogs e2fsprogs
libgpg-error libgpg-error
keyutils.lib keyutils.lib
libjack2 libjack2
fribidi fribidi
p11-kit p11-kit
gmp gmp
# libraries not on the upstream include list, but nevertheless expected # libraries not on the upstream include list, but nevertheless expected
# by at least one appimage # by at least one appimage
libtool.lib # for Synfigstudio libtool.lib # for Synfigstudio
xorg.libxshmfence # for apple-music-electron xorg.libxshmfence # for apple-music-electron
at-spi2-core at-spi2-core
pciutils # for FreeCAD pciutils # for FreeCAD
pipewire # immersed-vr wayland support pipewire # immersed-vr wayland support
]; ];
}; };
} }

View file

@ -6,9 +6,7 @@
# For example, in the Nixpkgs repo: # For example, in the Nixpkgs repo:
# nix-build -E 'with import ./. {}; mkBinaryCache { rootPaths = [hello]; }' # nix-build -E 'with import ./. {}; mkBinaryCache { rootPaths = [hello]; }'
{ name ? "binary-cache" { name ? "binary-cache", rootPaths }:
, rootPaths
}:
stdenv.mkDerivation { stdenv.mkDerivation {
inherit name; inherit name;

View file

@ -5,60 +5,48 @@
# script that sets up the right environment variables so that the # script that sets up the right environment variables so that the
# compiler and the linker just "work". # compiler and the linker just "work".
{ name ? "" { name ? "", lib, stdenvNoCC, runtimeShell, bintools ? null, libc ? null
, lib , coreutils ? null, gnugrep ? null, netbsd ? null, netbsdCross ? null
, stdenvNoCC , sharedLibraryLoader ? if libc == null then
, runtimeShell null
, bintools ? null, libc ? null, coreutils ? null, gnugrep ? null else if stdenvNoCC.targetPlatform.isNetBSD then
, netbsd ? null, netbsdCross ? null if !(targetPackages ? netbsdCross) then
, sharedLibraryLoader ? netbsd.ld_elf_so
if libc == null then else if libc != targetPackages.netbsdCross.headers then
null targetPackages.netbsdCross.ld_elf_so
else if stdenvNoCC.targetPlatform.isNetBSD then
if !(targetPackages ? netbsdCross) then
netbsd.ld_elf_so
else if libc != targetPackages.netbsdCross.headers then
targetPackages.netbsdCross.ld_elf_so
else
null
else else
lib.getLib libc null
, nativeTools, noLibc ? false, nativeLibc, nativePrefix ? "" else
, propagateDoc ? bintools != null && bintools ? man lib.getLib libc, nativeTools, noLibc ? false, nativeLibc, nativePrefix ? ""
, extraPackages ? [], extraBuildCommands ? "" , propagateDoc ? bintools != null && bintools ? man, extraPackages ? [ ]
, isGNU ? bintools.isGNU or false , extraBuildCommands ? "", isGNU ? bintools.isGNU or false
, isLLVM ? bintools.isLLVM or false , isLLVM ? bintools.isLLVM or false, isCCTools ? bintools.isCCTools or false
, isCCTools ? bintools.isCCTools or false , expand-response-params, targetPackages ? { }, useMacosReexportHack ? false
, expand-response-params
, targetPackages ? {}
, useMacosReexportHack ? false
, wrapGas ? false , wrapGas ? false
# Note: the hardening flags are part of the bintools-wrapper, rather than # Note: the hardening flags are part of the bintools-wrapper, rather than
# the cc-wrapper, because a few of them are handled by the linker. # the cc-wrapper, because a few of them are handled by the linker.
, defaultHardeningFlags ? [ , defaultHardeningFlags ? [
"bindnow" "bindnow"
"format" "format"
"fortify" "fortify"
"fortify3" "fortify3"
"pic" "pic"
"relro" "relro"
"stackprotector" "stackprotector"
"strictoverflow" "strictoverflow"
] ++ lib.optional (with stdenvNoCC; ] ++ lib.optional (with stdenvNoCC;
# Musl-based platforms will keep "pie", other platforms will not. # Musl-based platforms will keep "pie", other platforms will not.
# If you change this, make sure to update section `{#sec-hardening-in-nixpkgs}` # If you change this, make sure to update section `{#sec-hardening-in-nixpkgs}`
# in the nixpkgs manual to inform users about the defaults. # in the nixpkgs manual to inform users about the defaults.
targetPlatform.libc == "musl" targetPlatform.libc == "musl"
# Except when: # Except when:
# - static aarch64, where compilation works, but produces segfaulting dynamically linked binaries. # - static aarch64, where compilation works, but produces segfaulting dynamically linked binaries.
# - static armv7l, where compilation fails. # - static armv7l, where compilation fails.
&& !(targetPlatform.isAarch && targetPlatform.isStatic) && !(targetPlatform.isAarch && targetPlatform.isStatic)) "pie"
) "pie"
# Darwin code signing support utilities # Darwin code signing support utilities
, postLinkSignHook ? null, signingUtils ? null , postLinkSignHook ? null, signingUtils ? null }:
}:
assert nativeTools -> !propagateDoc && nativePrefix != ""; assert nativeTools -> !propagateDoc && nativePrefix != "";
assert !nativeTools -> bintools != null && coreutils != null && gnugrep != null; assert !nativeTools -> bintools != null && coreutils != null && gnugrep != null;
@ -67,22 +55,9 @@ assert (noLibc || nativeLibc) == (libc == null);
let let
inherit (lib) inherit (lib)
attrByPath attrByPath concatStringsSep getBin getDev getLib getName getVersion
concatStringsSep hasSuffix optional optionalAttrs optionals optionalString platforms
getBin removePrefix replaceStrings;
getDev
getLib
getName
getVersion
hasSuffix
optional
optionalAttrs
optionals
optionalString
platforms
removePrefix
replaceStrings
;
inherit (stdenvNoCC) hostPlatform targetPlatform; inherit (stdenvNoCC) hostPlatform targetPlatform;
@ -91,7 +66,7 @@ let
# TODO(@Ericson2314) Make unconditional, or optional but always true by # TODO(@Ericson2314) Make unconditional, or optional but always true by
# default. # default.
targetPrefix = optionalString (targetPlatform != hostPlatform) targetPrefix = optionalString (targetPlatform != hostPlatform)
(targetPlatform.config + "-"); (targetPlatform.config + "-");
bintoolsVersion = getVersion bintools; bintoolsVersion = getVersion bintools;
bintoolsName = removePrefix targetPrefix (getName bintools); bintoolsName = removePrefix targetPrefix (getName bintools);
@ -104,44 +79,61 @@ let
coreutils_bin = optionalString (!nativeTools) (getBin coreutils); coreutils_bin = optionalString (!nativeTools) (getBin coreutils);
# See description in cc-wrapper. # See description in cc-wrapper.
suffixSalt = replaceStrings ["-" "."] ["_" "_"] targetPlatform.config; suffixSalt = replaceStrings [ "-" "." ] [ "_" "_" ] targetPlatform.config;
# The dynamic linker has different names on different platforms. This is a # The dynamic linker has different names on different platforms. This is a
# shell glob that ought to match it. # shell glob that ought to match it.
dynamicLinker = dynamicLinker = if sharedLibraryLoader == null then
/**/ if sharedLibraryLoader == null then "" ""
else if targetPlatform.libc == "musl" then "${sharedLibraryLoader}/lib/ld-musl-*" else if targetPlatform.libc == "musl" then
else if targetPlatform.libc == "uclibc" then "${sharedLibraryLoader}/lib/ld*-uClibc.so.1" "${sharedLibraryLoader}/lib/ld-musl-*"
else if (targetPlatform.libc == "bionic" && targetPlatform.is32bit) then "/system/bin/linker" else if targetPlatform.libc == "uclibc" then
else if (targetPlatform.libc == "bionic" && targetPlatform.is64bit) then "/system/bin/linker64" "${sharedLibraryLoader}/lib/ld*-uClibc.so.1"
else if targetPlatform.libc == "nblibc" then "${sharedLibraryLoader}/libexec/ld.elf_so" else if (targetPlatform.libc == "bionic" && targetPlatform.is32bit) then
else if targetPlatform.system == "i686-linux" then "${sharedLibraryLoader}/lib/ld-linux.so.2" "/system/bin/linker"
else if targetPlatform.system == "x86_64-linux" then "${sharedLibraryLoader}/lib/ld-linux-x86-64.so.2" else if (targetPlatform.libc == "bionic" && targetPlatform.is64bit) then
"/system/bin/linker64"
else if targetPlatform.libc == "nblibc" then
"${sharedLibraryLoader}/libexec/ld.elf_so"
else if targetPlatform.system == "i686-linux" then
"${sharedLibraryLoader}/lib/ld-linux.so.2"
else if targetPlatform.system == "x86_64-linux" then
"${sharedLibraryLoader}/lib/ld-linux-x86-64.so.2"
# ELFv1 (.1) or ELFv2 (.2) ABI # ELFv1 (.1) or ELFv2 (.2) ABI
else if targetPlatform.isPower64 then "${sharedLibraryLoader}/lib/ld64.so.*" else if targetPlatform.isPower64 then
"${sharedLibraryLoader}/lib/ld64.so.*"
# ARM with a wildcard, which can be "" or "-armhf". # ARM with a wildcard, which can be "" or "-armhf".
else if (with targetPlatform; isAarch32 && isLinux) then "${sharedLibraryLoader}/lib/ld-linux*.so.3" else if (with targetPlatform; isAarch32 && isLinux) then
else if targetPlatform.system == "aarch64-linux" then "${sharedLibraryLoader}/lib/ld-linux-aarch64.so.1" "${sharedLibraryLoader}/lib/ld-linux*.so.3"
else if targetPlatform.system == "powerpc-linux" then "${sharedLibraryLoader}/lib/ld.so.1" else if targetPlatform.system == "aarch64-linux" then
else if targetPlatform.isMips then "${sharedLibraryLoader}/lib/ld.so.1" "${sharedLibraryLoader}/lib/ld-linux-aarch64.so.1"
else if targetPlatform.system == "powerpc-linux" then
"${sharedLibraryLoader}/lib/ld.so.1"
else if targetPlatform.isMips then
"${sharedLibraryLoader}/lib/ld.so.1"
# `ld-linux-riscv{32,64}-<abi>.so.1` # `ld-linux-riscv{32,64}-<abi>.so.1`
else if targetPlatform.isRiscV then "${sharedLibraryLoader}/lib/ld-linux-riscv*.so.1" else if targetPlatform.isRiscV then
else if targetPlatform.isLoongArch64 then "${sharedLibraryLoader}/lib/ld-linux-loongarch*.so.1" "${sharedLibraryLoader}/lib/ld-linux-riscv*.so.1"
else if targetPlatform.isDarwin then "/usr/lib/dyld" else if targetPlatform.isLoongArch64 then
else if targetPlatform.isFreeBSD then "/libexec/ld-elf.so.1" "${sharedLibraryLoader}/lib/ld-linux-loongarch*.so.1"
else if hasSuffix "pc-gnu" targetPlatform.config then "ld.so.1" else if targetPlatform.isDarwin then
else ""; "/usr/lib/dyld"
else if targetPlatform.isFreeBSD then
"/libexec/ld-elf.so.1"
else if hasSuffix "pc-gnu" targetPlatform.config then
"ld.so.1"
else
"";
in in stdenvNoCC.mkDerivation {
stdenvNoCC.mkDerivation {
pname = targetPrefix pname = targetPrefix
+ (if name != "" then name else "${bintoolsName}-wrapper"); + (if name != "" then name else "${bintoolsName}-wrapper");
version = optionalString (bintools != null) bintoolsVersion; version = optionalString (bintools != null) bintoolsVersion;
preferLocalBuild = true; preferLocalBuild = true;
outputs = [ "out" ] ++ optionals propagateDoc ([ "man" ] ++ optional (bintools ? info) "info"); outputs = [ "out" ]
++ optionals propagateDoc ([ "man" ] ++ optional (bintools ? info) "info");
passthru = { passthru = {
inherit targetPrefix suffixSalt; inherit targetPrefix suffixSalt;
@ -155,7 +147,7 @@ stdenvNoCC.mkDerivation {
(setenv "NIX_LDFLAGS_${suffixSalt}" (concat (getenv "NIX_LDFLAGS_${suffixSalt}") " -L" arg "/lib"))) (setenv "NIX_LDFLAGS_${suffixSalt}" (concat (getenv "NIX_LDFLAGS_${suffixSalt}") " -L" arg "/lib")))
(when (file-directory-p (concat arg "/lib64")) (when (file-directory-p (concat arg "/lib64"))
(setenv "NIX_LDFLAGS_${suffixSalt}" (concat (getenv "NIX_LDFLAGS_${suffixSalt}") " -L" arg "/lib64")))) (setenv "NIX_LDFLAGS_${suffixSalt}" (concat (getenv "NIX_LDFLAGS_${suffixSalt}") " -L" arg "/lib64"))))
'(${concatStringsSep " " (map (pkg: "\"${pkg}\"") pkgs)})) '(${concatStringsSep " " (map (pkg: ''"${pkg}"'') pkgs)}))
''; '';
inherit defaultHardeningFlags; inherit defaultHardeningFlags;
@ -170,36 +162,36 @@ stdenvNoCC.mkDerivation {
src=$PWD src=$PWD
''; '';
installPhase = installPhase = ''
'' mkdir -p $out/bin $out/nix-support
mkdir -p $out/bin $out/nix-support
wrap() { wrap() {
local dst="$1" local dst="$1"
local wrapper="$2" local wrapper="$2"
export prog="$3" export prog="$3"
export use_response_file_by_default=${if isCCTools then "1" else "0"} export use_response_file_by_default=${if isCCTools then "1" else "0"}
substituteAll "$wrapper" "$out/bin/$dst" substituteAll "$wrapper" "$out/bin/$dst"
chmod +x "$out/bin/$dst" chmod +x "$out/bin/$dst"
} }
'' ''
+ (if nativeTools then '' + (if nativeTools then ''
echo ${nativePrefix} > $out/nix-support/orig-bintools echo ${nativePrefix} > $out/nix-support/orig-bintools
ldPath="${nativePrefix}/bin" ldPath="${nativePrefix}/bin"
'' else '' '' else
echo $bintools_bin > $out/nix-support/orig-bintools ''
echo $bintools_bin > $out/nix-support/orig-bintools
ldPath="${bintools_bin}/bin" ldPath="${bintools_bin}/bin"
'' ''
# Solaris needs an additional ld wrapper. # Solaris needs an additional ld wrapper.
+ optionalString (targetPlatform.isSunOS && nativePrefix != "") '' + optionalString (targetPlatform.isSunOS && nativePrefix != "") ''
ldPath="${nativePrefix}/bin" ldPath="${nativePrefix}/bin"
exec="$ldPath/${targetPrefix}ld" exec="$ldPath/${targetPrefix}ld"
wrap ld-solaris ${./ld-solaris-wrapper.sh} wrap ld-solaris ${./ld-solaris-wrapper.sh}
'') '')
# If we are asked to wrap `gas` and this bintools has it, # If we are asked to wrap `gas` and this bintools has it,
# then symlink it (`as` will be symlinked next). # then symlink it (`as` will be symlinked next).
@ -224,11 +216,15 @@ stdenvNoCC.mkDerivation {
'' + (if !useMacosReexportHack then '' '' + (if !useMacosReexportHack then ''
if [ -e ''${ld:-$ldPath/${targetPrefix}ld} ]; then if [ -e ''${ld:-$ldPath/${targetPrefix}ld} ]; then
wrap ${targetPrefix}ld ${./ld-wrapper.sh} ''${ld:-$ldPath/${targetPrefix}ld} wrap ${targetPrefix}ld ${
./ld-wrapper.sh
} ''${ld:-$ldPath/${targetPrefix}ld}
fi fi
'' else '' '' else ''
ldInner="${targetPrefix}ld-reexport-delegate" ldInner="${targetPrefix}ld-reexport-delegate"
wrap "$ldInner" ${./macos-sierra-reexport-hack.bash} ''${ld:-$ldPath/${targetPrefix}ld} wrap "$ldInner" ${
./macos-sierra-reexport-hack.bash
} ''${ld:-$ldPath/${targetPrefix}ld}
wrap "${targetPrefix}ld" ${./ld-wrapper.sh} "$out/bin/$ldInner" wrap "${targetPrefix}ld" ${./ld-wrapper.sh} "$out/bin/$ldInner"
unset ldInner unset ldInner
'') + '' '') + ''
@ -242,10 +238,7 @@ stdenvNoCC.mkDerivation {
strictDeps = true; strictDeps = true;
depsTargetTargetPropagated = extraPackages; depsTargetTargetPropagated = extraPackages;
setupHooks = [ setupHooks = [ ../setup-hooks/role.bash ./setup-hook.sh ];
../setup-hooks/role.bash
./setup-hook.sh
];
postFixup = postFixup =
## ##
@ -253,45 +246,50 @@ stdenvNoCC.mkDerivation {
## ##
optionalString (libc != null) ('' optionalString (libc != null) (''
touch "$out/nix-support/libc-ldflags" touch "$out/nix-support/libc-ldflags"
echo "-L${libc_lib}${libc.libdir or "/lib"}" >> $out/nix-support/libc-ldflags echo "-L${libc_lib}${
libc.libdir or "/lib"
}" >> $out/nix-support/libc-ldflags
echo "${libc_lib}" > $out/nix-support/orig-libc echo "${libc_lib}" > $out/nix-support/orig-libc
echo "${libc_dev}" > $out/nix-support/orig-libc-dev echo "${libc_dev}" > $out/nix-support/orig-libc-dev
'' ''
## ##
## Dynamic linker support ## Dynamic linker support
## ##
+ optionalString (sharedLibraryLoader != null) '' + optionalString (sharedLibraryLoader != null) ''
if [[ -z ''${dynamicLinker+x} ]]; then if [[ -z ''${dynamicLinker+x} ]]; then
echo "Don't know the name of the dynamic linker for platform '${targetPlatform.config}', so guessing instead." >&2 echo "Don't know the name of the dynamic linker for platform '${targetPlatform.config}', so guessing instead." >&2
local dynamicLinker="${sharedLibraryLoader}/lib/ld*.so.?" local dynamicLinker="${sharedLibraryLoader}/lib/ld*.so.?"
fi fi
'' ''
# Expand globs to fill array of options # Expand globs to fill array of options
+ '' + ''
dynamicLinker=($dynamicLinker) dynamicLinker=($dynamicLinker)
case ''${#dynamicLinker[@]} in case ''${#dynamicLinker[@]} in
0) echo "No dynamic linker found for platform '${targetPlatform.config}'." >&2;; 0) echo "No dynamic linker found for platform '${targetPlatform.config}'." >&2;;
1) echo "Using dynamic linker: '$dynamicLinker'" >&2;; 1) echo "Using dynamic linker: '$dynamicLinker'" >&2;;
*) echo "Multiple dynamic linkers found for platform '${targetPlatform.config}'." >&2;; *) echo "Multiple dynamic linkers found for platform '${targetPlatform.config}'." >&2;;
esac esac
if [ -n "''${dynamicLinker-}" ]; then if [ -n "''${dynamicLinker-}" ]; then
echo $dynamicLinker > $out/nix-support/dynamic-linker echo $dynamicLinker > $out/nix-support/dynamic-linker
${if targetPlatform.isDarwin then '' ${
printf "export LD_DYLD_PATH=%q\n" "$dynamicLinker" >> $out/nix-support/setup-hook if targetPlatform.isDarwin then ''
'' else optionalString (sharedLibraryLoader != null) '' printf "export LD_DYLD_PATH=%q\n" "$dynamicLinker" >> $out/nix-support/setup-hook
if [ -e ${sharedLibraryLoader}/lib/32/ld-linux.so.2 ]; then '' else
echo ${sharedLibraryLoader}/lib/32/ld-linux.so.2 > $out/nix-support/dynamic-linker-m32 optionalString (sharedLibraryLoader != null) ''
fi if [ -e ${sharedLibraryLoader}/lib/32/ld-linux.so.2 ]; then
touch $out/nix-support/ld-set-dynamic-linker echo ${sharedLibraryLoader}/lib/32/ld-linux.so.2 > $out/nix-support/dynamic-linker-m32
''} fi
fi touch $out/nix-support/ld-set-dynamic-linker
'') ''
}
fi
'')
## ##
## User env support ## User env support
@ -301,7 +299,9 @@ stdenvNoCC.mkDerivation {
# install the wrapper, you get tools like objdump (same for any # install the wrapper, you get tools like objdump (same for any
# binaries of libc). # binaries of libc).
+ optionalString (!nativeTools) '' + optionalString (!nativeTools) ''
printWords ${bintools_bin} ${optionalString (libc != null) libc_bin} > $out/nix-support/propagated-user-env-packages printWords ${bintools_bin} ${
optionalString (libc != null) libc_bin
} > $out/nix-support/propagated-user-env-packages
'' ''
## ##
@ -376,19 +376,19 @@ stdenvNoCC.mkDerivation {
### ###
### Ensure consistent LC_VERSION_MIN_MACOSX ### Ensure consistent LC_VERSION_MIN_MACOSX
### ###
+ optionalString targetPlatform.isDarwin ( + optionalString targetPlatform.isDarwin (let
let inherit (targetPlatform)
inherit (targetPlatform) darwinPlatform darwinSdkVersion darwinMinVersion
darwinPlatform darwinSdkVersion darwinMinVersionVariable;
darwinMinVersion darwinMinVersionVariable; in ''
in '' export darwinPlatform=${darwinPlatform}
export darwinPlatform=${darwinPlatform} export darwinMinVersion=${darwinMinVersion}
export darwinMinVersion=${darwinMinVersion} export darwinSdkVersion=${darwinSdkVersion}
export darwinSdkVersion=${darwinSdkVersion} export darwinMinVersionVariable=${darwinMinVersionVariable}
export darwinMinVersionVariable=${darwinMinVersionVariable} substituteAll ${
substituteAll ${./add-darwin-ldflags-before.sh} $out/nix-support/add-local-ldflags-before.sh ./add-darwin-ldflags-before.sh
'' } $out/nix-support/add-local-ldflags-before.sh
) '')
## ##
## Code signing on Apple Silicon ## Code signing on Apple Silicon
@ -416,7 +416,8 @@ stdenvNoCC.mkDerivation {
env = { env = {
# for substitution in utils.bash # for substitution in utils.bash
# TODO(@sternenseemann): invent something cleaner than passing in "" in case of absence # TODO(@sternenseemann): invent something cleaner than passing in "" in case of absence
expandResponseParams = "${expand-response-params}/bin/expand-response-params"; expandResponseParams =
"${expand-response-params}/bin/expand-response-params";
# TODO(@sternenseemann): rename env var via stdenv rebuild # TODO(@sternenseemann): rename env var via stdenv rebuild
shell = (getBin runtimeShell + runtimeShell.shellPath or ""); shell = (getBin runtimeShell + runtimeShell.shellPath or "");
gnugrep_bin = optionalString (!nativeTools) gnugrep; gnugrep_bin = optionalString (!nativeTools) gnugrep;
@ -426,14 +427,12 @@ stdenvNoCC.mkDerivation {
default_hardening_flags_str = builtins.toString defaultHardeningFlags; default_hardening_flags_str = builtins.toString defaultHardeningFlags;
}; };
meta = meta = let bintools_ = optionalAttrs (bintools != null) bintools;
let bintools_ = optionalAttrs (bintools != null) bintools; in in (optionalAttrs (bintools_ ? meta)
(optionalAttrs (bintools_ ? meta) (removeAttrs bintools.meta ["priority"])) // (removeAttrs bintools.meta [ "priority" ])) // {
{ description = description =
attrByPath ["meta" "description"] "System binary utilities" bintools_ attrByPath [ "meta" "description" ] "System binary utilities" bintools_
+ " (wrapper script)"; + " (wrapper script)";
priority = 10; priority = 10;
} // optionalAttrs useMacosReexportHack { } // optionalAttrs useMacosReexportHack { platforms = platforms.darwin; };
platforms = platforms.darwin;
};
} }

View file

@ -1,36 +1,20 @@
{ stdenv { stdenv, cacert, lib, writeCBin }:
, cacert
, lib
, writeCBin
}:
args@{ args@{ name ? "${args.pname}-${args.version}", bazel, bazelFlags ? [ ]
name ? "${args.pname}-${args.version}" , bazelBuildFlags ? [ ], bazelTestFlags ? [ ], bazelRunFlags ? [ ]
, bazel , runTargetFlags ? [ ], bazelFetchFlags ? [ ], bazelTargets ? [ ]
, bazelFlags ? [] , bazelTestTargets ? [ ], bazelRunTarget ? null, buildAttrs, fetchAttrs
, bazelBuildFlags ? []
, bazelTestFlags ? []
, bazelRunFlags ? []
, runTargetFlags ? []
, bazelFetchFlags ? []
, bazelTargets ? []
, bazelTestTargets ? []
, bazelRunTarget ? null
, buildAttrs
, fetchAttrs
# Newer versions of Bazel are moving away from built-in rules_cc and instead # Newer versions of Bazel are moving away from built-in rules_cc and instead
# allow fetching it as an external dependency in a WORKSPACE file[1]. If # allow fetching it as an external dependency in a WORKSPACE file[1]. If
# removed in the fixed-output fetch phase, building will fail to download it. # removed in the fixed-output fetch phase, building will fail to download it.
# This can be seen e.g. in #73097 # This can be seen e.g. in #73097
# #
# This option allows configuring the removal of rules_cc in cases where a # This option allows configuring the removal of rules_cc in cases where a
# project depends on it via an external dependency. # project depends on it via an external dependency.
# #
# [1]: https://github.com/bazelbuild/rules_cc # [1]: https://github.com/bazelbuild/rules_cc
, removeRulesCC ? true , removeRulesCC ? true, removeLocalConfigCc ? true, removeLocal ? true
, removeLocalConfigCc ? true
, removeLocal ? true
# Use build --nobuild instead of fetch. This allows fetching the dependencies # Use build --nobuild instead of fetch. This allows fetching the dependencies
# required for the build as configured, rather than fetching all the dependencies # required for the build as configured, rather than fetching all the dependencies
@ -43,25 +27,13 @@ args@{
# Bazel wants all headers / libraries to come from, like when using # Bazel wants all headers / libraries to come from, like when using
# CROSSTOOL. Weirdly, we can still get the flags through the wrapped # CROSSTOOL. Weirdly, we can still get the flags through the wrapped
# compiler. # compiler.
, dontAddBazelOpts ? false , dontAddBazelOpts ? false, ... }:
, ...
}:
let let
fArgs = removeAttrs args [ "buildAttrs" "fetchAttrs" "removeRulesCC" ] // { fArgs = removeAttrs args [ "buildAttrs" "fetchAttrs" "removeRulesCC" ] // {
inherit inherit name bazelFlags bazelBuildFlags bazelTestFlags bazelRunFlags
name runTargetFlags bazelFetchFlags bazelTargets bazelTestTargets
bazelFlags bazelRunTarget dontAddBazelOpts;
bazelBuildFlags
bazelTestFlags
bazelRunFlags
runTargetFlags
bazelFetchFlags
bazelTargets
bazelTestTargets
bazelRunTarget
dontAddBazelOpts
;
}; };
fBuildAttrs = fArgs // buildAttrs; fBuildAttrs = fArgs // buildAttrs;
fFetchAttrs = fArgs // removeAttrs fetchAttrs [ "sha256" ]; fFetchAttrs = fArgs // removeAttrs fetchAttrs [ "sha256" ];
@ -83,7 +55,10 @@ let
$bazelFlags \ $bazelFlags \
${lib.strings.concatStringsSep " " additionalFlags} \ ${lib.strings.concatStringsSep " " additionalFlags} \
${lib.strings.concatStringsSep " " targets} \ ${lib.strings.concatStringsSep " " targets} \
${lib.optionalString (targetRunFlags != []) " -- " + lib.strings.concatStringsSep " " targetRunFlags} ${
lib.optionalString (targetRunFlags != [ ]) " -- "
+ lib.strings.concatStringsSep " " targetRunFlags
}
''; '';
# we need this to chmod dangling symlinks on darwin, gnu coreutils refuses to do so: # we need this to chmod dangling symlinks on darwin, gnu coreutils refuses to do so:
# chmod: cannot operate on dangling symlink '$symlink' # chmod: cannot operate on dangling symlink '$symlink'
@ -107,15 +82,15 @@ let
} }
} }
''; '';
in in stdenv.mkDerivation (fBuildAttrs // {
stdenv.mkDerivation (fBuildAttrs // {
deps = stdenv.mkDerivation (fFetchAttrs // { deps = stdenv.mkDerivation (fFetchAttrs // {
name = "${name}-deps.tar.gz"; name = "${name}-deps.tar.gz";
impureEnvVars = lib.fetchers.proxyImpureEnvVars ++ fFetchAttrs.impureEnvVars or []; impureEnvVars = lib.fetchers.proxyImpureEnvVars
++ fFetchAttrs.impureEnvVars or [ ];
nativeBuildInputs = fFetchAttrs.nativeBuildInputs or [] ++ [ bazel ]; nativeBuildInputs = fFetchAttrs.nativeBuildInputs or [ ] ++ [ bazel ];
preHook = fFetchAttrs.preHook or "" + '' preHook = fFetchAttrs.preHook or "" + ''
export bazelOut="$(echo ''${NIX_BUILD_TOP}/output | sed -e 's,//,/,g')" export bazelOut="$(echo ''${NIX_BUILD_TOP}/output | sed -e 's,//,/,g')"
@ -132,18 +107,16 @@ stdenv.mkDerivation (fBuildAttrs // {
buildPhase = fFetchAttrs.buildPhase or '' buildPhase = fFetchAttrs.buildPhase or ''
runHook preBuild runHook preBuild
${ ${bazelCmd {
bazelCmd { cmd = if fetchConfigured then "build --nobuild" else "fetch";
cmd = if fetchConfigured then "build --nobuild" else "fetch"; additionalFlags = [
additionalFlags = [ # We disable multithreading for the fetching phase since it can lead to timeouts with many dependencies/threads:
# We disable multithreading for the fetching phase since it can lead to timeouts with many dependencies/threads: # https://github.com/bazelbuild/bazel/issues/6502
# https://github.com/bazelbuild/bazel/issues/6502 "--loading_phase_threads=1"
"--loading_phase_threads=1" "$bazelFetchFlags"
"$bazelFetchFlags" ] ++ (if fetchConfigured then [ "--jobs" "$NIX_BUILD_CORES" ] else [ ]);
] ++ (if fetchConfigured then ["--jobs" "$NIX_BUILD_CORES"] else []); targets = fFetchAttrs.bazelTargets ++ fFetchAttrs.bazelTestTargets;
targets = fFetchAttrs.bazelTargets ++ fFetchAttrs.bazelTestTargets; }}
}
}
runHook postBuild runHook postBuild
''; '';
@ -153,10 +126,13 @@ stdenv.mkDerivation (fBuildAttrs // {
# Remove all built in external workspaces, Bazel will recreate them when building # Remove all built in external workspaces, Bazel will recreate them when building
rm -rf $bazelOut/external/{bazel_tools,\@bazel_tools.marker} rm -rf $bazelOut/external/{bazel_tools,\@bazel_tools.marker}
${lib.optionalString removeRulesCC "rm -rf $bazelOut/external/{rules_cc,\\@rules_cc.marker}"} ${lib.optionalString removeRulesCC
"rm -rf $bazelOut/external/{rules_cc,\\@rules_cc.marker}"}
rm -rf $bazelOut/external/{embedded_jdk,\@embedded_jdk.marker} rm -rf $bazelOut/external/{embedded_jdk,\@embedded_jdk.marker}
${lib.optionalString removeLocalConfigCc "rm -rf $bazelOut/external/{local_config_cc,\\@local_config_cc.marker}"} ${lib.optionalString removeLocalConfigCc
${lib.optionalString removeLocal "rm -rf $bazelOut/external/{local_*,\\@local_*.marker}"} "rm -rf $bazelOut/external/{local_config_cc,\\@local_config_cc.marker}"}
${lib.optionalString removeLocal
"rm -rf $bazelOut/external/{local_*,\\@local_*.marker}"}
# Clear markers # Clear markers
find $bazelOut/external -name '@*\.marker' -exec sh -c 'echo > {}' \; find $bazelOut/external -name '@*\.marker' -exec sh -c 'echo > {}' \;
@ -182,8 +158,8 @@ stdenv.mkDerivation (fBuildAttrs // {
rm "$symlink" rm "$symlink"
ln -sf "$new_target" "$symlink" ln -sf "$new_target" "$symlink"
'' + lib.optionalString stdenv.isDarwin '' '' + lib.optionalString stdenv.isDarwin ''
# on linux symlink permissions cannot be modified, so we modify those on darwin to match the linux ones # on linux symlink permissions cannot be modified, so we modify those on darwin to match the linux ones
${chmodder}/bin/chmodder "$symlink" ${chmodder}/bin/chmodder "$symlink"
'' + '' '' + ''
done done
@ -195,13 +171,14 @@ stdenv.mkDerivation (fBuildAttrs // {
''); '');
dontFixup = true; dontFixup = true;
allowedRequisites = []; allowedRequisites = [ ];
outputHashAlgo = "sha256"; outputHashAlgo = "sha256";
outputHash = fetchAttrs.sha256; outputHash = fetchAttrs.sha256;
}); });
nativeBuildInputs = fBuildAttrs.nativeBuildInputs or [] ++ [ (bazel.override { enableNixHacks = true; }) ]; nativeBuildInputs = fBuildAttrs.nativeBuildInputs or [ ]
++ [ (bazel.override { enableNixHacks = true; }) ];
preHook = fBuildAttrs.preHook or "" + '' preHook = fBuildAttrs.preHook or "" + ''
export bazelOut="$NIX_BUILD_TOP/output" export bazelOut="$NIX_BUILD_TOP/output"
@ -257,30 +234,27 @@ stdenv.mkDerivation (fBuildAttrs // {
done done
fi fi
${ ${bazelCmd {
bazelCmd { cmd = "test";
cmd = "test"; additionalFlags = [ "--test_output=errors" ] ++ fBuildAttrs.bazelTestFlags
additionalFlags = ++ [ "--jobs" "$NIX_BUILD_CORES" ];
["--test_output=errors"] ++ fBuildAttrs.bazelTestFlags ++ ["--jobs" "$NIX_BUILD_CORES"]; targets = fBuildAttrs.bazelTestTargets;
targets = fBuildAttrs.bazelTestTargets; }}
} ${bazelCmd {
} cmd = "build";
${ additionalFlags = fBuildAttrs.bazelBuildFlags
bazelCmd { ++ [ "--jobs" "$NIX_BUILD_CORES" ];
cmd = "build"; targets = fBuildAttrs.bazelTargets;
additionalFlags = fBuildAttrs.bazelBuildFlags ++ ["--jobs" "$NIX_BUILD_CORES"]; }}
targets = fBuildAttrs.bazelTargets; ${bazelCmd {
} cmd = "run";
} additionalFlags = fBuildAttrs.bazelRunFlags
${ ++ [ "--jobs" "$NIX_BUILD_CORES" ];
bazelCmd { # Bazel run only accepts a single target, but `bazelCmd` expects `targets` to be a list.
cmd = "run"; targets = lib.optionals (fBuildAttrs.bazelRunTarget != null)
additionalFlags = fBuildAttrs.bazelRunFlags ++ [ "--jobs" "$NIX_BUILD_CORES" ]; [ fBuildAttrs.bazelRunTarget ];
# Bazel run only accepts a single target, but `bazelCmd` expects `targets` to be a list. targetRunFlags = fBuildAttrs.runTargetFlags;
targets = lib.optionals (fBuildAttrs.bazelRunTarget != null) [ fBuildAttrs.bazelRunTarget ]; }}
targetRunFlags = fBuildAttrs.runTargetFlags;
}
}
runHook postBuild runHook postBuild
''; '';
}) })

View file

@ -1,22 +1,11 @@
{ lib { lib, stdenv, runCommandLocal, buildEnv, writeText, writeShellScriptBin, pkgs
, stdenv , pkgsi686Linux }:
, runCommandLocal
, buildEnv
, writeText
, writeShellScriptBin
, pkgs
, pkgsi686Linux
}:
{ profile ? "" { profile ? "", targetPkgs ? pkgs: [ ], multiPkgs ? pkgs: [ ]
, targetPkgs ? pkgs: []
, multiPkgs ? pkgs: []
, multiArch ? false # Whether to include 32bit packages , multiArch ? false # Whether to include 32bit packages
, extraBuildCommands ? "" , extraBuildCommands ? "", extraBuildCommandsMulti ? ""
, extraBuildCommandsMulti ? "" , extraOutputsToInstall ? [ ], ... # for name, or pname+version
, extraOutputsToInstall ? [] }@args:
, ... # for name, or pname+version
} @ args:
# HOWTO: # HOWTO:
# All packages (most likely programs) returned from targetPkgs will only be # All packages (most likely programs) returned from targetPkgs will only be
@ -36,9 +25,10 @@
let let
inherit (stdenv) is64bit; inherit (stdenv) is64bit;
name = if (args ? pname && args ? version) name = if (args ? pname && args ? version) then
then "${args.pname}-${args.version}" "${args.pname}-${args.version}"
else args.name; else
args.name;
# "use of glibc_multi is only supported on x86_64-linux" # "use of glibc_multi is only supported on x86_64-linux"
isMultiBuild = multiArch && stdenv.system == "x86_64-linux"; isMultiBuild = multiArch && stdenv.system == "x86_64-linux";
@ -46,7 +36,8 @@ let
# list of packages (usually programs) which match the host's architecture # list of packages (usually programs) which match the host's architecture
# (which includes stuff from multiPkgs) # (which includes stuff from multiPkgs)
targetPaths = targetPkgs pkgs ++ (if multiPkgs == null then [] else multiPkgs pkgs); targetPaths = targetPkgs pkgs
++ (if multiPkgs == null then [ ] else multiPkgs pkgs);
# list of packages which are for x86 (only multiPkgs, only for x86_64 hosts) # list of packages which are for x86 (only multiPkgs, only for x86_64 hosts)
multiPaths = multiPkgs pkgsi686Linux; multiPaths = multiPkgs pkgsi686Linux;
@ -74,13 +65,13 @@ let
bzip2 bzip2
xz xz
]; ];
baseMultiPaths = with pkgsi686Linux; [ baseMultiPaths = with pkgsi686Linux; [ (toString gcc.cc.lib) ];
(toString gcc.cc.lib)
];
ldconfig = writeShellScriptBin "ldconfig" '' ldconfig = writeShellScriptBin "ldconfig" ''
# due to a glibc bug, 64-bit ldconfig complains about patchelf'd 32-bit libraries, so we use 32-bit ldconfig when we have them # due to a glibc bug, 64-bit ldconfig complains about patchelf'd 32-bit libraries, so we use 32-bit ldconfig when we have them
exec ${if isMultiBuild then pkgsi686Linux.glibc.bin else pkgs.glibc.bin}/bin/ldconfig -f /etc/ld.so.conf -C /etc/ld.so.cache "$@" exec ${
if isMultiBuild then pkgsi686Linux.glibc.bin else pkgs.glibc.bin
}/bin/ldconfig -f /etc/ld.so.conf -C /etc/ld.so.cache "$@"
''; '';
etcProfile = writeText "profile" '' etcProfile = writeText "profile" ''
@ -207,9 +198,8 @@ let
ln -Ls ${staticUsrProfileTarget}/lib/32/ld-linux.so.2 lib/ ln -Ls ${staticUsrProfileTarget}/lib/32/ld-linux.so.2 lib/
''; '';
setupLibDirs = if isTargetBuild setupLibDirs =
then setupLibDirsTarget if isTargetBuild then setupLibDirsTarget else setupLibDirsMulti;
else setupLibDirsMulti;
# the target profile is the actual profile that will be used for the chroot # the target profile is the actual profile that will be used for the chroot
setupTargetProfile = '' setupTargetProfile = ''
@ -218,11 +208,11 @@ let
${setupLibDirs} ${setupLibDirs}
'' + lib.optionalString isMultiBuild '' '' + lib.optionalString isMultiBuild ''
if [ -d "${staticUsrProfileMulti}/share" ]; then if [ -d "${staticUsrProfileMulti}/share" ]; then
cp -rLf ${staticUsrProfileMulti}/share share cp -rLf ${staticUsrProfileMulti}/share share
fi fi
'' + '' '' + ''
if [ -d "${staticUsrProfileTarget}/share" ]; then if [ -d "${staticUsrProfileTarget}/share" ]; then
if [ -d share ]; then if [ -d share ]; then
chmod -R 755 share chmod -R 755 share
@ -254,7 +244,8 @@ let
in runCommandLocal "${name}-fhs" { in runCommandLocal "${name}-fhs" {
passthru = { passthru = {
inherit args baseTargetPaths targetPaths baseMultiPaths ldconfig isMultiBuild; inherit args baseTargetPaths targetPaths baseMultiPaths ldconfig
isMultiBuild;
}; };
} '' } ''
mkdir -p $out mkdir -p $out

View file

@ -1,55 +1,45 @@
{ lib { lib, stdenv, callPackage, runCommandLocal, writeShellScript, glibc
, stdenv , pkgsi686Linux, coreutils, bubblewrap }:
, callPackage
, runCommandLocal
, writeShellScript
, glibc
, pkgsi686Linux
, coreutils
, bubblewrap
}:
{ runScript ? "bash" { runScript ? "bash", extraInstallCommands ? "", meta ? { }, passthru ? { }
, extraInstallCommands ? "" , extraPreBwrapCmds ? "", extraBwrapArgs ? [ ], unshareUser ? false
, meta ? {} , unshareIpc ? false, unsharePid ? false, unshareNet ? false, unshareUts ? false
, passthru ? {} , unshareCgroup ? false, privateTmp ? false, dieWithParent ? true, ... }@args:
, extraPreBwrapCmds ? ""
, extraBwrapArgs ? []
, unshareUser ? false
, unshareIpc ? false
, unsharePid ? false
, unshareNet ? false
, unshareUts ? false
, unshareCgroup ? false
, privateTmp ? false
, dieWithParent ? true
, ...
} @ args:
assert (!args ? pname || !args ? version) -> (args ? name); # You must provide name if pname or version (preferred) is missing. assert (!args ? pname || !args ? version) -> (args
? name); # You must provide name if pname or version (preferred) is missing.
let let
inherit (lib) inherit (lib)
concatLines concatLines concatStringsSep escapeShellArgs filter optionalString
concatStringsSep splitString;
escapeShellArgs
filter
optionalString
splitString
;
inherit (lib.attrsets) removeAttrs; inherit (lib.attrsets) removeAttrs;
name = args.name or "${args.pname}-${args.version}"; name = args.name or "${args.pname}-${args.version}";
executableName = args.pname or args.name; executableName = args.pname or args.name;
# we don't know which have been supplied, and want to avoid defaulting missing attrs to null. Passed into runCommandLocal # we don't know which have been supplied, and want to avoid defaulting missing attrs to null. Passed into runCommandLocal
nameAttrs = lib.filterAttrs (key: value: builtins.elem key [ "name" "pname" "version" ]) args; nameAttrs =
lib.filterAttrs (key: value: builtins.elem key [ "name" "pname" "version" ])
args;
buildFHSEnv = callPackage ./buildFHSEnv.nix { }; buildFHSEnv = callPackage ./buildFHSEnv.nix { };
fhsenv = buildFHSEnv (removeAttrs args [ fhsenv = buildFHSEnv (removeAttrs args [
"runScript" "extraInstallCommands" "meta" "passthru" "extraPreBwrapCmds" "extraBwrapArgs" "dieWithParent" "runScript"
"unshareUser" "unshareCgroup" "unshareUts" "unshareNet" "unsharePid" "unshareIpc" "privateTmp" "extraInstallCommands"
"meta"
"passthru"
"extraPreBwrapCmds"
"extraBwrapArgs"
"dieWithParent"
"unshareUser"
"unshareCgroup"
"unshareUts"
"unshareNet"
"unsharePid"
"unshareIpc"
"privateTmp"
]); ]);
etcBindEntries = let etcBindEntries = let
@ -117,163 +107,165 @@ let
EOF EOF
ldconfig &> /dev/null ldconfig &> /dev/null
''; '';
init = run: writeShellScript "${name}-init" '' init = run:
source /etc/profile writeShellScript "${name}-init" ''
${createLdConfCache} source /etc/profile
exec ${run} "$@" ${createLdConfCache}
''; exec ${run} "$@"
'';
indentLines = str: concatLines (map (s: " " + s) (filter (s: s != "") (splitString "\n" str))); indentLines = str:
bwrapCmd = { initArgs ? "" }: '' concatLines
${extraPreBwrapCmds} (map (s: " " + s) (filter (s: s != "") (splitString "\n" str)));
ignored=(/nix /dev /proc /etc ${optionalString privateTmp "/tmp"}) bwrapCmd = { initArgs ? "" }:
ro_mounts=() ''
symlinks=() ${extraPreBwrapCmds}
etc_ignored=() ignored=(/nix /dev /proc /etc ${optionalString privateTmp "/tmp"})
ro_mounts=()
symlinks=()
etc_ignored=()
# loop through all entries of root in the fhs environment, except its /etc. # loop through all entries of root in the fhs environment, except its /etc.
for i in ${fhsenv}/*; do for i in ${fhsenv}/*; do
path="/''${i##*/}"
if [[ $path == '/etc' ]]; then
:
elif [[ -L $i ]]; then
symlinks+=(--symlink "$(${coreutils}/bin/readlink "$i")" "$path")
ignored+=("$path")
else
ro_mounts+=(--ro-bind "$i" "$path")
ignored+=("$path")
fi
done
# loop through the entries of /etc in the fhs environment.
if [[ -d ${fhsenv}/etc ]]; then
for i in ${fhsenv}/etc/*; do
path="/''${i##*/}" path="/''${i##*/}"
# NOTE: we're binding /etc/fonts and /etc/ssl/certs from the host so we if [[ $path == '/etc' ]]; then
# don't want to override it with a path from the FHS environment. :
if [[ $path == '/fonts' || $path == '/ssl' ]]; then elif [[ -L $i ]]; then
symlinks+=(--symlink "$(${coreutils}/bin/readlink "$i")" "$path")
ignored+=("$path")
else
ro_mounts+=(--ro-bind "$i" "$path")
ignored+=("$path")
fi
done
# loop through the entries of /etc in the fhs environment.
if [[ -d ${fhsenv}/etc ]]; then
for i in ${fhsenv}/etc/*; do
path="/''${i##*/}"
# NOTE: we're binding /etc/fonts and /etc/ssl/certs from the host so we
# don't want to override it with a path from the FHS environment.
if [[ $path == '/fonts' || $path == '/ssl' ]]; then
continue
fi
if [[ -L $i ]]; then
symlinks+=(--symlink "$i" "/etc$path")
else
ro_mounts+=(--ro-bind "$i" "/etc$path")
fi
etc_ignored+=("/etc$path")
done
fi
# propagate /etc from the actual host if nested
if [[ -e /.host-etc ]]; then
ro_mounts+=(--ro-bind /.host-etc /.host-etc)
else
ro_mounts+=(--ro-bind /etc /.host-etc)
fi
# link selected etc entries from the actual root
for i in ${escapeShellArgs etcBindEntries}; do
if [[ "''${etc_ignored[@]}" =~ "$i" ]]; then
continue continue
fi fi
if [[ -L $i ]]; then if [[ -e $i ]]; then
symlinks+=(--symlink "$i" "/etc$path") symlinks+=(--symlink "/.host-etc/''${i#/etc/}" "$i")
else
ro_mounts+=(--ro-bind "$i" "/etc$path")
fi fi
etc_ignored+=("/etc$path")
done done
fi
# propagate /etc from the actual host if nested declare -a auto_mounts
if [[ -e /.host-etc ]]; then # loop through all directories in the root
ro_mounts+=(--ro-bind /.host-etc /.host-etc) for dir in /*; do
else # if it is a directory and it is not ignored
ro_mounts+=(--ro-bind /etc /.host-etc) if [[ -d "$dir" ]] && [[ ! "''${ignored[@]}" =~ "$dir" ]]; then
fi # add it to the mount list
auto_mounts+=(--bind "$dir" "$dir")
# link selected etc entries from the actual root fi
for i in ${escapeShellArgs etcBindEntries}; do
if [[ "''${etc_ignored[@]}" =~ "$i" ]]; then
continue
fi
if [[ -e $i ]]; then
symlinks+=(--symlink "/.host-etc/''${i#/etc/}" "$i")
fi
done
declare -a auto_mounts
# loop through all directories in the root
for dir in /*; do
# if it is a directory and it is not ignored
if [[ -d "$dir" ]] && [[ ! "''${ignored[@]}" =~ "$dir" ]]; then
# add it to the mount list
auto_mounts+=(--bind "$dir" "$dir")
fi
done
declare -a x11_args
# Always mount a tmpfs on /tmp/.X11-unix
# Rationale: https://github.com/flatpak/flatpak/blob/be2de97e862e5ca223da40a895e54e7bf24dbfb9/common/flatpak-run.c#L277
x11_args+=(--tmpfs /tmp/.X11-unix)
# Try to guess X socket path. This doesn't cover _everything_, but it covers some things.
if [[ "$DISPLAY" == :* ]]; then
display_nr=''${DISPLAY#?}
local_socket=/tmp/.X11-unix/X$display_nr
x11_args+=(--ro-bind-try "$local_socket" "$local_socket")
fi
${optionalString privateTmp ''
# sddm places XAUTHORITY in /tmp
if [[ "$XAUTHORITY" == /tmp/* ]]; then
x11_args+=(--ro-bind-try "$XAUTHORITY" "$XAUTHORITY")
fi
# dbus-run-session puts the socket in /tmp
IFS=";" read -ra addrs <<<"$DBUS_SESSION_BUS_ADDRESS"
for addr in "''${addrs[@]}"; do
[[ "$addr" == unix:* ]] || continue
IFS="," read -ra parts <<<"''${addr#unix:}"
for part in "''${parts[@]}"; do
printf -v part '%s' "''${part//\\/\\\\}"
printf -v part '%b' "''${part//%/\\x}"
[[ "$part" == path=/tmp/* ]] || continue
x11_args+=(--ro-bind-try "''${part#path=}" "''${part#path=}")
done done
done
''}
cmd=( declare -a x11_args
${bubblewrap}/bin/bwrap # Always mount a tmpfs on /tmp/.X11-unix
--dev-bind /dev /dev # Rationale: https://github.com/flatpak/flatpak/blob/be2de97e862e5ca223da40a895e54e7bf24dbfb9/common/flatpak-run.c#L277
--proc /proc x11_args+=(--tmpfs /tmp/.X11-unix)
--chdir "$(pwd)"
${optionalString unshareUser "--unshare-user"} # Try to guess X socket path. This doesn't cover _everything_, but it covers some things.
${optionalString unshareIpc "--unshare-ipc"} if [[ "$DISPLAY" == :* ]]; then
${optionalString unsharePid "--unshare-pid"} display_nr=''${DISPLAY#?}
${optionalString unshareNet "--unshare-net"} local_socket=/tmp/.X11-unix/X$display_nr
${optionalString unshareUts "--unshare-uts"} x11_args+=(--ro-bind-try "$local_socket" "$local_socket")
${optionalString unshareCgroup "--unshare-cgroup"} fi
${optionalString dieWithParent "--die-with-parent"}
--ro-bind /nix /nix ${optionalString privateTmp ''
${optionalString privateTmp "--tmpfs /tmp"} # sddm places XAUTHORITY in /tmp
# Our glibc will look for the cache in its own path in `/nix/store`. if [[ "$XAUTHORITY" == /tmp/* ]]; then
# As such, we need a cache to exist there, because pressure-vessel x11_args+=(--ro-bind-try "$XAUTHORITY" "$XAUTHORITY")
# depends on the existence of an ld cache. However, adding one fi
# globally proved to be a bad idea (see #100655), the solution we
# settled on being mounting one via bwrap. # dbus-run-session puts the socket in /tmp
# Also, the cache needs to go to both 32 and 64 bit glibcs, for games IFS=";" read -ra addrs <<<"$DBUS_SESSION_BUS_ADDRESS"
# of both architectures to work. for addr in "''${addrs[@]}"; do
--tmpfs ${glibc}/etc \ [[ "$addr" == unix:* ]] || continue
--tmpfs /etc \ IFS="," read -ra parts <<<"''${addr#unix:}"
--symlink /etc/ld.so.conf ${glibc}/etc/ld.so.conf \ for part in "''${parts[@]}"; do
--symlink /etc/ld.so.cache ${glibc}/etc/ld.so.cache \ printf -v part '%s' "''${part//\\/\\\\}"
--ro-bind ${glibc}/etc/rpc ${glibc}/etc/rpc \ printf -v part '%b' "''${part//%/\\x}"
--remount-ro ${glibc}/etc \ [[ "$part" == path=/tmp/* ]] || continue
'' + optionalString fhsenv.isMultiBuild (indentLines '' x11_args+=(--ro-bind-try "''${part#path=}" "''${part#path=}")
done
done
''}
cmd=(
${bubblewrap}/bin/bwrap
--dev-bind /dev /dev
--proc /proc
--chdir "$(pwd)"
${optionalString unshareUser "--unshare-user"}
${optionalString unshareIpc "--unshare-ipc"}
${optionalString unsharePid "--unshare-pid"}
${optionalString unshareNet "--unshare-net"}
${optionalString unshareUts "--unshare-uts"}
${optionalString unshareCgroup "--unshare-cgroup"}
${optionalString dieWithParent "--die-with-parent"}
--ro-bind /nix /nix
${optionalString privateTmp "--tmpfs /tmp"}
# Our glibc will look for the cache in its own path in `/nix/store`.
# As such, we need a cache to exist there, because pressure-vessel
# depends on the existence of an ld cache. However, adding one
# globally proved to be a bad idea (see #100655), the solution we
# settled on being mounting one via bwrap.
# Also, the cache needs to go to both 32 and 64 bit glibcs, for games
# of both architectures to work.
--tmpfs ${glibc}/etc \
--tmpfs /etc \
--symlink /etc/ld.so.conf ${glibc}/etc/ld.so.conf \
--symlink /etc/ld.so.cache ${glibc}/etc/ld.so.cache \
--ro-bind ${glibc}/etc/rpc ${glibc}/etc/rpc \
--remount-ro ${glibc}/etc \
'' + optionalString fhsenv.isMultiBuild (indentLines ''
--tmpfs ${pkgsi686Linux.glibc}/etc \ --tmpfs ${pkgsi686Linux.glibc}/etc \
--symlink /etc/ld.so.conf ${pkgsi686Linux.glibc}/etc/ld.so.conf \ --symlink /etc/ld.so.conf ${pkgsi686Linux.glibc}/etc/ld.so.conf \
--symlink /etc/ld.so.cache ${pkgsi686Linux.glibc}/etc/ld.so.cache \ --symlink /etc/ld.so.cache ${pkgsi686Linux.glibc}/etc/ld.so.cache \
--ro-bind ${pkgsi686Linux.glibc}/etc/rpc ${pkgsi686Linux.glibc}/etc/rpc \ --ro-bind ${pkgsi686Linux.glibc}/etc/rpc ${pkgsi686Linux.glibc}/etc/rpc \
--remount-ro ${pkgsi686Linux.glibc}/etc \ --remount-ro ${pkgsi686Linux.glibc}/etc \
'') + '' '') + ''
"''${ro_mounts[@]}" "''${ro_mounts[@]}"
"''${symlinks[@]}" "''${symlinks[@]}"
"''${auto_mounts[@]}" "''${auto_mounts[@]}"
"''${x11_args[@]}" "''${x11_args[@]}"
${concatStringsSep "\n " extraBwrapArgs} ${concatStringsSep "\n " extraBwrapArgs}
${init runScript} ${initArgs} ${init runScript} ${initArgs}
) )
exec "''${cmd[@]}" exec "''${cmd[@]}"
''; '';
bin = writeShellScript "${name}-bwrap" (bwrapCmd { initArgs = ''"$@"''; }); bin = writeShellScript "${name}-bwrap" (bwrapCmd { initArgs = ''"$@"''; });
in runCommandLocal name (nameAttrs // { in runCommandLocal name (nameAttrs // {
inherit meta; inherit meta;
passthru = passthru // { passthru = passthru // {
env = runCommandLocal "${name}-shell-env" { env = runCommandLocal "${name}-shell-env" { shellHook = bwrapCmd { }; } ''
shellHook = bwrapCmd {};
} ''
echo >&2 "" echo >&2 ""
echo >&2 "*** User chroot 'env' attributes are intended for interactive nix-shell sessions, not for building! ***" echo >&2 "*** User chroot 'env' attributes are intended for interactive nix-shell sessions, not for building! ***"
echo >&2 "" echo >&2 ""

View file

@ -1,27 +1,35 @@
{ lib, callPackage, runCommandLocal, writeScript, stdenv, coreutils }: { lib, callPackage, runCommandLocal, writeScript, stdenv, coreutils }:
let buildFHSEnv = callPackage ./env.nix { }; in let buildFHSEnv = callPackage ./env.nix { };
args@{ name, version ? null, runScript ? "bash", extraInstallCommands ? "", meta ? {}, passthru ? {}, ... }: in args@{ name, version ? null, runScript ? "bash", extraInstallCommands ? ""
, meta ? { }, passthru ? { }, ... }:
let let
env = buildFHSEnv (removeAttrs args [ "version" "runScript" "extraInstallCommands" "meta" "passthru" ]); env = buildFHSEnv (removeAttrs args [
"version"
"runScript"
"extraInstallCommands"
"meta"
"passthru"
]);
chrootenv = callPackage ./chrootenv {}; chrootenv = callPackage ./chrootenv { };
init = run: writeScript "${name}-init" '' init = run:
#! ${stdenv.shell} writeScript "${name}-init" ''
for i in ${env}/* /host/*; do #! ${stdenv.shell}
path="/''${i##*/}" for i in ${env}/* /host/*; do
[ -e "$path" ] || ${coreutils}/bin/ln -s "$i" "$path" path="/''${i##*/}"
done [ -e "$path" ] || ${coreutils}/bin/ln -s "$i" "$path"
done
[ -d "$1" ] && [ -r "$1" ] && cd "$1" [ -d "$1" ] && [ -r "$1" ] && cd "$1"
shift shift
source /etc/profile source /etc/profile
exec ${run} "$@" exec ${run} "$@"
''; '';
versionStr = lib.optionalString (version != null) ("-" + version); versionStr = lib.optionalString (version != null) ("-" + version);

View file

@ -1,13 +1,8 @@
{ stdenv, lib, buildEnv, writeText, pkgs, pkgsi686Linux }: { stdenv, lib, buildEnv, writeText, pkgs, pkgsi686Linux }:
{ name { name, profile ? "", targetPkgs ? pkgs: [ ], multiPkgs ? pkgs: [ ]
, profile ? "" , extraBuildCommands ? "", extraBuildCommandsMulti ? ""
, targetPkgs ? pkgs: [] , extraOutputsToInstall ? [ ] }:
, multiPkgs ? pkgs: []
, extraBuildCommands ? ""
, extraBuildCommandsMulti ? ""
, extraOutputsToInstall ? []
}:
# HOWTO: # HOWTO:
# All packages (most likely programs) returned from targetPkgs will only be # All packages (most likely programs) returned from targetPkgs will only be
@ -27,12 +22,14 @@
let let
is64Bit = stdenv.hostPlatform.parsed.cpu.bits == 64; is64Bit = stdenv.hostPlatform.parsed.cpu.bits == 64;
# multi-lib glibc is only supported on x86_64 # multi-lib glibc is only supported on x86_64
isMultiBuild = multiPkgs != null && stdenv.hostPlatform.system == "x86_64-linux"; isMultiBuild = multiPkgs != null && stdenv.hostPlatform.system
== "x86_64-linux";
isTargetBuild = !isMultiBuild; isTargetBuild = !isMultiBuild;
# list of packages (usually programs) which are only be installed for the # list of packages (usually programs) which are only be installed for the
# host's architecture # host's architecture
targetPaths = targetPkgs pkgs ++ (if multiPkgs == null then [] else multiPkgs pkgs); targetPaths = targetPkgs pkgs
++ (if multiPkgs == null then [ ] else multiPkgs pkgs);
# list of packages which are installed for both x86 and x86_64 on x86_64 # list of packages which are installed for both x86 and x86_64 on x86_64
# systems # systems
@ -42,16 +39,26 @@ let
# these match the host's architecture, glibc_multi is used for multilib # these match the host's architecture, glibc_multi is used for multilib
# builds. glibcLocales must be before glibc or glibc_multi as otherwiese # builds. glibcLocales must be before glibc or glibc_multi as otherwiese
# the wrong LOCALE_ARCHIVE will be used where only C.UTF-8 is available. # the wrong LOCALE_ARCHIVE will be used where only C.UTF-8 is available.
basePkgs = with pkgs; basePkgs = with pkgs; [
[ glibcLocales glibcLocales
(if isMultiBuild then glibc_multi else glibc) (if isMultiBuild then glibc_multi else glibc)
(toString gcc.cc.lib) bashInteractiveFHS coreutils less shadow su (toString gcc.cc.lib)
gawk diffutils findutils gnused gnugrep bashInteractiveFHS
gnutar gzip bzip2 xz coreutils
]; less
baseMultiPkgs = with pkgsi686Linux; shadow
[ (toString gcc.cc.lib) su
]; gawk
diffutils
findutils
gnused
gnugrep
gnutar
gzip
bzip2
xz
];
baseMultiPkgs = with pkgsi686Linux; [ (toString gcc.cc.lib) ];
etcProfile = writeText "profile" '' etcProfile = writeText "profile" ''
export PS1='${name}-chrootenv:\u@\h:\w\$ ' export PS1='${name}-chrootenv:\u@\h:\w\$ '
@ -91,7 +98,7 @@ let
# Compose /etc for the chroot environment # Compose /etc for the chroot environment
etcPkg = stdenv.mkDerivation { etcPkg = stdenv.mkDerivation {
name = "${name}-chrootenv-etc"; name = "${name}-chrootenv-etc";
buildCommand = '' buildCommand = ''
mkdir -p $out/etc mkdir -p $out/etc
cd $out/etc cd $out/etc
@ -216,8 +223,8 @@ let
ln -Ls ${staticUsrProfileTarget}/lib/32/ld-linux.so.2 lib/ ln -Ls ${staticUsrProfileTarget}/lib/32/ld-linux.so.2 lib/
''; '';
setupLibDirs = if isTargetBuild then setupLibDirs_target setupLibDirs =
else setupLibDirs_multi; if isTargetBuild then setupLibDirs_target else setupLibDirs_multi;
# the target profile is the actual profile that will be used for the chroot # the target profile is the actual profile that will be used for the chroot
setupTargetProfile = '' setupTargetProfile = ''
@ -244,7 +251,7 @@ let
''; '';
in stdenv.mkDerivation { in stdenv.mkDerivation {
name = "${name}-fhs"; name = "${name}-fhs";
buildCommand = '' buildCommand = ''
mkdir -p $out mkdir -p $out
cd $out cd $out

View file

@ -1,30 +1,21 @@
{ lib { lib, stdenv, glibcLocales
, stdenv # The GraalVM derivation to use
, glibcLocales , graalvmDrv, removeReferencesTo, executable ? args.pname
# The GraalVM derivation to use
, graalvmDrv
, removeReferencesTo
, executable ? args.pname
# JAR used as input for GraalVM derivation, defaults to src # JAR used as input for GraalVM derivation, defaults to src
, jar ? args.src , jar ? args.src, dontUnpack ? (jar == args.src)
, dontUnpack ? (jar == args.src) # Default native-image arguments. You probably don't want to set this,
# Default native-image arguments. You probably don't want to set this, # except in special cases. In most cases, use extraNativeBuildArgs instead
# except in special cases. In most cases, use extraNativeBuildArgs instead
, nativeImageBuildArgs ? [ , nativeImageBuildArgs ? [
(lib.optionalString stdenv.isDarwin "-H:-CheckToolchain") (lib.optionalString stdenv.isDarwin "-H:-CheckToolchain")
(lib.optionalString (stdenv.isLinux && stdenv.isAarch64) "-H:PageSize=64K") (lib.optionalString (stdenv.isLinux && stdenv.isAarch64) "-H:PageSize=64K")
"-H:Name=${executable}" "-H:Name=${executable}"
"-march=compatibility" "-march=compatibility"
"--verbose" "--verbose"
] ]
# Extra arguments to be passed to the native-image # Extra arguments to be passed to the native-image
, extraNativeImageBuildArgs ? [ ] , extraNativeImageBuildArgs ? [ ]
# XMX size of GraalVM during build # XMX size of GraalVM during build
, graalvmXmx ? "-J-Xmx6g" , graalvmXmx ? "-J-Xmx6g", meta ? { }, LC_ALL ? "en_US.UTF-8", ... }@args:
, meta ? { }
, LC_ALL ? "en_US.UTF-8"
, ...
} @ args:
let let
extraArgs = builtins.removeAttrs args [ extraArgs = builtins.removeAttrs args [
@ -40,15 +31,16 @@ let
"installPhase" "installPhase"
"postInstall" "postInstall"
]; ];
in in stdenv.mkDerivation ({
stdenv.mkDerivation ({
inherit dontUnpack jar; inherit dontUnpack jar;
env = { inherit LC_ALL; }; env = { inherit LC_ALL; };
nativeBuildInputs = (args.nativeBuildInputs or [ ]) ++ [ graalvmDrv glibcLocales removeReferencesTo ]; nativeBuildInputs = (args.nativeBuildInputs or [ ])
++ [ graalvmDrv glibcLocales removeReferencesTo ];
nativeImageBuildArgs = nativeImageBuildArgs ++ extraNativeImageBuildArgs ++ [ graalvmXmx ]; nativeImageBuildArgs = nativeImageBuildArgs ++ extraNativeImageBuildArgs
++ [ graalvmXmx ];
buildPhase = args.buildPhase or '' buildPhase = args.buildPhase or ''
runHook preBuild runHook preBuild

View file

@ -8,74 +8,69 @@ let
src = ./builder.pl; src = ./builder.pl;
inherit (builtins) storeDir; inherit (builtins) storeDir;
}; };
in
lib.makeOverridable in lib.makeOverridable ({ name
({ name
, # The manifest file (if any). A symlink $out/manifest will be , # The manifest file (if any). A symlink $out/manifest will be
# created to it. # created to it.
manifest ? "" manifest ? ""
, # The paths to symlink. , # The paths to symlink.
paths paths
, # Whether to ignore collisions or abort. , # Whether to ignore collisions or abort.
ignoreCollisions ? false ignoreCollisions ? false
, # If there is a collision, check whether the contents and permissions match , # If there is a collision, check whether the contents and permissions match
# and only if not, throw a collision error. # and only if not, throw a collision error.
checkCollisionContents ? true checkCollisionContents ? true
, # The paths (relative to each element of `paths') that we want to , # The paths (relative to each element of `paths') that we want to
# symlink (e.g., ["/bin"]). Any file not inside any of the # symlink (e.g., ["/bin"]). Any file not inside any of the
# directories in the list is not symlinked. # directories in the list is not symlinked.
pathsToLink ? ["/"] pathsToLink ? [ "/" ]
, # The package outputs to include. By default, only the default , # The package outputs to include. By default, only the default
# output is included. # output is included.
extraOutputsToInstall ? [] extraOutputsToInstall ? [ ]
, # Root the result in directory "$out${extraPrefix}", e.g. "/share". , # Root the result in directory "$out${extraPrefix}", e.g. "/share".
extraPrefix ? "" extraPrefix ? ""
, # Shell commands to run after building the symlink tree. , # Shell commands to run after building the symlink tree.
postBuild ? "" postBuild ? ""
# Additional inputs # Additional inputs
, nativeBuildInputs ? [] # Handy e.g. if using makeWrapper in `postBuild`. , nativeBuildInputs ? [ ] # Handy e.g. if using makeWrapper in `postBuild`.
, buildInputs ? [] , buildInputs ? [ ]
, passthru ? {} , passthru ? { }, meta ? { } }:
, meta ? {}
}:
runCommand name runCommand name rec {
rec { inherit manifest ignoreCollisions checkCollisionContents passthru meta
inherit manifest ignoreCollisions checkCollisionContents passthru pathsToLink extraPrefix postBuild nativeBuildInputs buildInputs;
meta pathsToLink extraPrefix postBuild
nativeBuildInputs buildInputs;
pkgs = builtins.toJSON (map (drv: { pkgs = builtins.toJSON (map (drv: {
paths = paths =
# First add the usual output(s): respect if user has chosen explicitly, # First add the usual output(s): respect if user has chosen explicitly,
# and otherwise use `meta.outputsToInstall`. The attribute is guaranteed # and otherwise use `meta.outputsToInstall`. The attribute is guaranteed
# to exist in mkDerivation-created cases. The other cases (e.g. runCommand) # to exist in mkDerivation-created cases. The other cases (e.g. runCommand)
# aren't expected to have multiple outputs. # aren't expected to have multiple outputs.
(if (! drv ? outputSpecified || ! drv.outputSpecified) (if (!drv ? outputSpecified || !drv.outputSpecified)
&& drv.meta.outputsToInstall or null != null && drv.meta.outputsToInstall or null != null then
then map (outName: drv.${outName}) drv.meta.outputsToInstall map (outName: drv.${outName}) drv.meta.outputsToInstall
else [ drv ]) else
[ drv ])
# Add any extra outputs specified by the caller of `buildEnv`. # Add any extra outputs specified by the caller of `buildEnv`.
++ lib.filter (p: p!=null) ++ lib.filter (p: p != null)
(builtins.map (outName: drv.${outName} or null) extraOutputsToInstall); (builtins.map (outName: drv.${outName} or null) extraOutputsToInstall);
priority = drv.meta.priority or 5; priority = drv.meta.priority or 5;
}) paths); }) paths);
preferLocalBuild = true; preferLocalBuild = true;
allowSubstitutes = false; allowSubstitutes = false;
# XXX: The size is somewhat arbitrary # XXX: The size is somewhat arbitrary
passAsFile = if builtins.stringLength pkgs >= 128*1024 then [ "pkgs" ] else [ ]; passAsFile =
} if builtins.stringLength pkgs >= 128 * 1024 then [ "pkgs" ] else [ ];
'' } ''
${buildPackages.perl}/bin/perl -w ${builder} ${buildPackages.perl}/bin/perl -w ${builder}
eval "$postBuild" eval "$postBuild"
'') '')

View file

@ -5,56 +5,54 @@
# script that sets up the right environment variables so that the # script that sets up the right environment variables so that the
# compiler and the linker just "work". # compiler and the linker just "work".
{ name ? "" { name ? "", lib, stdenvNoCC, runtimeShell, cc ? null, libc ? null, bintools
, lib , coreutils ? null, zlib ? null, nativeTools, noLibc ? false, nativeLibc
, stdenvNoCC , nativePrefix ? "", propagateDoc ? cc != null && cc ? man, extraTools ? [ ]
, runtimeShell , extraPackages ? [ ], extraBuildCommands ? "", nixSupport ? { }, isGNU ? false
, cc ? null, libc ? null, bintools, coreutils ? null , isClang ? cc.isClang or false, isCcache ? cc.isCcache or false, gnugrep ? null
, zlib ? null , expand-response-params, libcxx ? null
, nativeTools, noLibc ? false, nativeLibc, nativePrefix ? ""
, propagateDoc ? cc != null && cc ? man
, extraTools ? [], extraPackages ? [], extraBuildCommands ? ""
, nixSupport ? {}
, isGNU ? false, isClang ? cc.isClang or false, isCcache ? cc.isCcache or false, gnugrep ? null
, expand-response-params
, libcxx ? null
# Whether or not to add `-B` and `-L` to `nix-support/cc-{c,ld}flags` # Whether or not to add `-B` and `-L` to `nix-support/cc-{c,ld}flags`
, useCcForLibs ? , useCcForLibs ?
# Always add these flags for Clang, because in order to compile (most # Always add these flags for Clang, because in order to compile (most
# software) it needs libraries that are shipped and compiled with gcc. # software) it needs libraries that are shipped and compiled with gcc.
if isClang then true if isClang then
true
# Never add these flags for a build!=host cross-compiler or a host!=target # Never add these flags for a build!=host cross-compiler or a host!=target
# ("cross-built-native") compiler; currently nixpkgs has a special build # ("cross-built-native") compiler; currently nixpkgs has a special build
# path for these (`crossStageStatic`). Hopefully at some point that build # path for these (`crossStageStatic`). Hopefully at some point that build
# path will be merged with this one and this conditional will be removed. # path will be merged with this one and this conditional will be removed.
else if (with stdenvNoCC; buildPlatform != hostPlatform || hostPlatform != targetPlatform) then false else if (with stdenvNoCC;
buildPlatform != hostPlatform || hostPlatform != targetPlatform) then
false
# Never add these flags when wrapping the bootstrapFiles' compiler; it has a # Never add these flags when wrapping the bootstrapFiles' compiler; it has a
# /usr/-like layout with everything smashed into a single outpath, so it has # /usr/-like layout with everything smashed into a single outpath, so it has
# no trouble finding its own libraries. # no trouble finding its own libraries.
else if (cc.passthru.isFromBootstrapFiles or false) then false else if (cc.passthru.isFromBootstrapFiles or false) then
false
# Add these flags when wrapping `xgcc` (the first compiler that nixpkgs builds) # Add these flags when wrapping `xgcc` (the first compiler that nixpkgs builds)
else if (cc.passthru.isXgcc or false) then true else if (cc.passthru.isXgcc or false) then
true
# Add these flags when wrapping `stdenv.cc` # Add these flags when wrapping `stdenv.cc`
else if (cc.stdenv.cc.cc.passthru.isXgcc or false) then true else if (cc.stdenv.cc.cc.passthru.isXgcc or false) then
true
# Do not add these flags in any other situation. This is `false` mainly to # Do not add these flags in any other situation. This is `false` mainly to
# prevent these flags from being added when wrapping *old* versions of gcc # prevent these flags from being added when wrapping *old* versions of gcc
# (e.g. `gcc6Stdenv`), since they will cause the old gcc to get `-B` and # (e.g. `gcc6Stdenv`), since they will cause the old gcc to get `-B` and
# `-L` flags pointing at the new gcc's libstdc++ headers. Example failure: # `-L` flags pointing at the new gcc's libstdc++ headers. Example failure:
# https://hydra.nixos.org/build/213125495 # https://hydra.nixos.org/build/213125495
else false else
false
# the derivation at which the `-B` and `-L` flags added by `useCcForLibs` will point # the derivation at which the `-B` and `-L` flags added by `useCcForLibs` will point
, gccForLibs ? if useCcForLibs then cc else null , gccForLibs ? if useCcForLibs then cc else null, fortify-headers ? null
, fortify-headers ? null , includeFortifyHeaders ? null }:
, includeFortifyHeaders ? null
}:
assert nativeTools -> !propagateDoc && nativePrefix != ""; assert nativeTools -> !propagateDoc && nativePrefix != "";
assert !nativeTools -> cc != null && coreutils != null && gnugrep != null; assert !nativeTools -> cc != null && coreutils != null && gnugrep != null;
@ -63,36 +61,22 @@ assert (noLibc || nativeLibc) == (libc == null);
let let
inherit (lib) inherit (lib)
attrByPath attrByPath concatMapStrings concatStringsSep escapeShellArg getBin getDev
concatMapStrings getLib getName getVersion mapAttrsToList optional optionalAttrs optionals
concatStringsSep optionalString removePrefix replaceStrings toList versionAtLeast;
escapeShellArg
getBin
getDev
getLib
getName
getVersion
mapAttrsToList
optional
optionalAttrs
optionals
optionalString
removePrefix
replaceStrings
toList
versionAtLeast
;
inherit (stdenvNoCC) hostPlatform targetPlatform; inherit (stdenvNoCC) hostPlatform targetPlatform;
includeFortifyHeaders' = if includeFortifyHeaders != null includeFortifyHeaders' = if includeFortifyHeaders != null then
then includeFortifyHeaders includeFortifyHeaders
else (targetPlatform.libc == "musl" && isGNU); else
(targetPlatform.libc == "musl" && isGNU);
# Prefix for binaries. Customarily ends with a dash separator. # Prefix for binaries. Customarily ends with a dash separator.
# #
# TODO(@Ericson2314) Make unconditional, or optional but always true by default. # TODO(@Ericson2314) Make unconditional, or optional but always true by default.
targetPrefix = optionalString (targetPlatform != hostPlatform) (targetPlatform.config + "-"); targetPrefix = optionalString (targetPlatform != hostPlatform)
(targetPlatform.config + "-");
ccVersion = getVersion cc; ccVersion = getVersion cc;
ccName = removePrefix targetPrefix (getName cc); ccName = removePrefix targetPrefix (getName cc);
@ -100,8 +84,8 @@ let
libc_bin = optionalString (libc != null) (getBin libc); libc_bin = optionalString (libc != null) (getBin libc);
libc_dev = optionalString (libc != null) (getDev libc); libc_dev = optionalString (libc != null) (getDev libc);
libc_lib = optionalString (libc != null) (getLib libc); libc_lib = optionalString (libc != null) (getLib libc);
cc_solib = getLib cc cc_solib = getLib cc + optionalString (targetPlatform != hostPlatform)
+ optionalString (targetPlatform != hostPlatform) "/${targetPlatform.config}"; "/${targetPlatform.config}";
# The wrapper scripts use 'cat' and 'grep', so we may need coreutils. # The wrapper scripts use 'cat' and 'grep', so we may need coreutils.
coreutils_bin = optionalString (!nativeTools) (getBin coreutils); coreutils_bin = optionalString (!nativeTools) (getBin coreutils);
@ -111,17 +95,15 @@ let
# without interfering. For the moment, it is defined as the target triple, # without interfering. For the moment, it is defined as the target triple,
# adjusted to be a valid bash identifier. This should be considered an # adjusted to be a valid bash identifier. This should be considered an
# unstable implementation detail, however. # unstable implementation detail, however.
suffixSalt = replaceStrings ["-" "."] ["_" "_"] targetPlatform.config; suffixSalt = replaceStrings [ "-" "." ] [ "_" "_" ] targetPlatform.config;
useGccForLibs = useCcForLibs useGccForLibs = useCcForLibs && libcxx == null && !targetPlatform.isDarwin
&& libcxx == null
&& !targetPlatform.isDarwin
&& !(targetPlatform.useLLVM or false) && !(targetPlatform.useLLVM or false)
&& !(targetPlatform.useAndroidPrebuilt or false) && !(targetPlatform.useAndroidPrebuilt or false)
&& !(targetPlatform.isiOS or false) && !(targetPlatform.isiOS or false) && gccForLibs != null;
&& gccForLibs != null;
gccForLibs_solib = getLib gccForLibs gccForLibs_solib = getLib gccForLibs
+ optionalString (targetPlatform != hostPlatform) "/${targetPlatform.config}"; + optionalString (targetPlatform != hostPlatform)
"/${targetPlatform.config}";
# Analogously to cc_solib and gccForLibs_solib # Analogously to cc_solib and gccForLibs_solib
libcxx_solib = "${getLib libcxx}/lib"; libcxx_solib = "${getLib libcxx}/lib";
@ -141,7 +123,9 @@ let
# -march=too-modern-cpu # -march=too-modern-cpu
isGccArchSupported = arch: isGccArchSupported = arch:
if targetPlatform.isPower then false else # powerpc does not allow -march= if targetPlatform.isPower then
false
else # powerpc does not allow -march=
if isGNU then if isGNU then
{ # Generic { # Generic
x86-64-v2 = versionAtLeast ccVersion "11.0"; x86-64-v2 = versionAtLeast ccVersion "11.0";
@ -149,41 +133,41 @@ let
x86-64-v4 = versionAtLeast ccVersion "11.0"; x86-64-v4 = versionAtLeast ccVersion "11.0";
# Intel # Intel
skylake = versionAtLeast ccVersion "6.0"; skylake = versionAtLeast ccVersion "6.0";
skylake-avx512 = versionAtLeast ccVersion "6.0"; skylake-avx512 = versionAtLeast ccVersion "6.0";
cannonlake = versionAtLeast ccVersion "8.0"; cannonlake = versionAtLeast ccVersion "8.0";
icelake-client = versionAtLeast ccVersion "8.0"; icelake-client = versionAtLeast ccVersion "8.0";
icelake-server = versionAtLeast ccVersion "8.0"; icelake-server = versionAtLeast ccVersion "8.0";
cascadelake = versionAtLeast ccVersion "9.0"; cascadelake = versionAtLeast ccVersion "9.0";
cooperlake = versionAtLeast ccVersion "10.0"; cooperlake = versionAtLeast ccVersion "10.0";
tigerlake = versionAtLeast ccVersion "10.0"; tigerlake = versionAtLeast ccVersion "10.0";
knm = versionAtLeast ccVersion "8.0"; knm = versionAtLeast ccVersion "8.0";
alderlake = versionAtLeast ccVersion "12.0"; alderlake = versionAtLeast ccVersion "12.0";
# AMD # AMD
znver1 = versionAtLeast ccVersion "6.0"; znver1 = versionAtLeast ccVersion "6.0";
znver2 = versionAtLeast ccVersion "9.0"; znver2 = versionAtLeast ccVersion "9.0";
znver3 = versionAtLeast ccVersion "11.0"; znver3 = versionAtLeast ccVersion "11.0";
znver4 = versionAtLeast ccVersion "13.0"; znver4 = versionAtLeast ccVersion "13.0";
}.${arch} or true }.${arch} or true
else if isClang then else if isClang then
{ #Generic { # Generic
x86-64-v2 = versionAtLeast ccVersion "12.0"; x86-64-v2 = versionAtLeast ccVersion "12.0";
x86-64-v3 = versionAtLeast ccVersion "12.0"; x86-64-v3 = versionAtLeast ccVersion "12.0";
x86-64-v4 = versionAtLeast ccVersion "12.0"; x86-64-v4 = versionAtLeast ccVersion "12.0";
# Intel # Intel
cannonlake = versionAtLeast ccVersion "5.0"; cannonlake = versionAtLeast ccVersion "5.0";
icelake-client = versionAtLeast ccVersion "7.0"; icelake-client = versionAtLeast ccVersion "7.0";
icelake-server = versionAtLeast ccVersion "7.0"; icelake-server = versionAtLeast ccVersion "7.0";
knm = versionAtLeast ccVersion "7.0"; knm = versionAtLeast ccVersion "7.0";
alderlake = versionAtLeast ccVersion "16.0"; alderlake = versionAtLeast ccVersion "16.0";
# AMD # AMD
znver1 = versionAtLeast ccVersion "4.0"; znver1 = versionAtLeast ccVersion "4.0";
znver2 = versionAtLeast ccVersion "9.0"; znver2 = versionAtLeast ccVersion "9.0";
znver3 = versionAtLeast ccVersion "12.0"; znver3 = versionAtLeast ccVersion "12.0";
znver4 = versionAtLeast ccVersion "16.0"; znver4 = versionAtLeast ccVersion "16.0";
}.${arch} or true }.${arch} or true
else else
false; false;
@ -195,24 +179,25 @@ let
generic = true; generic = true;
intel = true; intel = true;
}.${tune} or (isGccArchSupported tune) }.${tune} or (isGccArchSupported tune)
# on arm64, the -mtune= values are specific processors # on arm64, the -mtune= values are specific processors
else if targetPlatform.isAarch64 then else if targetPlatform.isAarch64 then
(if isGNU then (if isGNU then
{ {
cortex-a53 = versionAtLeast ccVersion "4.8"; # gcc 8c075f cortex-a53 = versionAtLeast ccVersion "4.8"; # gcc 8c075f
cortex-a72 = versionAtLeast ccVersion "5.1"; # gcc d8f70d cortex-a72 = versionAtLeast ccVersion "5.1"; # gcc d8f70d
"cortex-a72.cortex-a53" = versionAtLeast ccVersion "5.1"; # gcc d8f70d "cortex-a72.cortex-a53" = versionAtLeast ccVersion "5.1"; # gcc d8f70d
}.${tune} or false }.${tune} or false
else if isClang then else if isClang then
{ {
cortex-a53 = versionAtLeast ccVersion "3.9"; # llvm dfc5d1 cortex-a53 = versionAtLeast ccVersion "3.9"; # llvm dfc5d1
}.${tune} or false }.${tune} or false
else false) else
false)
else if targetPlatform.isPower then else if targetPlatform.isPower then
# powerpc does not support -march # powerpc does not support -march
true true
else if targetPlatform.isMips then else if targetPlatform.isMips then
# for mips -mtune= takes the same values as -march # for mips -mtune= takes the same values as -march
isGccArchSupported tune isGccArchSupported tune
else else
false; false;
@ -224,41 +209,42 @@ let
# Note: this function can make use of ccVersion; for example, `if # Note: this function can make use of ccVersion; for example, `if
# versionOlder ccVersion "12" then ...` # versionOlder ccVersion "12" then ...`
findBestTuneApproximation = tune: findBestTuneApproximation = tune:
let guess = if isClang let
then { guess = if isClang then
# clang does not tune for big.LITTLE chips {
"cortex-a72.cortex-a53" = "cortex-a72"; # clang does not tune for big.LITTLE chips
}.${tune} or tune "cortex-a72.cortex-a53" = "cortex-a72";
else tune; }.${tune} or tune
in if isGccTuneSupported guess else
then guess tune;
else null; in if isGccTuneSupported guess then guess else null;
defaultHardeningFlags = bintools.defaultHardeningFlags or []; defaultHardeningFlags = bintools.defaultHardeningFlags or [ ];
# if cc.hardeningUnsupportedFlagsByTargetPlatform exists, this is # if cc.hardeningUnsupportedFlagsByTargetPlatform exists, this is
# called with the targetPlatform as an argument and # called with the targetPlatform as an argument and
# cc.hardeningUnsupportedFlags is completely ignored - the function # cc.hardeningUnsupportedFlags is completely ignored - the function
# is responsible for including the constant hardeningUnsupportedFlags # is responsible for including the constant hardeningUnsupportedFlags
# list however it sees fit. # list however it sees fit.
ccHardeningUnsupportedFlags = if cc ? hardeningUnsupportedFlagsByTargetPlatform ccHardeningUnsupportedFlags =
then cc.hardeningUnsupportedFlagsByTargetPlatform targetPlatform if cc ? hardeningUnsupportedFlagsByTargetPlatform then
else (cc.hardeningUnsupportedFlags or []); cc.hardeningUnsupportedFlagsByTargetPlatform targetPlatform
else
(cc.hardeningUnsupportedFlags or [ ]);
darwinPlatformForCC = optionalString targetPlatform.isDarwin ( darwinPlatformForCC = optionalString targetPlatform.isDarwin
if (targetPlatform.darwinPlatform == "macos" && isGNU) then "macosx" (if (targetPlatform.darwinPlatform == "macos" && isGNU) then
else targetPlatform.darwinPlatform "macosx"
); else
targetPlatform.darwinPlatform);
darwinMinVersion = optionalString targetPlatform.isDarwin ( darwinMinVersion =
targetPlatform.darwinMinVersion optionalString targetPlatform.isDarwin (targetPlatform.darwinMinVersion);
);
darwinMinVersionVariable = optionalString targetPlatform.isDarwin darwinMinVersionVariable = optionalString targetPlatform.isDarwin
targetPlatform.darwinMinVersionVariable; targetPlatform.darwinMinVersionVariable;
in
assert includeFortifyHeaders' -> fortify-headers != null; in assert includeFortifyHeaders' -> fortify-headers != null;
# Ensure bintools matches # Ensure bintools matches
assert libc_bin == bintools.libc_bin; assert libc_bin == bintools.libc_bin;
@ -269,8 +255,7 @@ assert nativeLibc == bintools.nativeLibc;
assert nativePrefix == bintools.nativePrefix; assert nativePrefix == bintools.nativePrefix;
stdenvNoCC.mkDerivation { stdenvNoCC.mkDerivation {
pname = targetPrefix pname = targetPrefix + (if name != "" then name else "${ccName}-wrapper");
+ (if name != "" then name else "${ccName}-wrapper");
version = optionalString (cc != null) ccVersion; version = optionalString (cc != null) ccVersion;
preferLocalBuild = true; preferLocalBuild = true;
@ -292,7 +277,7 @@ stdenvNoCC.mkDerivation {
(lambda (arg) (lambda (arg)
(when (file-directory-p (concat arg "/include")) (when (file-directory-p (concat arg "/include"))
(setenv "NIX_CFLAGS_COMPILE_${suffixSalt}" (concat (getenv "NIX_CFLAGS_COMPILE_${suffixSalt}") " -isystem " arg "/include")))) (setenv "NIX_CFLAGS_COMPILE_${suffixSalt}" (concat (getenv "NIX_CFLAGS_COMPILE_${suffixSalt}") " -isystem " arg "/include"))))
'(${concatStringsSep " " (map (pkg: "\"${pkg}\"") pkgs)})) '(${concatStringsSep " " (map (pkg: ''"${pkg}"'') pkgs)}))
''; '';
# Expose expand-response-params we are /actually/ using. In stdenv # Expose expand-response-params we are /actually/ using. In stdenv
@ -315,22 +300,25 @@ stdenvNoCC.mkDerivation {
wrapper = ./cc-wrapper.sh; wrapper = ./cc-wrapper.sh;
installPhase = installPhase = ''
'' mkdir -p $out/bin $out/nix-support
mkdir -p $out/bin $out/nix-support
wrap() { wrap() {
local dst="$1" local dst="$1"
local wrapper="$2" local wrapper="$2"
export prog="$3" export prog="$3"
export use_response_file_by_default=${if isClang && !isCcache then "1" else "0"} export use_response_file_by_default=${
substituteAll "$wrapper" "$out/bin/$dst" if isClang && !isCcache then "1" else "0"
chmod +x "$out/bin/$dst"
} }
'' substituteAll "$wrapper" "$out/bin/$dst"
chmod +x "$out/bin/$dst"
}
''
+ (if nativeTools then '' + (if nativeTools then ''
echo ${if targetPlatform.isDarwin then cc else nativePrefix} > $out/nix-support/orig-cc echo ${
if targetPlatform.isDarwin then cc else nativePrefix
} > $out/nix-support/orig-cc
ccPath="${if targetPlatform.isDarwin then cc else nativePrefix}/bin" ccPath="${if targetPlatform.isDarwin then cc else nativePrefix}/bin"
'' else '' '' else ''
@ -384,7 +372,9 @@ stdenvNoCC.mkDerivation {
# No need to wrap gnat, gnatkr, gnatname or gnatprep; we can just symlink them in # No need to wrap gnat, gnatkr, gnatname or gnatprep; we can just symlink them in
+ optionalString cc.langAda or false '' + optionalString cc.langAda or false ''
for cmd in gnatbind gnatchop gnatclean gnatlink gnatls gnatmake; do for cmd in gnatbind gnatchop gnatclean gnatlink gnatls gnatmake; do
wrap ${targetPrefix}$cmd ${./gnat-wrapper.sh} $ccPath/${targetPrefix}$cmd wrap ${targetPrefix}$cmd ${
./gnat-wrapper.sh
} $ccPath/${targetPrefix}$cmd
done done
for cmd in gnat gnatkr gnatname gnatprep; do for cmd in gnat gnatkr gnatname gnatprep; do
@ -418,12 +408,13 @@ stdenvNoCC.mkDerivation {
''; '';
strictDeps = true; strictDeps = true;
propagatedBuildInputs = [ bintools ] ++ extraTools ++ optionals cc.langD or cc.langJava or false [ zlib ]; propagatedBuildInputs = [ bintools ] ++ extraTools
depsTargetTargetPropagated = optional (libcxx != null) libcxx ++ extraPackages; ++ optionals cc.langD or cc.langJava or false [ zlib ];
depsTargetTargetPropagated = optional (libcxx != null) libcxx
++ extraPackages;
setupHooks = [ setupHooks = [ ../setup-hooks/role.bash ]
../setup-hooks/role.bash ++ optional (cc.langC or true) ./setup-hook.sh
] ++ optional (cc.langC or true) ./setup-hook.sh
++ optional (cc.langFortran or false) ./fortran-hook.sh ++ optional (cc.langFortran or false) ./fortran-hook.sh
++ optional (targetPlatform.isWindows) (stdenvNoCC.mkDerivation { ++ optional (targetPlatform.isWindows) (stdenvNoCC.mkDerivation {
name = "win-dll-hook.sh"; name = "win-dll-hook.sh";
@ -463,8 +454,7 @@ stdenvNoCC.mkDerivation {
+ optionalString (useGccForLibs && isClang) '' + optionalString (useGccForLibs && isClang) ''
echo "-B${gccForLibs}/lib/gcc/${targetPlatform.config}/${gccForLibs.version}" >> $out/nix-support/cc-cflags echo "-B${gccForLibs}/lib/gcc/${targetPlatform.config}/${gccForLibs.version}" >> $out/nix-support/cc-cflags
'' '' + optionalString useGccForLibs ''
+ optionalString useGccForLibs ''
echo "-L${gccForLibs}/lib/gcc/${targetPlatform.config}/${gccForLibs.version}" >> $out/nix-support/cc-ldflags echo "-L${gccForLibs}/lib/gcc/${targetPlatform.config}/${gccForLibs.version}" >> $out/nix-support/cc-ldflags
echo "-L${gccForLibs_solib}/lib" >> $out/nix-support/cc-ldflags echo "-L${gccForLibs_solib}/lib" >> $out/nix-support/cc-ldflags
'' ''
@ -476,45 +466,50 @@ stdenvNoCC.mkDerivation {
# vs libstdc++, etc.) since Darwin isn't `useLLVM` on all counts. (See # vs libstdc++, etc.) since Darwin isn't `useLLVM` on all counts. (See
# https://clang.llvm.org/docs/Toolchain.html for all the axes one might # https://clang.llvm.org/docs/Toolchain.html for all the axes one might
# break `useLLVM` into.) # break `useLLVM` into.)
+ optionalString (isClang + optionalString (isClang && targetPlatform.isLinux
&& targetPlatform.isLinux && !(targetPlatform.useAndroidPrebuilt or false)
&& !(targetPlatform.useAndroidPrebuilt or false) && !(targetPlatform.useLLVM or false) && gccForLibs != null) (''
&& !(targetPlatform.useLLVM or false) echo "--gcc-toolchain=${gccForLibs}" >> $out/nix-support/cc-cflags
&& gccForLibs != null) (''
echo "--gcc-toolchain=${gccForLibs}" >> $out/nix-support/cc-cflags
# Pull in 'cc.out' target to get 'libstdc++fs.a'. It should be in # Pull in 'cc.out' target to get 'libstdc++fs.a'. It should be in
# 'cc.lib'. But it's a gcc package bug. # 'cc.lib'. But it's a gcc package bug.
# TODO(trofi): remove once gcc is fixed to move libraries to .lib output. # TODO(trofi): remove once gcc is fixed to move libraries to .lib output.
echo "-L${gccForLibs}/${optionalString (targetPlatform != hostPlatform) "/${targetPlatform.config}"}/lib" >> $out/nix-support/cc-ldflags echo "-L${gccForLibs}/${
'' optionalString (targetPlatform != hostPlatform)
# this ensures that when clang passes -lgcc_s to lld (as it does "/${targetPlatform.config}"
# when building e.g. firefox), lld is able to find libgcc_s.so }/lib" >> $out/nix-support/cc-ldflags
+ concatMapStrings (libgcc: '' ''
echo "-L${libgcc}/lib" >> $out/nix-support/cc-ldflags # this ensures that when clang passes -lgcc_s to lld (as it does
'') (toList (gccForLibs.libgcc or []))) # when building e.g. firefox), lld is able to find libgcc_s.so
+ concatMapStrings (libgcc: ''
echo "-L${libgcc}/lib" >> $out/nix-support/cc-ldflags
'') (toList (gccForLibs.libgcc or [ ])))
## ##
## General libc support ## General libc support
## ##
# The "-B${libc_lib}/lib/" flag is a quick hack to force gcc to link # The "-B${libc_lib}/lib/" flag is a quick hack to force gcc to link
# against the crt1.o from our own glibc, rather than the one in # against the crt1.o from our own glibc, rather than the one in
# /usr/lib. (This is only an issue when using an `impure' # /usr/lib. (This is only an issue when using an `impure'
# compiler/linker, i.e., one that searches /usr/lib and so on.) # compiler/linker, i.e., one that searches /usr/lib and so on.)
# #
# Unfortunately, setting -B appears to override the default search # Unfortunately, setting -B appears to override the default search
# path. Thus, the gcc-specific "../includes-fixed" directory is # path. Thus, the gcc-specific "../includes-fixed" directory is
# now longer searched and glibc's <limits.h> header fails to # now longer searched and glibc's <limits.h> header fails to
# compile, because it uses "#include_next <limits.h>" to find the # compile, because it uses "#include_next <limits.h>" to find the
# limits.h file in ../includes-fixed. To remedy the problem, # limits.h file in ../includes-fixed. To remedy the problem,
# another -idirafter is necessary to add that directory again. # another -idirafter is necessary to add that directory again.
+ optionalString (libc != null) ('' + optionalString (libc != null) (''
touch "$out/nix-support/libc-cflags" touch "$out/nix-support/libc-cflags"
touch "$out/nix-support/libc-ldflags" touch "$out/nix-support/libc-ldflags"
echo "-B${libc_lib}${libc.libdir or "/lib/"}" >> $out/nix-support/libc-crt1-cflags echo "-B${libc_lib}${
libc.libdir or "/lib/"
}" >> $out/nix-support/libc-crt1-cflags
'' + optionalString (!(cc.langD or false)) '' '' + optionalString (!(cc.langD or false)) ''
echo "-idirafter ${libc_dev}${libc.incdir or "/include"}" >> $out/nix-support/libc-cflags echo "-idirafter ${libc_dev}${
libc.incdir or "/include"
}" >> $out/nix-support/libc-cflags
'' + optionalString (isGNU && (!(cc.langD or false))) '' '' + optionalString (isGNU && (!(cc.langD or false))) ''
for dir in "${cc}"/lib/gcc/*/*/include-fixed; do for dir in "${cc}"/lib/gcc/*/*/include-fixed; do
echo '-idirafter' ''${dir} >> $out/nix-support/libc-cflags echo '-idirafter' ''${dir} >> $out/nix-support/libc-cflags
@ -524,16 +519,16 @@ stdenvNoCC.mkDerivation {
echo "${libc_lib}" > $out/nix-support/orig-libc echo "${libc_lib}" > $out/nix-support/orig-libc
echo "${libc_dev}" > $out/nix-support/orig-libc-dev echo "${libc_dev}" > $out/nix-support/orig-libc-dev
'' ''
# fortify-headers is a set of wrapper headers that augment libc # fortify-headers is a set of wrapper headers that augment libc
# and use #include_next to pass through to libc's true # and use #include_next to pass through to libc's true
# implementations, so must appear before them in search order. # implementations, so must appear before them in search order.
# in theory a correctly placed -idirafter could be used, but in # in theory a correctly placed -idirafter could be used, but in
# practice the compiler may have been built with a --with-headers # practice the compiler may have been built with a --with-headers
# like option that forces the libc headers before all -idirafter, # like option that forces the libc headers before all -idirafter,
# hence -isystem here. # hence -isystem here.
+ optionalString includeFortifyHeaders' '' + optionalString includeFortifyHeaders' ''
echo "-isystem ${fortify-headers}/include" >> $out/nix-support/libc-cflags echo "-isystem ${fortify-headers}/include" >> $out/nix-support/libc-cflags
'') '')
## ##
## General libc++ support ## General libc++ support
@ -541,26 +536,30 @@ stdenvNoCC.mkDerivation {
# We have a libc++ directly, we have one via "smuggled" GCC, or we have one # We have a libc++ directly, we have one via "smuggled" GCC, or we have one
# bundled with the C compiler because it is GCC # bundled with the C compiler because it is GCC
+ optionalString (libcxx != null || (useGccForLibs && gccForLibs.langCC or false) || (isGNU && cc.langCC or false)) '' + optionalString (libcxx != null
touch "$out/nix-support/libcxx-cxxflags" || (useGccForLibs && gccForLibs.langCC or false)
touch "$out/nix-support/libcxx-ldflags" || (isGNU && cc.langCC or false)) ''
'' touch "$out/nix-support/libcxx-cxxflags"
touch "$out/nix-support/libcxx-ldflags"
''
# Adding -isystem flags should be done only for clang; gcc # Adding -isystem flags should be done only for clang; gcc
# already knows how to find its own libstdc++, and adding # already knows how to find its own libstdc++, and adding
# additional -isystem flags will confuse gfortran (see # additional -isystem flags will confuse gfortran (see
# https://github.com/NixOS/nixpkgs/pull/209870#issuecomment-1500550903) # https://github.com/NixOS/nixpkgs/pull/209870#issuecomment-1500550903)
+ optionalString (libcxx == null && isClang && (useGccForLibs && gccForLibs.langCC or false)) '' + optionalString (libcxx == null && isClang
for dir in ${gccForLibs}/include/c++/*; do && (useGccForLibs && gccForLibs.langCC or false)) ''
echo "-isystem $dir" >> $out/nix-support/libcxx-cxxflags for dir in ${gccForLibs}/include/c++/*; do
done echo "-isystem $dir" >> $out/nix-support/libcxx-cxxflags
for dir in ${gccForLibs}/include/c++/*/${targetPlatform.config}; do done
echo "-isystem $dir" >> $out/nix-support/libcxx-cxxflags for dir in ${gccForLibs}/include/c++/*/${targetPlatform.config}; do
done echo "-isystem $dir" >> $out/nix-support/libcxx-cxxflags
'' done
+ optionalString (libcxx.isLLVM or false) '' '' + optionalString (libcxx.isLLVM or false) ''
echo "-isystem ${getDev libcxx}/include/c++/v1" >> $out/nix-support/libcxx-cxxflags echo "-isystem ${
echo "-stdlib=libc++" >> $out/nix-support/libcxx-ldflags getDev libcxx
'' }/include/c++/v1" >> $out/nix-support/libcxx-cxxflags
echo "-stdlib=libc++" >> $out/nix-support/libcxx-ldflags
''
## ##
## Initial CFLAGS ## Initial CFLAGS
@ -589,7 +588,8 @@ stdenvNoCC.mkDerivation {
'' + '' '' + ''
echo "$ccLDFlags" >> $out/nix-support/cc-ldflags echo "$ccLDFlags" >> $out/nix-support/cc-ldflags
echo "$ccCFlags" >> $out/nix-support/cc-cflags echo "$ccCFlags" >> $out/nix-support/cc-cflags
'' + optionalString (targetPlatform.isDarwin && (libcxx != null) && (cc.isClang or false)) '' '' + optionalString
(targetPlatform.isDarwin && (libcxx != null) && (cc.isClang or false)) ''
echo " -L${libcxx_solib}" >> $out/nix-support/cc-ldflags echo " -L${libcxx_solib}" >> $out/nix-support/cc-ldflags
'' ''
@ -607,7 +607,9 @@ stdenvNoCC.mkDerivation {
## Hardening support ## Hardening support
## ##
+ '' + ''
export hardening_unsupported_flags="${concatStringsSep " " ccHardeningUnsupportedFlags}" export hardening_unsupported_flags="${
concatStringsSep " " ccHardeningUnsupportedFlags
}"
'' ''
# Machine flags. These are necessary to support # Machine flags. These are necessary to support
@ -622,38 +624,40 @@ stdenvNoCC.mkDerivation {
# For clang, this is handled in add-clang-cc-cflags-before.sh # For clang, this is handled in add-clang-cc-cflags-before.sh
# TODO: aarch64-darwin has mcpu incompatible with gcc # TODO: aarch64-darwin has mcpu incompatible with gcc
+ optionalString ((targetPlatform ? gcc.arch) && !isClang && !(targetPlatform.isDarwin && targetPlatform.isAarch64) && + optionalString ((targetPlatform ? gcc.arch) && !isClang
isGccArchSupported targetPlatform.gcc.arch) '' && !(targetPlatform.isDarwin && targetPlatform.isAarch64)
echo "-march=${targetPlatform.gcc.arch}" >> $out/nix-support/cc-cflags-before && isGccArchSupported targetPlatform.gcc.arch) ''
'' echo "-march=${targetPlatform.gcc.arch}" >> $out/nix-support/cc-cflags-before
''
# -mcpu is not very useful, except on PowerPC where it is used # -mcpu is not very useful, except on PowerPC where it is used
# instead of march. On all other platforms you should use mtune # instead of march. On all other platforms you should use mtune
# and march instead. # and march instead.
# TODO: aarch64-darwin has mcpu incompatible with gcc # TODO: aarch64-darwin has mcpu incompatible with gcc
+ optionalString ((targetPlatform ? gcc.cpu) && (isClang || !(targetPlatform.isDarwin && targetPlatform.isAarch64))) '' + optionalString ((targetPlatform ? gcc.cpu)
echo "-mcpu=${targetPlatform.gcc.cpu}" >> $out/nix-support/cc-cflags-before && (isClang || !(targetPlatform.isDarwin && targetPlatform.isAarch64))) ''
'' echo "-mcpu=${targetPlatform.gcc.cpu}" >> $out/nix-support/cc-cflags-before
''
# -mfloat-abi only matters on arm32 but we set it here # -mfloat-abi only matters on arm32 but we set it here
# unconditionally just in case. If the abi specifically sets hard # unconditionally just in case. If the abi specifically sets hard
# vs. soft floats we use it here. # vs. soft floats we use it here.
+ optionalString (targetPlatform ? gcc.float-abi) '' + optionalString (targetPlatform ? gcc.float-abi) ''
echo "-mfloat-abi=${targetPlatform.gcc.float-abi}" >> $out/nix-support/cc-cflags-before echo "-mfloat-abi=${targetPlatform.gcc.float-abi}" >> $out/nix-support/cc-cflags-before
'' '' + optionalString (targetPlatform ? gcc.fpu) ''
+ optionalString (targetPlatform ? gcc.fpu) ''
echo "-mfpu=${targetPlatform.gcc.fpu}" >> $out/nix-support/cc-cflags-before echo "-mfpu=${targetPlatform.gcc.fpu}" >> $out/nix-support/cc-cflags-before
'' '' + optionalString (targetPlatform ? gcc.mode) ''
+ optionalString (targetPlatform ? gcc.mode) ''
echo "-mmode=${targetPlatform.gcc.mode}" >> $out/nix-support/cc-cflags-before echo "-mmode=${targetPlatform.gcc.mode}" >> $out/nix-support/cc-cflags-before
'' '' + optionalString (targetPlatform ? gcc.thumb) ''
+ optionalString (targetPlatform ? gcc.thumb) '' echo "-m${
echo "-m${if targetPlatform.gcc.thumb then "thumb" else "arm"}" >> $out/nix-support/cc-cflags-before if targetPlatform.gcc.thumb then "thumb" else "arm"
'' }" >> $out/nix-support/cc-cflags-before
+ (let tune = if targetPlatform ? gcc.tune '' + (let
then findBestTuneApproximation targetPlatform.gcc.tune tune = if targetPlatform ? gcc.tune then
else null; findBestTuneApproximation targetPlatform.gcc.tune
in optionalString (tune != null) '' else
null;
in optionalString (tune != null) ''
echo "-mtune=${tune}" >> $out/nix-support/cc-cflags-before echo "-mtune=${tune}" >> $out/nix-support/cc-cflags-before
'') '')
@ -664,9 +668,11 @@ stdenvNoCC.mkDerivation {
hardening_unsupported_flags+=" stackprotector fortify" hardening_unsupported_flags+=" stackprotector fortify"
'' + optionalString targetPlatform.isAvr '' '' + optionalString targetPlatform.isAvr ''
hardening_unsupported_flags+=" stackprotector pic" hardening_unsupported_flags+=" stackprotector pic"
'' + optionalString (targetPlatform.libc == "newlib" || targetPlatform.libc == "newlib-nano") '' '' + optionalString
(targetPlatform.libc == "newlib" || targetPlatform.libc == "newlib-nano") ''
hardening_unsupported_flags+=" stackprotector fortify pie pic" hardening_unsupported_flags+=" stackprotector fortify pie pic"
'' + optionalString (targetPlatform.libc == "musl" && targetPlatform.isx86_32) '' '' + optionalString
(targetPlatform.libc == "musl" && targetPlatform.isx86_32) ''
hardening_unsupported_flags+=" stackprotector" hardening_unsupported_flags+=" stackprotector"
'' + optionalString targetPlatform.isNetBSD '' '' + optionalString targetPlatform.isNetBSD ''
hardening_unsupported_flags+=" stackprotector fortify" hardening_unsupported_flags+=" stackprotector fortify"
@ -684,12 +690,14 @@ stdenvNoCC.mkDerivation {
+ optionalString (libc != null && targetPlatform.isAvr) '' + optionalString (libc != null && targetPlatform.isAvr) ''
for isa in avr5 avr3 avr4 avr6 avr25 avr31 avr35 avr51 avrxmega2 avrxmega4 avrxmega5 avrxmega6 avrxmega7 tiny-stack; do for isa in avr5 avr3 avr4 avr6 avr25 avr31 avr35 avr51 avrxmega2 avrxmega4 avrxmega5 avrxmega6 avrxmega7 tiny-stack; do
echo "-B${getLib libc}/avr/lib/$isa" >> $out/nix-support/libc-crt1-cflags echo "-B${
getLib libc
}/avr/lib/$isa" >> $out/nix-support/libc-crt1-cflags
done done
'' ''
+ optionalString targetPlatform.isDarwin '' + optionalString targetPlatform.isDarwin ''
echo "-arch ${targetPlatform.darwinArch}" >> $out/nix-support/cc-cflags echo "-arch ${targetPlatform.darwinArch}" >> $out/nix-support/cc-cflags
'' ''
+ optionalString targetPlatform.isAndroid '' + optionalString targetPlatform.isAndroid ''
@ -709,7 +717,9 @@ stdenvNoCC.mkDerivation {
'' ''
+ optionalString cc.langAda or false '' + optionalString cc.langAda or false ''
substituteAll ${./add-gnat-extra-flags.sh} $out/nix-support/add-gnat-extra-flags.sh substituteAll ${
./add-gnat-extra-flags.sh
} $out/nix-support/add-gnat-extra-flags.sh
'' ''
## ##
@ -718,29 +728,30 @@ stdenvNoCC.mkDerivation {
## ##
+ optionalString isClang '' + optionalString isClang ''
# Escape twice: once for this script, once for the one it gets substituted into. # Escape twice: once for this script, once for the one it gets substituted into.
export march=${escapeShellArg export march=${
(optionalString (targetPlatform ? gcc.arch) escapeShellArg (optionalString (targetPlatform ? gcc.arch)
(escapeShellArg "-march=${targetPlatform.gcc.arch}"))} (escapeShellArg "-march=${targetPlatform.gcc.arch}"))
}
export defaultTarget=${targetPlatform.config} export defaultTarget=${targetPlatform.config}
substituteAll ${./add-clang-cc-cflags-before.sh} $out/nix-support/add-local-cc-cflags-before.sh substituteAll ${
./add-clang-cc-cflags-before.sh
} $out/nix-support/add-local-cc-cflags-before.sh
'' ''
## ##
## Extra custom steps ## Extra custom steps
## ##
+ extraBuildCommands + extraBuildCommands + concatStringsSep "; " (mapAttrsToList
+ concatStringsSep "; " (name: value: "echo ${toString value} >> $out/nix-support/${name}")
(mapAttrsToList nixSupport);
(name: value: "echo ${toString value} >> $out/nix-support/${name}")
nixSupport);
env = { env = {
inherit isClang; inherit isClang;
# for substitution in utils.bash # for substitution in utils.bash
# TODO(@sternenseemann): invent something cleaner than passing in "" in case of absence # TODO(@sternenseemann): invent something cleaner than passing in "" in case of absence
expandResponseParams = "${expand-response-params}/bin/expand-response-params"; expandResponseParams =
"${expand-response-params}/bin/expand-response-params";
# TODO(@sternenseemann): rename env var via stdenv rebuild # TODO(@sternenseemann): rename env var via stdenv rebuild
shell = getBin runtimeShell + runtimeShell.shellPath or ""; shell = getBin runtimeShell + runtimeShell.shellPath or "";
gnugrep_bin = optionalString (!nativeTools) gnugrep; gnugrep_bin = optionalString (!nativeTools) gnugrep;
@ -754,11 +765,11 @@ stdenvNoCC.mkDerivation {
default_hardening_flags_str = builtins.toString defaultHardeningFlags; default_hardening_flags_str = builtins.toString defaultHardeningFlags;
}; };
meta = meta = let cc_ = optionalAttrs (cc != null) cc;
let cc_ = optionalAttrs (cc != null) cc; in in (optionalAttrs (cc_ ? meta) (removeAttrs cc.meta [ "priority" ])) // {
(optionalAttrs (cc_ ? meta) (removeAttrs cc.meta ["priority"])) // description = attrByPath [ "meta" "description" ] "System C compiler" cc_
{ description = attrByPath ["meta" "description"] "System C compiler" cc_ + " (wrapper script)"; + " (wrapper script)";
priority = 10; priority = 10;
mainProgram = if name != "" then name else ccName; mainProgram = if name != "" then name else ccName;
}; };
} }

View file

@ -1,93 +1,87 @@
{ lib { lib, buildPackages }:
, buildPackages
}:
let let
# rudimentary support for cross-compiling # rudimentary support for cross-compiling
# see: https://github.com/NixOS/nixpkgs/pull/279487#discussion_r1444449726 # see: https://github.com/NixOS/nixpkgs/pull/279487#discussion_r1444449726
inherit (buildPackages) inherit (buildPackages) mktemp rsync;
mktemp
rsync
;
in
rec { in rec {
/* Prepare a derivation for local builds. # Prepare a derivation for local builds.
* #
* This function prepares checkpoint builds by storing # This function prepares checkpoint builds by storing
* the build output and the sources for cross checking. # the build output and the sources for cross checking.
* The build output can be used later to allow checkpoint builds # The build output can be used later to allow checkpoint builds
* by passing the derivation output to the `mkCheckpointBuild` function. # by passing the derivation output to the `mkCheckpointBuild` function.
* #
* To build a project with checkpoints, follow these steps: # To build a project with checkpoints, follow these steps:
* - run `prepareCheckpointBuild` on the desired derivation, e.g. # - run `prepareCheckpointBuild` on the desired derivation, e.g.
* checkpointArtifacts = prepareCheckpointBuild virtualbox; # checkpointArtifacts = prepareCheckpointBuild virtualbox;
* - change something you want in the sources of the package, # - change something you want in the sources of the package,
* e.g. using source override: # e.g. using source override:
* changedVBox = pkgs.virtuabox.overrideAttrs (old: { # changedVBox = pkgs.virtuabox.overrideAttrs (old: {
* src = path/to/vbox/sources; # src = path/to/vbox/sources;
* }; # };
* - use `mkCheckpointBuild changedVBox checkpointArtifacts` # - use `mkCheckpointBuild changedVBox checkpointArtifacts`
* - enjoy shorter build times # - enjoy shorter build times
*/ prepareCheckpointBuild = drv:
prepareCheckpointBuild = drv: drv.overrideAttrs (old: { drv.overrideAttrs (old: {
outputs = [ "out" ]; outputs = [ "out" ];
name = drv.name + "-checkpointArtifacts"; name = drv.name + "-checkpointArtifacts";
# To determine differences between the state of the build directory # To determine differences between the state of the build directory
# from an earlier build and a later one we store the state of the build # from an earlier build and a later one we store the state of the build
# directory before build, but after patch phases. # directory before build, but after patch phases.
# This way, the same derivation can be used multiple times and only changes are detected. # This way, the same derivation can be used multiple times and only changes are detected.
# Additionally, removed files are handled correctly in later builds. # Additionally, removed files are handled correctly in later builds.
preBuild = (old.preBuild or "") + '' preBuild = (old.preBuild or "") + ''
mkdir -p $out/sources mkdir -p $out/sources
cp -r ./* $out/sources/ cp -r ./* $out/sources/
''; '';
# After the build, the build directory is copied again # After the build, the build directory is copied again
# to get the output files. # to get the output files.
# We copy the complete build folder, to take care of # We copy the complete build folder, to take care of
# build tools that build in the source directory, instead of # build tools that build in the source directory, instead of
# having a separate build directory such as the Linux kernel. # having a separate build directory such as the Linux kernel.
installPhase = '' installPhase = ''
runHook preCheckpointInstall runHook preCheckpointInstall
mkdir -p $out/outputs mkdir -p $out/outputs
cp -r ./* $out/outputs/ cp -r ./* $out/outputs/
runHook postCheckpointInstall runHook postCheckpointInstall
unset postPhases unset postPhases
''; '';
dontFixup = true; dontFixup = true;
doInstallCheck = false; doInstallCheck = false;
doDist = false; doDist = false;
}); });
/* Build a derivation based on the checkpoint output generated by # Build a derivation based on the checkpoint output generated by
* the `prepareCheckpointBuild` function. # the `prepareCheckpointBuild` function.
* #
* Usage: # Usage:
* let # let
* checkpointArtifacts = prepareCheckpointBuild drv; # checkpointArtifacts = prepareCheckpointBuild drv;
* in mkCheckpointBuild drv checkpointArtifacts # in mkCheckpointBuild drv checkpointArtifacts
*/ mkCheckpointBuild = drv: checkpointArtifacts:
mkCheckpointBuild = drv: checkpointArtifacts: drv.overrideAttrs (old: { drv.overrideAttrs (old: {
# The actual checkpoint build phase. # The actual checkpoint build phase.
# We compare the changed sources from a previous build with the current and create a patch. # We compare the changed sources from a previous build with the current and create a patch.
# Afterwards we clean the build directory and copy the previous output files (including the sources). # Afterwards we clean the build directory and copy the previous output files (including the sources).
# The source difference patch is then applied to get the latest changes again to allow short build times. # The source difference patch is then applied to get the latest changes again to allow short build times.
preBuild = (old.preBuild or "") + '' preBuild = (old.preBuild or "") + ''
set +e set +e
sourceDifferencePatchFile=$(${mktemp}/bin/mktemp) sourceDifferencePatchFile=$(${mktemp}/bin/mktemp)
diff -ur ${checkpointArtifacts}/sources ./ > "$sourceDifferencePatchFile" diff -ur ${checkpointArtifacts}/sources ./ > "$sourceDifferencePatchFile"
set -e set -e
shopt -s dotglob shopt -s dotglob
rm -r * rm -r *
${rsync}/bin/rsync \ ${rsync}/bin/rsync \
--checksum --times --atimes --chown=$USER:$USER --chmod=+w \ --checksum --times --atimes --chown=$USER:$USER --chmod=+w \
-r ${checkpointArtifacts}/outputs/ . -r ${checkpointArtifacts}/outputs/ .
patch -p 1 -i "$sourceDifferencePatchFile" patch -p 1 -i "$sourceDifferencePatchFile"
rm "$sourceDifferencePatchFile" rm "$sourceDifferencePatchFile"
''; '';
}); });
mkCheckpointedBuild = lib.warn mkCheckpointedBuild = lib.warn
"`mkCheckpointedBuild` is deprecated, use `mkCheckpointBuild` instead!" "`mkCheckpointedBuild` is deprecated, use `mkCheckpointBuild` instead!"

View file

@ -21,22 +21,21 @@ stdenv.mkDerivation {
nativeBuildInputs = [ coreutils jq ]; nativeBuildInputs = [ coreutils jq ];
empty = rootPaths == []; empty = rootPaths == [ ];
buildCommand = buildCommand = ''
'' out=''${outputs[out]}
out=''${outputs[out]}
mkdir $out mkdir $out
if [[ -n "$empty" ]]; then if [[ -n "$empty" ]]; then
echo 0 > $out/total-nar-size echo 0 > $out/total-nar-size
touch $out/registration $out/store-paths touch $out/registration $out/store-paths
else else
jq -r ".closure | map(.narSize) | add" < "$NIX_ATTRS_JSON_FILE" > $out/total-nar-size jq -r ".closure | map(.narSize) | add" < "$NIX_ATTRS_JSON_FILE" > $out/total-nar-size
jq -r '.closure | map([.path, .narHash, .narSize, "", (.references | length)] + .references) | add | map("\(.)\n") | add' < "$NIX_ATTRS_JSON_FILE" | head -n -1 > $out/registration jq -r '.closure | map([.path, .narHash, .narSize, "", (.references | length)] + .references) | add | map("\(.)\n") | add' < "$NIX_ATTRS_JSON_FILE" | head -n -1 > $out/registration
jq -r '.closure[].path' < "$NIX_ATTRS_JSON_FILE" > $out/store-paths jq -r '.closure[].path' < "$NIX_ATTRS_JSON_FILE" > $out/store-paths
fi fi
''; '';
} }

View file

@ -1,155 +1,155 @@
{ lib, stdenv, coqPackages, coq, which, fetchzip }@args: { lib, stdenv, coqPackages, coq, which, fetchzip }@args:
let let
lib = import ./extra-lib.nix { lib = import ./extra-lib.nix { inherit (args) lib; };
inherit (args) lib;
};
inherit (lib) inherit (lib)
concatStringsSep concatStringsSep flip foldl isFunction isString optional optionalAttrs
flip optionals optionalString pred remove switch versions;
foldl
isFunction
isString
optional
optionalAttrs
optionals
optionalString
pred
remove
switch
versions
;
inherit (lib.attrsets) removeAttrs; inherit (lib.attrsets) removeAttrs;
inherit (lib.strings) match; inherit (lib.strings) match;
isGitHubDomain = d: match "^github.*" d != null; isGitHubDomain = d: match "^github.*" d != null;
isGitLabDomain = d: match "^gitlab.*" d != null; isGitLabDomain = d: match "^gitlab.*" d != null;
in
{ pname, in { pname, version ? null, fetcher ? null, owner ? "coq-community"
version ? null, , domain ? "github.com", repo ? pname, defaultVersion ? null
fetcher ? null, , releaseRev ? (v: v), displayVersion ? { }, release ? { }, buildInputs ? [ ]
owner ? "coq-community", , nativeBuildInputs ? [ ], extraBuildInputs ? [ ], extraNativeBuildInputs ? [ ]
domain ? "github.com", , overrideBuildInputs ? [ ], overrideNativeBuildInputs ? [ ]
repo ? pname, , namePrefix ? [ "coq" ], enableParallelBuilding ? true, extraInstallFlags ? [ ]
defaultVersion ? null, , setCOQBIN ? true, mlPlugin ? false, useMelquiondRemake ? null, dropAttrs ? [ ]
releaseRev ? (v: v), , keepAttrs ? [ ], dropDerivationAttrs ? [ ], useDuneifVersion ? (x: false)
displayVersion ? {}, , useDune ? false, opam-name ? (concatStringsSep "-" (namePrefix ++ [ pname ]))
release ? {}, , ... }@args:
buildInputs ? [],
nativeBuildInputs ? [],
extraBuildInputs ? [],
extraNativeBuildInputs ? [],
overrideBuildInputs ? [],
overrideNativeBuildInputs ? [],
namePrefix ? [ "coq" ],
enableParallelBuilding ? true,
extraInstallFlags ? [],
setCOQBIN ? true,
mlPlugin ? false,
useMelquiondRemake ? null,
dropAttrs ? [],
keepAttrs ? [],
dropDerivationAttrs ? [],
useDuneifVersion ? (x: false),
useDune ? false,
opam-name ? (concatStringsSep "-" (namePrefix ++ [ pname ])),
...
}@args:
let let
args-to-remove = foldl (flip remove) ([ args-to-remove = foldl (flip remove) ([
"version" "fetcher" "repo" "owner" "domain" "releaseRev" "version"
"displayVersion" "defaultVersion" "useMelquiondRemake" "fetcher"
"repo"
"owner"
"domain"
"releaseRev"
"displayVersion"
"defaultVersion"
"useMelquiondRemake"
"release" "release"
"buildInputs" "nativeBuildInputs" "buildInputs"
"extraBuildInputs" "extraNativeBuildInputs" "nativeBuildInputs"
"overrideBuildInputs" "overrideNativeBuildInputs" "extraBuildInputs"
"extraNativeBuildInputs"
"overrideBuildInputs"
"overrideNativeBuildInputs"
"namePrefix" "namePrefix"
"meta" "useDuneifVersion" "useDune" "opam-name" "meta"
"extraInstallFlags" "setCOQBIN" "mlPlugin" "useDuneifVersion"
"dropAttrs" "dropDerivationAttrs" "keepAttrs" ] ++ dropAttrs) keepAttrs; "useDune"
fetch = import ../coq/meta-fetch/default.nix "opam-name"
{ inherit lib stdenv fetchzip; } ({ "extraInstallFlags"
"setCOQBIN"
"mlPlugin"
"dropAttrs"
"dropDerivationAttrs"
"keepAttrs"
] ++ dropAttrs) keepAttrs;
fetch = import ../coq/meta-fetch/default.nix { inherit lib stdenv fetchzip; }
({
inherit release releaseRev; inherit release releaseRev;
location = { inherit domain owner repo; }; location = { inherit domain owner repo; };
} // optionalAttrs (args?fetcher) {inherit fetcher;}); } // optionalAttrs (args ? fetcher) { inherit fetcher; });
fetched = fetch (if version != null then version else defaultVersion); fetched = fetch (if version != null then version else defaultVersion);
display-pkg = n: sep: v: display-pkg = n: sep: v:
let d = displayVersion.${n} or (if sep == "" then ".." else true); in let d = displayVersion.${n} or (if sep == "" then ".." else true);
n + optionalString (v != "" && v != null) (switch d [ in n + optionalString (v != "" && v != null) (switch d [
{ case = true; out = sep + v; } {
{ case = "."; out = sep + versions.major v; } case = true;
{ case = ".."; out = sep + versions.majorMinor v; } out = sep + v;
{ case = "..."; out = sep + versions.majorMinorPatch v; } }
{ case = isFunction; out = optionalString (d v != "") (sep + d v); } {
{ case = isString; out = optionalString (d != "") (sep + d); } case = ".";
out = sep + versions.major v;
}
{
case = "..";
out = sep + versions.majorMinor v;
}
{
case = "...";
out = sep + versions.majorMinorPatch v;
}
{
case = isFunction;
out = optionalString (d v != "") (sep + d v);
}
{
case = isString;
out = optionalString (d != "") (sep + d);
}
] "") + optionalString (v == null) "-broken"; ] "") + optionalString (v == null) "-broken";
append-version = p: n: p + display-pkg n "" coqPackages.${n}.version + "-"; append-version = p: n: p + display-pkg n "" coqPackages.${n}.version + "-";
prefix-name = foldl append-version "" namePrefix; prefix-name = foldl append-version "" namePrefix;
useDune = args.useDune or (useDuneifVersion fetched.version); useDune = args.useDune or (useDuneifVersion fetched.version);
coqlib-flags = switch coq.coq-version [ coqlib-flags = switch coq.coq-version [{
{ case = v: versions.isLe "8.6" v && v != "dev" ; case = v: versions.isLe "8.6" v && v != "dev";
out = [ "COQLIB=$(out)/lib/coq/${coq.coq-version}/" ]; } out = [ "COQLIB=$(out)/lib/coq/${coq.coq-version}/" ];
] [ "COQLIBINSTALL=$(out)/lib/coq/${coq.coq-version}/user-contrib" }] [
"COQPLUGININSTALL=$(OCAMLFIND_DESTDIR)" ]; "COQLIBINSTALL=$(out)/lib/coq/${coq.coq-version}/user-contrib"
docdir-flags = switch coq.coq-version [ "COQPLUGININSTALL=$(OCAMLFIND_DESTDIR)"
{ case = v: versions.isLe "8.6" v && v != "dev"; ];
out = [ "DOCDIR=$(out)/share/coq/${coq.coq-version}/" ]; } docdir-flags = switch coq.coq-version [{
] [ "COQDOCINSTALL=$(out)/share/coq/${coq.coq-version}/user-contrib" ]; case = v: versions.isLe "8.6" v && v != "dev";
in out = [ "DOCDIR=$(out)/share/coq/${coq.coq-version}/" ];
}] [ "COQDOCINSTALL=$(out)/share/coq/${coq.coq-version}/user-contrib" ];
stdenv.mkDerivation (removeAttrs ({ in stdenv.mkDerivation (removeAttrs ({
name = prefix-name + (display-pkg pname "-" fetched.version); name = prefix-name + (display-pkg pname "-" fetched.version);
inherit (fetched) version src; inherit (fetched) version src;
nativeBuildInputs = args.overrideNativeBuildInputs nativeBuildInputs = args.overrideNativeBuildInputs or ([ which ]
or ([ which ] ++ optional useDune coq.ocamlPackages.dune_3
++ optional useDune coq.ocamlPackages.dune_3 ++ optionals (useDune || mlPlugin) [
++ optionals (useDune || mlPlugin) [ coq.ocamlPackages.ocaml coq.ocamlPackages.findlib ] coq.ocamlPackages.ocaml
++ (args.nativeBuildInputs or []) ++ extraNativeBuildInputs); coq.ocamlPackages.findlib
buildInputs = args.overrideBuildInputs ] ++ (args.nativeBuildInputs or [ ]) ++ extraNativeBuildInputs);
or ([ coq ] ++ (args.buildInputs or []) ++ extraBuildInputs); buildInputs = args.overrideBuildInputs or ([ coq ]
++ (args.buildInputs or [ ]) ++ extraBuildInputs);
inherit enableParallelBuilding; inherit enableParallelBuilding;
meta = ({ platforms = coq.meta.platforms; } // meta = ({
(switch domain [{ platforms = coq.meta.platforms;
case = pred.union isGitHubDomain isGitLabDomain; } // (switch domain [{
out = { homepage = "https://${domain}/${owner}/${repo}"; }; case = pred.union isGitHubDomain isGitLabDomain;
}] {}) // out = { homepage = "https://${domain}/${owner}/${repo}"; };
optionalAttrs (fetched.broken or false) { coqFilter = true; broken = true; }) // }] { }) // optionalAttrs (fetched.broken or false) {
(args.meta or {}) ; coqFilter = true;
broken = true;
}) // (args.meta or { });
} } // (optionalAttrs setCOQBIN { COQBIN = "${coq}/bin/"; })
// (optionalAttrs setCOQBIN { COQBIN = "${coq}/bin/"; }) // (optionalAttrs (!args ? installPhase && !args ? useMelquiondRemake) {
// (optionalAttrs (!args?installPhase && !args?useMelquiondRemake) { installFlags = coqlib-flags ++ docdir-flags ++ extraInstallFlags;
installFlags = }) // (optionalAttrs useDune {
coqlib-flags ++ docdir-flags ++ buildPhase = ''
extraInstallFlags; runHook preBuild
}) dune build -p ${opam-name} ''${enableParallelBuilding:+-j $NIX_BUILD_CORES}
// (optionalAttrs useDune { runHook postBuild
buildPhase = '' '';
runHook preBuild installPhase = ''
dune build -p ${opam-name} ''${enableParallelBuilding:+-j $NIX_BUILD_CORES} runHook preInstall
runHook postBuild dune install ${opam-name} --prefix=$out
''; mv $out/lib/coq $out/lib/TEMPORARY
installPhase = '' mkdir $out/lib/coq/
runHook preInstall mv $out/lib/TEMPORARY $out/lib/coq/${coq.coq-version}
dune install ${opam-name} --prefix=$out runHook postInstall
mv $out/lib/coq $out/lib/TEMPORARY '';
mkdir $out/lib/coq/ }) // (optionalAttrs (args ? useMelquiondRemake) rec {
mv $out/lib/TEMPORARY $out/lib/coq/${coq.coq-version} COQUSERCONTRIB = "$out/lib/coq/${coq.coq-version}/user-contrib";
runHook postInstall preConfigurePhases = "autoconf";
''; configureFlags =
}) [ "--libdir=${COQUSERCONTRIB}/${useMelquiondRemake.logpath or ""}" ];
// (optionalAttrs (args?useMelquiondRemake) rec { buildPhase = "./remake -j$NIX_BUILD_CORES";
COQUSERCONTRIB = "$out/lib/coq/${coq.coq-version}/user-contrib"; installPhase = "./remake install";
preConfigurePhases = "autoconf"; }) // (removeAttrs args args-to-remove)) dropDerivationAttrs)
configureFlags = [ "--libdir=${COQUSERCONTRIB}/${useMelquiondRemake.logpath or ""}" ];
buildPhase = "./remake -j$NIX_BUILD_CORES";
installPhase = "./remake install";
})
// (removeAttrs args args-to-remove)) dropDerivationAttrs)

View file

@ -2,31 +2,17 @@
let let
inherit (lib) inherit (lib)
all all concatStringsSep findFirst flip getAttr head isFunction length
concatStringsSep recursiveUpdate splitVersion tail take versionAtLeast versionOlder
findFirst zipListsWith;
flip in recursiveUpdate lib (rec {
getAttr
head
isFunction
length
recursiveUpdate
splitVersion
tail
take
versionAtLeast
versionOlder
zipListsWith
;
in
recursiveUpdate lib (rec {
versions = versions = let
let truncate = n: v: concatStringsSep "." (take n (splitVersion v));
truncate = n: v: concatStringsSep "." (take n (splitVersion v)); opTruncate = op: v0: v:
opTruncate = op: v0: v: let n = length (splitVersion v0); in let n = length (splitVersion v0);
op (truncate n v) (truncate n v0); in op (truncate n v) (truncate n v0);
in rec { in rec {
/* Get string of the first n parts of a version string. /* Get string of the first n parts of a version string.
@ -50,34 +36,33 @@ recursiveUpdate lib (rec {
majorMinorPatch = truncate 3; majorMinorPatch = truncate 3;
/* Version comparison predicates, /* Version comparison predicates,
- isGe v0 v <-> v is greater or equal than v0 [*] - isGe v0 v <-> v is greater or equal than v0 [*]
- isLe v0 v <-> v is lesser or equal than v0 [*] - isLe v0 v <-> v is lesser or equal than v0 [*]
- isGt v0 v <-> v is strictly greater than v0 [*] - isGt v0 v <-> v is strictly greater than v0 [*]
- isLt v0 v <-> v is strictly lesser than v0 [*] - isLt v0 v <-> v is strictly lesser than v0 [*]
- isEq v0 v <-> v is equal to v0 [*] - isEq v0 v <-> v is equal to v0 [*]
- range low high v <-> v is between low and high [**] - range low high v <-> v is between low and high [**]
[*] truncating v to the same number of digits as v0 [*] truncating v to the same number of digits as v0
[**] truncating v to low for the lower bound and high for the upper bound [**] truncating v to low for the lower bound and high for the upper bound
Examples:
- isGe "8.10" "8.10.1"
=> true
- isLe "8.10" "8.10.1"
=> true
- isGt "8.10" "8.10.1"
=> false
- isGt "8.10.0" "8.10.1"
=> true
- isEq "8.10" "8.10.1"
=> true
- range "8.10" "8.11" "8.11.1"
=> true
- range "8.10" "8.11+" "8.11.0"
=> false
- range "8.10" "8.11+" "8.11+beta1"
=> false
Examples:
- isGe "8.10" "8.10.1"
=> true
- isLe "8.10" "8.10.1"
=> true
- isGt "8.10" "8.10.1"
=> false
- isGt "8.10.0" "8.10.1"
=> true
- isEq "8.10" "8.10.1"
=> true
- range "8.10" "8.11" "8.11.1"
=> true
- range "8.10" "8.11+" "8.11.0"
=> false
- range "8.10" "8.11+" "8.11+beta1"
=> false
*/ */
isGe = opTruncate versionAtLeast; isGe = opTruncate versionAtLeast;
isGt = opTruncate (flip versionOlder); isGt = opTruncate (flip versionOlder);
@ -88,80 +73,99 @@ recursiveUpdate lib (rec {
}; };
/* Returns a list of list, splitting it using a predicate. /* Returns a list of list, splitting it using a predicate.
This is analoguous to builtins.split sep list, This is analoguous to builtins.split sep list,
with a predicate as a separator and a list instead of a string. with a predicate as a separator and a list instead of a string.
Type: splitList :: (a -> bool) -> [a] -> [[a]] Type: splitList :: (a -> bool) -> [a] -> [[a]]
Example: Example:
splitList (x: x == "x") [ "y" "x" "z" "t" ] splitList (x: x == "x") [ "y" "x" "z" "t" ]
=> [ [ "y" ] "x" [ "z" "t" ] ] => [ [ "y" ] "x" [ "z" "t" ] ]
*/ */
splitList = pred: l: # put in file lists splitList = pred: l: # put in file lists
let loop = (vv: v: l: if l == [] then vv ++ [v] let
else let hd = head l; tl = tail l; in loop = (vv: v: l:
if pred hd then loop (vv ++ [ v hd ]) [] tl else loop vv (v ++ [hd]) tl); if l == [ ] then
in loop [] [] l; vv ++ [ v ]
else
let
hd = head l;
tl = tail l;
in if pred hd then
loop (vv ++ [ v hd ]) [ ] tl
else
loop vv (v ++ [ hd ]) tl);
in loop [ ] [ ] l;
pred = { pred = {
/* Predicate intersection, union, and complement */ # Predicate intersection, union, and complement
inter = p: q: x: p x && q x; inter = p: q: x: p x && q x;
union = p: q: x: p x || q x; union = p: q: x: p x || q x;
compl = p: x: ! p x; compl = p: x: !p x;
true = p: true; true = p: true;
false = p: false; false = p: false;
/* predicate "being equal to y" */ # predicate "being equal to y"
equal = y: x: x == y; equal = y: x: x == y;
}; };
/* Emulate a "switch - case" construct, /* Emulate a "switch - case" construct,
instead of relying on `if then else if ...` */ instead of relying on `if then else if ...`
*/
/* Usage: /* Usage:
```nix ```nix
switch-if [ switch-if [
if-clause-1 if-clause-1
.. ..
if-clause-k if-clause-k
] default-out ] default-out
``` ```
where a if-clause has the form `{ cond = b; out = r; }` where a if-clause has the form `{ cond = b; out = r; }`
the first branch such as `b` is true */ the first branch such as `b` is true
*/
switch-if = c: d: (findFirst (getAttr "cond") {} c).out or d; switch-if = c: d: (findFirst (getAttr "cond") { } c).out or d;
/* Usage: /* Usage:
```nix ```nix
switch x [ switch x [
simple-clause-1 simple-clause-1
.. ..
simple-clause-k simple-clause-k
] default-out ] default-out
``` ```
where a simple-clause has the form `{ case = p; out = r; }` where a simple-clause has the form `{ case = p; out = r; }`
the first branch such as `p x` is true the first branch such as `p x` is true
or or
```nix ```nix
switch [ x1 .. xn ] [ switch [ x1 .. xn ] [
complex-clause-1 complex-clause-1
.. ..
complex-clause-k complex-clause-k
] default-out ] default-out
``` ```
where a complex-clause is either a simple-clause where a complex-clause is either a simple-clause
or has the form { cases = [ p1 .. pn ]; out = r; } or has the form { cases = [ p1 .. pn ]; out = r; }
in which case the first branch such as all `pi x` are true in which case the first branch such as all `pi x` are true
if the variables p are not functions, if the variables p are not functions,
they are converted to a equal p they are converted to a equal p
if out is missing the default-out is taken */ if out is missing the default-out is taken
*/
switch = var: clauses: default: with pred; let switch = var: clauses: default:
compare = f: if isFunction f then f else equal f; with pred;
let
compare = f: if isFunction f then f else equal f;
combine = cl: var: combine = cl: var:
if cl?case then compare cl.case var if cl ? case then
else all (equal true) (zipListsWith compare cl.cases var); in compare cl.case var
switch-if (map (cl: { cond = combine cl var; inherit (cl) out; }) clauses) default; else
all (equal true) (zipListsWith compare cl.cases var);
in switch-if (map (cl: {
cond = combine cl var;
inherit (cl) out;
}) clauses) default;
/* Override arguments to mkCoqDerivation for a Coq library. /* Override arguments to mkCoqDerivation for a Coq library.
@ -207,7 +211,8 @@ recursiveUpdate lib (rec {
coqPackages.QuickChick.override { version = "1.4.0"; } coqPackages.QuickChick.override { version = "1.4.0"; }
``` ```
*/ */
overrideCoqDerivation = f: drv: (drv.override (args: { overrideCoqDerivation = f: drv:
mkCoqDerivation = drv_: (args.mkCoqDerivation drv_).override f; (drv.override (args: {
})); mkCoqDerivation = drv_: (args.mkCoqDerivation drv_).override f;
}));
}) })

View file

@ -1,95 +1,118 @@
{ lib, stdenv, fetchzip }@args: { lib, stdenv, fetchzip }@args:
let let
lib = import ../extra-lib.nix { lib = import ../extra-lib.nix { inherit (args) lib; };
inherit (args) lib;
};
inherit (lib) inherit (lib)
attrNames attrNames fakeSha256 filter findFirst head isAttrs isPath isString last
fakeSha256 length optionalAttrs pathExists pred sort switch switch-if versionAtLeast
filter versions;
findFirst
head
isAttrs
isPath
isString
last
length
optionalAttrs
pathExists
pred
sort
switch
switch-if
versionAtLeast
versions
;
inherit (lib.strings) match split; inherit (lib.strings) match split;
default-fetcher = {domain ? "github.com", owner ? "", repo, rev, name ? "source", sha256 ? null, ...}@args: default-fetcher = { domain ? "github.com", owner ? "", repo, rev
let ext = if args?sha256 then "zip" else "tar.gz"; , name ? "source", sha256 ? null, ... }@args:
fmt = if args?sha256 then "zip" else "tarball"; let
pr = match "^#(.*)$" rev; ext = if args ? sha256 then "zip" else "tar.gz";
url = switch-if [ fmt = if args ? sha256 then "zip" else "tarball";
{ cond = pr == null && (match "^github.*" domain) != null; pr = match "^#(.*)$" rev;
out = "https://${domain}/${owner}/${repo}/archive/${rev}.${ext}"; } url = switch-if [
{ cond = pr != null && (match "^github.*" domain) != null; {
out = "https://api.${domain}/repos/${owner}/${repo}/${fmt}/pull/${head pr}/head"; } cond = pr == null && (match "^github.*" domain) != null;
{ cond = pr == null && (match "^gitlab.*" domain) != null; out = "https://${domain}/${owner}/${repo}/archive/${rev}.${ext}";
out = "https://${domain}/${owner}/${repo}/-/archive/${rev}/${repo}-${rev}.${ext}"; } }
{ cond = (match "(www.)?mpi-sws.org" domain) != null; {
out = "https://www.mpi-sws.org/~${owner}/${repo}/download/${repo}-${rev}.${ext}";} cond = pr != null && (match "^github.*" domain) != null;
] (throw "meta-fetch: no fetcher found for domain ${domain} on ${rev}"); out = "https://api.${domain}/repos/${owner}/${repo}/${fmt}/pull/${
fetch = x: if args?sha256 then fetchzip (x // { inherit sha256; }) else builtins.fetchTarball x; head pr
in fetch { inherit url ; }; }/head";
in }
{ {
fetcher ? default-fetcher, cond = pr == null && (match "^gitlab.*" domain) != null;
location, out =
release ? {}, "https://${domain}/${owner}/${repo}/-/archive/${rev}/${repo}-${rev}.${ext}";
releaseRev ? (v: v), }
}: {
let isVersion = x: isString x && match "^/.*" x == null && release?${x}; cond = (match "(www.)?mpi-sws.org" domain) != null;
shortVersion = x: if (isString x && match "^/.*" x == null) out =
then findFirst (v: versions.majorMinor v == x) null "https://www.mpi-sws.org/~${owner}/${repo}/download/${repo}-${rev}.${ext}";
(sort versionAtLeast (attrNames release)) }
else null; ] (throw "meta-fetch: no fetcher found for domain ${domain} on ${rev}");
isShortVersion = x: shortVersion x != null; fetch = x:
isPathString = x: isString x && match "^/.*" x != null && pathExists x; in if args ? sha256 then
arg: fetchzip (x // { inherit sha256; })
else
builtins.fetchTarball x;
in fetch { inherit url; };
in { fetcher ? default-fetcher, location, release ? { }, releaseRev ? (v: v), }:
let
isVersion = x: isString x && match "^/.*" x == null && release ? ${x};
shortVersion = x:
if (isString x && match "^/.*" x == null) then
findFirst (v: versions.majorMinor v == x) null
(sort versionAtLeast (attrNames release))
else
null;
isShortVersion = x: shortVersion x != null;
isPathString = x: isString x && match "^/.*" x != null && pathExists x;
in arg:
switch arg [ switch arg [
{ case = isNull; out = { version = "broken"; src = ""; broken = true; }; } {
{ case = isPathString; out = { version = "dev"; src = arg; }; } case = isNull;
{ case = pred.union isVersion isShortVersion; out = {
version = "broken";
src = "";
broken = true;
};
}
{
case = isPathString;
out = {
version = "dev";
src = arg;
};
}
{
case = pred.union isVersion isShortVersion;
out = let out = let
v = if isVersion arg then arg else shortVersion arg; v = if isVersion arg then arg else shortVersion arg;
given-sha256 = release.${v}.sha256 or ""; given-sha256 = release.${v}.sha256 or "";
sha256 = if given-sha256 == "" then fakeSha256 else given-sha256; sha256 = if given-sha256 == "" then fakeSha256 else given-sha256;
rv = release.${v} // { inherit sha256; }; rv = release.${v} // { inherit sha256; };
in in {
{ version = rv.version or v;
version = rv.version or v; src = rv.src or fetcher (location // { rev = releaseRev v; } // rv);
src = rv.src or fetcher (location // { rev = releaseRev v; } // rv); };
}; }
} {
{ case = isString; case = isString;
out = let out = let
splitted = filter isString (split ":" arg); splitted = filter isString (split ":" arg);
rev = last splitted; rev = last splitted;
has-owner = length splitted > 1; has-owner = length splitted > 1;
version = "dev"; in { version = "dev";
in {
inherit version; inherit version;
src = fetcher (location // { inherit rev; } // src = fetcher (location // {
(optionalAttrs has-owner { owner = head splitted; })); inherit rev;
}; } } // (optionalAttrs has-owner { owner = head splitted; }));
{ case = isAttrs; };
}
{
case = isAttrs;
out = { out = {
version = arg.version or "dev"; version = arg.version or "dev";
src = (arg.fetcher or fetcher) (location // (arg.location or {})); }; } src = (arg.fetcher or fetcher) (location // (arg.location or { }));
{ case = isPath; };
}
{
case = isPath;
out = { out = {
version = "dev" ; version = "dev";
src = builtins.path {path = arg; name = location.name or "source";}; }; } src = builtins.path {
path = arg;
name = location.name or "source";
};
};
}
] (throw "not a valid source description") ] (throw "not a valid source description")

View file

@ -1,33 +1,16 @@
{ lib { lib, stdenv, callPackage, runCommand, writeText, pub2nix, dartHooks
, stdenv , makeWrapper, dart, nodejs, darwin, jq, yq }:
, callPackage
, runCommand
, writeText
, pub2nix
, dartHooks
, makeWrapper
, dart
, nodejs
, darwin
, jq
, yq
}:
{ src { src, sourceRoot ? "source"
, sourceRoot ? "source"
, packageRoot ? (lib.removePrefix "/" (lib.removePrefix "source" sourceRoot)) , packageRoot ? (lib.removePrefix "/" (lib.removePrefix "source" sourceRoot))
, gitHashes ? { } , gitHashes ? { }, sdkSourceBuilders ? { }, customSourceBuilders ? { }
, sdkSourceBuilders ? { }
, customSourceBuilders ? { }
, sdkSetupScript ? "" , sdkSetupScript ? "", extraPackageConfigSetup ? ""
, extraPackageConfigSetup ? ""
# Output type to produce. Can be any kind supported by dart # Output type to produce. Can be any kind supported by dart
# https://dart.dev/tools/dart-compile#types-of-output # https://dart.dev/tools/dart-compile#types-of-output
# If using jit, you might want to pass some arguments to `dartJitFlags` # If using jit, you might want to pass some arguments to `dartJitFlags`
, dartOutputType ? "exe" , dartOutputType ? "exe", dartCompileCommand ? "dart compile"
, dartCompileCommand ? "dart compile"
, dartCompileFlags ? [ ] , dartCompileFlags ? [ ]
# These come at the end of the command, useful to pass flags to the jit run # These come at the end of the command, useful to pass flags to the jit run
, dartJitFlags ? [ ] , dartJitFlags ? [ ]
@ -39,31 +22,40 @@
, dartEntryPoints ? null , dartEntryPoints ? null
# Used when wrapping aot, jit, kernel, and js builds. # Used when wrapping aot, jit, kernel, and js builds.
# Set to null to disable wrapping. # Set to null to disable wrapping.
, dartRuntimeCommand ? if dartOutputType == "aot-snapshot" then "${dart}/bin/dartaotruntime" , dartRuntimeCommand ? if dartOutputType == "aot-snapshot" then
else if (dartOutputType == "jit-snapshot" || dartOutputType == "kernel") then "${dart}/bin/dart" "${dart}/bin/dartaotruntime"
else if dartOutputType == "js" then "${nodejs}/bin/node" else if (dartOutputType == "jit-snapshot" || dartOutputType == "kernel") then
else null "${dart}/bin/dart"
else if dartOutputType == "js" then
"${nodejs}/bin/node"
else
null
, runtimeDependencies ? [ ] , runtimeDependencies ? [ ], extraWrapProgramArgs ? ""
, extraWrapProgramArgs ? ""
, autoPubspecLock ? null , autoPubspecLock ? null, pubspecLock ? if autoPubspecLock == null then
, pubspecLock ? if autoPubspecLock == null then throw
throw "The pubspecLock argument is required. If import-from-derivation is allowed (it isn't in Nixpkgs), you can set autoPubspecLock to the path to a pubspec.lock instead." "The pubspecLock argument is required. If import-from-derivation is allowed (it isn't in Nixpkgs), you can set autoPubspecLock to the path to a pubspec.lock instead."
else else
assert lib.assertMsg (builtins.pathExists autoPubspecLock) "The pubspec.lock file could not be found!"; assert lib.assertMsg (builtins.pathExists autoPubspecLock)
lib.importJSON (runCommand "${lib.getName args}-pubspec-lock-json" { nativeBuildInputs = [ yq ]; } ''yq . '${autoPubspecLock}' > "$out"'') "The pubspec.lock file could not be found!";
, ... lib.importJSON (runCommand "${lib.getName args}-pubspec-lock-json" {
}@args: nativeBuildInputs = [ yq ];
} ''yq . '${autoPubspecLock}' > "$out"''), ... }@args:
let let
generators = callPackage ./generators.nix { inherit dart; } { buildDrvArgs = args; }; generators =
callPackage ./generators.nix { inherit dart; } { buildDrvArgs = args; };
pubspecLockFile = builtins.toJSON pubspecLock; pubspecLockFile = builtins.toJSON pubspecLock;
pubspecLockData = pub2nix.readPubspecLock { inherit src packageRoot pubspecLock gitHashes sdkSourceBuilders customSourceBuilders; }; pubspecLockData = pub2nix.readPubspecLock {
inherit src packageRoot pubspecLock gitHashes sdkSourceBuilders
customSourceBuilders;
};
packageConfig = generators.linkPackageConfig { packageConfig = generators.linkPackageConfig {
packageConfig = pub2nix.generatePackageConfig { packageConfig = pub2nix.generatePackageConfig {
pname = if args.pname != null then "${args.pname}-${args.version}" else null; pname =
if args.pname != null then "${args.pname}-${args.version}" else null;
dependencies = dependencies =
# Ideally, we'd only include the main dependencies and their transitive # Ideally, we'd only include the main dependencies and their transitive
@ -80,53 +72,56 @@ let
extraSetupCommands = extraPackageConfigSetup; extraSetupCommands = extraPackageConfigSetup;
}; };
inherit (dartHooks.override { inherit dart; }) dartConfigHook dartBuildHook dartInstallHook dartFixupHook; inherit (dartHooks.override { inherit dart; })
dartConfigHook dartBuildHook dartInstallHook dartFixupHook;
baseDerivation = stdenv.mkDerivation (finalAttrs: (builtins.removeAttrs args [ "gitHashes" "sdkSourceBuilders" "pubspecLock" "customSourceBuilders" ]) // { baseDerivation = stdenv.mkDerivation (finalAttrs:
inherit pubspecLockFile packageConfig sdkSetupScript (builtins.removeAttrs args [
dartCompileCommand dartOutputType dartRuntimeCommand dartCompileFlags "gitHashes"
dartJitFlags; "sdkSourceBuilders"
"pubspecLock"
"customSourceBuilders"
]) // {
inherit pubspecLockFile packageConfig sdkSetupScript dartCompileCommand
dartOutputType dartRuntimeCommand dartCompileFlags dartJitFlags;
outputs = [ "out" "pubcache" ] ++ args.outputs or [ ]; outputs = [ "out" "pubcache" ] ++ args.outputs or [ ];
dartEntryPoints = dartEntryPoints = if (dartEntryPoints != null) then
if (dartEntryPoints != null) writeText "entrypoints.json" (builtins.toJSON dartEntryPoints)
then writeText "entrypoints.json" (builtins.toJSON dartEntryPoints) else
else null; null;
runtimeDependencies = map lib.getLib runtimeDependencies; runtimeDependencies = map lib.getLib runtimeDependencies;
nativeBuildInputs = (args.nativeBuildInputs or [ ]) ++ [ nativeBuildInputs = (args.nativeBuildInputs or [ ]) ++ [
dart dart
dartConfigHook dartConfigHook
dartBuildHook dartBuildHook
dartInstallHook dartInstallHook
dartFixupHook dartFixupHook
makeWrapper makeWrapper
jq jq
] ++ lib.optionals stdenv.isDarwin [ ] ++ lib.optionals stdenv.isDarwin [ darwin.sigtool ] ++
darwin.sigtool # Ensure that we inherit the propagated build inputs from the dependencies.
] ++ builtins.attrValues pubspecLockData.dependencySources;
# Ensure that we inherit the propagated build inputs from the dependencies.
builtins.attrValues pubspecLockData.dependencySources;
preConfigure = args.preConfigure or "" + '' preConfigure = args.preConfigure or "" + ''
ln -sf "$pubspecLockFilePath" pubspec.lock ln -sf "$pubspecLockFilePath" pubspec.lock
''; '';
# When stripping, it seems some ELF information is lost and the dart VM cli # When stripping, it seems some ELF information is lost and the dart VM cli
# runs instead of the expected program. Don't strip if it's an exe output. # runs instead of the expected program. Don't strip if it's an exe output.
dontStrip = args.dontStrip or (dartOutputType == "exe"); dontStrip = args.dontStrip or (dartOutputType == "exe");
passAsFile = [ "pubspecLockFile" ]; passAsFile = [ "pubspecLockFile" ];
passthru = { passthru = { pubspecLock = pubspecLockData; } // (args.passthru or { });
pubspecLock = pubspecLockData;
} // (args.passthru or { });
meta = (args.meta or { }) // { platforms = args.meta.platforms or dart.meta.platforms; }; meta = (args.meta or { }) // {
}); platforms = args.meta.platforms or dart.meta.platforms;
in };
assert !(builtins.isString dartOutputType && dartOutputType != "") -> });
throw "dartOutputType must be a non-empty string"; in assert !(builtins.isString dartOutputType && dartOutputType != "")
-> throw "dartOutputType must be a non-empty string";
baseDerivation baseDerivation

View file

@ -1,20 +1,11 @@
{ lib { lib, stdenvNoCC, dart, dartHooks, jq, yq, cacert }:
, stdenvNoCC
, dart
, dartHooks
, jq
, yq
, cacert
}:
{ {
# Arguments used in the derivation that builds the Dart package. # Arguments used in the derivation that builds the Dart package.
# Passing these is recommended to ensure that the same steps are made to # Passing these is recommended to ensure that the same steps are made to
# prepare the sources in both this derivation and the one that builds the Dart # prepare the sources in both this derivation and the one that builds the Dart
# package. # package.
buildDrvArgs ? { } buildDrvArgs ? { }, ... }@args:
, ...
}@args:
# This is a derivation and setup hook that can be used to fetch dependencies for Dart projects. # This is a derivation and setup hook that can be used to fetch dependencies for Dart projects.
# It is designed to be placed in the nativeBuildInputs of a derivation that builds a Dart package. # It is designed to be placed in the nativeBuildInputs of a derivation that builds a Dart package.
@ -38,37 +29,36 @@ let
"postPatch" "postPatch"
]; ];
buildDrvInheritArgs = builtins.foldl' buildDrvInheritArgs = builtins.foldl' (attrs: arg:
(attrs: arg: if buildDrvArgs ? ${arg} then
if buildDrvArgs ? ${arg} attrs // { ${arg} = buildDrvArgs.${arg}; }
then attrs // { ${arg} = buildDrvArgs.${arg}; } else
else attrs) attrs) { } buildDrvInheritArgNames;
{ }
buildDrvInheritArgNames;
drvArgs = buildDrvInheritArgs // (removeAttrs args [ "buildDrvArgs" ]); drvArgs = buildDrvInheritArgs // (removeAttrs args [ "buildDrvArgs" ]);
name = (if drvArgs ? name then drvArgs.name else "${drvArgs.pname}-${drvArgs.version}"); name = (if drvArgs ? name then
drvArgs.name
else
"${drvArgs.pname}-${drvArgs.version}");
# Adds the root package to a dependency package_config.json file from pub2nix. # Adds the root package to a dependency package_config.json file from pub2nix.
linkPackageConfig = { packageConfig, extraSetupCommands ? "" }: stdenvNoCC.mkDerivation (drvArgs // { linkPackageConfig = { packageConfig, extraSetupCommands ? "" }:
name = "${name}-package-config-with-root.json"; stdenvNoCC.mkDerivation (drvArgs // {
name = "${name}-package-config-with-root.json";
nativeBuildInputs = drvArgs.nativeBuildInputs or [ ] ++ args.nativeBuildInputs or [ ] ++ [ jq yq ]; nativeBuildInputs = drvArgs.nativeBuildInputs or [ ]
++ args.nativeBuildInputs or [ ] ++ [ jq yq ];
dontBuild = true; dontBuild = true;
installPhase = '' installPhase = ''
runHook preInstall runHook preInstall
packageName="$(yq --raw-output .name pubspec.yaml)" packageName="$(yq --raw-output .name pubspec.yaml)"
jq --arg name "$packageName" '.packages |= . + [{ name: $name, rootUri: "../", packageUri: "lib/" }]' '${packageConfig}' > "$out" jq --arg name "$packageName" '.packages |= . + [{ name: $name, rootUri: "../", packageUri: "lib/" }]' '${packageConfig}' > "$out"
${extraSetupCommands} ${extraSetupCommands}
runHook postInstall runHook postInstall
''; '';
}); });
in in { inherit linkPackageConfig; }
{
inherit
linkPackageConfig;
}

View file

@ -11,10 +11,8 @@
substitutions.yq = "${yq}/bin/yq"; substitutions.yq = "${yq}/bin/yq";
substitutions.jq = "${jq}/bin/jq"; substitutions.jq = "${jq}/bin/jq";
} ./dart-build-hook.sh; } ./dart-build-hook.sh;
dartInstallHook = makeSetupHook { dartInstallHook =
name = "dart-install-hook"; makeSetupHook { name = "dart-install-hook"; } ./dart-install-hook.sh;
} ./dart-install-hook.sh; dartFixupHook =
dartFixupHook = makeSetupHook { makeSetupHook { name = "dart-fixup-hook"; } ./dart-fixup-hook.sh;
name = "dart-fixup-hook";
} ./dart-fixup-hook.sh;
} }

View file

@ -1,68 +1,63 @@
{ lib { lib, runCommand, jq, yq }:
, runCommand
, jq
, yq
}:
{ pname ? null { pname ? null
# A list of dependency package names. # A list of dependency package names.
, dependencies , dependencies
# An attribute set of package names to sources. # An attribute set of package names to sources.
, dependencySources , dependencySources }:
}:
let let
packages = lib.genAttrs dependencies (dependency: rec { packages = lib.genAttrs dependencies (dependency: rec {
src = dependencySources.${dependency}; src = dependencySources.${dependency};
inherit (src) packageRoot; inherit (src) packageRoot;
}); });
in in (runCommand
(runCommand "${lib.optionalString (pname != null) "${pname}-"}package-config.json" { "${lib.optionalString (pname != null) "${pname}-"}package-config.json" {
inherit packages; inherit packages;
nativeBuildInputs = [ jq yq ]; nativeBuildInputs = [ jq yq ];
__structuredAttrs = true; __structuredAttrs = true;
}) '' }) ''
declare -A packageSources declare -A packageSources
declare -A packageRoots declare -A packageRoots
while IFS=',' read -r name src packageRoot; do while IFS=',' read -r name src packageRoot; do
packageSources["$name"]="$src" packageSources["$name"]="$src"
packageRoots["$name"]="$packageRoot" packageRoots["$name"]="$packageRoot"
done < <(jq -r '.packages | to_entries | map("\(.key),\(.value.src),\(.value.packageRoot)") | .[]' "$NIX_ATTRS_JSON_FILE") done < <(jq -r '.packages | to_entries | map("\(.key),\(.value.src),\(.value.packageRoot)") | .[]' "$NIX_ATTRS_JSON_FILE")
for package in "''${!packageSources[@]}"; do for package in "''${!packageSources[@]}"; do
if [ ! -e "''${packageSources["$package"]}/''${packageRoots["$package"]}/pubspec.yaml" ]; then if [ ! -e "''${packageSources["$package"]}/''${packageRoots["$package"]}/pubspec.yaml" ]; then
echo >&2 "The package sources for $package are missing. Is the following path inside the source derivation?" echo >&2 "The package sources for $package are missing. Is the following path inside the source derivation?"
echo >&2 "Source path: ''${packageSources["$package"]}/''${packageRoots["$package"]}/pubspec.yaml" echo >&2 "Source path: ''${packageSources["$package"]}/''${packageRoots["$package"]}/pubspec.yaml"
exit 1 exit 1
fi fi
languageConstraint="$(yq -r .environment.sdk "''${packageSources["$package"]}/''${packageRoots["$package"]}/pubspec.yaml")" languageConstraint="$(yq -r .environment.sdk "''${packageSources["$package"]}/''${packageRoots["$package"]}/pubspec.yaml")"
if [[ "$languageConstraint" =~ ^[[:space:]]*(\^|>=|>)?[[:space:]]*([[:digit:]]+\.[[:digit:]]+)\.[[:digit:]]+.*$ ]]; then if [[ "$languageConstraint" =~ ^[[:space:]]*(\^|>=|>)?[[:space:]]*([[:digit:]]+\.[[:digit:]]+)\.[[:digit:]]+.*$ ]]; then
languageVersionJson="\"''${BASH_REMATCH[2]}\"" languageVersionJson="\"''${BASH_REMATCH[2]}\""
elif [ "$languageConstraint" = 'any' ]; then elif [ "$languageConstraint" = 'any' ]; then
languageVersionJson='null' languageVersionJson='null'
else else
# https://github.com/dart-lang/pub/blob/68dc2f547d0a264955c1fa551fa0a0e158046494/lib/src/language_version.dart#L106C35-L106C35 # https://github.com/dart-lang/pub/blob/68dc2f547d0a264955c1fa551fa0a0e158046494/lib/src/language_version.dart#L106C35-L106C35
languageVersionJson='"2.7"' languageVersionJson='"2.7"'
fi fi
jq --null-input \ jq --null-input \
--arg name "$package" \ --arg name "$package" \
--arg path "''${packageSources["$package"]}/''${packageRoots["$package"]}" \ --arg path "''${packageSources["$package"]}/''${packageRoots["$package"]}" \
--argjson languageVersion "$languageVersionJson" \ --argjson languageVersion "$languageVersionJson" \
'{ '{
name: $name, name: $name,
rootUri: "file://\($path)", rootUri: "file://\($path)",
packageUri: "lib/", packageUri: "lib/",
languageVersion: $languageVersion, languageVersion: $languageVersion,
}' }'
done | jq > "$out" --slurp '{ done | jq > "$out" --slurp '{
configVersion: 2, configVersion: 2,
generator: "nixpkgs", generator: "nixpkgs",
packages: ., packages: .,
}' }'
'' ''

View file

@ -1,23 +1,18 @@
{ lib { lib, callPackage, fetchurl, fetchgit, runCommand }:
, callPackage
, fetchurl
, fetchgit
, runCommand
}:
{ {
# The source directory of the package. # The source directory of the package.
src src
# The package subdirectory within src. # The package subdirectory within src.
# Useful if the package references sibling packages with relative paths. # Useful if the package references sibling packages with relative paths.
, packageRoot ? "." , packageRoot ? "."
# The pubspec.lock file, in attribute set form. # The pubspec.lock file, in attribute set form.
, pubspecLock , pubspecLock
# Hashes for Git dependencies. # Hashes for Git dependencies.
# Pub does not record these itself, so they must be manually provided. # Pub does not record these itself, so they must be manually provided.
, gitHashes ? { } , gitHashes ? { }
# Functions to generate SDK package sources. # Functions to generate SDK package sources.
@ -30,11 +25,11 @@
# source, and source files are given in an attribute set argument. # source, and source files are given in an attribute set argument.
# #
# The passthru of the source derivation should be propagated. # The passthru of the source derivation should be propagated.
, customSourceBuilders ? { } , customSourceBuilders ? { } }:
}:
let let
dependencyVersions = builtins.mapAttrs (name: details: details.version) pubspecLock.packages; dependencyVersions =
builtins.mapAttrs (name: details: details.version) pubspecLock.packages;
dependencyTypes = { dependencyTypes = {
"direct main" = "main"; "direct main" = "main";
@ -43,8 +38,11 @@ let
"transitive" = "transitive"; "transitive" = "transitive";
}; };
dependencies = lib.foldlAttrs dependencies = lib.foldlAttrs (dependencies: name: details:
(dependencies: name: details: dependencies // { ${dependencyTypes.${details.dependency}} = dependencies.${dependencyTypes.${details.dependency}} ++ [ name ]; }) dependencies // {
${dependencyTypes.${details.dependency}} =
dependencies.${dependencyTypes.${details.dependency}} ++ [ name ];
})
(lib.genAttrs (builtins.attrValues dependencyTypes) (dependencyType: [ ])) (lib.genAttrs (builtins.attrValues dependencyTypes) (dependencyType: [ ]))
pubspecLock.packages; pubspecLock.packages;
@ -54,47 +52,56 @@ let
let let
archive = fetchurl { archive = fetchurl {
name = "pub-${name}-${details.version}.tar.gz"; name = "pub-${name}-${details.version}.tar.gz";
url = "${details.description.url}/packages/${details.description.name}/versions/${details.version}.tar.gz"; url =
"${details.description.url}/packages/${details.description.name}/versions/${details.version}.tar.gz";
sha256 = details.description.sha256; sha256 = details.description.sha256;
}; };
in in runCommand "pub-${name}-${details.version}" {
runCommand "pub-${name}-${details.version}" { passthru.packageRoot = "."; } '' passthru.packageRoot = ".";
} ''
mkdir -p "$out" mkdir -p "$out"
tar xf '${archive}' -C "$out" tar xf '${archive}' -C "$out"
''; '';
mkGitDependencySource = name: details: (fetchgit { mkGitDependencySource = name: details:
name = "pub-${name}-${details.version}"; (fetchgit {
url = details.description.url; name = "pub-${name}-${details.version}";
rev = details.description.resolved-ref; url = details.description.url;
hash = gitHashes.${name} or (throw "A Git hash is required for ${name}! Set to an empty string to obtain it."); rev = details.description.resolved-ref;
}).overrideAttrs ({ passthru ? { }, ... }: { hash = gitHashes.${name} or (throw
passthru = passthru // { "A Git hash is required for ${name}! Set to an empty string to obtain it.");
packageRoot = details.description.path; }).overrideAttrs ({ passthru ? { }, ... }: {
}; passthru = passthru // { packageRoot = details.description.path; };
});
mkPathDependencySource = name: details:
assert lib.assertMsg details.description.relative "Only relative paths are supported - ${name} has an absolue path!";
(if lib.isDerivation src then src else (runCommand "pub-${name}-${details.version}" { } ''cp -r '${src}' "$out"'')).overrideAttrs ({ passthru ? { }, ... }: {
passthru = passthru // {
packageRoot = "${packageRoot}/${details.description.path}";
};
}); });
mkPathDependencySource = name: details:
assert lib.assertMsg details.description.relative
"Only relative paths are supported - ${name} has an absolue path!";
(if lib.isDerivation src then
src
else
(runCommand "pub-${name}-${details.version}" { }
''cp -r '${src}' "$out"'')).overrideAttrs ({ passthru ? { }, ... }: {
passthru = passthru // {
packageRoot = "${packageRoot}/${details.description.path}";
};
});
mkSdkDependencySource = name: details: mkSdkDependencySource = name: details:
(sdkSourceBuilders.${details.description} or (throw "No SDK source builder has been given for ${details.description}!")) name; (sdkSourceBuilders.${details.description} or (throw
"No SDK source builder has been given for ${details.description}!")) name;
addDependencySourceUtils = dependencySource: details: dependencySource.overrideAttrs ({ passthru, ... }: { addDependencySourceUtils = dependencySource: details:
passthru = passthru // { dependencySource.overrideAttrs ({ passthru, ... }: {
inherit (details) version; passthru = passthru // { inherit (details) version; };
}; });
});
sourceBuilders = callPackage ../../../development/compilers/dart/package-source-builders { } // customSourceBuilders; sourceBuilders =
callPackage ../../../development/compilers/dart/package-source-builders { }
// customSourceBuilders;
dependencySources = lib.filterAttrs (name: src: src != null) (builtins.mapAttrs dependencySources = lib.filterAttrs (name: src: src != null)
(name: details: (builtins.mapAttrs (name: details:
(sourceBuilders.${name} or ({ src, ... }: src)) { (sourceBuilders.${name} or ({ src, ... }: src)) {
inherit (details) version source; inherit (details) version source;
src = ((addDependencySourceUtils (({ src = ((addDependencySourceUtils (({
@ -103,12 +110,10 @@ let
"path" = mkPathDependencySource; "path" = mkPathDependencySource;
"sdk" = mkSdkDependencySource; "sdk" = mkSdkDependencySource;
}.${details.source} name) details)) details); }.${details.source} name) details)) details);
}) }) pubspecLock.packages);
pubspecLock.packages); in {
in
{
inherit inherit
# An attribute set of dependency categories to package name lists. # An attribute set of dependency categories to package name lists.
dependencies dependencies
# An attribute set of package names to their versions. # An attribute set of package names to their versions.

View file

@ -1,11 +1,5 @@
# expr and script based on our lsb_release # expr and script based on our lsb_release
{ stdenv { stdenv, lib, substituteAll, coreutils, getopt, modDirVersion ? "" }:
, lib
, substituteAll
, coreutils
, getopt
, modDirVersion ? ""
}:
substituteAll { substituteAll {
name = "uname"; name = "uname";
@ -17,7 +11,10 @@ substituteAll {
inherit coreutils getopt; inherit coreutils getopt;
uSystem = if stdenv.buildPlatform.uname.system != null then stdenv.buildPlatform.uname.system else "unknown"; uSystem = if stdenv.buildPlatform.uname.system != null then
stdenv.buildPlatform.uname.system
else
"unknown";
inherit (stdenv.buildPlatform.uname) processor; inherit (stdenv.buildPlatform.uname) processor;
# uname -o # uname -o
@ -25,12 +22,12 @@ substituteAll {
# https://github.com/coreutils/coreutils/blob/7fc84d1c0f6b35231b0b4577b70aaa26bf548a7c/src/uname.c#L373-L374 # https://github.com/coreutils/coreutils/blob/7fc84d1c0f6b35231b0b4577b70aaa26bf548a7c/src/uname.c#L373-L374
# https://stackoverflow.com/questions/61711186/where-does-host-operating-system-in-uname-c-comes-from # https://stackoverflow.com/questions/61711186/where-does-host-operating-system-in-uname-c-comes-from
# https://github.com/coreutils/gnulib/blob/master/m4/host-os.m4 # https://github.com/coreutils/gnulib/blob/master/m4/host-os.m4
operatingSystem = operatingSystem = if stdenv.buildPlatform.isLinux then
if stdenv.buildPlatform.isLinux "GNU/Linux"
then "GNU/Linux" else if stdenv.buildPlatform.isDarwin then
else if stdenv.buildPlatform.isDarwin "Darwin" # darwin isn't in host-os.m4 so where does this come from?
then "Darwin" # darwin isn't in host-os.m4 so where does this come from? else
else "unknown"; "unknown";
# in os-specific/linux module packages # in os-specific/linux module packages
# --replace '$(shell uname -r)' "${kernel.modDirVersion}" \ # --replace '$(shell uname -r)' "${kernel.modDirVersion}" \
@ -38,7 +35,8 @@ substituteAll {
modDirVersion = if modDirVersion != "" then modDirVersion else "unknown"; modDirVersion = if modDirVersion != "" then modDirVersion else "unknown";
meta = with lib; { meta = with lib; {
description = "Print certain system information (hardcoded with lib/system values)"; description =
"Print certain system information (hardcoded with lib/system values)";
mainProgram = "uname"; mainProgram = "uname";
longDescription = '' longDescription = ''
This package provides a replacement for `uname` whose output depends only This package provides a replacement for `uname` whose output depends only

View file

@ -1,4 +1,4 @@
{ dhallPackages, dhallPackageToNix}: { dhallPackages, dhallPackageToNix }:
# `dhallDirectoryToNix is a utility function to take a directory of Dhall files # `dhallDirectoryToNix is a utility function to take a directory of Dhall files
# and read them in as a Nix expression. # and read them in as a Nix expression.
@ -11,15 +11,12 @@
# `dhallDirectoryToNix` utility. It is not possible to use # `dhallDirectoryToNix` utility. It is not possible to use
# `dhallDirectoryToNix` in Nixpkgs, since the Nixpkgs Hydra doesn't allow IFD. # `dhallDirectoryToNix` in Nixpkgs, since the Nixpkgs Hydra doesn't allow IFD.
{ src { src, # The file to import, relative to the src root directory
, # The file to import, relative to the src root directory file ? "package.dhall" }@args:
file ? "package.dhall"
}@args:
let let
generatedPkg = dhallPackages.generateDhallDirectoryPackage args; generatedPkg = dhallPackages.generateDhallDirectoryPackage args;
builtPkg = dhallPackages.callPackage generatedPkg { }; builtPkg = dhallPackages.callPackage generatedPkg { };
in in dhallPackageToNix builtPkg
dhallPackageToNix builtPkg

View file

@ -1,4 +1,3 @@
# `dhallPackageToNix` is a utility function to take a Nixpkgs Dhall package # `dhallPackageToNix` is a utility function to take a Nixpkgs Dhall package
# (created with a function like `dhallPackages.buildDhallDirectoryPackage`) # (created with a function like `dhallPackages.buildDhallDirectoryPackage`)
# and read it in as a Nix expression. # and read it in as a Nix expression.
@ -14,23 +13,22 @@
{ stdenv, dhall-nix }: { stdenv, dhall-nix }:
dhallPackage: dhallPackage:
let let
drv = stdenv.mkDerivation { drv = stdenv.mkDerivation {
name = "dhall-compiled-package.nix"; name = "dhall-compiled-package.nix";
buildCommand = '' buildCommand = ''
# Dhall requires that the cache is writable, even if it is never written to. # Dhall requires that the cache is writable, even if it is never written to.
# We copy the cache from the input package to the current directory and # We copy the cache from the input package to the current directory and
# set the cache as writable. # set the cache as writable.
cp -r "${dhallPackage}/.cache" ./ cp -r "${dhallPackage}/.cache" ./
export XDG_CACHE_HOME=$PWD/.cache export XDG_CACHE_HOME=$PWD/.cache
chmod -R +w ./.cache chmod -R +w ./.cache
dhall-to-nix <<< "${dhallPackage}/binary.dhall" > $out dhall-to-nix <<< "${dhallPackage}/binary.dhall" > $out
''; '';
nativeBuildInputs = [ dhall-nix ]; nativeBuildInputs = [ dhall-nix ];
}; };
in in import drv
import drv

View file

@ -18,7 +18,7 @@
{ stdenv, dhall-nix, writeText }: { stdenv, dhall-nix, writeText }:
let let
dhallToNix = code : dhallToNix = code:
let let
file = writeText "dhall-expression" code; file = writeText "dhall-expression" code;
@ -32,7 +32,5 @@ let
buildInputs = [ dhall-nix ]; buildInputs = [ dhall-nix ];
}; };
in in import drv;
import drv; in dhallToNix
in
dhallToNix

View file

@ -1,124 +1,97 @@
{ { lib, stdenv, fetchurl, linkFarm, dub, ldc, removeReferencesTo, }:
lib,
stdenv,
fetchurl,
linkFarm,
dub,
ldc,
removeReferencesTo,
}:
# See https://nixos.org/manual/nixpkgs/unstable#dlang for more detailed usage information # See https://nixos.org/manual/nixpkgs/unstable#dlang for more detailed usage information
{ {
# A lockfile generated by `dub-to-nix` from the source of the package. # A lockfile generated by `dub-to-nix` from the source of the package.
# Can be either a path to the file, or an attrset already parsed with `lib.importJSON`. # Can be either a path to the file, or an attrset already parsed with `lib.importJSON`.
dubLock, dubLock,
# The build type to pass to `dub build` as a value for the `--build=` flag. # The build type to pass to `dub build` as a value for the `--build=` flag.
dubBuildType ? "release", dubBuildType ? "release",
# The flags to pass to `dub build` and `dub test`. # The flags to pass to `dub build` and `dub test`.
dubFlags ? [ ], dubFlags ? [ ],
# The flags to pass to `dub build`. # The flags to pass to `dub build`.
dubBuildFlags ? [ ], dubBuildFlags ? [ ],
# The flags to pass to `dub test`. # The flags to pass to `dub test`.
dubTestFlags ? [ ], dubTestFlags ? [ ],
# The D compiler to be used by `dub`. # The D compiler to be used by `dub`.
compiler ? ldc, compiler ? ldc, ... }@args:
...
}@args:
let let
makeDubDep = makeDubDep = { pname, version, sha256, }: {
{ inherit pname version;
pname, src = fetchurl {
version, name = "dub-${pname}-${version}.zip";
sha256, url = "mirror://dub/${pname}/${version}.zip";
}: inherit sha256;
{
inherit pname version;
src = fetchurl {
name = "dub-${pname}-${version}.zip";
url = "mirror://dub/${pname}/${version}.zip";
inherit sha256;
};
}; };
};
lockJson = if lib.isPath dubLock then lib.importJSON dubLock else dubLock; lockJson = if lib.isPath dubLock then lib.importJSON dubLock else dubLock;
lockedDeps = lib.mapAttrsToList ( lockedDeps = lib.mapAttrsToList
pname: { version, sha256 }: makeDubDep { inherit pname version sha256; } (pname: { version, sha256 }: makeDubDep { inherit pname version sha256; })
) lockJson.dependencies; lockJson.dependencies;
# a directory with multiple single element registries # a directory with multiple single element registries
# one big directory with all .zip files leads to version parsing errors # one big directory with all .zip files leads to version parsing errors
# when the name of a package is a prefix of the name of another package # when the name of a package is a prefix of the name of another package
dubRegistryBase = linkFarm "dub-registry-base" ( dubRegistryBase = linkFarm "dub-registry-base" (map (dep: {
map (dep: { name = "${dep.pname}/${dep.pname}-${dep.version}.zip";
name = "${dep.pname}/${dep.pname}-${dep.version}.zip"; path = dep.src;
path = dep.src; }) lockedDeps);
}) lockedDeps
);
combinedFlags = "--skip-registry=all --compiler=${lib.getExe compiler} ${toString dubFlags}"; combinedFlags = "--skip-registry=all --compiler=${lib.getExe compiler} ${
combinedBuildFlags = "${combinedFlags} --build=${dubBuildType} ${toString dubBuildFlags}"; toString dubFlags
}";
combinedBuildFlags =
"${combinedFlags} --build=${dubBuildType} ${toString dubBuildFlags}";
combinedTestFlags = "${combinedFlags} ${toString dubTestFlags}"; combinedTestFlags = "${combinedFlags} ${toString dubTestFlags}";
in in stdenv.mkDerivation (builtins.removeAttrs args [ "dubLock" ] // {
stdenv.mkDerivation ( strictDeps = args.strictDeps or true;
builtins.removeAttrs args [ "dubLock" ]
// {
strictDeps = args.strictDeps or true;
nativeBuildInputs = args.nativeBuildInputs or [ ] ++ [ nativeBuildInputs = args.nativeBuildInputs or [ ]
dub ++ [ dub compiler removeReferencesTo ];
compiler
removeReferencesTo
];
configurePhase = configurePhase = args.configurePhase or ''
args.configurePhase or '' runHook preConfigure
runHook preConfigure
export DUB_HOME="$NIX_BUILD_TOP/.dub" export DUB_HOME="$NIX_BUILD_TOP/.dub"
mkdir -p $DUB_HOME mkdir -p $DUB_HOME
# register dependencies # register dependencies
${lib.concatMapStringsSep "\n" (dep: '' ${lib.concatMapStringsSep "\n" (dep: ''
dub fetch ${dep.pname}@${dep.version} --cache=user --skip-registry=standard --registry=file://${dubRegistryBase}/${dep.pname} dub fetch ${dep.pname}@${dep.version} --cache=user --skip-registry=standard --registry=file://${dubRegistryBase}/${dep.pname}
'') lockedDeps} '') lockedDeps}
runHook postConfigure runHook postConfigure
''; '';
buildPhase = buildPhase = args.buildPhase or ''
args.buildPhase or '' runHook preBuild
runHook preBuild
dub build ${combinedBuildFlags} dub build ${combinedBuildFlags}
runHook postBuild runHook postBuild
''; '';
doCheck = args.doCheck or false; doCheck = args.doCheck or false;
checkPhase = checkPhase = args.checkPhase or ''
args.checkPhase or '' runHook preCheck
runHook preCheck
dub test ${combinedTestFlags} dub test ${combinedTestFlags}
runHook postCheck runHook postCheck
''; '';
preFixup = '' preFixup = ''
${args.preFixup or ""} ${args.preFixup or ""}
find "$out" -type f -exec remove-references-to -t ${compiler} '{}' + find "$out" -type f -exec remove-references-to -t ${compiler} '{}' +
''; '';
disallowedReferences = [ compiler ]; disallowedReferences = [ compiler ];
meta = { meta = { platforms = dub.meta.platforms; } // args.meta or { };
platforms = dub.meta.platforms; })
} // args.meta or { };
}
)

View file

@ -1,5 +1,4 @@
{ callPackage }: { callPackage }: {
{
buildDubPackage = callPackage ./builddubpackage { }; buildDubPackage = callPackage ./builddubpackage { };
dub-to-nix = callPackage ./dub-to-nix { }; dub-to-nix = callPackage ./dub-to-nix { };
} }

View file

@ -1,19 +1,11 @@
{ { lib, runCommand, makeWrapper, python3, nix, }:
lib,
runCommand,
makeWrapper,
python3,
nix,
}:
runCommand "dub-to-nix" runCommand "dub-to-nix" {
{ nativeBuildInputs = [ makeWrapper ];
nativeBuildInputs = [ makeWrapper ]; buildInputs = [ python3 ];
buildInputs = [ python3 ]; } ''
} install -Dm755 ${./dub-to-nix.py} "$out/bin/dub-to-nix"
'' patchShebangs "$out/bin/dub-to-nix"
install -Dm755 ${./dub-to-nix.py} "$out/bin/dub-to-nix" wrapProgram "$out/bin/dub-to-nix" \
patchShebangs "$out/bin/dub-to-nix" --prefix PATH : ${lib.makeBinPath [ nix ]}
wrapProgram "$out/bin/dub-to-nix" \ ''
--prefix PATH : ${lib.makeBinPath [ nix ]}
''

File diff suppressed because it is too large Load diff

View file

@ -7,19 +7,18 @@
# $ nix-build '<nixpkgs>' -A dockerTools.examples.redis # $ nix-build '<nixpkgs>' -A dockerTools.examples.redis
# $ docker load < result # $ docker load < result
{ pkgs, buildImage, buildLayeredImage, fakeNss, pullImage, shadowSetup, buildImageWithNixDb, pkgsCross, streamNixShellImage }: { pkgs, buildImage, buildLayeredImage, fakeNss, pullImage, shadowSetup
, buildImageWithNixDb, pkgsCross, streamNixShellImage }:
let let
nixosLib = import ../../../nixos/lib { nixosLib = import ../../../nixos/lib {
# Experimental features need testing too, but there's no point in warning # Experimental features need testing too, but there's no point in warning
# about it, so we enable the feature flag. # about it, so we enable the feature flag.
featureFlags.minimalModules = {}; featureFlags.minimalModules = { };
}; };
evalMinimalConfig = module: nixosLib.evalModules { modules = [ module ]; }; evalMinimalConfig = module: nixosLib.evalModules { modules = [ module ]; };
in in rec {
rec {
# 1. basic example # 1. basic example
bash = buildImage { bash = buildImage {
name = "bash"; name = "bash";
@ -53,9 +52,7 @@ rec {
config = { config = {
Cmd = [ "/bin/redis-server" ]; Cmd = [ "/bin/redis-server" ];
WorkingDir = "/data"; WorkingDir = "/data";
Volumes = { Volumes = { "/data" = { }; };
"/data" = {};
};
}; };
}; };
@ -82,14 +79,10 @@ rec {
nginxWebRoot = pkgs.writeTextDir "index.html" '' nginxWebRoot = pkgs.writeTextDir "index.html" ''
<html><body><h1>Hello from NGINX</h1></body></html> <html><body><h1>Hello from NGINX</h1></body></html>
''; '';
in in buildLayeredImage {
buildLayeredImage {
name = "nginx-container"; name = "nginx-container";
tag = "latest"; tag = "latest";
contents = [ contents = [ fakeNss pkgs.nginx ];
fakeNss
pkgs.nginx
];
extraCommands = '' extraCommands = ''
mkdir -p tmp/nginx_client_body mkdir -p tmp/nginx_client_body
@ -101,16 +94,15 @@ rec {
config = { config = {
Cmd = [ "nginx" "-c" nginxConf ]; Cmd = [ "nginx" "-c" nginxConf ];
ExposedPorts = { ExposedPorts = { "${nginxPort}/tcp" = { }; };
"${nginxPort}/tcp" = {};
};
}; };
}; };
# 4. example of pulling an image. could be used as a base for other images # 4. example of pulling an image. could be used as a base for other images
nixFromDockerHub = pullImage { nixFromDockerHub = pullImage {
imageName = "nixos/nix"; imageName = "nixos/nix";
imageDigest = "sha256:85299d86263a3059cf19f419f9d286cc9f06d3c13146a8ebbb21b3437f598357"; imageDigest =
"sha256:85299d86263a3059cf19f419f9d286cc9f06d3c13146a8ebbb21b3437f598357";
sha256 = "19fw0n3wmddahzr20mhdqv6jkjn1kanh6n2mrr08ai53dr8ph5n7"; sha256 = "19fw0n3wmddahzr20mhdqv6jkjn1kanh6n2mrr08ai53dr8ph5n7";
finalImageTag = "2.2.1"; finalImageTag = "2.2.1";
finalImageName = "nix"; finalImageName = "nix";
@ -119,7 +111,8 @@ rec {
# NOTE: Only use this for testing, or you'd be wasting a lot of time, network and space. # NOTE: Only use this for testing, or you'd be wasting a lot of time, network and space.
testNixFromDockerHub = pkgs.testers.invalidateFetcherByDrvHash pullImage { testNixFromDockerHub = pkgs.testers.invalidateFetcherByDrvHash pullImage {
imageName = "nixos/nix"; imageName = "nixos/nix";
imageDigest = "sha256:85299d86263a3059cf19f419f9d286cc9f06d3c13146a8ebbb21b3437f598357"; imageDigest =
"sha256:85299d86263a3059cf19f419f9d286cc9f06d3c13146a8ebbb21b3437f598357";
sha256 = "19fw0n3wmddahzr20mhdqv6jkjn1kanh6n2mrr08ai53dr8ph5n7"; sha256 = "19fw0n3wmddahzr20mhdqv6jkjn1kanh6n2mrr08ai53dr8ph5n7";
finalImageTag = "2.2.1"; finalImageTag = "2.2.1";
finalImageName = "nix"; finalImageName = "nix";
@ -131,13 +124,7 @@ rec {
copyToRoot = pkgs.buildEnv { copyToRoot = pkgs.buildEnv {
name = "image-root"; name = "image-root";
pathsToLink = [ "/bin" ]; pathsToLink = [ "/bin" ];
paths = [ paths = [ pkgs.coreutils pkgs.bash pkgs.emacs pkgs.vim pkgs.nano ];
pkgs.coreutils
pkgs.bash
pkgs.emacs
pkgs.vim
pkgs.nano
];
}; };
}; };
@ -231,9 +218,7 @@ rec {
config = { config = {
Env = [ "PATH=${pkgs.coreutils}/bin/" ]; Env = [ "PATH=${pkgs.coreutils}/bin/" ];
WorkingDir = "/example-output"; WorkingDir = "/example-output";
Cmd = [ Cmd = [ "${pkgs.bash}/bin/bash" "-c" "echo hello > foo; cat foo" ];
"${pkgs.bash}/bin/bash" "-c" "echo hello > foo; cat foo"
];
}; };
}; };
@ -249,9 +234,7 @@ rec {
config = { config = {
Env = [ "PATH=${pkgs.coreutils}/bin/" ]; Env = [ "PATH=${pkgs.coreutils}/bin/" ];
WorkingDir = "/example-output"; WorkingDir = "/example-output";
Cmd = [ Cmd = [ "${pkgs.bash}/bin/bash" "-c" "echo hello > foo; cat foo" ];
"${pkgs.bash}/bin/bash" "-c" "echo hello > foo; cat foo"
];
}; };
}; };
@ -312,12 +295,7 @@ rec {
environmentVariablesParent = pkgs.dockerTools.buildImage { environmentVariablesParent = pkgs.dockerTools.buildImage {
name = "parent"; name = "parent";
tag = "latest"; tag = "latest";
config = { config = { Env = [ "FROM_PARENT=true" "LAST_LAYER=parent" ]; };
Env = [
"FROM_PARENT=true"
"LAST_LAYER=parent"
];
};
}; };
environmentVariables = pkgs.dockerTools.buildImage { environmentVariables = pkgs.dockerTools.buildImage {
@ -329,12 +307,7 @@ rec {
pathsToLink = [ "/bin" ]; pathsToLink = [ "/bin" ];
paths = [ pkgs.coreutils ]; paths = [ pkgs.coreutils ];
}; };
config = { config = { Env = [ "FROM_CHILD=true" "LAST_LAYER=child" ]; };
Env = [
"FROM_CHILD=true"
"LAST_LAYER=child"
];
};
}; };
environmentVariablesLayered = pkgs.dockerTools.buildLayeredImage { environmentVariablesLayered = pkgs.dockerTools.buildLayeredImage {
@ -342,12 +315,7 @@ rec {
fromImage = environmentVariablesParent; fromImage = environmentVariablesParent;
tag = "latest"; tag = "latest";
contents = [ pkgs.coreutils ]; contents = [ pkgs.coreutils ];
config = { config = { Env = [ "FROM_CHILD=true" "LAST_LAYER=child" ]; };
Env = [
"FROM_CHILD=true"
"LAST_LAYER=child"
];
};
}; };
# 16. Create another layered image, for comparing layers with image 10. # 16. Create another layered image, for comparing layers with image 10.
@ -371,9 +339,7 @@ rec {
bulk-layer = pkgs.dockerTools.buildLayeredImage { bulk-layer = pkgs.dockerTools.buildLayeredImage {
name = "bulk-layer"; name = "bulk-layer";
tag = "latest"; tag = "latest";
contents = with pkgs; [ contents = with pkgs; [ coreutils hello ];
coreutils hello
];
maxLayers = 2; maxLayers = 2;
}; };
@ -383,9 +349,7 @@ rec {
name = "layered-bulk-layer"; name = "layered-bulk-layer";
tag = "latest"; tag = "latest";
fromImage = two-layered-image; fromImage = two-layered-image;
contents = with pkgs; [ contents = with pkgs; [ coreutils hello ];
coreutils hello
];
maxLayers = 4; maxLayers = 4;
}; };
@ -455,8 +419,7 @@ rec {
# 23. Ensure that layers are unpacked in the correct order before the # 23. Ensure that layers are unpacked in the correct order before the
# runAsRoot script is executed. # runAsRoot script is executed.
layersUnpackOrder = layersUnpackOrder = let
let
layerOnTopOf = parent: layerName: layerOnTopOf = parent: layerName:
pkgs.dockerTools.buildImage { pkgs.dockerTools.buildImage {
name = "layers-unpack-order-${layerName}"; name = "layers-unpack-order-${layerName}";
@ -475,7 +438,7 @@ rec {
# When executing the runAsRoot script when building layer C, if layer B is # When executing the runAsRoot script when building layer C, if layer B is
# not unpacked on top of layer A, the contents of /layer-order will not be # not unpacked on top of layer A, the contents of /layer-order will not be
# "ABC". # "ABC".
layerA = layerOnTopOf null "a"; layerA = layerOnTopOf null "a";
layerB = layerOnTopOf layerA "b"; layerB = layerOnTopOf layerA "b";
layerC = layerOnTopOf layerB "c"; layerC = layerOnTopOf layerB "c";
in layerC; in layerC;
@ -532,47 +495,42 @@ rec {
}; };
# buildLayeredImage with non-root user # buildLayeredImage with non-root user
bashLayeredWithUser = bashLayeredWithUser = let
let nonRootShadowSetup = { user, uid, gid ? uid }:
nonRootShadowSetup = { user, uid, gid ? uid }: with pkgs; [ with pkgs; [
( (writeTextDir "etc/shadow" ''
writeTextDir "etc/shadow" '' root:!x:::::::
root:!x::::::: ${user}:!:::::::
${user}:!::::::: '')
'' (writeTextDir "etc/passwd" ''
) root:x:0:0::/root:${runtimeShell}
( ${user}:x:${toString uid}:${toString gid}::/home/${user}:
writeTextDir "etc/passwd" '' '')
root:x:0:0::/root:${runtimeShell} (writeTextDir "etc/group" ''
${user}:x:${toString uid}:${toString gid}::/home/${user}: root:x:0:
'' ${user}:x:${toString gid}:
) '')
( (writeTextDir "etc/gshadow" ''
writeTextDir "etc/group" '' root:x::
root:x:0: ${user}:x::
${user}:x:${toString gid}: '')
'' ];
) in pkgs.dockerTools.buildLayeredImage {
( name = "bash-layered-with-user";
writeTextDir "etc/gshadow" '' tag = "latest";
root:x:: contents = [ pkgs.bash pkgs.coreutils ] ++ nonRootShadowSetup {
${user}:x:: uid = 999;
'' user = "somebody";
)
];
in
pkgs.dockerTools.buildLayeredImage {
name = "bash-layered-with-user";
tag = "latest";
contents = [ pkgs.bash pkgs.coreutils ] ++ nonRootShadowSetup { uid = 999; user = "somebody"; };
}; };
};
# basic example, with cross compilation # basic example, with cross compilation
cross = let cross = let
# Cross compile for x86_64 if on aarch64 # Cross compile for x86_64 if on aarch64
crossPkgs = crossPkgs = if pkgs.stdenv.hostPlatform.system == "aarch64-linux" then
if pkgs.stdenv.hostPlatform.system == "aarch64-linux" then pkgsCross.gnu64 pkgsCross.gnu64
else pkgsCross.aarch64-multiplatform; else
pkgsCross.aarch64-multiplatform;
in crossPkgs.dockerTools.buildImage { in crossPkgs.dockerTools.buildImage {
name = "hello-cross"; name = "hello-cross";
tag = "latest"; tag = "latest";
@ -584,16 +542,16 @@ rec {
}; };
# layered image where a store path is itself a symlink # layered image where a store path is itself a symlink
layeredStoreSymlink = layeredStoreSymlink = let
let
target = pkgs.writeTextDir "dir/target" "Content doesn't matter."; target = pkgs.writeTextDir "dir/target" "Content doesn't matter.";
symlink = pkgs.runCommand "symlink" {} "ln -s ${target} $out"; symlink = pkgs.runCommand "symlink" { } "ln -s ${target} $out";
in in pkgs.dockerTools.buildLayeredImage {
pkgs.dockerTools.buildLayeredImage { name = "layeredstoresymlink";
name = "layeredstoresymlink"; tag = "latest";
tag = "latest"; contents = [ pkgs.bash symlink ];
contents = [ pkgs.bash symlink ]; } // {
} // { passthru = { inherit symlink; }; }; passthru = { inherit symlink; };
};
# image with registry/ prefix # image with registry/ prefix
prefixedImage = pkgs.dockerTools.buildImage { prefixedImage = pkgs.dockerTools.buildImage {
@ -613,44 +571,34 @@ rec {
layeredImageWithFakeRootCommands = pkgs.dockerTools.buildLayeredImage { layeredImageWithFakeRootCommands = pkgs.dockerTools.buildLayeredImage {
name = "layered-image-with-fake-root-commands"; name = "layered-image-with-fake-root-commands";
tag = "latest"; tag = "latest";
contents = [ contents = [ pkgs.pkgsStatic.busybox ];
pkgs.pkgsStatic.busybox
];
fakeRootCommands = '' fakeRootCommands = ''
mkdir -p ./home/alice mkdir -p ./home/alice
chown 1000 ./home/alice chown 1000 ./home/alice
ln -s ${pkgs.hello.overrideAttrs (o: { ln -s ${
# A unique `hello` to make sure that it isn't included via another mechanism by accident. pkgs.hello.overrideAttrs (o: {
configureFlags = o.configureFlags or [] ++ [ " --program-prefix=layeredImageWithFakeRootCommands-" ]; # A unique `hello` to make sure that it isn't included via another mechanism by accident.
doCheck = false; configureFlags = o.configureFlags or [ ]
})} ./hello ++ [ " --program-prefix=layeredImageWithFakeRootCommands-" ];
doCheck = false;
})
} ./hello
''; '';
}; };
# tarball consisting of both bash and redis images # tarball consisting of both bash and redis images
mergedBashAndRedis = pkgs.dockerTools.mergeImages [ mergedBashAndRedis = pkgs.dockerTools.mergeImages [ bash redis ];
bash
redis
];
# tarball consisting of bash (without tag) and redis images # tarball consisting of bash (without tag) and redis images
mergedBashNoTagAndRedis = pkgs.dockerTools.mergeImages [ mergedBashNoTagAndRedis = pkgs.dockerTools.mergeImages [ bashNoTag redis ];
bashNoTag
redis
];
# tarball consisting of bash and layered image with different owner of the # tarball consisting of bash and layered image with different owner of the
# /home/alice directory # /home/alice directory
mergedBashFakeRoot = pkgs.dockerTools.mergeImages [ mergedBashFakeRoot =
bash pkgs.dockerTools.mergeImages [ bash layeredImageWithFakeRootCommands ];
layeredImageWithFakeRootCommands
];
mergeVaryingCompressor = pkgs.dockerTools.mergeImages [ mergeVaryingCompressor =
redis pkgs.dockerTools.mergeImages [ redis bashUncompressed bashZstdCompressed ];
bashUncompressed
bashZstdCompressed
];
helloOnRoot = pkgs.dockerTools.streamLayeredImage { helloOnRoot = pkgs.dockerTools.streamLayeredImage {
name = "hello"; name = "hello";
@ -691,36 +639,32 @@ rec {
enableFakechroot = true; enableFakechroot = true;
}; };
etc = etc = let
let inherit (pkgs) lib;
inherit (pkgs) lib; nixosCore = (evalMinimalConfig ({ config, ... }: {
nixosCore = (evalMinimalConfig ({ config, ... }: { imports = [ pkgs.pkgsModule ../../../nixos/modules/system/etc/etc.nix ];
imports = [ environment.etc."some-config-file" = {
pkgs.pkgsModule text = ''
../../../nixos/modules/system/etc/etc.nix 127.0.0.1 localhost
]; ::1 localhost
environment.etc."some-config-file" = { '';
text = '' # For executables:
127.0.0.1 localhost # mode = "0755";
::1 localhost };
''; }));
# For executables: in pkgs.dockerTools.streamLayeredImage {
# mode = "0755"; name = "etc";
}; tag = "latest";
})); enableFakechroot = true;
in pkgs.dockerTools.streamLayeredImage { fakeRootCommands = ''
name = "etc"; mkdir -p /etc
tag = "latest"; ${nixosCore.config.system.build.etcActivationCommands}
enableFakechroot = true; '';
fakeRootCommands = '' config.Cmd = pkgs.writeScript "etc-cmd" ''
mkdir -p /etc #!${pkgs.busybox}/bin/sh
${nixosCore.config.system.build.etcActivationCommands} ${pkgs.busybox}/bin/cat /etc/some-config-file
''; '';
config.Cmd = pkgs.writeScript "etc-cmd" '' };
#!${pkgs.busybox}/bin/sh
${pkgs.busybox}/bin/cat /etc/some-config-file
'';
};
# Example export of the bash image # Example export of the bash image
exportBash = pkgs.dockerTools.exportImage { fromImage = bash; }; exportBash = pkgs.dockerTools.exportImage { fromImage = bash; };
@ -774,14 +718,10 @@ rec {
copyToRoot = pkgs.buildEnv { copyToRoot = pkgs.buildEnv {
name = "image-with-certs-root"; name = "image-with-certs-root";
paths = [ paths = [ pkgs.coreutils pkgs.dockerTools.caCertificates ];
pkgs.coreutils
pkgs.dockerTools.caCertificates
];
}; };
config = { config = { };
};
}; };
nix-shell-basic = streamNixShellImage { nix-shell-basic = streamNixShellImage {
@ -804,11 +744,7 @@ rec {
nix-shell-inputs = streamNixShellImage { nix-shell-inputs = streamNixShellImage {
name = "nix-shell-inputs"; name = "nix-shell-inputs";
tag = "latest"; tag = "latest";
drv = pkgs.mkShell { drv = pkgs.mkShell { nativeBuildInputs = [ pkgs.hello ]; };
nativeBuildInputs = [
pkgs.hello
];
};
command = '' command = ''
hello hello
''; '';
@ -829,7 +765,7 @@ rec {
nix-shell-run = streamNixShellImage { nix-shell-run = streamNixShellImage {
name = "nix-shell-run"; name = "nix-shell-run";
tag = "latest"; tag = "latest";
drv = pkgs.mkShell {}; drv = pkgs.mkShell { };
run = '' run = ''
case "$-" in case "$-" in
*i*) echo This shell is interactive ;; *i*) echo This shell is interactive ;;
@ -841,7 +777,7 @@ rec {
nix-shell-command = streamNixShellImage { nix-shell-command = streamNixShellImage {
name = "nix-shell-command"; name = "nix-shell-command";
tag = "latest"; tag = "latest";
drv = pkgs.mkShell {}; drv = pkgs.mkShell { };
command = '' command = ''
case "$-" in case "$-" in
*i*) echo This shell is interactive ;; *i*) echo This shell is interactive ;;
@ -853,7 +789,7 @@ rec {
nix-shell-writable-home = streamNixShellImage { nix-shell-writable-home = streamNixShellImage {
name = "nix-shell-writable-home"; name = "nix-shell-writable-home";
tag = "latest"; tag = "latest";
drv = pkgs.mkShell {}; drv = pkgs.mkShell { };
run = '' run = ''
if [[ "$HOME" != "$(eval "echo ~$(whoami)")" ]]; then if [[ "$HOME" != "$(eval "echo ~$(whoami)")" ]]; then
echo "\$HOME ($HOME) is not the same as ~\$(whoami) ($(eval "echo ~$(whoami)"))" echo "\$HOME ($HOME) is not the same as ~\$(whoami) ($(eval "echo ~$(whoami)"))"
@ -871,7 +807,7 @@ rec {
nix-shell-nonexistent-home = streamNixShellImage { nix-shell-nonexistent-home = streamNixShellImage {
name = "nix-shell-nonexistent-home"; name = "nix-shell-nonexistent-home";
tag = "latest"; tag = "latest";
drv = pkgs.mkShell {}; drv = pkgs.mkShell { };
homeDirectory = "/homeless-shelter"; homeDirectory = "/homeless-shelter";
run = '' run = ''
if [[ "$HOME" != "$(eval "echo ~$(whoami)")" ]]; then if [[ "$HOME" != "$(eval "echo ~$(whoami)")" ]]; then

View file

@ -17,7 +17,8 @@ stdenv.mkDerivation {
preferLocalBuild = true; preferLocalBuild = true;
meta = with lib; { meta = with lib; {
description = "Script used to obtain source hashes for dockerTools.pullImage"; description =
"Script used to obtain source hashes for dockerTools.pullImage";
mainProgram = "nix-prefetch-docker"; mainProgram = "nix-prefetch-docker";
maintainers = with maintainers; [ offline ]; maintainers = with maintainers; [ offline ];
platforms = platforms.unix; platforms = platforms.unix;

View file

@ -32,11 +32,7 @@ stdenv.mkDerivation {
runHook postInstall runHook postInstall
''; '';
passthru = { passthru = { tests = { dockerTools = nixosTests.docker-tools; }; };
tests = {
dockerTools = nixosTests.docker-tools;
};
};
meta.platforms = go.meta.platforms; meta.platforms = go.meta.platforms;
meta.mainProgram = "tarsum"; meta.mainProgram = "tarsum";

View file

@ -1,20 +1,17 @@
{ buildDotnetModule, emptyDirectory, mkNugetDeps, dotnet-sdk }: { buildDotnetModule, emptyDirectory, mkNugetDeps, dotnet-sdk }:
{ pname { pname, version
, version # Name of the nuget package to install, if different from pname
# Name of the nuget package to install, if different from pname
, nugetName ? pname , nugetName ? pname
# Hash of the nuget package to install, will be given on first build # Hash of the nuget package to install, will be given on first build
, nugetSha256 ? "" , nugetSha256 ? ""
# Additional nuget deps needed by the tool package # Additional nuget deps needed by the tool package
, nugetDeps ? (_: []) , nugetDeps ? (_: [ ])
# Executables to wrap into `$out/bin`, same as in `buildDotnetModule`, but with # Executables to wrap into `$out/bin`, same as in `buildDotnetModule`, but with
# a default of `pname` instead of null, to avoid auto-wrapping everything # a default of `pname` instead of null, to avoid auto-wrapping everything
, executables ? pname , executables ? pname
# The dotnet runtime to use, dotnet tools need a full SDK to function # The dotnet runtime to use, dotnet tools need a full SDK to function
, dotnet-runtime ? dotnet-sdk , dotnet-runtime ? dotnet-sdk, ... }@args:
, ...
} @ args:
buildDotnetModule (args // { buildDotnetModule (args // {
inherit pname version dotnet-runtime executables; inherit pname version dotnet-runtime executables;
@ -23,9 +20,14 @@ buildDotnetModule (args // {
nugetDeps = mkNugetDeps { nugetDeps = mkNugetDeps {
name = pname; name = pname;
nugetDeps = { fetchNuGet }: [ nugetDeps = { fetchNuGet }:
(fetchNuGet { pname = nugetName; inherit version; sha256 = nugetSha256; }) [
] ++ (nugetDeps fetchNuGet); (fetchNuGet {
pname = nugetName;
inherit version;
sha256 = nugetSha256;
})
] ++ (nugetDeps fetchNuGet);
}; };
projectFile = ""; projectFile = "";

View file

@ -1,24 +1,9 @@
{ lib { lib, stdenvNoCC, callPackage, writeShellScript, srcOnly, linkFarmFromDrvs
, stdenvNoCC , symlinkJoin, makeWrapper, dotnetCorePackages, mkNugetSource, mkNugetDeps
, callPackage , nuget-to-nix, cacert, coreutils, runtimeShellPackage }:
, writeShellScript
, srcOnly
, linkFarmFromDrvs
, symlinkJoin
, makeWrapper
, dotnetCorePackages
, mkNugetSource
, mkNugetDeps
, nuget-to-nix
, cacert
, coreutils
, runtimeShellPackage
}:
{ name ? "${args.pname}-${args.version}" { name ? "${args.pname}-${args.version}", pname ? name
, pname ? name , enableParallelBuilding ? true, doCheck ? false
, enableParallelBuilding ? true
, doCheck ? false
# Flags to pass to `makeWrapper`. This is done to avoid double wrapping. # Flags to pass to `makeWrapper`. This is done to avoid double wrapping.
, makeWrapperArgs ? [ ] , makeWrapperArgs ? [ ]
@ -85,38 +70,41 @@
# The dotnet runtime to use. # The dotnet runtime to use.
, dotnet-runtime ? dotnetCorePackages.runtime_6_0 , dotnet-runtime ? dotnetCorePackages.runtime_6_0
# The dotnet SDK to run tests against. This can differentiate from the SDK compiled against. # The dotnet SDK to run tests against. This can differentiate from the SDK compiled against.
, dotnet-test-sdk ? dotnet-sdk , dotnet-test-sdk ? dotnet-sdk, ... }@args:
, ...
} @ args:
let let
platforms = platforms = if args ? meta.platforms then
if args ? meta.platforms lib.intersectLists args.meta.platforms dotnet-sdk.meta.platforms
then lib.intersectLists args.meta.platforms dotnet-sdk.meta.platforms else
else dotnet-sdk.meta.platforms; dotnet-sdk.meta.platforms;
inherit (callPackage ./hooks { inherit (callPackage ./hooks {
inherit dotnet-sdk dotnet-test-sdk disabledTests nuget-source dotnet-runtime runtimeDeps buildType; inherit dotnet-sdk dotnet-test-sdk disabledTests nuget-source dotnet-runtime
runtimeId = runtimeDeps buildType;
if runtimeId != null runtimeId = if runtimeId != null then
then runtimeId runtimeId
else dotnetCorePackages.systemToDotnetRid stdenvNoCC.targetPlatform.system; else
}) dotnetConfigureHook dotnetBuildHook dotnetCheckHook dotnetInstallHook dotnetFixupHook; dotnetCorePackages.systemToDotnetRid stdenvNoCC.targetPlatform.system;
})
dotnetConfigureHook dotnetBuildHook dotnetCheckHook dotnetInstallHook
dotnetFixupHook;
localDeps = localDeps = if (projectReferences != [ ]) then
if (projectReferences != [ ]) linkFarmFromDrvs "${name}-project-references" projectReferences
then linkFarmFromDrvs "${name}-project-references" projectReferences else
else null; null;
_nugetDeps = _nugetDeps = if (nugetDeps != null) then
if (nugetDeps != null) then if lib.isDerivation nugetDeps then
if lib.isDerivation nugetDeps nugetDeps
then nugetDeps else
else mkNugetDeps { mkNugetDeps {
inherit name; inherit name;
sourceFile = nugetDeps; sourceFile = nugetDeps;
} }
else throw "Defining the `nugetDeps` attribute is required, as to lock the NuGet dependencies. This file can be generated by running the `passthru.fetch-deps` script."; else
throw
"Defining the `nugetDeps` attribute is required, as to lock the NuGet dependencies. This file can be generated by running the `passthru.fetch-deps` script.";
# contains the actual package dependencies # contains the actual package dependencies
dependenciesSource = mkNugetSource { dependenciesSource = mkNugetSource {
@ -131,7 +119,8 @@ let
sdkDeps = lib.lists.flatten [ dotnet-sdk.packages ]; sdkDeps = lib.lists.flatten [ dotnet-sdk.packages ];
sdkSource = let sdkSource = let
version = dotnet-sdk.version or (lib.concatStringsSep "-" dotnet-sdk.versions); version =
dotnet-sdk.version or (lib.concatStringsSep "-" dotnet-sdk.versions);
in mkNugetSource { in mkNugetSource {
name = "dotnet-sdk-${version}-source"; name = "dotnet-sdk-${version}-source";
deps = sdkDeps; deps = sdkDeps;
@ -143,8 +132,7 @@ let
}; };
nugetDepsFile = _nugetDeps.sourceFile; nugetDepsFile = _nugetDeps.sourceFile;
in in stdenvNoCC.mkDerivation (args // {
stdenvNoCC.mkDerivation (args // {
nativeBuildInputs = args.nativeBuildInputs or [ ] ++ [ nativeBuildInputs = args.nativeBuildInputs or [ ] ++ [
dotnetConfigureHook dotnetConfigureHook
dotnetBuildHook dotnetBuildHook
@ -159,23 +147,29 @@ stdenvNoCC.mkDerivation (args // {
# Parse the version attr into a format acceptable for the Version msbuild property # Parse the version attr into a format acceptable for the Version msbuild property
# The actual version attr is saved in InformationalVersion, which accepts an arbitrary string # The actual version attr is saved in InformationalVersion, which accepts an arbitrary string
versionForDotnet = if !(lib.hasAttr "version" args) || args.version == null versionForDotnet =
then null else let if !(lib.hasAttr "version" args) || args.version == null then
components = lib.pipe args.version [ null
lib.splitVersion else
(lib.filter (x: (lib.strings.match "[0-9]+" x) != null)) let
(lib.filter (x: (lib.toIntBase10 x) < 65535)) # one version component in dotnet has to fit in 16 bits components = lib.pipe args.version [
]; lib.splitVersion
in if (lib.length components) == 0 (lib.filter (x: (lib.strings.match "[0-9]+" x) != null))
then null (lib.filter (x:
else lib.concatStringsSep "." ((lib.take 4 components) (lib.toIntBase10 x)
++ (if (lib.length components) < 4 < 65535)) # one version component in dotnet has to fit in 16 bits
then lib.replicate (4 - (lib.length components)) "0" ];
else [ ])); in if (lib.length components) == 0 then
null
else
lib.concatStringsSep "." ((lib.take 4 components)
++ (if (lib.length components) < 4 then
lib.replicate (4 - (lib.length components)) "0"
else
[ ]));
makeWrapperArgs = args.makeWrapperArgs or [ ] ++ [ makeWrapperArgs = args.makeWrapperArgs or [ ]
"--prefix LD_LIBRARY_PATH : ${dotnet-sdk.icu}/lib" ++ [ "--prefix LD_LIBRARY_PATH : ${dotnet-sdk.icu}/lib" ];
];
# Stripping breaks the executable # Stripping breaks the executable
dontStrip = args.dontStrip or true; dontStrip = args.dontStrip or true;
@ -188,136 +182,148 @@ stdenvNoCC.mkDerivation (args // {
passthru = { passthru = {
inherit nuget-source; inherit nuget-source;
} // lib.optionalAttrs (!lib.isDerivation nugetDeps) { } // lib.optionalAttrs (!lib.isDerivation nugetDeps) {
fetch-deps = fetch-deps = let
let flags = dotnetFlags ++ dotnetRestoreFlags;
flags = dotnetFlags ++ dotnetRestoreFlags; runtimeIds = if runtimeId != null then
runtimeIds = [ runtimeId ]
if runtimeId != null else
then [ runtimeId ] map (system: dotnetCorePackages.systemToDotnetRid system) platforms;
else map (system: dotnetCorePackages.systemToDotnetRid system) platforms; defaultDepsFile =
defaultDepsFile = # Wire in the nugetDeps file such that running the script with no args
# Wire in the nugetDeps file such that running the script with no args # runs it agains the correct deps file by default.
# runs it agains the correct deps file by default. # Note that toString is necessary here as it results in the path at
# Note that toString is necessary here as it results in the path at # eval time (i.e. to the file in your local Nixpkgs checkout) rather
# eval time (i.e. to the file in your local Nixpkgs checkout) rather # than the Nix store path of the path after it's been imported.
# than the Nix store path of the path after it's been imported. if lib.isPath nugetDepsFile
if lib.isPath nugetDepsFile && !lib.hasPrefix "${builtins.storeDir}/" (toString nugetDepsFile) && !lib.hasPrefix "${builtins.storeDir}/" (toString nugetDepsFile) then
then toString nugetDepsFile toString nugetDepsFile
else ''$(mktemp -t "${pname}-deps-XXXXXX.nix")''; else
in ''$(mktemp -t "${pname}-deps-XXXXXX.nix")'';
writeShellScript "fetch-${pname}-deps" '' in writeShellScript "fetch-${pname}-deps" ''
set -euo pipefail set -euo pipefail
export PATH="${lib.makeBinPath [ coreutils runtimeShellPackage dotnet-sdk (nuget-to-nix.override { inherit dotnet-sdk; }) ]}" export PATH="${
lib.makeBinPath [
coreutils
runtimeShellPackage
dotnet-sdk
(nuget-to-nix.override { inherit dotnet-sdk; })
]
}"
for arg in "$@"; do for arg in "$@"; do
case "$arg" in case "$arg" in
--keep-sources|-k) --keep-sources|-k)
keepSources=1 keepSources=1
shift shift
;; ;;
--help|-h) --help|-h)
echo "usage: $0 [--keep-sources] [--help] <output path>" echo "usage: $0 [--keep-sources] [--help] <output path>"
echo " <output path> The path to write the lockfile to. A temporary file is used if this is not set" echo " <output path> The path to write the lockfile to. A temporary file is used if this is not set"
echo " --keep-sources Dont remove temporary directories upon exit, useful for debugging" echo " --keep-sources Dont remove temporary directories upon exit, useful for debugging"
echo " --help Show this help message" echo " --help Show this help message"
exit exit
;; ;;
esac esac
done done
if [[ ''${TMPDIR:-} == /run/user/* ]]; then if [[ ''${TMPDIR:-} == /run/user/* ]]; then
# /run/user is usually a tmpfs in RAM, which may be too small # /run/user is usually a tmpfs in RAM, which may be too small
# to store all downloaded dotnet packages # to store all downloaded dotnet packages
unset TMPDIR unset TMPDIR
fi fi
export tmp=$(mktemp -td "deps-${pname}-XXXXXX") export tmp=$(mktemp -td "deps-${pname}-XXXXXX")
HOME=$tmp/home HOME=$tmp/home
exitTrap() { exitTrap() {
test -n "''${ranTrap-}" && return test -n "''${ranTrap-}" && return
ranTrap=1 ranTrap=1
if test -n "''${keepSources-}"; then if test -n "''${keepSources-}"; then
echo -e "Path to the source: $tmp/src\nPath to the fake home: $tmp/home" echo -e "Path to the source: $tmp/src\nPath to the fake home: $tmp/home"
else else
rm -rf "$tmp" rm -rf "$tmp"
fi fi
# Since mktemp is used this will be empty if the script didnt succesfully complete # Since mktemp is used this will be empty if the script didnt succesfully complete
if ! test -s "$depsFile"; then if ! test -s "$depsFile"; then
rm -rf "$depsFile" rm -rf "$depsFile"
fi fi
} }
trap exitTrap EXIT INT TERM trap exitTrap EXIT INT TERM
dotnetRestore() { dotnetRestore() {
local -r project="''${1-}" local -r project="''${1-}"
local -r rid="$2" local -r rid="$2"
dotnet restore ''${project-} \ dotnet restore ''${project-} \
-p:ContinuousIntegrationBuild=true \ -p:ContinuousIntegrationBuild=true \
-p:Deterministic=true \ -p:Deterministic=true \
--packages "$tmp/nuget_pkgs" \ --packages "$tmp/nuget_pkgs" \
--runtime "$rid" \ --runtime "$rid" \
--no-cache \ --no-cache \
--force \ --force \
${lib.optionalString (!enableParallelBuilding) "--disable-parallel"} \ ${
${lib.optionalString (flags != []) (toString flags)} lib.optionalString (!enableParallelBuilding)
} "--disable-parallel"
} \
${lib.optionalString (flags != [ ]) (toString flags)}
}
declare -a projectFiles=( ${toString (lib.toList projectFile)} ) declare -a projectFiles=( ${toString (lib.toList projectFile)} )
declare -a testProjectFiles=( ${toString (lib.toList testProjectFile)} ) declare -a testProjectFiles=( ${toString (lib.toList testProjectFile)} )
export DOTNET_NOLOGO=1 export DOTNET_NOLOGO=1
export DOTNET_CLI_TELEMETRY_OPTOUT=1 export DOTNET_CLI_TELEMETRY_OPTOUT=1
depsFile=$(realpath "''${1:-${defaultDepsFile}}") depsFile=$(realpath "''${1:-${defaultDepsFile}}")
echo Will write lockfile to "$depsFile" echo Will write lockfile to "$depsFile"
mkdir -p "$tmp/nuget_pkgs" mkdir -p "$tmp/nuget_pkgs"
storeSrc="${srcOnly args}" storeSrc="${srcOnly args}"
src=$tmp/src src=$tmp/src
cp -rT "$storeSrc" "$src" cp -rT "$storeSrc" "$src"
chmod -R +w "$src" chmod -R +w "$src"
cd "$src" cd "$src"
echo "Restoring project..." echo "Restoring project..."
${dotnet-sdk}/bin/dotnet tool restore ${dotnet-sdk}/bin/dotnet tool restore
cp -r $HOME/.nuget/packages/* $tmp/nuget_pkgs || true cp -r $HOME/.nuget/packages/* $tmp/nuget_pkgs || true
for rid in "${lib.concatStringsSep "\" \"" runtimeIds}"; do for rid in "${lib.concatStringsSep ''" "'' runtimeIds}"; do
(( ''${#projectFiles[@]} == 0 )) && dotnetRestore "" "$rid" (( ''${#projectFiles[@]} == 0 )) && dotnetRestore "" "$rid"
for project in ''${projectFiles[@]-} ''${testProjectFiles[@]-}; do for project in ''${projectFiles[@]-} ''${testProjectFiles[@]-}; do
dotnetRestore "$project" "$rid" dotnetRestore "$project" "$rid"
done done
done done
# Second copy, makes sure packages restored by ie. paket are included # Second copy, makes sure packages restored by ie. paket are included
cp -r $HOME/.nuget/packages/* $tmp/nuget_pkgs || true cp -r $HOME/.nuget/packages/* $tmp/nuget_pkgs || true
echo "Succesfully restored project" echo "Succesfully restored project"
echo "Writing lockfile..." echo "Writing lockfile..."
excluded_sources="${lib.concatStringsSep " " sdkDeps}" excluded_sources="${lib.concatStringsSep " " sdkDeps}"
for excluded_source in ''${excluded_sources[@]}; do for excluded_source in ''${excluded_sources[@]}; do
ls "$excluded_source" >> "$tmp/excluded_list" ls "$excluded_source" >> "$tmp/excluded_list"
done done
tmpFile="$tmp"/deps.nix tmpFile="$tmp"/deps.nix
echo -e "# This file was automatically generated by passthru.fetch-deps.\n# Please dont edit it manually, your changes might get overwritten!\n" > "$tmpFile" echo -e "# This file was automatically generated by passthru.fetch-deps.\n# Please dont edit it manually, your changes might get overwritten!\n" > "$tmpFile"
nuget-to-nix "$tmp/nuget_pkgs" "$tmp/excluded_list" >> "$tmpFile" nuget-to-nix "$tmp/nuget_pkgs" "$tmp/excluded_list" >> "$tmpFile"
mv "$tmpFile" "$depsFile" mv "$tmpFile" "$depsFile"
echo "Succesfully wrote lockfile to $depsFile" echo "Succesfully wrote lockfile to $depsFile"
''; '';
} // args.passthru or { }; } // args.passthru or { };
meta = (args.meta or { }) // { inherit platforms; }; meta = (args.meta or { }) // { inherit platforms; };
} }
# ICU tries to unconditionally load files from /usr/share/icu on Darwin, which makes builds fail # ICU tries to unconditionally load files from /usr/share/icu on Darwin, which makes builds fail
# in the sandbox, so disable ICU on Darwin. This, as far as I know, shouldn't cause any built packages # in the sandbox, so disable ICU on Darwin. This, as far as I know, shouldn't cause any built packages
# to behave differently, just the dotnet build tool. # to behave differently, just the dotnet build tool.
// lib.optionalAttrs stdenvNoCC.isDarwin { DOTNET_SYSTEM_GLOBALIZATION_INVARIANT = 1; }) // lib.optionalAttrs stdenvNoCC.isDarwin {
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT = 1;
})

View file

@ -1,27 +1,10 @@
{ lib { lib, stdenv, which, coreutils, zlib, openssl, callPackage, makeSetupHook
, stdenv , makeWrapper, dotnet-sdk, dotnet-test-sdk, disabledTests, nuget-source
, which , dotnet-runtime, runtimeDeps, buildType, runtimeId }:
, coreutils
, zlib
, openssl
, callPackage
, makeSetupHook
, makeWrapper
, dotnet-sdk
, dotnet-test-sdk
, disabledTests
, nuget-source
, dotnet-runtime
, runtimeDeps
, buildType
, runtimeId
}:
assert (builtins.isString runtimeId); assert (builtins.isString runtimeId);
let let libraryPath = lib.makeLibraryPath runtimeDeps;
libraryPath = lib.makeLibraryPath runtimeDeps; in {
in
{
dotnetConfigureHook = callPackage ({ }: dotnetConfigureHook = callPackage ({ }:
makeSetupHook { makeSetupHook {
name = "dotnet-configure-hook"; name = "dotnet-configure-hook";
@ -44,9 +27,7 @@ in
makeSetupHook { makeSetupHook {
name = "dotnet-build-hook"; name = "dotnet-build-hook";
propagatedBuildInputs = [ dotnet-sdk ]; propagatedBuildInputs = [ dotnet-sdk ];
substitutions = { substitutions = { inherit buildType runtimeId; };
inherit buildType runtimeId;
};
} ./dotnet-build-hook.sh) { }; } ./dotnet-build-hook.sh) { };
dotnetCheckHook = callPackage ({ }: dotnetCheckHook = callPackage ({ }:
@ -55,12 +36,12 @@ in
propagatedBuildInputs = [ dotnet-test-sdk ]; propagatedBuildInputs = [ dotnet-test-sdk ];
substitutions = { substitutions = {
inherit buildType runtimeId libraryPath; inherit buildType runtimeId libraryPath;
disabledTests = lib.optionalString (disabledTests != []) disabledTests = lib.optionalString (disabledTests != [ ]) (let
(let escapedNames =
escapedNames = lib.lists.map (n: lib.replaceStrings [","] ["%2C"] n) disabledTests; lib.lists.map (n: lib.replaceStrings [ "," ] [ "%2C" ] n)
filters = lib.lists.map (n: "FullyQualifiedName!=${n}") escapedNames; disabledTests;
in filters = lib.lists.map (n: "FullyQualifiedName!=${n}") escapedNames;
"${lib.concatStringsSep "&" filters}"); in "${lib.concatStringsSep "&" filters}");
}; };
} ./dotnet-check-hook.sh) { }; } ./dotnet-check-hook.sh) { };
@ -68,9 +49,7 @@ in
makeSetupHook { makeSetupHook {
name = "dotnet-install-hook"; name = "dotnet-install-hook";
propagatedBuildInputs = [ dotnet-sdk ]; propagatedBuildInputs = [ dotnet-sdk ];
substitutions = { substitutions = { inherit buildType runtimeId; };
inherit buildType runtimeId;
};
} ./dotnet-install-hook.sh) { }; } ./dotnet-install-hook.sh) { };
dotnetFixupHook = callPackage ({ }: dotnetFixupHook = callPackage ({ }:

View file

@ -1,116 +1,108 @@
{ stdenv, lib, makeWrapper, pkg-config, mono, dotnetbuildhelpers }: { stdenv, lib, makeWrapper, pkg-config, mono, dotnetbuildhelpers }:
attrsOrig @ attrsOrig@{ pname, version, nativeBuildInputs ? [ ], xBuildFiles ? [ ]
{ pname
, version
, nativeBuildInputs ? []
, xBuildFiles ? [ ]
, xBuildFlags ? [ "/p:Configuration=Release" ] , xBuildFlags ? [ "/p:Configuration=Release" ]
, outputFiles ? [ "bin/Release/*" ] , outputFiles ? [ "bin/Release/*" ], dllFiles ? [ "*.dll" ], exeFiles ? [
, dllFiles ? [ "*.dll" ] "*.exe"
, exeFiles ? [ "*.exe" ] ]
# Additional arguments to pass to the makeWrapper function, which wraps # Additional arguments to pass to the makeWrapper function, which wraps
# generated binaries. # generated binaries.
, makeWrapperArgs ? [ ] , makeWrapperArgs ? [ ], ... }:
, ... }: let
let arrayToShell =
arrayToShell = (a: toString (map (lib.escape (lib.stringToCharacters "\\ ';$`()|<>\t") ) a)); (a: toString (map (lib.escape (lib.stringToCharacters "\\ ';$`()|<> ")) a));
attrs = { attrs = {
inherit pname version; inherit pname version;
nativeBuildInputs = [ nativeBuildInputs = [ pkg-config makeWrapper dotnetbuildhelpers mono ]
pkg-config ++ nativeBuildInputs;
makeWrapper
dotnetbuildhelpers
mono
] ++ nativeBuildInputs;
configurePhase = '' configurePhase = ''
runHook preConfigure runHook preConfigure
[ -z "''${dontPlacateNuget-}" ] && placate-nuget.sh [ -z "''${dontPlacateNuget-}" ] && placate-nuget.sh
[ -z "''${dontPlacatePaket-}" ] && placate-paket.sh [ -z "''${dontPlacatePaket-}" ] && placate-paket.sh
[ -z "''${dontPatchFSharpTargets-}" ] && patch-fsharp-targets.sh [ -z "''${dontPatchFSharpTargets-}" ] && patch-fsharp-targets.sh
runHook postConfigure runHook postConfigure
''; '';
buildPhase = '' buildPhase = ''
runHook preBuild runHook preBuild
echo Building dotNET packages... echo Building dotNET packages...
# Probably needs to be moved to fsharp # Probably needs to be moved to fsharp
if pkg-config FSharp.Core if pkg-config FSharp.Core
then then
export FSharpTargetsPath="$(dirname $(pkg-config FSharp.Core --variable=Libraries))/Microsoft.FSharp.Targets" export FSharpTargetsPath="$(dirname $(pkg-config FSharp.Core --variable=Libraries))/Microsoft.FSharp.Targets"
fi fi
ran="" ran=""
for xBuildFile in ${arrayToShell xBuildFiles} ''${xBuildFilesExtra} for xBuildFile in ${arrayToShell xBuildFiles} ''${xBuildFilesExtra}
do
ran="yes"
xbuild ${arrayToShell xBuildFlags} ''${xBuildFlagsArray} $xBuildFile
done
[ -z "$ran" ] && xbuild ${arrayToShell xBuildFlags} ''${xBuildFlagsArray}
runHook postBuild
'';
dontStrip = true;
installPhase = ''
runHook preInstall
target="$out/lib/dotnet/${pname}"
mkdir -p "$target"
cp -rv ${arrayToShell outputFiles} "''${outputFilesArray[@]}" "$target"
if [ -z "''${dontRemoveDuplicatedDlls-}" ]
then
pushd "$out"
remove-duplicated-dlls.sh
popd
fi
set -f
for dllPattern in ${arrayToShell dllFiles} ''${dllFilesArray[@]}
do
set +f
for dll in "$target"/$dllPattern
do do
ran="yes" [ -f "$dll" ] || continue
xbuild ${arrayToShell xBuildFlags} ''${xBuildFlagsArray} $xBuildFile if pkg-config $(basename -s .dll "$dll")
then
echo "$dll already exported by a buildInputs, not re-exporting"
else
create-pkg-config-for-dll.sh "$out/lib/pkgconfig" "$dll"
fi
done done
done
[ -z "$ran" ] && xbuild ${arrayToShell xBuildFlags} ''${xBuildFlagsArray} set -f
for exePattern in ${arrayToShell exeFiles} ''${exeFilesArray[@]}
runHook postBuild do
''; set +f
for exe in "$target"/$exePattern
dontStrip = true;
installPhase = ''
runHook preInstall
target="$out/lib/dotnet/${pname}"
mkdir -p "$target"
cp -rv ${arrayToShell outputFiles} "''${outputFilesArray[@]}" "$target"
if [ -z "''${dontRemoveDuplicatedDlls-}" ]
then
pushd "$out"
remove-duplicated-dlls.sh
popd
fi
set -f
for dllPattern in ${arrayToShell dllFiles} ''${dllFilesArray[@]}
do do
set +f [ -f "$exe" ] || continue
for dll in "$target"/$dllPattern mkdir -p "$out"/bin
do commandName="$(basename -s .exe "$(echo "$exe" | tr "[A-Z]" "[a-z]")")"
[ -f "$dll" ] || continue makeWrapper \
if pkg-config $(basename -s .dll "$dll") "${mono}/bin/mono" \
then "$out"/bin/"$commandName" \
echo "$dll already exported by a buildInputs, not re-exporting" --add-flags "\"$exe\"" \
else ''${makeWrapperArgs}
create-pkg-config-for-dll.sh "$out/lib/pkgconfig" "$dll"
fi
done
done done
done
set -f runHook postInstall
for exePattern in ${arrayToShell exeFiles} ''${exeFilesArray[@]} '';
do };
set +f in stdenv.mkDerivation
for exe in "$target"/$exePattern (attrs // (builtins.removeAttrs attrsOrig [ "nativeBuildInputs" ]))
do
[ -f "$exe" ] || continue
mkdir -p "$out"/bin
commandName="$(basename -s .exe "$(echo "$exe" | tr "[A-Z]" "[a-z]")")"
makeWrapper \
"${mono}/bin/mono" \
"$out"/bin/"$commandName" \
--add-flags "\"$exe\"" \
''${makeWrapperArgs}
done
done
runHook postInstall
'';
};
in
stdenv.mkDerivation (attrs // (builtins.removeAttrs attrsOrig [ "nativeBuildInputs" ] ))

View file

@ -1,18 +1,17 @@
{ runCommand, mono, pkg-config }: { runCommand, mono, pkg-config }:
runCommand runCommand "dotnetbuildhelpers" { preferLocalBuild = true; } ''
"dotnetbuildhelpers" target="$out/bin"
{ preferLocalBuild = true; } mkdir -p "$target"
''
target="$out/bin"
mkdir -p "$target"
for script in ${./create-pkg-config-for-dll.sh} ${./patch-fsharp-targets.sh} ${./remove-duplicated-dlls.sh} ${./placate-nuget.sh} ${./placate-paket.sh} for script in ${./create-pkg-config-for-dll.sh} ${
do ./patch-fsharp-targets.sh
scriptName="$(basename "$script" | cut -f 2- -d -)" } ${./remove-duplicated-dlls.sh} ${./placate-nuget.sh} ${./placate-paket.sh}
cp -v "$script" "$target"/"$scriptName" do
chmod 755 "$target"/"$scriptName" scriptName="$(basename "$script" | cut -f 2- -d -)"
patchShebangs "$target"/"$scriptName" cp -v "$script" "$target"/"$scriptName"
substituteInPlace "$target"/"$scriptName" --replace pkg-config ${pkg-config}/bin/${pkg-config.targetPrefix}pkg-config chmod 755 "$target"/"$scriptName"
substituteInPlace "$target"/"$scriptName" --replace monodis ${mono}/bin/monodis patchShebangs "$target"/"$scriptName"
done substituteInPlace "$target"/"$scriptName" --replace pkg-config ${pkg-config}/bin/${pkg-config.targetPrefix}pkg-config
'' substituteInPlace "$target"/"$scriptName" --replace monodis ${mono}/bin/monodis
done
''

View file

@ -1,16 +1,7 @@
{ lib, stdenv, dotnetfx }: { lib, stdenv, dotnetfx }:
{ name { name, src, baseDir ? ".", slnFile, targets ? "ReBuild", verbosity ? "detailed"
, src , options ? "/p:Configuration=Debug;Platform=Win32", assemblyInputs ? [ ]
, baseDir ? "." , preBuild ? "", modifyPublicMain ? false, mainClassFile ? null }:
, slnFile
, targets ? "ReBuild"
, verbosity ? "detailed"
, options ? "/p:Configuration=Debug;Platform=Win32"
, assemblyInputs ? []
, preBuild ? ""
, modifyPublicMain ? false
, mainClassFile ? null
}:
assert modifyPublicMain -> mainClassFile != null; assert modifyPublicMain -> mainClassFile != null;
@ -31,55 +22,57 @@ stdenv.mkDerivation {
''; '';
installPhase = '' installPhase = ''
addDeps() addDeps()
{ {
if [ -f $1/nix-support/dotnet-assemblies ] if [ -f $1/nix-support/dotnet-assemblies ]
then then
for i in $(cat $1/nix-support/dotnet-assemblies) for i in $(cat $1/nix-support/dotnet-assemblies)
do do
windowsPath=$(cygpath --windows $i) windowsPath=$(cygpath --windows $i)
assemblySearchPaths="$assemblySearchPaths;$windowsPath" assemblySearchPaths="$assemblySearchPaths;$windowsPath"
addDeps $i addDeps $i
done done
fi fi
} }
for i in ${toString assemblyInputs} for i in ${toString assemblyInputs}
do do
windowsPath=$(cygpath --windows $i) windowsPath=$(cygpath --windows $i)
echo "Using assembly path: $windowsPath" echo "Using assembly path: $windowsPath"
if [ "$assemblySearchPaths" = "" ] if [ "$assemblySearchPaths" = "" ]
then then
assemblySearchPaths="$windowsPath" assemblySearchPaths="$windowsPath"
else else
assemblySearchPaths="$assemblySearchPaths;$windowsPath" assemblySearchPaths="$assemblySearchPaths;$windowsPath"
fi fi
addDeps $i addDeps $i
done done
echo "Assembly search paths are: $assemblySearchPaths" echo "Assembly search paths are: $assemblySearchPaths"
if [ "$assemblySearchPaths" != "" ] if [ "$assemblySearchPaths" != "" ]
then then
echo "Using assembly search paths args: $assemblySearchPathsArg" echo "Using assembly search paths args: $assemblySearchPathsArg"
export AssemblySearchPaths=$assemblySearchPaths export AssemblySearchPaths=$assemblySearchPaths
fi fi
mkdir -p $out mkdir -p $out
MSBuild.exe ${toString slnFile} /nologo /t:${targets} /p:IntermediateOutputPath=$(cygpath --windows $out)\\ /p:OutputPath=$(cygpath --windows $out)\\ /verbosity:${verbosity} ${options} MSBuild.exe ${
toString slnFile
} /nologo /t:${targets} /p:IntermediateOutputPath=$(cygpath --windows $out)\\ /p:OutputPath=$(cygpath --windows $out)\\ /verbosity:${verbosity} ${options}
# Because .NET assemblies store strings as UTF-16 internally, we cannot detect # Because .NET assemblies store strings as UTF-16 internally, we cannot detect
# hashes. Therefore a text files containing the proper paths is created # hashes. Therefore a text files containing the proper paths is created
# We can also use this file the propagate transitive dependencies. # We can also use this file the propagate transitive dependencies.
mkdir -p $out/nix-support mkdir -p $out/nix-support
for i in ${toString assemblyInputs} for i in ${toString assemblyInputs}
do do
echo $i >> $out/nix-support/dotnet-assemblies echo $i >> $out/nix-support/dotnet-assemblies
done done
''; '';
} }

View file

@ -1,17 +1,15 @@
{ lib, stdenv, dotnetfx }: { lib, stdenv, dotnetfx }:
let dotnetenv = let
{ dotnetenv = {
buildSolution = import ./build-solution.nix { buildSolution = import ./build-solution.nix {
inherit lib stdenv; inherit lib stdenv;
dotnetfx = dotnetfx.pkg; dotnetfx = dotnetfx.pkg;
}; };
buildWrapper = import ./wrapper.nix { buildWrapper = import ./wrapper.nix { inherit dotnetenv; };
inherit dotnetenv;
};
inherit (dotnetfx) assembly20Path wcfPath referenceAssembly30Path referenceAssembly35Path; inherit (dotnetfx)
}; assembly20Path wcfPath referenceAssembly30Path referenceAssembly35Path;
in };
dotnetenv in dotnetenv

View file

@ -1,19 +1,9 @@
{dotnetenv}: { dotnetenv }:
{ name { name, src, baseDir ? ".", slnFile, targets ? "ReBuild", verbosity ? "detailed"
, src , options ? "/p:Configuration=Debug;Platform=Win32", assemblyInputs ? [ ]
, baseDir ? "." , preBuild ? "", namespace, mainClassName, mainClassFile
, slnFile , modifyPublicMain ? true }:
, targets ? "ReBuild"
, verbosity ? "detailed"
, options ? "/p:Configuration=Debug;Platform=Win32"
, assemblyInputs ? []
, preBuild ? ""
, namespace
, mainClassName
, mainClassFile
, modifyPublicMain ? true
}:
let let
application = dotnetenv.buildSolution { application = dotnetenv.buildSolution {
@ -21,44 +11,43 @@ let
inherit options assemblyInputs preBuild; inherit options assemblyInputs preBuild;
inherit modifyPublicMain mainClassFile; inherit modifyPublicMain mainClassFile;
}; };
in in dotnetenv.buildSolution {
dotnetenv.buildSolution {
name = "${name}-wrapper"; name = "${name}-wrapper";
src = ./Wrapper; src = ./Wrapper;
slnFile = "Wrapper.sln"; slnFile = "Wrapper.sln";
assemblyInputs = [ application ]; assemblyInputs = [ application ];
preBuild = '' preBuild = ''
addRuntimeDeps() addRuntimeDeps()
{ {
if [ -f $1/nix-support/dotnet-assemblies ] if [ -f $1/nix-support/dotnet-assemblies ]
then then
for i in $(cat $1/nix-support/dotnet-assemblies) for i in $(cat $1/nix-support/dotnet-assemblies)
do do
windowsPath=$(cygpath --windows $i | sed 's|\\|\\\\|g') windowsPath=$(cygpath --windows $i | sed 's|\\|\\\\|g')
assemblySearchArray="$assemblySearchArray @\"$windowsPath\"" assemblySearchArray="$assemblySearchArray @\"$windowsPath\""
addRuntimeDeps $i addRuntimeDeps $i
done done
fi fi
} }
export exePath=$(cygpath --windows $(find ${application} -name \*.exe) | sed 's|\\|\\\\|g') export exePath=$(cygpath --windows $(find ${application} -name \*.exe) | sed 's|\\|\\\\|g')
# Generate assemblySearchPaths string array contents # Generate assemblySearchPaths string array contents
for path in ${toString assemblyInputs} for path in ${toString assemblyInputs}
do do
assemblySearchArray="$assemblySearchArray @\"$(cygpath --windows $path | sed 's|\\|\\\\|g')\", " assemblySearchArray="$assemblySearchArray @\"$(cygpath --windows $path | sed 's|\\|\\\\|g')\", "
addRuntimeDeps $path addRuntimeDeps $path
done done
sed -e "s|@ROOTNAMESPACE@|${namespace}Wrapper|" \ sed -e "s|@ROOTNAMESPACE@|${namespace}Wrapper|" \
-e "s|@ASSEMBLYNAME@|${namespace}|" \ -e "s|@ASSEMBLYNAME@|${namespace}|" \
Wrapper/Wrapper.csproj.in > Wrapper/Wrapper.csproj Wrapper/Wrapper.csproj.in > Wrapper/Wrapper.csproj
sed -e "s|@NAMESPACE@|${namespace}|g" \ sed -e "s|@NAMESPACE@|${namespace}|g" \
-e "s|@MAINCLASSNAME@|${mainClassName}|g" \ -e "s|@MAINCLASSNAME@|${mainClassName}|g" \
-e "s|@EXEPATH@|$exePath|g" \ -e "s|@EXEPATH@|$exePath|g" \
-e "s|@ASSEMBLYSEARCHPATH@|$assemblySearchArray|" \ -e "s|@ASSEMBLYSEARCHPATH@|$assemblySearchArray|" \
Wrapper/Wrapper.cs.in > Wrapper/Wrapper.cs Wrapper/Wrapper.cs.in > Wrapper/Wrapper.cs
''; '';
} }

View file

@ -1,13 +1,8 @@
{ fetchurl, buildDotnetPackage, unzip }: { fetchurl, buildDotnetPackage, unzip }:
attrs @ attrs@{ pname, version
{ pname , url ? "https://www.nuget.org/api/v2/package/${pname}/${version}", sha256 ? ""
, version , md5 ? "", ... }:
, url ? "https://www.nuget.org/api/v2/package/${pname}/${version}"
, sha256 ? ""
, md5 ? ""
, ...
}:
if md5 != "" then if md5 != "" then
throw "fetchnuget does not support md5 anymore, please use sha256" throw "fetchnuget does not support md5 anymore, please use sha256"
else else
@ -39,5 +34,5 @@ else
} }
traverseRename traverseRename
''; '';
} // attrs) } // attrs)

View file

@ -1,10 +1,6 @@
{ lib, python3, stdenvNoCC }: { lib, python3, stdenvNoCC }:
{ name { name, description ? "", deps ? [ ], ... }@args:
, description ? ""
, deps ? []
, ...
}@args:
stdenvNoCC.mkDerivation (lib.recursiveUpdate { stdenvNoCC.mkDerivation (lib.recursiveUpdate {
inherit name; inherit name;

View file

@ -1,35 +1,17 @@
{ lib { lib, runCommandLocal, runtimeShell, substituteAll, nix, coreutils, jq, yq
, runCommandLocal , curl, gnugrep, gawk, dotnet-sdk }:
, runtimeShell
, substituteAll
, nix
, coreutils
, jq
, yq
, curl
, gnugrep
, gawk
, dotnet-sdk
}:
runCommandLocal "nuget-to-nix" { runCommandLocal "nuget-to-nix" {
script = substituteAll { script = substituteAll {
src = ./nuget-to-nix.sh; src = ./nuget-to-nix.sh;
inherit runtimeShell; inherit runtimeShell;
binPath = lib.makeBinPath [ binPath =
nix lib.makeBinPath [ nix coreutils jq yq curl gnugrep gawk dotnet-sdk ];
coreutils
jq
yq
curl
gnugrep
gawk
dotnet-sdk
];
}; };
meta.description = "Convert a nuget packages directory to a lockfile for buildDotnetModule"; meta.description =
"Convert a nuget packages directory to a lockfile for buildDotnetModule";
} '' } ''
install -Dm755 $script $out/bin/nuget-to-nix install -Dm755 $script $out/bin/nuget-to-nix
'' ''

View file

@ -4,9 +4,11 @@
{ lib, writeText, inherit-local }: { lib, writeText, inherit-local }:
rec { rec {
withPackages = pkgs': let withPackages = pkgs':
let
pkgs = builtins.filter (x: x != null) pkgs'; pkgs = builtins.filter (x: x != null) pkgs';
extras = map (x: x.emacsBufferSetup pkgs) (builtins.filter (builtins.hasAttr "emacsBufferSetup") pkgs); extras = map (x: x.emacsBufferSetup pkgs)
(builtins.filter (builtins.hasAttr "emacsBufferSetup") pkgs);
in writeText "dir-locals.el" '' in writeText "dir-locals.el" ''
(require 'inherit-local "${inherit-local}/share/emacs/site-lisp/elpa/inherit-local-${inherit-local.version}/inherit-local.elc") (require 'inherit-local "${inherit-local}/share/emacs/site-lisp/elpa/inherit-local-${inherit-local.version}/inherit-local.elc")
@ -42,10 +44,16 @@ rec {
(inherit-local 'process-environment) (inherit-local 'process-environment)
; setenv modifies in place, so copy the environment first ; setenv modifies in place, so copy the environment first
(setq process-environment (copy-tree process-environment)) (setq process-environment (copy-tree process-environment))
(setenv "PATH" (concat "${lib.makeSearchPath "bin" pkgs}:" (getenv "PATH"))) (setenv "PATH" (concat "${
(inherit-local-permanent exec-path (append '(${builtins.concatStringsSep " " (map (p: "\"${p}/bin\"") pkgs)}) exec-path)) lib.makeSearchPath "bin" pkgs
}:" (getenv "PATH")))
(inherit-local-permanent exec-path (append '(${
builtins.concatStringsSep " " (map (p: ''"${p}/bin"'') pkgs)
}) exec-path))
(inherit-local-permanent eshell-path-env (concat "${lib.makeSearchPath "bin" pkgs}:" (if (boundp 'eshell-path-env) eshell-path-env (getenv "PATH")))) (inherit-local-permanent eshell-path-env (concat "${
lib.makeSearchPath "bin" pkgs
}:" (if (boundp 'eshell-path-env) eshell-path-env (getenv "PATH"))))
(setq nixpkgs--is-nixpkgs-buffer t) (setq nixpkgs--is-nixpkgs-buffer t)
(inherit-local 'nixpkgs--is-nixpkgs-buffer) (inherit-local 'nixpkgs--is-nixpkgs-buffer)
@ -55,23 +63,22 @@ rec {
# nix-buffer function for a project with a bunch of haskell packages # nix-buffer function for a project with a bunch of haskell packages
# in one directory # in one directory
haskellMonoRepo = { project-root # The monorepo root haskellMonoRepo = { project-root # The monorepo root
, haskellPackages # The composed haskell packages set that contains all of the packages , haskellPackages # The composed haskell packages set that contains all of the packages
}: { root }: }:
{ root }:
let # The haskell paths. let # The haskell paths.
haskell-paths = lib.filesystem.haskellPathsInDir project-root; haskell-paths = lib.filesystem.haskellPathsInDir project-root;
# Find the haskell package that the 'root' is in, if any. # Find the haskell package that the 'root' is in, if any.
haskell-path-parent = haskell-path-parent = let
let filtered = builtins.filter (name: filtered = builtins.filter (name:
lib.hasPrefix (toString (project-root + "/${name}")) (toString root) lib.hasPrefix (toString (project-root + "/${name}")) (toString root))
) (builtins.attrNames haskell-paths); (builtins.attrNames haskell-paths);
in in if filtered == [ ] then null else builtins.head filtered;
if filtered == [] then null else builtins.head filtered; # We're in the directory of a haskell package
# We're in the directory of a haskell package is-haskell-package = haskell-path-parent != null;
is-haskell-package = haskell-path-parent != null; haskell-package = haskellPackages.${haskell-path-parent};
haskell-package = haskellPackages.${haskell-path-parent}; # GHC environment with all needed deps for the haskell package
# GHC environment with all needed deps for the haskell package haskell-package-env = builtins.head haskell-package.env.nativeBuildInputs;
haskell-package-env = in lib.optionalAttrs is-haskell-package
builtins.head haskell-package.env.nativeBuildInputs; (withPackages [ haskell-package-env ]);
in
lib.optionalAttrs is-haskell-package (withPackages [ haskell-package-env ]);
} }

View file

@ -4,16 +4,10 @@
let let
handledArgs = [ "files" "fileSpecs" "meta" ]; handledArgs = [ "files" "fileSpecs" "meta" ];
genericBuild = import ./generic.nix { inherit lib stdenv emacs texinfo writeText gcc; }; genericBuild =
import ./generic.nix { inherit lib stdenv emacs texinfo writeText gcc; };
in in { pname, version, src, meta ? { }, ... }@args:
{ pname
, version
, src
, meta ? {}
, ...
}@args:
genericBuild ({ genericBuild ({
@ -30,8 +24,9 @@ genericBuild ({
''; '';
meta = { meta = {
homepage = args.src.meta.homepage or "https://elpa.gnu.org/packages/${pname}.html"; homepage =
args.src.meta.homepage or "https://elpa.gnu.org/packages/${pname}.html";
} // meta; } // meta;
} }
// removeAttrs args handledArgs) // removeAttrs args handledArgs)

View file

@ -20,71 +20,65 @@ let
fi fi
''; '';
in in { pname, version, buildInputs ? [ ], packageRequires ? [ ], meta ? { }, ...
{ pname
, version
, buildInputs ? []
, packageRequires ? []
, meta ? {}
, ...
}@args: }@args:
stdenv.mkDerivation (finalAttrs: ({ stdenv.mkDerivation (finalAttrs:
name = "emacs-${pname}-${finalAttrs.version}"; ({
name = "emacs-${pname}-${finalAttrs.version}";
unpackCmd = '' unpackCmd = ''
case "$curSrc" in case "$curSrc" in
*.el) *.el)
# keep original source filename without the hash # keep original source filename without the hash
local filename=$(basename "$curSrc") local filename=$(basename "$curSrc")
filename="''${filename:33}" filename="''${filename:33}"
cp $curSrc $filename cp $curSrc $filename
chmod +w $filename chmod +w $filename
sourceRoot="." sourceRoot="."
;; ;;
*) *)
_defaultUnpack "$curSrc" _defaultUnpack "$curSrc"
;; ;;
esac esac
''; '';
buildInputs = [emacs texinfo] ++ packageRequires ++ buildInputs; buildInputs = [ emacs texinfo ] ++ packageRequires ++ buildInputs;
propagatedBuildInputs = packageRequires; propagatedBuildInputs = packageRequires;
propagatedUserEnvPkgs = packageRequires; propagatedUserEnvPkgs = packageRequires;
inherit setupHook; inherit setupHook;
doCheck = false; doCheck = false;
meta = { meta = {
broken = false; broken = false;
platforms = emacs.meta.platforms; platforms = emacs.meta.platforms;
} // optionalAttrs ((args.src.meta.homepage or "") != "") { } // optionalAttrs ((args.src.meta.homepage or "") != "") {
homepage = args.src.meta.homepage; homepage = args.src.meta.homepage;
} // meta; } // meta;
} }
// optionalAttrs (emacs.withNativeCompilation or false) { // optionalAttrs (emacs.withNativeCompilation or false) {
LIBRARY_PATH = "${getLib stdenv.cc.libc}/lib"; LIBRARY_PATH = "${getLib stdenv.cc.libc}/lib";
nativeBuildInputs = [ gcc ]; nativeBuildInputs = [ gcc ];
addEmacsNativeLoadPath = true; addEmacsNativeLoadPath = true;
postInstall = '' postInstall = ''
# Besides adding the output directory to the native load path, make sure # Besides adding the output directory to the native load path, make sure
# the current package's elisp files are in the load path, otherwise # the current package's elisp files are in the load path, otherwise
# (require 'file-b) from file-a.el in the same package will fail. # (require 'file-b) from file-a.el in the same package will fail.
mkdir -p $out/share/emacs/native-lisp mkdir -p $out/share/emacs/native-lisp
source ${./emacs-funcs.sh} source ${./emacs-funcs.sh}
addEmacsVars "$out" addEmacsVars "$out"
find $out/share/emacs -type f -name '*.el' -print0 \ find $out/share/emacs -type f -name '*.el' -print0 \
| xargs -0 -I {} -n 1 -P $NIX_BUILD_CORES sh -c \ | xargs -0 -I {} -n 1 -P $NIX_BUILD_CORES sh -c \
"emacs --batch --eval '(setq large-file-warning-threshold nil)' -f batch-native-compile {} || true" "emacs --batch --eval '(setq large-file-warning-threshold nil)' -f batch-native-compile {} || true"
''; '';
} }
// removeAttrs args handledArgs)) // removeAttrs args handledArgs))

View file

@ -4,7 +4,8 @@
{ lib, stdenv, fetchFromGitHub, emacs, texinfo, writeText, gcc }: { lib, stdenv, fetchFromGitHub, emacs, texinfo, writeText, gcc }:
let let
genericBuild = import ./generic.nix { inherit lib stdenv emacs texinfo writeText gcc; }; genericBuild =
import ./generic.nix { inherit lib stdenv emacs texinfo writeText gcc; };
packageBuild = stdenv.mkDerivation { packageBuild = stdenv.mkDerivation {
name = "package-build"; name = "package-build";
@ -20,35 +21,20 @@ let
dontConfigure = true; dontConfigure = true;
dontBuild = true; dontBuild = true;
installPhase = " installPhase = "\n mkdir -p $out\n cp -r * $out\n ";
mkdir -p $out
cp -r * $out
";
}; };
in in {
/* pname: Nix package name without special symbols and without version or
{ /* "emacs-" prefix.
pname: Nix package name without special symbols and without version or */
"emacs-" prefix. pname
*/ # ename: Original Emacs package name, possibly containing special symbols.
pname , ename ? null, version, recipe, meta ? { }, ... }@args:
/*
ename: Original Emacs package name, possibly containing special symbols.
*/
, ename ? null
, version
, recipe
, meta ? {}
, ...
}@args:
genericBuild ({ genericBuild ({
ename = ename = if ename == null then pname else ename;
if ename == null
then pname
else ename;
elpa2nix = ./elpa2nix.el; elpa2nix = ./elpa2nix.el;
melpa2nix = ./melpa2nix.el; melpa2nix = ./melpa2nix.el;
@ -83,7 +69,7 @@ genericBuild ({
$ename $version $commit $ename $version $commit
runHook postBuild runHook postBuild
''; '';
installPhase = '' installPhase = ''
runHook preInstall runHook preInstall
@ -106,4 +92,4 @@ genericBuild ({
} // meta; } // meta;
} }
// removeAttrs args [ "meta" ]) // removeAttrs args [ "meta" ])

View file

@ -25,4 +25,4 @@ callPackage ./generic.nix envargs ({
''; '';
} }
// args) // args)

View file

@ -1,35 +1,32 @@
/* /* # Usage
# Usage `emacs.pkgs.withPackages` takes a single argument: a function from a package
set to a list of packages (the packages that will be available in
Emacs). For example,
```
emacs.pkgs.withPackages (epkgs: [ epkgs.evil epkgs.magit ])
```
All the packages in the list should come from the provided package
set. It is possible to add any package to the list, but the provided
set is guaranteed to have consistent dependencies and be built with
the correct version of Emacs.
`emacs.pkgs.withPackages` takes a single argument: a function from a package # Overriding
set to a list of packages (the packages that will be available in
Emacs). For example,
```
emacs.pkgs.withPackages (epkgs: [ epkgs.evil epkgs.magit ])
```
All the packages in the list should come from the provided package
set. It is possible to add any package to the list, but the provided
set is guaranteed to have consistent dependencies and be built with
the correct version of Emacs.
# Overriding
`emacs.pkgs.withPackages` inherits the package set which contains it, so the
correct way to override the provided package set is to override the
set which contains `emacs.pkgs.withPackages`. For example, to override
`emacs.pkgs.emacs.pkgs.withPackages`,
```
let customEmacsPackages =
emacs.pkgs.overrideScope (self: super: {
# use a custom version of emacs
emacs = ...;
# use the unstable MELPA version of magit
magit = self.melpaPackages.magit;
});
in customEmacsPackages.withPackages (epkgs: [ epkgs.evil epkgs.magit ])
```
`emacs.pkgs.withPackages` inherits the package set which contains it, so the
correct way to override the provided package set is to override the
set which contains `emacs.pkgs.withPackages`. For example, to override
`emacs.pkgs.emacs.pkgs.withPackages`,
```
let customEmacsPackages =
emacs.pkgs.overrideScope (self: super: {
# use a custom version of emacs
emacs = ...;
# use the unstable MELPA version of magit
magit = self.melpaPackages.magit;
});
in customEmacsPackages.withPackages (epkgs: [ epkgs.evil epkgs.magit ])
```
*/ */
{ lib, lndir, makeBinaryWrapper, runCommand, gcc }: { lib, lndir, makeBinaryWrapper, runCommand, gcc }:
@ -38,199 +35,196 @@ let
inherit (self) emacs; inherit (self) emacs;
withNativeCompilation = emacs.withNativeCompilation or false; withNativeCompilation = emacs.withNativeCompilation or false;
withTreeSitter = emacs.withTreeSitter or false; withTreeSitter = emacs.withTreeSitter or false;
in in packagesFun: # packages explicitly requested by the user
packagesFun: # packages explicitly requested by the user
let let
explicitRequires = explicitRequires =
if lib.isFunction packagesFun if lib.isFunction packagesFun then packagesFun self else packagesFun;
then packagesFun self in runCommand (lib.appendToName "with-packages" emacs).name {
else packagesFun; inherit emacs explicitRequires;
in nativeBuildInputs = [ emacs lndir makeBinaryWrapper ];
runCommand
(lib.appendToName "with-packages" emacs).name
{
inherit emacs explicitRequires;
nativeBuildInputs = [ emacs lndir makeBinaryWrapper ];
preferLocalBuild = true; preferLocalBuild = true;
allowSubstitutes = false; allowSubstitutes = false;
# Store all paths we want to add to emacs here, so that we only need to add # Store all paths we want to add to emacs here, so that we only need to add
# one path to the load lists # one path to the load lists
deps = runCommand "emacs-packages-deps" deps = runCommand "emacs-packages-deps" ({
({ inherit explicitRequires lndir emacs;
inherit explicitRequires lndir emacs; nativeBuildInputs = lib.optional withNativeCompilation gcc;
nativeBuildInputs = lib.optional withNativeCompilation gcc; } // lib.optionalAttrs withNativeCompilation {
} // lib.optionalAttrs withNativeCompilation { inherit (emacs) LIBRARY_PATH;
inherit (emacs) LIBRARY_PATH; }) ''
}) findInputsOld() {
'' local pkg="$1"; shift
findInputsOld() { local var="$1"; shift
local pkg="$1"; shift local propagatedBuildInputsFiles=("$@")
local var="$1"; shift
local propagatedBuildInputsFiles=("$@")
# TODO(@Ericson2314): Restore using associative array once Darwin # TODO(@Ericson2314): Restore using associative array once Darwin
# nix-shell doesn't use impure bash. This should replace the O(n) # nix-shell doesn't use impure bash. This should replace the O(n)
# case with an O(1) hash map lookup, assuming bash is implemented # case with an O(1) hash map lookup, assuming bash is implemented
# well :D. # well :D.
local varSlice="$var[*]" local varSlice="$var[*]"
# ''${..-} to hack around old bash empty array problem # ''${..-} to hack around old bash empty array problem
case "''${!varSlice-}" in case "''${!varSlice-}" in
*" $pkg "*) return 0 ;; *" $pkg "*) return 0 ;;
esac esac
unset -v varSlice unset -v varSlice
eval "$var"'+=("$pkg")' eval "$var"'+=("$pkg")'
if ! [ -e "$pkg" ]; then if ! [ -e "$pkg" ]; then
echo "build input $pkg does not exist" >&2 echo "build input $pkg does not exist" >&2
exit 1 exit 1
fi fi
local file local file
for file in "''${propagatedBuildInputsFiles[@]}"; do for file in "''${propagatedBuildInputsFiles[@]}"; do
file="$pkg/nix-support/$file" file="$pkg/nix-support/$file"
[[ -f "$file" ]] || continue [[ -f "$file" ]] || continue
local pkgNext local pkgNext
for pkgNext in $(< "$file"); do for pkgNext in $(< "$file"); do
findInputsOld "$pkgNext" "$var" "''${propagatedBuildInputsFiles[@]}" findInputsOld "$pkgNext" "$var" "''${propagatedBuildInputsFiles[@]}"
done
done done
} done
mkdir -p $out/bin }
mkdir -p $out/share/emacs/site-lisp mkdir -p $out/bin
${lib.optionalString withNativeCompilation '' mkdir -p $out/share/emacs/site-lisp
mkdir -p $out/share/emacs/native-lisp ${lib.optionalString withNativeCompilation ''
''} mkdir -p $out/share/emacs/native-lisp
${lib.optionalString withTreeSitter '' ''}
mkdir -p $out/lib ${lib.optionalString withTreeSitter ''
''} mkdir -p $out/lib
''}
local requires local requires
for pkg in $explicitRequires; do for pkg in $explicitRequires; do
findInputsOld $pkg requires propagated-user-env-packages findInputsOld $pkg requires propagated-user-env-packages
done done
# requires now holds all requested packages and their transitive dependencies # requires now holds all requested packages and their transitive dependencies
linkPath() { linkPath() {
local pkg=$1 local pkg=$1
local origin_path=$2 local origin_path=$2
local dest_path=$3 local dest_path=$3
# Add the path to the search path list, but only if it exists # Add the path to the search path list, but only if it exists
if [[ -d "$pkg/$origin_path" ]]; then if [[ -d "$pkg/$origin_path" ]]; then
$lndir/bin/lndir -silent "$pkg/$origin_path" "$out/$dest_path" $lndir/bin/lndir -silent "$pkg/$origin_path" "$out/$dest_path"
fi fi
} }
linkEmacsPackage() { linkEmacsPackage() {
linkPath "$1" "bin" "bin" linkPath "$1" "bin" "bin"
linkPath "$1" "share/emacs/site-lisp" "share/emacs/site-lisp" linkPath "$1" "share/emacs/site-lisp" "share/emacs/site-lisp"
${lib.optionalString withNativeCompilation '' ${
linkPath "$1" "share/emacs/native-lisp" "share/emacs/native-lisp" lib.optionalString withNativeCompilation ''
''} linkPath "$1" "share/emacs/native-lisp" "share/emacs/native-lisp"
${lib.optionalString withTreeSitter '' ''
linkPath "$1" "lib" "lib" }
''} ${
} lib.optionalString withTreeSitter ''
linkPath "$1" "lib" "lib"
''
}
}
# Iterate over the array of inputs (avoiding nix's own interpolation) # Iterate over the array of inputs (avoiding nix's own interpolation)
for pkg in "''${requires[@]}"; do for pkg in "''${requires[@]}"; do
linkEmacsPackage $pkg linkEmacsPackage $pkg
done
siteStart="$out/share/emacs/site-lisp/site-start.el"
siteStartByteCompiled="$siteStart"c
subdirs="$out/share/emacs/site-lisp/subdirs.el"
subdirsByteCompiled="$subdirs"c
# A dependency may have brought the original siteStart or subdirs, delete
# it and create our own
# Begin the new site-start.el by loading the original, which sets some
# NixOS-specific paths. Paths are searched in the reverse of the order
# they are specified in, so user and system profile paths are searched last.
#
# NOTE: Avoid displaying messages early at startup by binding
# inhibit-message to t. This would prevent the Emacs GUI from showing up
# prematurely. The messages would still be logged to the *Messages*
# buffer.
rm -f $siteStart $siteStartByteCompiled $subdirs $subdirsByteCompiled
cat >"$siteStart" <<EOF
(let ((inhibit-message t))
(load "$emacs/share/emacs/site-lisp/site-start"))
;; "$out/share/emacs/site-lisp" is added to load-path in wrapper.sh
;; "$out/share/emacs/native-lisp" is added to native-comp-eln-load-path in wrapper.sh
(add-to-list 'exec-path "$out/bin")
${lib.optionalString withTreeSitter ''
(add-to-list 'treesit-extra-load-path "$out/lib/")
''}
EOF
# Generate a subdirs.el that statically adds all subdirectories to load-path.
$emacs/bin/emacs \
--batch \
--load ${./mk-wrapper-subdirs.el} \
--eval "(prin1 (macroexpand-1 '(mk-subdirs-expr \"$out/share/emacs/site-lisp\")))" \
> "$subdirs"
# Byte-compiling improves start-up time only slightly, but costs nothing.
$emacs/bin/emacs --batch -f batch-byte-compile "$siteStart" "$subdirs"
${lib.optionalString withNativeCompilation ''
$emacs/bin/emacs --batch \
--eval "(add-to-list 'native-comp-eln-load-path \"$out/share/emacs/native-lisp/\")" \
-f batch-native-compile "$siteStart" "$subdirs"
''}
'';
inherit (emacs) meta;
}
''
mkdir -p "$out/bin"
# Wrap emacs and friends so they find our site-start.el before the original.
for prog in $emacs/bin/*; do # */
local progname=$(basename "$prog")
rm -f "$out/bin/$progname"
substitute ${./wrapper.sh} $out/bin/$progname \
--subst-var-by bash ${emacs.stdenv.shell} \
--subst-var-by wrapperSiteLisp "$deps/share/emacs/site-lisp" \
--subst-var-by wrapperSiteLispNative "$deps/share/emacs/native-lisp" \
--subst-var prog
chmod +x $out/bin/$progname
# Create a “NOP” binary wrapper for the pure sake of it becoming a
# non-shebang, actual binary. See the makeBinaryWrapper docs for rationale
# (summary: it allows you to use emacs as a shebang itself on Darwin,
# e.g. #!$ {emacs}/bin/emacs --script)
wrapProgramBinary $out/bin/$progname
done done
# Wrap MacOS app siteStart="$out/share/emacs/site-lisp/site-start.el"
# this has to pick up resources and metadata siteStartByteCompiled="$siteStart"c
# to recognize it as an "app" subdirs="$out/share/emacs/site-lisp/subdirs.el"
if [ -d "$emacs/Applications/Emacs.app" ]; then subdirsByteCompiled="$subdirs"c
mkdir -p $out/Applications/Emacs.app/Contents/MacOS
cp -r $emacs/Applications/Emacs.app/Contents/Info.plist \ # A dependency may have brought the original siteStart or subdirs, delete
$emacs/Applications/Emacs.app/Contents/PkgInfo \ # it and create our own
$emacs/Applications/Emacs.app/Contents/Resources \ # Begin the new site-start.el by loading the original, which sets some
$out/Applications/Emacs.app/Contents # NixOS-specific paths. Paths are searched in the reverse of the order
# they are specified in, so user and system profile paths are searched last.
#
# NOTE: Avoid displaying messages early at startup by binding
# inhibit-message to t. This would prevent the Emacs GUI from showing up
# prematurely. The messages would still be logged to the *Messages*
# buffer.
rm -f $siteStart $siteStartByteCompiled $subdirs $subdirsByteCompiled
cat >"$siteStart" <<EOF
(let ((inhibit-message t))
(load "$emacs/share/emacs/site-lisp/site-start"))
;; "$out/share/emacs/site-lisp" is added to load-path in wrapper.sh
;; "$out/share/emacs/native-lisp" is added to native-comp-eln-load-path in wrapper.sh
(add-to-list 'exec-path "$out/bin")
${lib.optionalString withTreeSitter ''
(add-to-list 'treesit-extra-load-path "$out/lib/")
''}
EOF
# Generate a subdirs.el that statically adds all subdirectories to load-path.
$emacs/bin/emacs \
--batch \
--load ${./mk-wrapper-subdirs.el} \
--eval "(prin1 (macroexpand-1 '(mk-subdirs-expr \"$out/share/emacs/site-lisp\")))" \
> "$subdirs"
# Byte-compiling improves start-up time only slightly, but costs nothing.
$emacs/bin/emacs --batch -f batch-byte-compile "$siteStart" "$subdirs"
${lib.optionalString withNativeCompilation ''
$emacs/bin/emacs --batch \
--eval "(add-to-list 'native-comp-eln-load-path \"$out/share/emacs/native-lisp/\")" \
-f batch-native-compile "$siteStart" "$subdirs"
''}
'';
inherit (emacs) meta;
} ''
mkdir -p "$out/bin"
# Wrap emacs and friends so they find our site-start.el before the original.
for prog in $emacs/bin/*; do # */
local progname=$(basename "$prog")
rm -f "$out/bin/$progname"
substitute ${./wrapper.sh} $out/bin/$progname \
--subst-var-by bash ${emacs.stdenv.shell} \
--subst-var-by wrapperSiteLisp "$deps/share/emacs/site-lisp" \
--subst-var-by wrapperSiteLispNative "$deps/share/emacs/native-lisp" \
--subst-var prog
chmod +x $out/bin/$progname
# Create a “NOP” binary wrapper for the pure sake of it becoming a
# non-shebang, actual binary. See the makeBinaryWrapper docs for rationale
# (summary: it allows you to use emacs as a shebang itself on Darwin,
# e.g. #!$ {emacs}/bin/emacs --script)
wrapProgramBinary $out/bin/$progname
done
# Wrap MacOS app
# this has to pick up resources and metadata
# to recognize it as an "app"
if [ -d "$emacs/Applications/Emacs.app" ]; then
mkdir -p $out/Applications/Emacs.app/Contents/MacOS
cp -r $emacs/Applications/Emacs.app/Contents/Info.plist \
$emacs/Applications/Emacs.app/Contents/PkgInfo \
$emacs/Applications/Emacs.app/Contents/Resources \
$out/Applications/Emacs.app/Contents
substitute ${./wrapper.sh} $out/Applications/Emacs.app/Contents/MacOS/Emacs \ substitute ${
--subst-var-by bash ${emacs.stdenv.shell} \ ./wrapper.sh
--subst-var-by wrapperSiteLisp "$deps/share/emacs/site-lisp" \ } $out/Applications/Emacs.app/Contents/MacOS/Emacs \
--subst-var-by wrapperSiteLispNative "$deps/share/emacs/native-lisp" \ --subst-var-by bash ${emacs.stdenv.shell} \
--subst-var-by prog "$emacs/Applications/Emacs.app/Contents/MacOS/Emacs" --subst-var-by wrapperSiteLisp "$deps/share/emacs/site-lisp" \
chmod +x $out/Applications/Emacs.app/Contents/MacOS/Emacs --subst-var-by wrapperSiteLispNative "$deps/share/emacs/native-lisp" \
wrapProgramBinary $out/Applications/Emacs.app/Contents/MacOS/Emacs --subst-var-by prog "$emacs/Applications/Emacs.app/Contents/MacOS/Emacs"
fi chmod +x $out/Applications/Emacs.app/Contents/MacOS/Emacs
wrapProgramBinary $out/Applications/Emacs.app/Contents/MacOS/Emacs
fi
mkdir -p $out/share mkdir -p $out/share
# Link icons and desktop files into place # Link icons and desktop files into place
for dir in applications icons info man; do for dir in applications icons info man; do
ln -s $emacs/share/$dir $out/share/$dir ln -s $emacs/share/$dir $out/share/$dir
done done
'' ''

View file

@ -27,7 +27,8 @@ stdenv.mkDerivation {
''; '';
meta = { meta = {
description = "Internal tool used by the nixpkgs wrapper scripts for processing response files"; description =
"Internal tool used by the nixpkgs wrapper scripts for processing response files";
longDescription = '' longDescription = ''
expand-response-params is a tool that allows for obtaining a full list of all expand-response-params is a tool that allows for obtaining a full list of all
arguments passed in a given compiler command line including those passed via arguments passed in a given compiler command line including those passed via

View file

@ -2,17 +2,22 @@
# Useful when packaging binaries that insist on using nss to look up # Useful when packaging binaries that insist on using nss to look up
# username/groups (like nginx). # username/groups (like nginx).
# /bin/sh is fine to not exist, and provided by another shim. # /bin/sh is fine to not exist, and provided by another shim.
{ lib, symlinkJoin, writeTextDir, runCommand, extraPasswdLines ? [], extraGroupLines ? [] }: { lib, symlinkJoin, writeTextDir, runCommand, extraPasswdLines ? [ ]
, extraGroupLines ? [ ] }:
symlinkJoin { symlinkJoin {
name = "fake-nss"; name = "fake-nss";
paths = [ paths = [
(writeTextDir "etc/passwd" '' (writeTextDir "etc/passwd" ''
root:x:0:0:root user:/var/empty:/bin/sh root:x:0:0:root user:/var/empty:/bin/sh
${lib.concatStrings (map (line: line + "\n") extraPasswdLines)}nobody:x:65534:65534:nobody:/var/empty:/bin/sh ${
lib.concatStrings (map (line: line + "\n") extraPasswdLines)
}nobody:x:65534:65534:nobody:/var/empty:/bin/sh
'') '')
(writeTextDir "etc/group" '' (writeTextDir "etc/group" ''
root:x:0: root:x:0:
${lib.concatStrings (map (line: line + "\n") extraGroupLines)}nobody:x:65534: ${
lib.concatStrings (map (line: line + "\n") extraGroupLines)
}nobody:x:65534:
'') '')
(writeTextDir "etc/nsswitch.conf" '' (writeTextDir "etc/nsswitch.conf" ''
hosts: files dns hosts: files dns

View file

@ -1,18 +1,19 @@
{ fetchgit, fetchzip, lib }: { fetchgit, fetchzip, lib }:
lib.makeOverridable ( lib.makeOverridable ({ owner, repo, rev, domain ? "git.9front.org"
{ owner , name ? "source", leaveDotGit ? false, deepClone ? false
, repo
, rev
, domain ? "git.9front.org"
, name ? "source"
, leaveDotGit ? false
, deepClone ? false
, ... # For hash agility , ... # For hash agility
} @ args: }@args:
let let
passthruAttrs = removeAttrs args [ "domain" "owner" "repo" "rev" "leaveDotGit" "deepClone" ]; passthruAttrs = removeAttrs args [
"domain"
"owner"
"repo"
"rev"
"leaveDotGit"
"deepClone"
];
useFetchGit = leaveDotGit || deepClone; useFetchGit = leaveDotGit || deepClone;
fetcher = if useFetchGit then fetchgit else fetchzip; fetcher = if useFetchGit then fetchgit else fetchzip;
@ -26,11 +27,9 @@ lib.makeOverridable (
} else { } else {
url = "https://${domain}/${owner}/${repo}/${rev}/snap.tar.gz"; url = "https://${domain}/${owner}/${repo}/${rev}/snap.tar.gz";
passthru = { passthru = { inherit gitRepoUrl; };
inherit gitRepoUrl; }) // passthruAttrs // {
}; inherit name;
}) // passthruAttrs // { inherit name; }; };
in
fetcher fetcherArgs // { inherit rev; } in fetcher fetcherArgs // { inherit rev; })
)

View file

@ -1,11 +1,11 @@
{ fetchzip, lib }: { fetchzip, lib }:
lib.makeOverridable ( lib.makeOverridable ({ owner, repo, rev, name ? "source", ... # For hash agility
{ owner, repo, rev, name ? "source" }@args:
, ... # For hash agility fetchzip ({
}@args: fetchzip ({ inherit name;
inherit name; url = "https://bitbucket.org/${owner}/${repo}/get/${rev}.tar.gz";
url = "https://bitbucket.org/${owner}/${repo}/get/${rev}.tar.gz"; meta.homepage = "https://bitbucket.org/${owner}/${repo}/";
meta.homepage = "https://bitbucket.org/${owner}/${repo}/"; } // removeAttrs args [ "owner" "repo" "rev" ]) // {
} // removeAttrs args [ "owner" "repo" "rev" ]) // { inherit rev; } inherit rev;
) })

View file

@ -4,25 +4,27 @@ let
let let
components = lib.splitString "#" version; components = lib.splitString "#" version;
hash = lib.last components; hash = lib.last components;
ver = if builtins.length components == 1 then (cleanName version) else hash; ver =
if builtins.length components == 1 then (cleanName version) else hash;
in ver; in ver;
cleanName = name: lib.replaceStrings ["/" ":"] ["-" "-"] name; cleanName = name: lib.replaceStrings [ "/" ":" ] [ "-" "-" ] name;
fetchbower = name: version: target: outputHash: stdenvNoCC.mkDerivation { fetchbower = name: version: target: outputHash:
name = "${cleanName name}-${bowerVersion version}"; stdenvNoCC.mkDerivation {
buildCommand = '' name = "${cleanName name}-${bowerVersion version}";
fetch-bower --quiet --out=$PWD/out "${name}" "${target}" "${version}" buildCommand = ''
# In some cases, the result of fetchBower is different depending fetch-bower --quiet --out=$PWD/out "${name}" "${target}" "${version}"
# on the output directory (e.g. if the bower package contains # In some cases, the result of fetchBower is different depending
# symlinks). So use a local output directory before copying to # on the output directory (e.g. if the bower package contains
# $out. # symlinks). So use a local output directory before copying to
cp -R out $out # $out.
''; cp -R out $out
outputHashMode = "recursive"; '';
outputHashAlgo = "sha256"; outputHashMode = "recursive";
inherit outputHash; outputHashAlgo = "sha256";
nativeBuildInputs = [ bower2nix cacert ]; inherit outputHash;
}; nativeBuildInputs = [ bower2nix cacert ];
};
in fetchbower in fetchbower

View file

@ -3,20 +3,18 @@
# tag="<tagname>" (get version by tag name) # tag="<tagname>" (get version by tag name)
# If you don't specify neither one date="NOW" will be used (get latest) # If you don't specify neither one date="NOW" will be used (get latest)
{stdenvNoCC, cvs, openssh, lib}: { stdenvNoCC, cvs, openssh, lib }:
lib.makeOverridable ( lib.makeOverridable ({ cvsRoot, module, tag ? null, date ? null, sha256 }:
{cvsRoot, module, tag ? null, date ? null, sha256}:
stdenvNoCC.mkDerivation { stdenvNoCC.mkDerivation {
name = "cvs-export"; name = "cvs-export";
builder = ./builder.sh; builder = ./builder.sh;
nativeBuildInputs = [cvs openssh]; nativeBuildInputs = [ cvs openssh ];
outputHashAlgo = "sha256"; outputHashAlgo = "sha256";
outputHashMode = "recursive"; outputHashMode = "recursive";
outputHash = sha256; outputHash = sha256;
inherit cvsRoot module sha256 tag date; inherit cvsRoot module sha256 tag date;
} })
)

View file

@ -1,21 +1,15 @@
{stdenvNoCC, darcs, cacert, lib}: { stdenvNoCC, darcs, cacert, lib }:
lib.makeOverridable ( lib.makeOverridable
{ url ({ url, rev ? null, context ? null, sha256 ? "", name ? "fetchdarcs" }:
, rev ? null
, context ? null
, sha256 ? ""
, name ? "fetchdarcs"
}:
stdenvNoCC.mkDerivation { stdenvNoCC.mkDerivation {
builder = ./builder.sh; builder = ./builder.sh;
nativeBuildInputs = [cacert darcs]; nativeBuildInputs = [ cacert darcs ];
outputHashAlgo = "sha256"; outputHashAlgo = "sha256";
outputHashMode = "recursive"; outputHashMode = "recursive";
outputHash = sha256; outputHash = sha256;
inherit url rev context name; inherit url rev context name;
} })
)

View file

@ -1,19 +1,16 @@
{ lib, fetchpatch }: { lib, fetchpatch }:
lib.makeOverridable ( lib.makeOverridable ({ pname, version, debianRevision ? null, area ? "main"
{ pname, version, debianRevision ? null, area ? "main", , patch, name ? patch, hash }:
patch, name ? patch, hash }:
let let
inherit (lib.strings) hasPrefix substring; inherit (lib.strings) hasPrefix substring;
prefix = prefix = substring 0 (if hasPrefix "lib" pname then 4 else 1) pname;
substring 0 (if hasPrefix "lib" pname then 4 else 1) pname; versionString = if debianRevision == null then
versionString = version
if debianRevision == null then version else
else "${version}-${debianRevision}"; "${version}-${debianRevision}";
in fetchpatch { in fetchpatch {
inherit name hash; inherit name hash;
url = url = "https://sources.debian.org/data/${area}/${prefix}/"
"https://sources.debian.org/data/${area}/${prefix}/"
+ "${pname}/${versionString}/debian/patches/${patch}"; + "${pname}/${versionString}/debian/patches/${patch}";
} })
)

View file

@ -32,8 +32,6 @@
# DOCKER_CREDENTIALS path # DOCKER_CREDENTIALS path
let let
pathParts = pathParts =
(builtins.filter (builtins.filter ({ prefix, path }: "DOCKER_CREDENTIALS" == prefix)
({prefix, path}: "DOCKER_CREDENTIALS" == prefix) builtins.nixPath);
builtins.nixPath); in lib.optionalString (pathParts != [ ]) ((builtins.head pathParts).path)
in
lib.optionalString (pathParts != []) ((builtins.head pathParts).path)

View file

@ -1,53 +1,40 @@
{ stdenv, lib, coreutils, bash, gnutar, writeText }: { stdenv, lib, coreutils, bash, gnutar, writeText }:
let let
stripScheme = stripScheme = builtins.replaceStrings [ "https://" "http://" ] [ "" "" ];
builtins.replaceStrings [ "https://" "http://" ] [ "" "" ]; stripNixStore = s: lib.removePrefix "${builtins.storeDir}/" s;
stripNixStore = in { name, registry ? "https://registry-1.docker.io/v2/", repository ? "library"
s: lib.removePrefix "${builtins.storeDir}/" s; , imageName, tag, imageLayers, imageConfig
in , image ? "${stripScheme registry}/${repository}/${imageName}:${tag}" }:
{ name
, registry ? "https://registry-1.docker.io/v2/"
, repository ? "library"
, imageName
, tag
, imageLayers
, imageConfig
, image ? "${stripScheme registry}/${repository}/${imageName}:${tag}"
}:
# Make sure there are *no* slashes in the repository or container # Make sure there are *no* slashes in the repository or container
# names since we use these to make the output derivation name for the # names since we use these to make the output derivation name for the
# nix-store path. # nix-store path.
assert null == lib.findFirst (c: "/"==c) null (lib.stringToCharacters repository); assert null
assert null == lib.findFirst (c: "/"==c) null (lib.stringToCharacters imageName); == lib.findFirst (c: "/" == c) null (lib.stringToCharacters repository);
assert null
== lib.findFirst (c: "/" == c) null (lib.stringToCharacters imageName);
let let
# Abuse paths to collapse possible double slashes # Abuse paths to collapse possible double slashes
repoTag0 = builtins.toString (/. + "/${stripScheme registry}/${repository}/${imageName}"); repoTag0 = builtins.toString
(/. + "/${stripScheme registry}/${repository}/${imageName}");
repoTag1 = lib.removePrefix "/" repoTag0; repoTag1 = lib.removePrefix "/" repoTag0;
layers = builtins.map stripNixStore imageLayers; layers = builtins.map stripNixStore imageLayers;
manifest = manifest = writeText "manifest.json" (builtins.toJSON [{
writeText "manifest.json" (builtins.toJSON [ Config = stripNixStore imageConfig;
{ Config = stripNixStore imageConfig; Layers = layers;
Layers = layers; RepoTags = [ "${repoTag1}:${tag}" ];
RepoTags = [ "${repoTag1}:${tag}" ]; }]);
}]);
repositories = repositories = writeText "repositories"
writeText "repositories" (builtins.toJSON { (builtins.toJSON { ${repoTag1} = { ${tag} = lib.last layers; }; });
${repoTag1} = {
${tag} = lib.last layers;
};
});
imageFileStorePaths = imageFileStorePaths = writeText "imageFileStorePaths.txt"
writeText "imageFileStorePaths.txt" (lib.concatStringsSep "\n" ((lib.unique imageLayers) ++ [ imageConfig ]));
(lib.concatStringsSep "\n" ((lib.unique imageLayers) ++ [imageConfig])); in stdenv.mkDerivation {
in builder = ./fetchdocker-builder.sh;
stdenv.mkDerivation {
builder = ./fetchdocker-builder.sh;
buildInputs = [ coreutils ]; buildInputs = [ coreutils ];
preferLocalBuild = true; preferLocalBuild = true;
@ -55,7 +42,5 @@ stdenv.mkDerivation {
inherit bash gnutar manifest repositories; inherit bash gnutar manifest repositories;
inherit imageFileStorePaths; inherit imageFileStorePaths;
passthru = { passthru = { inherit image; };
inherit image;
};
} }

View file

@ -1,13 +1,10 @@
pkgargs@{ stdenv, lib, haskellPackages, writeText, gawk }: pkgargs@{ stdenv, lib, haskellPackages, writeText, gawk }:
let let generic-fetcher = import ./generic-fetcher.nix pkgargs;
generic-fetcher =
import ./generic-fetcher.nix pkgargs;
in
args@{ repository ? "library", imageName, tag, ... }: in args@{ repository ? "library", imageName, tag, ... }:
generic-fetcher ({ generic-fetcher ({
fetcher = "hocker-config"; fetcher = "hocker-config";
name = "${repository}_${imageName}_${tag}-config.json"; name = "${repository}_${imageName}_${tag}-config.json";
tag = "unused"; tag = "unused";
} // args) } // args)

View file

@ -1,13 +1,10 @@
pkgargs@{ stdenv, lib, haskellPackages, writeText, gawk }: pkgargs@{ stdenv, lib, haskellPackages, writeText, gawk }:
let let generic-fetcher = import ./generic-fetcher.nix pkgargs;
generic-fetcher =
import ./generic-fetcher.nix pkgargs;
in
args@{ layerDigest, ... }: in args@{ layerDigest, ... }:
generic-fetcher ({ generic-fetcher ({
fetcher = "hocker-layer"; fetcher = "hocker-layer";
name = "docker-layer-${layerDigest}.tar.gz"; name = "docker-layer-${layerDigest}.tar.gz";
tag = "unused"; tag = "unused";
} // args) } // args)

View file

@ -1,38 +1,31 @@
{ stdenv, lib, haskellPackages, writeText, gawk }: { stdenv, lib, haskellPackages, writeText, gawk }:
let let
awk = "${gawk}/bin/awk"; awk = "${gawk}/bin/awk";
dockerCredentialsFile = import ./credentials.nix { inherit lib; }; dockerCredentialsFile = import ./credentials.nix { inherit lib; };
in in { fetcher, name, registry ? "https://registry-1.docker.io/v2/"
{ fetcher , repository ? "library", imageName, sha256, tag ? "", layerDigest ? "" }:
, name
, registry ? "https://registry-1.docker.io/v2/"
, repository ? "library"
, imageName
, sha256
, tag ? ""
, layerDigest ? ""
}:
# There must be no slashes in the repository or container names since # There must be no slashes in the repository or container names since
# we use these to make the output derivation name for the nix store # we use these to make the output derivation name for the nix store
# path # path
assert null == lib.findFirst (c: "/"==c) null (lib.stringToCharacters repository); assert null
assert null == lib.findFirst (c: "/"==c) null (lib.stringToCharacters imageName); == lib.findFirst (c: "/" == c) null (lib.stringToCharacters repository);
assert null
== lib.findFirst (c: "/" == c) null (lib.stringToCharacters imageName);
# Only allow hocker-config and hocker-layer as fetchers for now # Only allow hocker-config and hocker-layer as fetchers for now
assert (builtins.elem fetcher ["hocker-config" "hocker-layer"]); assert (builtins.elem fetcher [ "hocker-config" "hocker-layer" ]);
# If layerDigest is non-empty then it must not have a 'sha256:' prefix! # If layerDigest is non-empty then it must not have a 'sha256:' prefix!
assert assert (if layerDigest != "" then
(if layerDigest != "" !lib.hasPrefix "sha256:" layerDigest
then !lib.hasPrefix "sha256:" layerDigest else
else true); true);
let let
layerDigestFlag = layerDigestFlag =
lib.optionalString (layerDigest != "") "--layer ${layerDigest}"; lib.optionalString (layerDigest != "") "--layer ${layerDigest}";
in in stdenv.mkDerivation {
stdenv.mkDerivation {
inherit name; inherit name;
builder = writeText "${fetcher}-builder.sh" '' builder = writeText "${fetcher}-builder.sh" ''
source "$stdenv/setup" source "$stdenv/setup"

View file

@ -1,36 +1,21 @@
{ stdenv { stdenv, fetchurl, jq, strip-nondeterminism, unzip, writeScript, zip }:
, fetchurl
, jq
, strip-nondeterminism
, unzip
, writeScript
, zip
}:
{ name { name, url ? null, sha1 ? "", sha256 ? "", sha512 ? "", fixedExtid ? null
, url ? null , hash ? "", src ? "" }:
, sha1 ? ""
, sha256 ? ""
, sha512 ? ""
, fixedExtid ? null
, hash ? ""
, src ? ""
}:
let let
extid = if fixedExtid == null then "nixos@${name}" else fixedExtid; extid = if fixedExtid == null then "nixos@${name}" else fixedExtid;
source = if url == null then src else source = if url == null then
fetchurl { src
url = url; else
inherit sha1 sha256 sha512 hash; fetchurl {
}; url = url;
in inherit sha1 sha256 sha512 hash;
stdenv.mkDerivation { };
in stdenv.mkDerivation {
inherit name; inherit name;
passthru = { passthru = { inherit extid; };
inherit extid;
};
builder = writeScript "xpibuilder" '' builder = writeScript "xpibuilder" ''
source $stdenv/setup source $stdenv/setup
@ -48,10 +33,5 @@ stdenv.mkDerivation {
rm -r "$out/$UUID" rm -r "$out/$UUID"
''; '';
nativeBuildInputs = [ nativeBuildInputs = [ jq strip-nondeterminism unzip zip ];
jq
strip-nondeterminism
unzip
zip
];
} }

View file

@ -4,18 +4,18 @@
simple = testers.invalidateFetcherByDrvHash fetchFirefoxAddon { simple = testers.invalidateFetcherByDrvHash fetchFirefoxAddon {
name = "image-search-options"; name = "image-search-options";
# Chosen because its only 147KB # Chosen because its only 147KB
url = "https://addons.mozilla.org/firefox/downloads/file/3059971/image_search_options-3.0.12-fx.xpi"; url =
"https://addons.mozilla.org/firefox/downloads/file/3059971/image_search_options-3.0.12-fx.xpi";
sha256 = "sha256-H73YWX/DKxvhEwKpWOo7orAQ7c/rQywpljeyxYxv0Gg="; sha256 = "sha256-H73YWX/DKxvhEwKpWOo7orAQ7c/rQywpljeyxYxv0Gg=";
}; };
overridden-source = overridden-source = let
let image-search-options = fetchurl {
image-search-options = fetchurl { url =
url = "https://addons.mozilla.org/firefox/downloads/file/3059971/image_search_options-3.0.12-fx.xpi"; "https://addons.mozilla.org/firefox/downloads/file/3059971/image_search_options-3.0.12-fx.xpi";
sha256 = "sha256-H73YWX/DKxvhEwKpWOo7orAQ7c/rQywpljeyxYxv0Gg="; sha256 = "sha256-H73YWX/DKxvhEwKpWOo7orAQ7c/rQywpljeyxYxv0Gg=";
};
in
testers.invalidateFetcherByDrvHash fetchFirefoxAddon {
name = "image-search-options";
src = image-search-options;
}; };
in testers.invalidateFetcherByDrvHash fetchFirefoxAddon {
name = "image-search-options";
src = image-search-options;
};
} }

View file

@ -1,33 +1,28 @@
{stdenv, lib, fossil, cacert}: { stdenv, lib, fossil, cacert }:
{ name ? null { name ? null, url, rev, sha256 ? "", hash ? "" }:
, url
, rev
, sha256 ? ""
, hash ? ""
}:
if hash != "" && sha256 != "" then if hash != "" && sha256 != "" then
throw "Only one of sha256 or hash can be set" throw "Only one of sha256 or hash can be set"
else else
stdenv.mkDerivation { stdenv.mkDerivation {
name = "fossil-archive" + (lib.optionalString (name != null) "-${name}"); name = "fossil-archive" + (lib.optionalString (name != null) "-${name}");
builder = ./builder.sh; builder = ./builder.sh;
nativeBuildInputs = [fossil cacert]; nativeBuildInputs = [ fossil cacert ];
# Envvar docs are hard to find. A link for the future: # Envvar docs are hard to find. A link for the future:
# https://www.fossil-scm.org/index.html/doc/trunk/www/env-opts.md # https://www.fossil-scm.org/index.html/doc/trunk/www/env-opts.md
impureEnvVars = [ "http_proxy" ]; impureEnvVars = [ "http_proxy" ];
outputHashAlgo = if hash != "" then null else "sha256"; outputHashAlgo = if hash != "" then null else "sha256";
outputHashMode = "recursive"; outputHashMode = "recursive";
outputHash = if hash != "" then outputHash = if hash != "" then
hash hash
else if sha256 != "" then else if sha256 != "" then
sha256 sha256
else else
lib.fakeSha256; lib.fakeSha256;
inherit url rev; inherit url rev;
preferLocalBuild = true; preferLocalBuild = true;
} }

View file

@ -1,110 +1,105 @@
{lib, stdenvNoCC, git, git-lfs, cacert}: let { lib, stdenvNoCC, git, git-lfs, cacert }:
urlToName = url: rev: let let
inherit (lib) removeSuffix splitString last; urlToName = url: rev:
base = last (splitString ":" (baseNameOf (removeSuffix "/" url))); let
inherit (lib) removeSuffix splitString last;
base = last (splitString ":" (baseNameOf (removeSuffix "/" url)));
matched = builtins.match "(.*)\\.git" base; matched = builtins.match "(.*)\\.git" base;
short = builtins.substring 0 7 rev; short = builtins.substring 0 7 rev;
appendShort = lib.optionalString ((builtins.match "[a-f0-9]*" rev) != null) "-${short}"; appendShort =
in "${if matched == null then base else builtins.head matched}${appendShort}"; lib.optionalString ((builtins.match "[a-f0-9]*" rev) != null)
in "-${short}";
lib.makeOverridable ( in "${
{ url, rev ? "HEAD", sha256 ? "", hash ? "", leaveDotGit ? deepClone if matched == null then base else builtins.head matched
, fetchSubmodules ? true, deepClone ? false }${appendShort}";
, branchName ? null in lib.makeOverridable ({ url, rev ? "HEAD", sha256 ? "", hash ? ""
, sparseCheckout ? [] , leaveDotGit ? deepClone, fetchSubmodules ? true, deepClone ? false
, nonConeMode ? false , branchName ? null, sparseCheckout ? [ ], nonConeMode ? false
, name ? urlToName url rev , name ? urlToName url rev
, # Shell code executed after the file has been fetched , # Shell code executed after the file has been fetched
# successfully. This can do things like check or transform the file. # successfully. This can do things like check or transform the file.
postFetch ? "" postFetch ? "", preferLocalBuild ? true, fetchLFS ? false
, preferLocalBuild ? true , # Shell code to build a netrc file for BASIC auth
, fetchLFS ? false
, # Shell code to build a netrc file for BASIC auth
netrcPhase ? null netrcPhase ? null
, # Impure env vars (https://nixos.org/nix/manual/#sec-advanced-attributes) , # Impure env vars (https://nixos.org/nix/manual/#sec-advanced-attributes)
# needed for netrcPhase # needed for netrcPhase
netrcImpureEnvVars ? [] netrcImpureEnvVars ? [ ], meta ? { }, allowedRequisites ? null }:
, meta ? {}
, allowedRequisites ? null
}:
/* NOTE: /* NOTE:
fetchgit has one problem: git fetch only works for refs. fetchgit has one problem: git fetch only works for refs.
This is because fetching arbitrary (maybe dangling) commits creates garbage collection risks This is because fetching arbitrary (maybe dangling) commits creates garbage collection risks
and checking whether a commit belongs to a ref is expensive. This may and checking whether a commit belongs to a ref is expensive. This may
change in the future when some caching is added to git (?) change in the future when some caching is added to git (?)
Usually refs are either tags (refs/tags/*) or branches (refs/heads/*) Usually refs are either tags (refs/tags/*) or branches (refs/heads/*)
Cloning branches will make the hash check fail when there is an update. Cloning branches will make the hash check fail when there is an update.
But not all patches we want can be accessed by tags. But not all patches we want can be accessed by tags.
The workaround is getting the last n commits so that it's likely that they The workaround is getting the last n commits so that it's likely that they
still contain the hash we want. still contain the hash we want.
for now : increase depth iteratively (TODO) for now : increase depth iteratively (TODO)
real fix: ask git folks to add a real fix: ask git folks to add a
git fetch $HASH contained in $BRANCH git fetch $HASH contained in $BRANCH
facility because checking that $HASH is contained in $BRANCH is less facility because checking that $HASH is contained in $BRANCH is less
expensive than fetching --depth $N. expensive than fetching --depth $N.
Even if git folks implemented this feature soon it may take years until Even if git folks implemented this feature soon it may take years until
server admins start using the new version? server admins start using the new version?
*/ */
assert deepClone -> leaveDotGit; assert deepClone -> leaveDotGit;
assert nonConeMode -> (sparseCheckout != []); assert nonConeMode -> (sparseCheckout != [ ]);
if hash != "" && sha256 != "" then if hash != "" && sha256 != "" then
throw "Only one of sha256 or hash can be set" throw "Only one of sha256 or hash can be set"
else if builtins.isString sparseCheckout then else if builtins.isString sparseCheckout then
# Changed to throw on 2023-06-04 # Changed to throw on 2023-06-04
throw "Please provide directories/patterns for sparse checkout as a list of strings. Passing a (multi-line) string is not supported any more." throw
else "Please provide directories/patterns for sparse checkout as a list of strings. Passing a (multi-line) string is not supported any more."
stdenvNoCC.mkDerivation {
inherit name;
builder = ./builder.sh;
fetcher = ./nix-prefetch-git;
nativeBuildInputs = [ git ]
++ lib.optionals fetchLFS [ git-lfs ];
outputHashAlgo = if hash != "" then null else "sha256";
outputHashMode = "recursive";
outputHash = if hash != "" then
hash
else if sha256 != "" then
sha256
else else
lib.fakeSha256; stdenvNoCC.mkDerivation {
inherit name;
builder = ./builder.sh;
fetcher = ./nix-prefetch-git;
# git-sparse-checkout(1) says: nativeBuildInputs = [ git ] ++ lib.optionals fetchLFS [ git-lfs ];
# > When the --stdin option is provided, the directories or patterns are read
# > from standard in as a newline-delimited list instead of from the arguments.
sparseCheckout = builtins.concatStringsSep "\n" sparseCheckout;
inherit url rev leaveDotGit fetchLFS fetchSubmodules deepClone branchName nonConeMode postFetch; outputHashAlgo = if hash != "" then null else "sha256";
outputHashMode = "recursive";
outputHash = if hash != "" then
hash
else if sha256 != "" then
sha256
else
lib.fakeSha256;
postHook = if netrcPhase == null then null else '' # git-sparse-checkout(1) says:
${netrcPhase} # > When the --stdin option is provided, the directories or patterns are read
# required that git uses the netrc file # > from standard in as a newline-delimited list instead of from the arguments.
mv {,.}netrc sparseCheckout = builtins.concatStringsSep "\n" sparseCheckout;
export NETRC=$PWD/.netrc
export HOME=$PWD
'';
GIT_SSL_CAINFO = "${cacert}/etc/ssl/certs/ca-bundle.crt"; inherit url rev leaveDotGit fetchLFS fetchSubmodules deepClone branchName
nonConeMode postFetch;
impureEnvVars = lib.fetchers.proxyImpureEnvVars ++ netrcImpureEnvVars ++ [ postHook = if netrcPhase == null then
"GIT_PROXY_COMMAND" "NIX_GIT_SSL_CAINFO" "SOCKS_SERVER" null
]; else ''
${netrcPhase}
# required that git uses the netrc file
mv {,.}netrc
export NETRC=$PWD/.netrc
export HOME=$PWD
'';
GIT_SSL_CAINFO = "${cacert}/etc/ssl/certs/ca-bundle.crt";
inherit preferLocalBuild meta allowedRequisites; impureEnvVars = lib.fetchers.proxyImpureEnvVars ++ netrcImpureEnvVars
++ [ "GIT_PROXY_COMMAND" "NIX_GIT_SSL_CAINFO" "SOCKS_SERVER" ];
passthru = { inherit preferLocalBuild meta allowedRequisites;
gitRepoUrl = url;
}; passthru = { gitRepoUrl = url; };
} })
)

View file

@ -10,10 +10,7 @@
name = "sparse-checkout-nix-source"; name = "sparse-checkout-nix-source";
url = "https://github.com/NixOS/nix"; url = "https://github.com/NixOS/nix";
rev = "9d9dbe6ed05854e03811c361a3380e09183f4f4a"; rev = "9d9dbe6ed05854e03811c361a3380e09183f4f4a";
sparseCheckout = [ sparseCheckout = [ "src" "tests" ];
"src"
"tests"
];
sha256 = "sha256-g1PHGTWgAcd/+sXHo1o6AjVWCvC6HiocOfMbMh873LQ="; sha256 = "sha256-g1PHGTWgAcd/+sXHo1o6AjVWCvC6HiocOfMbMh873LQ=";
}; };
@ -21,10 +18,7 @@
name = "sparse-checkout-non-cone-nix-source"; name = "sparse-checkout-non-cone-nix-source";
url = "https://github.com/NixOS/nix"; url = "https://github.com/NixOS/nix";
rev = "9d9dbe6ed05854e03811c361a3380e09183f4f4a"; rev = "9d9dbe6ed05854e03811c361a3380e09183f4f4a";
sparseCheckout = [ sparseCheckout = [ "src" "tests" ];
"src"
"tests"
];
nonConeMode = true; nonConeMode = true;
sha256 = "sha256-FknO6C/PSnMPfhUqObD4vsW4PhkwdmPa9blNzcNvJQ4="; sha256 = "sha256-FknO6C/PSnMPfhUqObD4vsW4PhkwdmPa9blNzcNvJQ4=";
}; };

View file

@ -2,8 +2,6 @@
{ lib, fetchFromGitHub }: { lib, fetchFromGitHub }:
lib.makeOverridable ( lib.makeOverridable ({ domain, ... }@args:
{ domain, ... }@args:
fetchFromGitHub ((removeAttrs args [ "domain" ]) // { githubBase = domain; }) fetchFromGitHub ((removeAttrs args [ "domain" ]) // { githubBase = domain; }))
)

View file

@ -1,68 +1,80 @@
{ lib, fetchgit, fetchzip }: { lib, fetchgit, fetchzip }:
lib.makeOverridable ( lib.makeOverridable ({ owner, repo, rev, name ? "source"
{ owner, repo, rev, name ? "source" , fetchSubmodules ? false, leaveDotGit ? null, deepClone ? false
, fetchSubmodules ? false, leaveDotGit ? null , private ? false, forceFetchGit ? false, sparseCheckout ? [ ]
, deepClone ? false, private ? false, forceFetchGit ? false , githubBase ? "github.com", varPrefix ? null, meta ? { }
, sparseCheckout ? [] , ... # For hash agility
, githubBase ? "github.com", varPrefix ? null }@args:
, meta ? { }
, ... # For hash agility
}@args:
let let
position = (if args.meta.description or null != null position = (if args.meta.description or null != null then
then builtins.unsafeGetAttrPos "description" args.meta builtins.unsafeGetAttrPos "description" args.meta
else builtins.unsafeGetAttrPos "rev" args else
); builtins.unsafeGetAttrPos "rev" args);
baseUrl = "https://${githubBase}/${owner}/${repo}"; baseUrl = "https://${githubBase}/${owner}/${repo}";
newMeta = meta // { newMeta = meta // {
homepage = meta.homepage or baseUrl; homepage = meta.homepage or baseUrl;
} // lib.optionalAttrs (position != null) { } // lib.optionalAttrs (position != null) {
# to indicate where derivation originates, similar to make-derivation.nix's mkDerivation # to indicate where derivation originates, similar to make-derivation.nix's mkDerivation
position = "${position.file}:${toString position.line}"; position = "${position.file}:${toString position.line}";
}; };
passthruAttrs = removeAttrs args [ "owner" "repo" "rev" "fetchSubmodules" "forceFetchGit" "private" "githubBase" "varPrefix" ]; passthruAttrs = removeAttrs args [
varBase = "NIX${lib.optionalString (varPrefix != null) "_${varPrefix}"}_GITHUB_PRIVATE_"; "owner"
useFetchGit = fetchSubmodules || (leaveDotGit == true) || deepClone || forceFetchGit || (sparseCheckout != []); "repo"
# We prefer fetchzip in cases we don't need submodules as the hash "rev"
# is more stable in that case. "fetchSubmodules"
fetcher = "forceFetchGit"
if useFetchGit then fetchgit "private"
# fetchzip may not be overridable when using external tools, for example nix-prefetch "githubBase"
else if fetchzip ? override then fetchzip.override { withUnzip = false; } "varPrefix"
else fetchzip; ];
privateAttrs = lib.optionalAttrs private { varBase = "NIX${
netrcPhase = '' lib.optionalString (varPrefix != null) "_${varPrefix}"
if [ -z "''$${varBase}USERNAME" -o -z "''$${varBase}PASSWORD" ]; then }_GITHUB_PRIVATE_";
echo "Error: Private fetchFromGitHub requires the nix building process (nix-daemon in multi user mode) to have the ${varBase}USERNAME and ${varBase}PASSWORD env vars set." >&2 useFetchGit = fetchSubmodules || (leaveDotGit == true) || deepClone
exit 1 || forceFetchGit || (sparseCheckout != [ ]);
fi # We prefer fetchzip in cases we don't need submodules as the hash
cat > netrc <<EOF # is more stable in that case.
machine ${githubBase} fetcher = if useFetchGit then
login ''$${varBase}USERNAME fetchgit
password ''$${varBase}PASSWORD # fetchzip may not be overridable when using external tools, for example nix-prefetch
EOF else if fetchzip ? override then
''; fetchzip.override { withUnzip = false; }
netrcImpureEnvVars = [ "${varBase}USERNAME" "${varBase}PASSWORD" ]; else
}; fetchzip;
privateAttrs = lib.optionalAttrs private {
netrcPhase = ''
if [ -z "''$${varBase}USERNAME" -o -z "''$${varBase}PASSWORD" ]; then
echo "Error: Private fetchFromGitHub requires the nix building process (nix-daemon in multi user mode) to have the ${varBase}USERNAME and ${varBase}PASSWORD env vars set." >&2
exit 1
fi
cat > netrc <<EOF
machine ${githubBase}
login ''$${varBase}USERNAME
password ''$${varBase}PASSWORD
EOF
'';
netrcImpureEnvVars = [ "${varBase}USERNAME" "${varBase}PASSWORD" ];
};
gitRepoUrl = "${baseUrl}.git"; gitRepoUrl = "${baseUrl}.git";
fetcherArgs = (if useFetchGit fetcherArgs = (if useFetchGit then
then { {
inherit rev deepClone fetchSubmodules sparseCheckout; url = gitRepoUrl; inherit rev deepClone fetchSubmodules sparseCheckout;
} // lib.optionalAttrs (leaveDotGit != null) { inherit leaveDotGit; } url = gitRepoUrl;
} // lib.optionalAttrs (leaveDotGit != null) { inherit leaveDotGit; }
else { else {
url = "${baseUrl}/archive/${rev}.tar.gz"; url = "${baseUrl}/archive/${rev}.tar.gz";
passthru = { passthru = { inherit gitRepoUrl; };
inherit gitRepoUrl; }) // privateAttrs // passthruAttrs // {
}; inherit name;
} };
) // privateAttrs // passthruAttrs // { inherit name; };
in
fetcher fetcherArgs // { meta = newMeta; inherit rev owner repo; } in fetcher fetcherArgs // {
) meta = newMeta;
inherit rev owner repo;
})

View file

@ -1,12 +1,12 @@
{ fetchzip, lib }: { fetchzip, lib }:
lib.makeOverridable ( lib.makeOverridable ({ url, rev, name ? "source", ... }@args:
{ url, rev, name ? "source", ... } @ args:
fetchzip ({ fetchzip ({
inherit name; inherit name;
url = "${url}/+archive/${rev}.tar.gz"; url = "${url}/+archive/${rev}.tar.gz";
stripRoot = false; stripRoot = false;
meta.homepage = url; meta.homepage = url;
} // removeAttrs args [ "url" "rev" ]) // { inherit rev; } } // removeAttrs args [ "url" "rev" ]) // {
) inherit rev;
})

View file

@ -1,36 +1,50 @@
{ lib, fetchgit, fetchzip }: { lib, fetchgit, fetchzip }:
lib.makeOverridable ( lib.makeOverridable (
# gitlab example # gitlab example
{ owner, repo, rev, protocol ? "https", domain ? "gitlab.com", name ? "source", group ? null { owner, repo, rev, protocol ? "https", domain ? "gitlab.com", name ? "source"
, fetchSubmodules ? false, leaveDotGit ? false , group ? null, fetchSubmodules ? false, leaveDotGit ? false
, deepClone ? false, forceFetchGit ? false , deepClone ? false, forceFetchGit ? false, sparseCheckout ? [ ]
, sparseCheckout ? [] , ... # For hash agility
, ... # For hash agility }@args:
} @ args:
let let
slug = lib.concatStringsSep "/" ((lib.optional (group != null) group) ++ [ owner repo ]); slug = lib.concatStringsSep "/"
escapedSlug = lib.replaceStrings [ "." "/" ] [ "%2E" "%2F" ] slug; ((lib.optional (group != null) group) ++ [ owner repo ]);
escapedRev = lib.replaceStrings [ "+" "%" "/" ] [ "%2B" "%25" "%2F" ] rev; escapedSlug = lib.replaceStrings [ "." "/" ] [ "%2E" "%2F" ] slug;
passthruAttrs = removeAttrs args [ "protocol" "domain" "owner" "group" "repo" "rev" "fetchSubmodules" "forceFetchGit" "leaveDotGit" "deepClone" ]; escapedRev = lib.replaceStrings [ "+" "%" "/" ] [ "%2B" "%25" "%2F" ] rev;
passthruAttrs = removeAttrs args [
"protocol"
"domain"
"owner"
"group"
"repo"
"rev"
"fetchSubmodules"
"forceFetchGit"
"leaveDotGit"
"deepClone"
];
useFetchGit = fetchSubmodules || leaveDotGit || deepClone || forceFetchGit || (sparseCheckout != []); useFetchGit = fetchSubmodules || leaveDotGit || deepClone || forceFetchGit
fetcher = if useFetchGit then fetchgit else fetchzip; || (sparseCheckout != [ ]);
fetcher = if useFetchGit then fetchgit else fetchzip;
gitRepoUrl = "${protocol}://${domain}/${slug}.git"; gitRepoUrl = "${protocol}://${domain}/${slug}.git";
fetcherArgs = (if useFetchGit then { fetcherArgs = (if useFetchGit then {
inherit rev deepClone fetchSubmodules sparseCheckout leaveDotGit; inherit rev deepClone fetchSubmodules sparseCheckout leaveDotGit;
url = gitRepoUrl; url = gitRepoUrl;
} else { } else {
url = "${protocol}://${domain}/api/v4/projects/${escapedSlug}/repository/archive.tar.gz?sha=${escapedRev}"; url =
"${protocol}://${domain}/api/v4/projects/${escapedSlug}/repository/archive.tar.gz?sha=${escapedRev}";
passthru = { passthru = { inherit gitRepoUrl; };
inherit gitRepoUrl; }) // passthruAttrs // {
inherit name;
}; };
}) // passthruAttrs // { inherit name; };
in
fetcher fetcherArgs // { meta.homepage = "${protocol}://${domain}/${slug}/"; inherit rev owner repo; } in fetcher fetcherArgs // {
) meta.homepage = "${protocol}://${domain}/${slug}/";
inherit rev owner repo;
})

View file

@ -1,13 +1,12 @@
{ runCommand, git, lib }: { runCommand, git, lib }:
lib.makeOverridable ( lib.makeOverridable (src:
src:
let let
srcStr = toString src; srcStr = toString src;
# Adds the current directory (respecting ignored files) to the git store, and returns the hash # Adds the current directory (respecting ignored files) to the git store, and returns the hash
gitHashFile = runCommand "put-in-git" { gitHashFile = runCommand "put-in-git" {
nativeBuildInputs = [ git ]; nativeBuildInputs = [ git ];
dummy = builtins.currentTime; # impure, do every time dummy = builtins.currentTime; # impure, do every time
preferLocalBuild = true; preferLocalBuild = true;
@ -27,9 +26,9 @@ let
mv $DOT_GIT/index-user $DOT_GIT/index # restore index mv $DOT_GIT/index-user $DOT_GIT/index # restore index
''; '';
gitHash = builtins.readFile gitHashFile; # cache against git hash gitHash = builtins.readFile gitHashFile; # cache against git hash
nixPath = runCommand "put-in-nix" { nixPath = runCommand "put-in-nix" {
nativeBuildInputs = [ git ]; nativeBuildInputs = [ git ];
preferLocalBuild = true; preferLocalBuild = true;
} '' } ''
@ -40,5 +39,4 @@ let
| tar xf - -C $out | tar xf - -C $out
''; '';
in nixPath in nixPath)
)

View file

@ -1,34 +1,29 @@
{ lib, stdenvNoCC, mercurial }: { lib, stdenvNoCC, mercurial }:
{ name ? null { name ? null, url, rev ? null, sha256 ? null, hash ? null
, url , fetchSubrepos ? false, preferLocalBuild ? true }:
, rev ? null
, sha256 ? null
, hash ? null
, fetchSubrepos ? false
, preferLocalBuild ? true }:
if hash != null && sha256 != null then if hash != null && sha256 != null then
throw "Only one of sha256 or hash can be set" throw "Only one of sha256 or hash can be set"
else else
# TODO: statically check if mercurial as the https support if the url starts woth https. # TODO: statically check if mercurial as the https support if the url starts woth https.
stdenvNoCC.mkDerivation { stdenvNoCC.mkDerivation {
name = "hg-archive" + (lib.optionalString (name != null) "-${name}"); name = "hg-archive" + (lib.optionalString (name != null) "-${name}");
builder = ./builder.sh; builder = ./builder.sh;
nativeBuildInputs = [mercurial]; nativeBuildInputs = [ mercurial ];
impureEnvVars = lib.fetchers.proxyImpureEnvVars; impureEnvVars = lib.fetchers.proxyImpureEnvVars;
subrepoClause = lib.optionalString fetchSubrepos "S"; subrepoClause = lib.optionalString fetchSubrepos "S";
outputHashAlgo = if hash != null then null else "sha256"; outputHashAlgo = if hash != null then null else "sha256";
outputHashMode = "recursive"; outputHashMode = "recursive";
outputHash = if hash != null then outputHash = if hash != null then
hash hash
else if sha256 != null then else if sha256 != null then
sha256 sha256
else else
lib.fakeSha256; lib.fakeSha256;
inherit url rev; inherit url rev;
inherit preferLocalBuild; inherit preferLocalBuild;
} }

View file

@ -1,50 +1,49 @@
{ stdenv { stdenv, curl }:
, curl
}:
{ ipfs { ipfs, url ? "", curlOpts ? "", outputHash ? "", outputHashAlgo ? "", md5 ? ""
, url ? "" , sha1 ? "", sha256 ? "", sha512 ? "", meta ? { }, port ? "8080", postFetch ? ""
, curlOpts ? "" , preferLocalBuild ? true }:
, outputHash ? ""
, outputHashAlgo ? ""
, md5 ? ""
, sha1 ? ""
, sha256 ? ""
, sha512 ? ""
, meta ? {}
, port ? "8080"
, postFetch ? ""
, preferLocalBuild ? true
}:
let let
hasHash = (outputHash != "" && outputHashAlgo != "") hasHash = (outputHash != "" && outputHashAlgo != "") || md5 != "" || sha1
|| md5 != "" || sha1 != "" || sha256 != "" || sha512 != ""; != "" || sha256 != "" || sha512 != "";
in in if (!hasHash) then
throw "Specify sha for fetchipfs fixed-output derivation"
else
stdenv.mkDerivation {
name = ipfs;
builder = ./builder.sh;
nativeBuildInputs = [ curl ];
if (!hasHash) then throw "Specify sha for fetchipfs fixed-output derivation" else stdenv.mkDerivation { # New-style output content requirements.
name = ipfs; outputHashAlgo = if outputHashAlgo != "" then
builder = ./builder.sh; outputHashAlgo
nativeBuildInputs = [ curl ]; else if sha512 != "" then
"sha512"
else if sha256 != "" then
"sha256"
else if sha1 != "" then
"sha1"
else
"md5";
outputHash = if outputHash != "" then
outputHash
else if sha512 != "" then
sha512
else if sha256 != "" then
sha256
else if sha1 != "" then
sha1
else
md5;
# New-style output content requirements. outputHashMode = "recursive";
outputHashAlgo = if outputHashAlgo != "" then outputHashAlgo else
if sha512 != "" then "sha512" else if sha256 != "" then "sha256" else if sha1 != "" then "sha1" else "md5";
outputHash = if outputHash != "" then outputHash else
if sha512 != "" then sha512 else if sha256 != "" then sha256 else if sha1 != "" then sha1 else md5;
outputHashMode = "recursive"; inherit curlOpts postFetch ipfs url port meta;
inherit curlOpts # Doing the download on a remote machine just duplicates network
postFetch # traffic, so don't do that.
ipfs inherit preferLocalBuild;
url }
port
meta;
# Doing the download on a remote machine just duplicates network
# traffic, so don't do that.
inherit preferLocalBuild;
}

View file

@ -8,66 +8,67 @@ let
"https://oss.sonatype.org/content/repositories/public" "https://oss.sonatype.org/content/repositories/public"
"https://repo.typesafe.com/typesafe/releases" "https://repo.typesafe.com/typesafe/releases"
]; ];
in
args@ in args@{ # Example: "org.apache.httpcomponents"
{ # Example: "org.apache.httpcomponents" groupId, # Example: "httpclient"
groupId artifactId, # Example: "4.3.6"
, # Example: "httpclient" version, # Example: "jdk11"
artifactId classifier ? null
, # Example: "4.3.6"
version
, # Example: "jdk11"
classifier ? null
, # List of maven repositories from where to fetch the artifact. , # List of maven repositories from where to fetch the artifact.
# Example: [ http://oss.sonatype.org/content/repositories/public ]. # Example: [ http://oss.sonatype.org/content/repositories/public ].
repos ? defaultRepos repos ? defaultRepos
# The `url` and `urls` parameters, if specified should point to the JAR # The `url` and `urls` parameters, if specified should point to the JAR
# file and will take precedence over the `repos` parameter. Only one of `url` # file and will take precedence over the `repos` parameter. Only one of `url`
# and `urls` can be specified, not both. # and `urls` can be specified, not both.
, url ? "" , url ? "", urls ? [ ]
, urls ? []
, # The rest of the arguments are just forwarded to `fetchurl`. , # The rest of the arguments are just forwarded to `fetchurl`.
... ... }:
}:
# only one of url and urls can be specified at a time. # only one of url and urls can be specified at a time.
assert (url == "") || (urls == []); assert (url == "") || (urls == [ ]);
# if repos is empty, then url or urls must be specified. # if repos is empty, then url or urls must be specified.
assert (repos != []) || (url != "") || (urls != []); assert (repos != [ ]) || (url != "") || (urls != [ ]);
let let
pname = (lib.replaceStrings [ "." ] [ "_" ] groupId) + "_" + (lib.replaceStrings [ "." ] [ "_" ] artifactId); pname = (lib.replaceStrings [ "." ] [ "_" ] groupId) + "_"
+ (lib.replaceStrings [ "." ] [ "_" ] artifactId);
suffix = lib.optionalString (classifier != null) "-${classifier}"; suffix = lib.optionalString (classifier != null) "-${classifier}";
filename = "${artifactId}-${version}${suffix}.jar"; filename = "${artifactId}-${version}${suffix}.jar";
mkJarUrl = repoUrl: mkJarUrl = repoUrl:
lib.concatStringsSep "/" [ lib.concatStringsSep "/" [
(lib.removeSuffix "/" repoUrl) (lib.removeSuffix "/" repoUrl)
(lib.replaceStrings ["."] ["/"] groupId) (lib.replaceStrings [ "." ] [ "/" ] groupId)
artifactId artifactId
version version
filename filename
]; ];
urls_ = urls_ = if url != "" then
if url != "" then [url] [ url ]
else if urls != [] then urls else if urls != [ ] then
else map mkJarUrl repos; urls
jar = else
fetchurl ( map mkJarUrl repos;
builtins.removeAttrs args [ "groupId" "artifactId" "version" "classifier" "repos" "url" ] jar = fetchurl (builtins.removeAttrs args [
// { urls = urls_; name = "${pname}-${version}.jar"; } "groupId"
); "artifactId"
in "version"
stdenv.mkDerivation { "classifier"
inherit pname version; "repos"
dontUnpack = true; "url"
# By moving the jar to $out/share/java we make it discoverable by java ] // {
# packages packages that mention this derivation in their buildInputs. urls = urls_;
installPhase = '' name = "${pname}-${version}.jar";
mkdir -p $out/share/java });
ln -s ${jar} $out/share/java/${filename} in stdenv.mkDerivation {
''; inherit pname version;
# We also add a `jar` attribute that can be used to easily obtain the path dontUnpack = true;
# to the downloaded jar file. # By moving the jar to $out/share/java we make it discoverable by java
passthru.jar = jar; # packages packages that mention this derivation in their buildInputs.
} installPhase = ''
mkdir -p $out/share/java
ln -s ${jar} $out/share/java/${filename}
'';
# We also add a `jar` attribute that can be used to easily obtain the path
# to the downloaded jar file.
passthru.jar = jar;
}

View file

@ -1,16 +1,16 @@
# You can specify some extra mirrors and a cache DB via options # You can specify some extra mirrors and a cache DB via options
{lib, stdenvNoCC, monotone, defaultDBMirrors ? [], cacheDB ? "./mtn-checkout.db"}: { lib, stdenvNoCC, monotone, defaultDBMirrors ? [ ]
, cacheDB ? "./mtn-checkout.db" }:
# dbs is a list of strings # dbs is a list of strings
# each is an url for sync # each is an url for sync
# selector is mtn selector, like h:org.example.branch # selector is mtn selector, like h:org.example.branch
# #
{name ? "mtn-checkout", dbs ? [], sha256 { name ? "mtn-checkout", dbs ? [ ], sha256, selector ? "h:" + branch, branch }:
, selector ? "h:" + branch, branch}:
stdenvNoCC.mkDerivation { stdenvNoCC.mkDerivation {
builder = ./builder.sh; builder = ./builder.sh;
nativeBuildInputs = [monotone]; nativeBuildInputs = [ monotone ];
outputHashAlgo = "sha256"; outputHashAlgo = "sha256";
outputHashMode = "recursive"; outputHashMode = "recursive";

View file

@ -1,14 +1,6 @@
{ stdenv, fetchzip, applyPatches, lib, ... }: { stdenv, fetchzip, applyPatches, lib, ... }:
{ url { url, hash ? "", sha256 ? "", appName ? null, appVersion ? null, license
, hash ? "" , patches ? [ ], description ? null, homepage ? null }:
, sha256 ? ""
, appName ? null
, appVersion ? null
, license
, patches ? [ ]
, description ? null
, homepage ? null
}:
applyPatches ({ applyPatches ({
inherit patches; inherit patches;
src = fetchzip { src = fetchzip {
@ -27,9 +19,7 @@ applyPatches ({
inherit homepage; inherit homepage;
} // lib.optionalAttrs (description != null) { } // lib.optionalAttrs (description != null) {
longDescription = description; longDescription = description;
} // lib.optionalAttrs (homepage != null) { } // lib.optionalAttrs (homepage != null) { inherit homepage; };
inherit homepage;
};
}; };
} // lib.optionalAttrs (appName != null && appVersion != null) { } // lib.optionalAttrs (appName != null && appVersion != null) {
name = "nextcloud-app-${appName}-${appVersion}"; name = "nextcloud-app-${appName}-${appVersion}";

View file

@ -6,16 +6,10 @@
{ lib, fetchurl, patchutils }: { lib, fetchurl, patchutils }:
{ relative ? null { relative ? null, stripLen ? 0
, stripLen ? 0
, decode ? "cat" # custom command to decode patch e.g. base64 -d , decode ? "cat" # custom command to decode patch e.g. base64 -d
, extraPrefix ? null , extraPrefix ? null, excludes ? [ ], includes ? [ ], revert ? false
, excludes ? [] , postFetch ? "", ... }@args:
, includes ? []
, revert ? false
, postFetch ? ""
, ...
}@args:
let let
args' = if relative != null then { args' = if relative != null then {
stripLen = 1 + lib.length (lib.splitString "/" relative) + stripLen; stripLen = 1 + lib.length (lib.splitString "/" relative) + stripLen;
@ -23,12 +17,9 @@ let
} else { } else {
inherit stripLen extraPrefix; inherit stripLen extraPrefix;
}; };
in let in let inherit (args') stripLen extraPrefix;
inherit (args') stripLen extraPrefix; in lib.throwIfNot (excludes == [ ] || includes == [ ])
in "fetchpatch: cannot use excludes and includes simultaneously" fetchurl ({
lib.throwIfNot (excludes == [] || includes == [])
"fetchpatch: cannot use excludes and includes simultaneously"
fetchurl ({
postFetch = '' postFetch = ''
tmpfile="$TMPDIR/patch" tmpfile="$TMPDIR/patch"
@ -40,7 +31,9 @@ fetchurl ({
set +e set +e
${decode} < "$out" > "$tmpfile" ${decode} < "$out" > "$tmpfile"
if [ $? -ne 0 ] || [ ! -s "$tmpfile" ]; then if [ $? -ne 0 ] || [ ! -s "$tmpfile" ]; then
echo 'Failed to decode patch with command "'${lib.escapeShellArg decode}'"' >&2 echo 'Failed to decode patch with command "'${
lib.escapeShellArg decode
}'"' >&2
echo 'Fetched file was (limited to 128 bytes):' >&2 echo 'Fetched file was (limited to 128 bytes):' >&2
od -A x -t x1z -v -N 128 "$out" >&2 od -A x -t x1z -v -N 128 "$out" >&2
exit 1 exit 1
@ -49,17 +42,22 @@ fetchurl ({
mv "$tmpfile" "$out" mv "$tmpfile" "$out"
"${patchutils}/bin/lsdiff" \ "${patchutils}/bin/lsdiff" \
${lib.optionalString (relative != null) "-p1 -i ${lib.escapeShellArg relative}/'*'"} \ ${
lib.optionalString (relative != null)
"-p1 -i ${lib.escapeShellArg relative}/'*'"
} \
"$out" \ "$out" \
| sort -u | sed -e 's/[*?]/\\&/g' \ | sort -u | sed -e 's/[*?]/\\&/g' \
| xargs -I{} \ | xargs -I{} \
"${patchutils}/bin/filterdiff" \ "${patchutils}/bin/filterdiff" \
--include={} \ --include={} \
--strip=${toString stripLen} \ --strip=${toString stripLen} \
${lib.optionalString (extraPrefix != null) '' ${
lib.optionalString (extraPrefix != null) ''
--addoldprefix=a/${lib.escapeShellArg extraPrefix} \ --addoldprefix=a/${lib.escapeShellArg extraPrefix} \
--addnewprefix=b/${lib.escapeShellArg extraPrefix} \ --addnewprefix=b/${lib.escapeShellArg extraPrefix} \
''} \ ''
} \
--clean "$out" > "$tmpfile" --clean "$out" > "$tmpfile"
if [ ! -s "$tmpfile" ]; then if [ ! -s "$tmpfile" ]; then
@ -72,8 +70,14 @@ fetchurl ({
${patchutils}/bin/filterdiff \ ${patchutils}/bin/filterdiff \
-p1 \ -p1 \
${builtins.toString (builtins.map (x: "-x ${lib.escapeShellArg x}") excludes)} \ ${
${builtins.toString (builtins.map (x: "-i ${lib.escapeShellArg x}") includes)} \ builtins.toString
(builtins.map (x: "-x ${lib.escapeShellArg x}") excludes)
} \
${
builtins.toString
(builtins.map (x: "-i ${lib.escapeShellArg x}") includes)
} \
"$tmpfile" > "$out" "$tmpfile" > "$out"
if [ ! -s "$out" ]; then if [ ! -s "$out" ]; then
@ -88,6 +92,12 @@ fetchurl ({
mv "$tmpfile" "$out" mv "$tmpfile" "$out"
'' + postFetch; '' + postFetch;
} // builtins.removeAttrs args [ } // builtins.removeAttrs args [
"relative" "stripLen" "decode" "extraPrefix" "excludes" "includes" "revert" "relative"
"stripLen"
"decode"
"extraPrefix"
"excludes"
"includes"
"revert"
"postFetch" "postFetch"
]) ])

View file

@ -1,35 +1,49 @@
{ testers, fetchpatch, ... }: { testers, fetchpatch, ... }:
let let isFetchpatch2 = fetchpatch.version == 2;
isFetchpatch2 = fetchpatch.version == 2;
in
{ in {
simple = testers.invalidateFetcherByDrvHash fetchpatch { simple = testers.invalidateFetcherByDrvHash fetchpatch {
url = "https://github.com/facebook/zstd/pull/2724/commits/e1f85dbca3a0ed5ef06c8396912a0914db8dea6a.patch"; url =
sha256 = if isFetchpatch2 then "sha256-01BrkHLye4KOdqCw3tv7AJzIF6578pl2fl270TJFTmw=" else "sha256-PuYAqnJWAE+L9bsroOnnBGJhERW8LHrGSLtIEkKU9vg="; "https://github.com/facebook/zstd/pull/2724/commits/e1f85dbca3a0ed5ef06c8396912a0914db8dea6a.patch";
sha256 = if isFetchpatch2 then
"sha256-01BrkHLye4KOdqCw3tv7AJzIF6578pl2fl270TJFTmw="
else
"sha256-PuYAqnJWAE+L9bsroOnnBGJhERW8LHrGSLtIEkKU9vg=";
}; };
relative = testers.invalidateFetcherByDrvHash fetchpatch { relative = testers.invalidateFetcherByDrvHash fetchpatch {
url = "https://github.com/boostorg/math/commit/7d482f6ebc356e6ec455ccb5f51a23971bf6ce5b.patch"; url =
"https://github.com/boostorg/math/commit/7d482f6ebc356e6ec455ccb5f51a23971bf6ce5b.patch";
relative = "include"; relative = "include";
sha256 = if isFetchpatch2 then "sha256-1TtmuKeNIl/Yp+sfzBMR8Ue78tPIgjqGgjasa5IN52o=" else "sha256-KlmIbixcds6GyKYt1fx5BxDIrU7msrgDdYo9Va/KJR4="; sha256 = if isFetchpatch2 then
"sha256-1TtmuKeNIl/Yp+sfzBMR8Ue78tPIgjqGgjasa5IN52o="
else
"sha256-KlmIbixcds6GyKYt1fx5BxDIrU7msrgDdYo9Va/KJR4=";
}; };
full = testers.invalidateFetcherByDrvHash fetchpatch { full = testers.invalidateFetcherByDrvHash fetchpatch {
url = "https://github.com/boostorg/math/commit/7d482f6ebc356e6ec455ccb5f51a23971bf6ce5b.patch"; url =
"https://github.com/boostorg/math/commit/7d482f6ebc356e6ec455ccb5f51a23971bf6ce5b.patch";
relative = "test"; relative = "test";
stripLen = 1; stripLen = 1;
extraPrefix = "foo/bar/"; extraPrefix = "foo/bar/";
excludes = [ "foo/bar/bernoulli_no_atomic_mp.cpp" ]; excludes = [ "foo/bar/bernoulli_no_atomic_mp.cpp" ];
revert = true; revert = true;
sha256 = if isFetchpatch2 then "sha256-+UKmEbr2rIAweCav/hR/7d4ZrYV84ht/domTrHtm8sM=" else "sha256-+UKmEbr2rIAweCav/hR/7d4ZrYV84ht/domTrHtm8sM="; sha256 = if isFetchpatch2 then
"sha256-+UKmEbr2rIAweCav/hR/7d4ZrYV84ht/domTrHtm8sM="
else
"sha256-+UKmEbr2rIAweCav/hR/7d4ZrYV84ht/domTrHtm8sM=";
}; };
decode = testers.invalidateFetcherByDrvHash fetchpatch { decode = testers.invalidateFetcherByDrvHash fetchpatch {
name = "gcc.patch"; name = "gcc.patch";
url = "https://chromium.googlesource.com/aosp/platform/external/libchrome/+/f37ae3b1a873d74182a2ac31d96742ead9c1f523^!?format=TEXT"; url =
"https://chromium.googlesource.com/aosp/platform/external/libchrome/+/f37ae3b1a873d74182a2ac31d96742ead9c1f523^!?format=TEXT";
decode = "base64 -d"; decode = "base64 -d";
sha256 = if isFetchpatch2 then "sha256-oMvPlmzE51ArI+EvFxONXkqmNee39106/O1ikG0Bdso=" else "sha256-SJHk8XrutqAyoIdORlhCpBCN626P+uzed7mjKz5eQYY="; sha256 = if isFetchpatch2 then
"sha256-oMvPlmzE51ArI+EvFxONXkqmNee39106/O1ikG0Bdso="
else
"sha256-SJHk8XrutqAyoIdORlhCpBCN626P+uzed7mjKz5eQYY=";
}; };
} }

View file

@ -1,59 +1,50 @@
{ lib, stdenvNoCC, pijul, cacert }: { lib, stdenvNoCC, pijul, cacert }:
lib.makeOverridable ( lib.makeOverridable ({ url, hash ? "", change ? null, state ? null
{ url , channel ? "main", name ? "fetchpijul"
, hash ? "" , # TODO: Changes in pijul are unordered so there's many ways to end up with the same repository state.
, change ? null
, state ? null
, channel ? "main"
, name ? "fetchpijul"
, # TODO: Changes in pijul are unordered so there's many ways to end up with the same repository state.
# This makes leaveDotPijul unfeasible to implement until pijul CLI implements # This makes leaveDotPijul unfeasible to implement until pijul CLI implements
# a way of reordering changes to sort them in a consistent and deterministic manner. # a way of reordering changes to sort them in a consistent and deterministic manner.
# leaveDotPijul ? false # leaveDotPijul ? false
}: }:
if change != null && state != null then if change != null && state != null then
throw "Only one of 'change' or 'state' can be set" throw "Only one of 'change' or 'state' can be set"
else else
stdenvNoCC.mkDerivation { stdenvNoCC.mkDerivation {
inherit name; inherit name;
nativeBuildInputs = [ pijul cacert ]; nativeBuildInputs = [ pijul cacert ];
strictDeps = true; strictDeps = true;
dontUnpack = true; dontUnpack = true;
dontConfigure = true; dontConfigure = true;
dontBuild = true; dontBuild = true;
installPhase = '' installPhase = ''
runHook preInstall runHook preInstall
pijul clone \ pijul clone \
''${change:+--change "$change"} \ ''${change:+--change "$change"} \
''${state:+--state "$state"} \ ''${state:+--state "$state"} \
--channel "$channel" \ --channel "$channel" \
"$url" \ "$url" \
"$out" "$out"
runHook postInstall runHook postInstall
''; '';
fixupPhase = '' fixupPhase = ''
runHook preFixup runHook preFixup
rm -rf "$out/.pijul" rm -rf "$out/.pijul"
runHook postFixup runHook postFixup
''; '';
outputHashAlgo = if hash != "" then null else "sha256"; outputHashAlgo = if hash != "" then null else "sha256";
outputHashMode = "recursive"; outputHashMode = "recursive";
outputHash = if hash != "" then outputHash = if hash != "" then hash else lib.fakeSha256;
hash
else
lib.fakeSha256;
inherit url change state channel; inherit url change state channel;
impureEnvVars = lib.fetchers.proxyImpureEnvVars; impureEnvVars = lib.fetchers.proxyImpureEnvVars;
} })
)

View file

@ -1,28 +1,33 @@
# `fetchPypi` function for fetching artifacts from PyPI. # `fetchPypi` function for fetching artifacts from PyPI.
{ fetchurl { fetchurl, makeOverridable }:
, makeOverridable
}:
let let
computeUrl = {format ? "setuptools", ... } @attrs: let computeUrl = { format ? "setuptools", ... }@attrs:
computeWheelUrl = {pname, version, dist ? "py2.py3", python ? "py2.py3", abi ? "none", platform ? "any"}: let
# Fetch a wheel. By default we fetch an universal wheel. computeWheelUrl = { pname, version, dist ? "py2.py3", python ? "py2.py3"
# See https://www.python.org/dev/peps/pep-0427/#file-name-convention for details regarding the optional arguments. , abi ? "none", platform ? "any" }:
"https://files.pythonhosted.org/packages/${dist}/${builtins.substring 0 1 pname}/${pname}/${pname}-${version}-${python}-${abi}-${platform}.whl"; # Fetch a wheel. By default we fetch an universal wheel.
# See https://www.python.org/dev/peps/pep-0427/#file-name-convention for details regarding the optional arguments.
"https://files.pythonhosted.org/packages/${dist}/${
builtins.substring 0 1 pname
}/${pname}/${pname}-${version}-${python}-${abi}-${platform}.whl";
computeSourceUrl = {pname, version, extension ? "tar.gz"}: computeSourceUrl = { pname, version, extension ? "tar.gz" }:
# Fetch a source tarball. # Fetch a source tarball.
"mirror://pypi/${builtins.substring 0 1 pname}/${pname}/${pname}-${version}.${extension}"; "mirror://pypi/${
builtins.substring 0 1 pname
}/${pname}/${pname}-${version}.${extension}";
compute = (if format == "wheel" then computeWheelUrl compute = (if format == "wheel" then
else if format == "setuptools" then computeSourceUrl computeWheelUrl
else throw "Unsupported format ${format}"); else if format == "setuptools" then
computeSourceUrl
else
throw "Unsupported format ${format}");
in compute (builtins.removeAttrs attrs ["format"]); in compute (builtins.removeAttrs attrs [ "format" ]);
in makeOverridable( {format ? "setuptools", sha256 ? "", hash ? "", ... } @attrs: in makeOverridable
let ({ format ? "setuptools", sha256 ? "", hash ? "", ... }@attrs:
url = computeUrl (builtins.removeAttrs attrs ["sha256" "hash"]) ; let url = computeUrl (builtins.removeAttrs attrs [ "sha256" "hash" ]);
in fetchurl { in fetchurl { inherit url sha256 hash; })
inherit url sha256 hash;
})

View file

@ -1,45 +1,38 @@
# Fetch from PyPi legacy API as documented in https://warehouse.pypa.io/api-reference/legacy.html # Fetch from PyPi legacy API as documented in https://warehouse.pypa.io/api-reference/legacy.html
{ runCommand { runCommand, lib, python3 }:
, lib
, python3
}:
{ {
# package name # package name
pname, pname,
# Package index # Package index
url ? null, url ? null,
# Multiple package indices to consider # Multiple package indices to consider
urls ? [ ], urls ? [ ],
# filename including extension # filename including extension
file, file,
# SRI hash # SRI hash
hash, hash,
# allow overriding the derivation name # allow overriding the derivation name
name ? null, name ? null, }:
}:
let let
urls' = urls ++ lib.optional (url != null) url; urls' = urls ++ lib.optional (url != null) url;
pathParts = lib.filter ({ prefix, path }: "NETRC" == prefix) builtins.nixPath; pathParts = lib.filter ({ prefix, path }: "NETRC" == prefix) builtins.nixPath;
netrc_file = netrc_file = if (pathParts != [ ]) then (lib.head pathParts).path else "";
if (pathParts != [ ])
then (lib.head pathParts).path
else "";
in # Assert that we have at least one URL
# Assert that we have at least one URL in assert urls' != [ ];
assert urls' != [ ]; runCommand file runCommand file ({
({ nativeBuildInputs = [ python3 ];
nativeBuildInputs = [ python3 ]; impureEnvVars = lib.fetchers.proxyImpureEnvVars;
impureEnvVars = lib.fetchers.proxyImpureEnvVars; outputHashMode = "flat";
outputHashMode = "flat"; # if hash is empty select a default algo to let nix propose the actual hash.
# if hash is empty select a default algo to let nix propose the actual hash. outputHashAlgo = if hash == "" then "sha256" else null;
outputHashAlgo = if hash == "" then "sha256" else null; outputHash = hash;
outputHash = hash; NETRC = netrc_file;
NETRC = netrc_file; } // (lib.optionalAttrs (name != null) { inherit name; })) ''
} python ${./fetch-legacy.py} ${
// (lib.optionalAttrs (name != null) {inherit name;})) lib.concatStringsSep " "
'' (map (url: "--url ${lib.escapeShellArg url}") urls')
python ${./fetch-legacy.py} ${lib.concatStringsSep " " (map (url: "--url ${lib.escapeShellArg url}") urls')} --pname ${pname} --filename ${file} } --pname ${pname} --filename ${file}
mv ${file} $out mv ${file} $out
'' ''

View file

@ -1,10 +1,12 @@
{ fetchzip }: { fetchzip }:
# gitweb example, snapshot support is optional in gitweb # gitweb example, snapshot support is optional in gitweb
{ repo, rev, name ? "source" { repo, rev, name ? "source", ... # For hash agility
, ... # For hash agility }@args:
}@args: fetchzip ({ fetchzip ({
inherit name; inherit name;
url = "https://repo.or.cz/${repo}.git/snapshot/${rev}.tar.gz"; url = "https://repo.or.cz/${repo}.git/snapshot/${rev}.tar.gz";
meta.homepage = "https://repo.or.cz/${repo}.git/"; meta.homepage = "https://repo.or.cz/${repo}.git/";
} // removeAttrs args [ "repo" "rev" ]) // { inherit rev; } } // removeAttrs args [ "repo" "rev" ]) // {
inherit rev;
}

View file

@ -3,19 +3,13 @@
{ name, manifest, rev ? "HEAD", sha256 { name, manifest, rev ? "HEAD", sha256
# Optional parameters: # Optional parameters:
, repoRepoURL ? "", repoRepoRev ? "", referenceDir ? "", manifestName ? "" , repoRepoURL ? "", repoRepoRev ? "", referenceDir ? "", manifestName ? ""
, localManifests ? [], createMirror ? false, useArchive ? false , localManifests ? [ ], createMirror ? false, useArchive ? false }:
}:
assert repoRepoRev != "" -> repoRepoURL != ""; assert repoRepoRev != "" -> repoRepoURL != "";
assert createMirror -> !useArchive; assert createMirror -> !useArchive;
let let
inherit (lib) inherit (lib) concatMapStringsSep concatStringsSep fetchers optionalString;
concatMapStringsSep
concatStringsSep
fetchers
optionalString
;
extraRepoInitFlags = [ extraRepoInitFlags = [
(optionalString (repoRepoURL != "") "--repo-url=${repoRepoURL}") (optionalString (repoRepoURL != "") "--repo-url=${repoRepoURL}")
@ -46,9 +40,8 @@ in stdenvNoCC.mkDerivation {
preferLocalBuild = true; preferLocalBuild = true;
enableParallelBuilding = true; enableParallelBuilding = true;
impureEnvVars = fetchers.proxyImpureEnvVars ++ [ impureEnvVars = fetchers.proxyImpureEnvVars
"GIT_PROXY_COMMAND" "SOCKS_SERVER" ++ [ "GIT_PROXY_COMMAND" "SOCKS_SERVER" ];
];
nativeBuildInputs = [ gitRepo cacert ]; nativeBuildInputs = [ gitRepo cacert ];
@ -62,9 +55,11 @@ in stdenvNoCC.mkDerivation {
cd $out cd $out
mkdir .repo mkdir .repo
${optionalString (local_manifests != []) '' ${optionalString (local_manifests != [ ]) ''
mkdir .repo/local_manifests mkdir .repo/local_manifests
for local_manifest in ${concatMapStringsSep " " toString local_manifests}; do for local_manifest in ${
concatMapStringsSep " " toString local_manifests
}; do
cp $local_manifest .repo/local_manifests/$(stripHash $local_manifest) cp $local_manifest .repo/local_manifests/$(stripHash $local_manifest)
done done
''} ''}

View file

@ -1,13 +1,8 @@
{ lib, runCommand, awscli }: { lib, runCommand, awscli }:
{ s3url { s3url, name ? builtins.baseNameOf s3url, sha256, region ? "us-east-1"
, name ? builtins.baseNameOf s3url
, sha256
, region ? "us-east-1"
, credentials ? null # Default to looking at local EC2 metadata service , credentials ? null # Default to looking at local EC2 metadata service
, recursiveHash ? false , recursiveHash ? false, postFetch ? null }:
, postFetch ? null
}:
let let
mkCredentials = { access_key_id, secret_access_key, session_token ? null }: { mkCredentials = { access_key_id, secret_access_key, session_token ? null }: {
@ -16,7 +11,8 @@ let
AWS_SESSION_TOKEN = session_token; AWS_SESSION_TOKEN = session_token;
}; };
credentialAttrs = lib.optionalAttrs (credentials != null) (mkCredentials credentials); credentialAttrs =
lib.optionalAttrs (credentials != null) (mkCredentials credentials);
in runCommand name ({ in runCommand name ({
nativeBuildInputs = [ awscli ]; nativeBuildInputs = [ awscli ];
@ -31,6 +27,6 @@ in runCommand name ({
downloadedFile="$(mktemp)" downloadedFile="$(mktemp)"
aws s3 cp ${s3url} $downloadedFile aws s3 cp ${s3url} $downloadedFile
${postFetch} ${postFetch}
'' else '' '' else ''
aws s3 cp ${s3url} $out aws s3 cp ${s3url} $out
'') '')

View file

@ -1,12 +1,14 @@
{ fetchzip, lib }: { fetchzip, lib }:
lib.makeOverridable ( lib.makeOverridable (
# cgit example, snapshot support is optional in cgit # cgit example, snapshot support is optional in cgit
{ repo, rev, name ? "source" { repo, rev, name ? "source", ... # For hash agility
, ... # For hash agility }@args:
}@args: fetchzip ({ fetchzip ({
inherit name; inherit name;
url = "https://git.savannah.gnu.org/cgit/${repo}.git/snapshot/${repo}-${rev}.tar.gz"; url =
meta.homepage = "https://git.savannah.gnu.org/cgit/${repo}.git/"; "https://git.savannah.gnu.org/cgit/${repo}.git/snapshot/${repo}-${rev}.tar.gz";
} // removeAttrs args [ "repo" "rev" ]) // { inherit rev; } meta.homepage = "https://git.savannah.gnu.org/cgit/${repo}.git/";
) } // removeAttrs args [ "repo" "rev" ]) // {
inherit rev;
})

View file

@ -1,62 +1,53 @@
{ fetchgit, fetchhg, fetchzip, lib }: { fetchgit, fetchhg, fetchzip, lib }:
let let inherit (lib) assertOneOf makeOverridable optionalString;
inherit (lib)
assertOneOf
makeOverridable
optionalString
;
in
makeOverridable ( in makeOverridable ({ owner, repo, rev, domain ? "sr.ht", vc ? "git"
{ owner , name ? "source", fetchSubmodules ? false, ... # For hash agility
, repo, rev }@args:
, domain ? "sr.ht"
, vc ? "git"
, name ? "source"
, fetchSubmodules ? false
, ... # For hash agility
} @ args:
assert (assertOneOf "vc" vc [ "hg" "git" ]); assert (assertOneOf "vc" vc [ "hg" "git" ]);
let let
urlFor = resource: "https://${resource}.${domain}/${owner}/${repo}"; urlFor = resource: "https://${resource}.${domain}/${owner}/${repo}";
baseUrl = urlFor vc; baseUrl = urlFor vc;
baseArgs = { baseArgs = {
inherit name; inherit name;
} // removeAttrs args [ } // removeAttrs args [
"owner" "repo" "rev" "domain" "vc" "name" "fetchSubmodules" "owner"
]; "repo"
vcArgs = baseArgs // { "rev"
inherit rev; "domain"
url = baseUrl; "vc"
}; "name"
fetcher = if fetchSubmodules then vc else "zip"; "fetchSubmodules"
cases = { ];
git = { vcArgs = baseArgs // {
fetch = fetchgit; inherit rev;
arguments = vcArgs // { fetchSubmodules = true; }; url = baseUrl;
}; };
hg = { fetcher = if fetchSubmodules then vc else "zip";
fetch = fetchhg; cases = {
arguments = vcArgs // { fetchSubrepos = true; }; git = {
}; fetch = fetchgit;
zip = { arguments = vcArgs // { fetchSubmodules = true; };
fetch = fetchzip; };
arguments = baseArgs // { hg = {
url = "${baseUrl}/archive/${rev}.tar.gz"; fetch = fetchhg;
postFetch = optionalString (vc == "hg") '' arguments = vcArgs // { fetchSubrepos = true; };
rm -f "$out/.hg_archival.txt" };
''; # impure file; see #12002 zip = {
passthru = { fetch = fetchzip;
gitRepoUrl = urlFor "git"; arguments = baseArgs // {
url = "${baseUrl}/archive/${rev}.tar.gz";
postFetch = optionalString (vc == "hg") ''
rm -f "$out/.hg_archival.txt"
''; # impure file; see #12002
passthru = { gitRepoUrl = urlFor "git"; };
}; };
}; };
}; };
}; in cases.${fetcher}.fetch cases.${fetcher}.arguments // {
in cases.${fetcher}.fetch cases.${fetcher}.arguments // { inherit rev;
inherit rev; meta.homepage = "${baseUrl}";
meta.homepage = "${baseUrl}"; })
}
)

View file

@ -1,11 +1,8 @@
{ lib, stdenvNoCC, buildPackages { lib, stdenvNoCC, buildPackages, subversion, glibcLocales, sshSupport ? true
, subversion, glibcLocales, sshSupport ? true, openssh ? null , openssh ? null }:
}:
{ url, rev ? "HEAD", sha256 ? "", hash ? "" { url, rev ? "HEAD", sha256 ? "", hash ? "", ignoreExternals ? false
, ignoreExternals ? false, ignoreKeywords ? false, name ? null , ignoreKeywords ? false, name ? null, preferLocalBuild ? true }:
, preferLocalBuild ? true
}:
assert sshSupport -> openssh != null; assert sshSupport -> openssh != null;
@ -19,41 +16,43 @@ let
(p: if head p == "" then tail p else p) # ~ drop final slash if any (p: if head p == "" then tail p else p) # ~ drop final slash if any
(reverseList (splitString "/" url)); (reverseList (splitString "/" url));
path = [ (removeSuffix "/" (head path_)) ] ++ (tail path_); path = [ (removeSuffix "/" (head path_)) ] ++ (tail path_);
in
# ../repo/trunk -> repo # ../repo/trunk -> repo
if fst path == "trunk" then snd path in if fst path == "trunk" then
snd path
# ../repo/branches/branch -> repo-branch # ../repo/branches/branch -> repo-branch
else if snd path == "branches" then "${trd path}-${fst path}" else if snd path == "branches" then
"${trd path}-${fst path}"
# ../repo/tags/tag -> repo-tag # ../repo/tags/tag -> repo-tag
else if snd path == "tags" then "${trd path}-${fst path}" else if snd path == "tags" then
"${trd path}-${fst path}"
# ../repo (no trunk) -> repo # ../repo (no trunk) -> repo
else fst path; else
fst path;
name_ = if name == null then "${repoName}-r${toString rev}" else name; name_ = if name == null then "${repoName}-r${toString rev}" else name;
in
if hash != "" && sha256 != "" then in if hash != "" && sha256 != "" then
throw "Only one of sha256 or hash can be set" throw "Only one of sha256 or hash can be set"
else else
stdenvNoCC.mkDerivation { stdenvNoCC.mkDerivation {
name = name_; name = name_;
builder = ./builder.sh; builder = ./builder.sh;
nativeBuildInputs = [ subversion glibcLocales ] nativeBuildInputs = [ subversion glibcLocales ]
++ lib.optional sshSupport openssh; ++ lib.optional sshSupport openssh;
SVN_SSH = if sshSupport then "${buildPackages.openssh}/bin/ssh" else null; SVN_SSH = if sshSupport then "${buildPackages.openssh}/bin/ssh" else null;
outputHashAlgo = if hash != "" then null else "sha256"; outputHashAlgo = if hash != "" then null else "sha256";
outputHashMode = "recursive"; outputHashMode = "recursive";
outputHash = if hash != "" then outputHash = if hash != "" then
hash hash
else if sha256 != "" then else if sha256 != "" then
sha256 sha256
else else
lib.fakeSha256; lib.fakeSha256;
inherit url rev ignoreExternals ignoreKeywords; inherit url rev ignoreExternals ignoreKeywords;
impureEnvVars = lib.fetchers.proxyImpureEnvVars; impureEnvVars = lib.fetchers.proxyImpureEnvVars;
inherit preferLocalBuild; inherit preferLocalBuild;
} }

View file

@ -1,10 +1,9 @@
runCommand: subversion: repository: runCommand: subversion: repository:
import (runCommand "head-revision" import (runCommand "head-revision" {
{ buildInputs = [ subversion ]; buildInputs = [ subversion ];
dummy = builtins.currentTime; dummy = builtins.currentTime;
} } ''
'' rev=$(echo p | svn ls -v --depth empty ${repository} |awk '{ print $1 }')
rev=$(echo p | svn ls -v --depth empty ${repository} |awk '{ print $1 }') echo "[ \"$rev\" ]" > $out
echo "[ \"$rev\" ]" > $out echo Latest revision is $rev
echo Latest revision is $rev '')
'')

View file

@ -1,11 +1,10 @@
{stdenvNoCC, subversion, sshSupport ? true, openssh ? null, expect}: { stdenvNoCC, subversion, sshSupport ? true, openssh ? null, expect }:
{username, password, url, rev ? "HEAD", sha256 ? ""}: { username, password, url, rev ? "HEAD", sha256 ? "" }:
stdenvNoCC.mkDerivation { stdenvNoCC.mkDerivation {
name = "svn-export-ssh"; name = "svn-export-ssh";
builder = ./builder.sh; builder = ./builder.sh;
nativeBuildInputs = [subversion expect]; nativeBuildInputs = [ subversion expect ];
outputHashAlgo = "sha256"; outputHashAlgo = "sha256";
outputHashMode = "recursive"; outputHashMode = "recursive";

View file

@ -1,21 +1,17 @@
{ lib, runCommand, transmission_noSystemd, rqbit, writeShellScript, formats, cacert, rsync }: { lib, runCommand, transmission_noSystemd, rqbit, writeShellScript, formats
let , cacert, rsync }:
urlRegexp = ''.*xt=urn:bt[im]h:([^&]{64}|[^&]{40}).*''; let urlRegexp = ".*xt=urn:bt[im]h:([^&]{64}|[^&]{40}).*";
in in { url, name ? if (builtins.match urlRegexp url) == null then
{ url "bittorrent"
, name ? else
if (builtins.match urlRegexp url) == null then "bittorrent-" + builtins.head (builtins.match urlRegexp url), config ?
"bittorrent" if (backend == "transmission") then
{ }
else else
"bittorrent-" + builtins.head (builtins.match urlRegexp url) throw
, config ? if (backend == "transmission") then { } else throw "json config for configuring fetchFromBitorrent only works with the transmission backend" "json config for configuring fetchFromBitorrent only works with the transmission backend"
, hash , hash, backend ? "transmission", recursiveHash ? true, postFetch ? ""
, backend ? "transmission" , postUnpack ? "", meta ? { } }:
, recursiveHash ? true
, postFetch ? ""
, postUnpack ? ""
, meta ? {}
}:
let let
afterSuccess = writeShellScript "fetch-bittorrent-done.sh" '' afterSuccess = writeShellScript "fetch-bittorrent-done.sh" ''
${postUnpack} ${postUnpack}
@ -28,11 +24,16 @@ let
${postFetch} ${postFetch}
kill $PPID kill $PPID
''; '';
jsonConfig = (formats.json {}).generate "jsonConfig" config; jsonConfig = (formats.json { }).generate "jsonConfig" config;
in in runCommand name {
runCommand name {
inherit meta; inherit meta;
nativeBuildInputs = [ cacert ] ++ (if (backend == "transmission" ) then [ transmission_noSystemd ] else if (backend == "rqbit") then [ rqbit ] else throw "rqbit or transmission are the only available backends for fetchtorrent"); nativeBuildInputs = [ cacert ] ++ (if (backend == "transmission") then
[ transmission_noSystemd ]
else if (backend == "rqbit") then
[ rqbit ]
else
throw
"rqbit or transmission are the only available backends for fetchtorrent");
outputHashAlgo = if hash != "" then null else "sha256"; outputHashAlgo = if hash != "" then null else "sha256";
outputHash = hash; outputHash = hash;
outputHashMode = if recursiveHash then "recursive" else "flat"; outputHashMode = if recursiveHash then "recursive" else "flat";
@ -41,8 +42,7 @@ runCommand name {
# by external tools, such as tools that may want to seed fetchtorrent calls # by external tools, such as tools that may want to seed fetchtorrent calls
# in nixpkgs # in nixpkgs
inherit url; inherit url;
} } (if (backend == "transmission") then ''
(if (backend == "transmission") then ''
export HOME=$TMP export HOME=$TMP
export downloadedDirectory=$out/downloadedDirectory export downloadedDirectory=$out/downloadedDirectory
mkdir -p $downloadedDirectory mkdir -p $downloadedDirectory
@ -55,8 +55,7 @@ runCommand name {
} }
trap handleChild CHLD trap handleChild CHLD
transmission-cli --port $(shuf -n 1 -i 49152-65535) --portmap --finish ${afterSuccess} --download-dir $downloadedDirectory --config-dir "$HOME"/.config/transmission "$url" transmission-cli --port $(shuf -n 1 -i 49152-65535) --portmap --finish ${afterSuccess} --download-dir $downloadedDirectory --config-dir "$HOME"/.config/transmission "$url"
'' else '' else ''
''
export HOME=$TMP export HOME=$TMP
rqbit --disable-dht-persistence --http-api-listen-addr "127.0.0.1:$(shuf -n 1 -i 49152-65535)" download -o $out --exit-on-finish "$url" rqbit --disable-dht-persistence --http-api-listen-addr "127.0.0.1:$(shuf -n 1 -i 49152-65535)" download -o $out --exit-on-finish "$url"
'') '')

View file

@ -17,9 +17,8 @@ let
free = true; # no use in advertisement free = true; # no use in advertisement
} }
]; ];
in
{ in {
http-link = testers.invalidateFetcherByDrvHash fetchtorrent { http-link = testers.invalidateFetcherByDrvHash fetchtorrent {
url = "https://webtorrent.io/torrents/wired-cd.torrent"; url = "https://webtorrent.io/torrents/wired-cd.torrent";
hash = "sha256-OCsC22WuanqoN6lPv5wDT5ZxPcEHDpZ1EgXGvz1SDYo="; hash = "sha256-OCsC22WuanqoN6lPv5wDT5ZxPcEHDpZ1EgXGvz1SDYo=";
@ -27,7 +26,8 @@ in
inherit (wired-cd) meta; inherit (wired-cd) meta;
}; };
magnet-link = testers.invalidateFetcherByDrvHash fetchtorrent { magnet-link = testers.invalidateFetcherByDrvHash fetchtorrent {
url = "magnet:?xt=urn:btih:a88fda5954e89178c372716a6a78b8180ed4dad3&dn=The+WIRED+CD+-+Rip.+Sample.+Mash.+Share&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fwired-cd.torrent"; url =
"magnet:?xt=urn:btih:a88fda5954e89178c372716a6a78b8180ed4dad3&dn=The+WIRED+CD+-+Rip.+Sample.+Mash.+Share&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fwired-cd.torrent";
hash = "sha256-OCsC22WuanqoN6lPv5wDT5ZxPcEHDpZ1EgXGvz1SDYo="; hash = "sha256-OCsC22WuanqoN6lPv5wDT5ZxPcEHDpZ1EgXGvz1SDYo=";
backend = "transmission"; backend = "transmission";
inherit (wired-cd) meta; inherit (wired-cd) meta;
@ -39,7 +39,8 @@ in
inherit (wired-cd) meta; inherit (wired-cd) meta;
}; };
magnet-link-rqbit = testers.invalidateFetcherByDrvHash fetchtorrent { magnet-link-rqbit = testers.invalidateFetcherByDrvHash fetchtorrent {
url = "magnet:?xt=urn:btih:a88fda5954e89178c372716a6a78b8180ed4dad3&dn=The+WIRED+CD+-+Rip.+Sample.+Mash.+Share&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fwired-cd.torrent"; url =
"magnet:?xt=urn:btih:a88fda5954e89178c372716a6a78b8180ed4dad3&dn=The+WIRED+CD+-+Rip.+Sample.+Mash.+Share&tr=udp%3A%2F%2Fexplodie.org%3A6969&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Ftracker.empire-js.us%3A1337&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Ftracker.opentrackr.org%3A1337&tr=wss%3A%2F%2Ftracker.btorrent.xyz&tr=wss%3A%2F%2Ftracker.fastcast.nz&tr=wss%3A%2F%2Ftracker.openwebtorrent.com&ws=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2F&xs=https%3A%2F%2Fwebtorrent.io%2Ftorrents%2Fwired-cd.torrent";
hash = "sha256-OCsC22WuanqoN6lPv5wDT5ZxPcEHDpZ1EgXGvz1SDYo="; hash = "sha256-OCsC22WuanqoN6lPv5wDT5ZxPcEHDpZ1EgXGvz1SDYo=";
backend = "rqbit"; backend = "rqbit";
inherit (wired-cd) meta; inherit (wired-cd) meta;

View file

@ -1,13 +1,9 @@
let mirrors = import ./mirrors.nix; in let mirrors = import ./mirrors.nix;
{ system }: in { system }:
{ url ? builtins.head urls { url ? builtins.head urls, urls ? [ ], sha256 ? "", hash ? ""
, urls ? [] , name ? baseNameOf (toString url) }:
, sha256 ? ""
, hash ? ""
, name ? baseNameOf (toString url)
}:
# assert exactly one hash is set # assert exactly one hash is set
assert hash != "" || sha256 != ""; assert hash != "" || sha256 != "";
@ -19,7 +15,9 @@ import <nix/fetchurl.nix> {
url = url =
# Handle mirror:// URIs. Since <nix/fetchurl.nix> currently # Handle mirror:// URIs. Since <nix/fetchurl.nix> currently
# supports only one URI, use the first listed mirror. # supports only one URI, use the first listed mirror.
let m = builtins.match "mirror://([a-z]+)/(.*)" url; in let m = builtins.match "mirror://([a-z]+)/(.*)" url;
if m == null then url in if m == null then
else builtins.head (mirrors.${builtins.elemAt m 0}) + (builtins.elemAt m 1); url
else
builtins.head (mirrors.${builtins.elemAt m 0}) + (builtins.elemAt m 1);
} }

Some files were not shown because too many files have changed in this diff Show more