core/pkgs/build-support/release/nix-build.nix
2024-05-13 11:34:52 -04:00

175 lines
5.3 KiB
Nix

# This function builds and tests an Autoconf-style source tarball.
# The result can be installed normally in an environment (e.g., after
# making it available through a channel). If `doCoverageAnalysis' is
# true, it does an ordinary build from a source tarball, except that
# it turns on GCC's coverage analysis feature. It then runs `make
# check' and produces a coverage analysis report using `lcov'.
{ buildOutOfSourceTree ? false
, preConfigure ? null
, doCoverageAnalysis ? false
, doClangAnalysis ? false
, doCoverityAnalysis ? false
, lcovFilter ? []
, lcovExtraTraceFiles ? []
, src, lib, stdenv
, name ? if doCoverageAnalysis then "nix-coverage" else "nix-build"
, failureHook ? null
, prePhases ? []
, postPhases ? []
, buildInputs ? []
, preHook ? ""
, postHook ? ""
, ... } @ args:
let
doingAnalysis = doCoverageAnalysis || doClangAnalysis || doCoverityAnalysis;
in
stdenv.mkDerivation (
{
# Also run a `make check'.
doCheck = true;
# When doing coverage analysis, we don't care about the result.
dontInstall = doingAnalysis;
useTempPrefix = doingAnalysis;
showBuildStats = true;
finalPhase =
''
# Propagate the release name of the source tarball. This is
# to get nice package names in channels.
if test -e $origSrc/nix-support/hydra-release-name; then
cp $origSrc/nix-support/hydra-release-name $out/nix-support/hydra-release-name
fi
# Package up Coverity analysis results
if [ ! -z "${toString doCoverityAnalysis}" ]; then
if [ -d "_coverity_$name/cov-int" ]; then
mkdir -p $out/tarballs
NAME=`cat $out/nix-support/hydra-release-name`
cd _coverity_$name
tar caf $out/tarballs/$NAME-coverity-int.xz cov-int
echo "file cov-build $out/tarballs/$NAME-coverity-int.xz" >> $out/nix-support/hydra-build-products
fi
fi
# Package up Clang analysis results
if [ ! -z "${toString doClangAnalysis}" ]; then
if [ ! -z "`ls _clang_analyze_$name`" ]; then
cd _clang_analyze_$name && mv * $out/analysis
else
mkdir -p $out/analysis
echo "No bugs found." >> $out/analysis/index.html
fi
echo "report analysis $out/analysis" >> $out/nix-support/hydra-build-products
fi
'';
failureHook = (lib.optionalString (failureHook != null) failureHook) +
''
if test -n "$succeedOnFailure"; then
if test -n "$keepBuildDirectory"; then
KEEPBUILDDIR="$out/`basename $TMPDIR`"
echo "Copying build directory to $KEEPBUILDDIR"
mkdir -p $KEEPBUILDDIR
cp -R "$TMPDIR/"* $KEEPBUILDDIR
fi
fi
'';
}
// removeAttrs args [ "lib" ] # Propagating lib causes the evaluation to fail, because lib is a function that can't be converted to a string
// {
name = name + (lib.optionalString (src ? version) "-${src.version}");
postHook = ''
. ${./functions.sh}
origSrc=$src
src=$(findTarball $src)
${postHook}
'';
preHook = ''
# Perform Coverity Analysis
if [ ! -z "${toString doCoverityAnalysis}" ]; then
shopt -s expand_aliases
mkdir _coverity_$name
alias make="cov-build --dir _coverity_$name/cov-int make"
fi
# Perform Clang Analysis
if [ ! -z "${toString doClangAnalysis}" ]; then
shopt -s expand_aliases
alias make="scan-build -o _clang_analyze_$name --html-title='Scan results for $name' make"
fi
${preHook}
'';
# Clean up after analysis
postBuild = ''
if [ ! -z "${toString (doCoverityAnalysis || doClangAnalysis)}" ]; then
unalias make
fi
'';
initPhase = ''
mkdir -p $out/nix-support
echo "$system" > $out/nix-support/system
if [ -z "${toString doingAnalysis}" ]; then
for i in $(getAllOutputNames); do
if [ "$i" = out ]; then j=none; else j="$i"; fi
mkdir -p ''${!i}/nix-support
echo "nix-build $j ''${!i}" >> ''${!i}/nix-support/hydra-build-products
done
fi
'';
prePhases = ["initPhase"] ++ prePhases;
buildInputs =
buildInputs ++
(lib.optional doCoverageAnalysis args.makeGCOVReport) ++
(lib.optional doClangAnalysis args.clang-analyzer) ++
(lib.optional doCoverityAnalysis args.cov-build) ++
(lib.optional doCoverityAnalysis args.xz);
lcovFilter = ["${builtins.storeDir}/*"] ++ lcovFilter;
inherit lcovExtraTraceFiles;
postPhases = postPhases ++ ["finalPhase"];
meta = (lib.optionalAttrs (args ? meta) args.meta) // {
description = if doCoverageAnalysis then "Coverage analysis" else "Nix package for ${stdenv.hostPlatform.system}";
};
}
//
(lib.optionalAttrs buildOutOfSourceTree
{
preConfigure =
# Build out of source tree and make the source tree read-only. This
# helps catch violations of the GNU Coding Standards (info
# "(standards) Configuration"), like `make distcheck' does.
'' mkdir "../build"
cd "../build"
configureScript="../$sourceRoot/configure"
chmod -R a-w "../$sourceRoot"
echo "building out of source tree, from \`$PWD'..."
${lib.optionalString (preConfigure != null) preConfigure}
'';
}
)
)