diff --git a/pkgs/build-support/release/default.nix b/pkgs/build-support/release/default.nix new file mode 100644 index 00000000000..6156dd2933a --- /dev/null +++ b/pkgs/build-support/release/default.nix @@ -0,0 +1,20 @@ +{pkgs}: + +with pkgs; + +rec { + + makeSourceTarball = args: import ./make-source-tarball.nix + ({inherit stdenv autoconf automake libtool;} // args); + + nixBuild = args: import ./nix-build.nix ( + { inherit stdenv; + doCoverageAnalysis = false; + } // args); + + coverageAnalysis = args: nixBuild ( + { inherit lcov; + doCoverageAnalysis = true; + } // args); + +} \ No newline at end of file diff --git a/pkgs/build-support/release/make-source-tarball.nix b/pkgs/build-support/release/make-source-tarball.nix new file mode 100644 index 00000000000..b8cf88f517c --- /dev/null +++ b/pkgs/build-support/release/make-source-tarball.nix @@ -0,0 +1,100 @@ +# This function converts an un-Autoconfed source tarball (typically a +# checkout from a Subversion or CVS repository) into a source tarball +# by running `autoreconf', `configure' and `make dist'. + +args: with args; + +stdenv.mkDerivation ( + + # First, attributes that can be overriden by the caller (via args): + { + name = "source-tarball"; + + # By default, only configure and build a source distribution. + # Some packages can only build a distribution after a general + # `make' (or even `make install'). + dontBuild = true; + dontInstall = true; + doDist = true; + + # If we do install, install to a dummy location. + useTempPrefix = true; + + showBuildStats = true; + + phases = "unpackPhase patchPhase autoconfPhase configurePhase buildPhase installPhase checkPhase distPhase"; + } + + # Then, the caller-supplied attributes. + // args // + + # And finally, our own stuff. + { + src = src.path; + + buildInputs = + stdenv.lib.optionals (args ? buildInputs) args.buildInputs ++ + [autoconf automake]; + + postHook = '' + ensureDir $out/nix-support + ''; + + postUnpack = '' + # Set all source files to the current date. This is because Nix + # resets the timestamp on all files to 0 (1/1/1970), which some + # people don't like (in particular GNU tar prints harmless but + # frightening warnings about it). + touch now + touch -d "1970-01-01 00:00:00 UTC" then + find $sourceRoot ! -newer then -print0 | xargs -0r touch --reference now + eval "$nextPostUnpack" + ''; + + nextPostUnpack = if args ? postUnpack then args.postUnpack else ""; + + preConfigure = '' + # Some packages1 use the file `svn-revision' to construct the + # release name. + rev="${if src ? rev then toString src.rev else ""}" + if test -n "$rev"; then echo "$rev" > svn-revision; fi + eval "$nextPreConfigure" + ''; + + nextPreConfigure = if args ? preConfigure then args.preConfigure else ""; + + # Autoconfiscate the sources. + autoconfPhase = '' + eval "$preAutoconf" + + if test -f ./bootstrap; then ./bootstrap + elif test -f ./bootstrap.sh; then ./bootstrap.sh + elif test -f ./reconf; then ./reconf + elif test -f ./configure.in || test -f ./configure.ac; then + autoreconf --install --force --verbose + else + echo "No bootstrap, bootstrap.sh, configure.in or configure.ac. Assuming this is not an GNU Autotools package." + fi + + eval "$postAutoconf" + ''; + + # Cause distPhase to copy tar.bz2 in addition to tar.gz. + tarballs = "*.tar.gz *.tar.bz2"; + + postDist = '' + shopt -s nullglob + for i in $out/tarballs/*; do + echo "file source-dist $i" >> $out/nix-support/hydra-build-products + done + ''; # */ + + passthru = {inherit src;}; + + meta = { + description = "Build of a source distribution from a checkout"; + }; + + } + +) diff --git a/pkgs/build-support/release/nix-build.nix b/pkgs/build-support/release/nix-build.nix new file mode 100644 index 00000000000..aa026ac3a57 --- /dev/null +++ b/pkgs/build-support/release/nix-build.nix @@ -0,0 +1,91 @@ +# 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'. + +args: with args; + +stdenv.mkDerivation ( + + { + name = "nix-build"; + + # Also run a `make check'. + doCheck = true; + + # When doing coverage analysis, we don't care about the result. + dontInstall = doCoverageAnalysis; + + showBuildStats = true; + + lcovFilter = ["/nix/store/*"]; + + # Hack - swap checkPhase and installPhase (otherwise Stratego barfs). + phases = "unpackPhase patchPhase configurePhase buildPhase installPhase checkPhase fixupPhase distPhase ${if doCoverageAnalysis then "coverageReportPhase" else ""}"; + } + + // args // + + { + src = src.path; + + postHook = '' + ensureDir $out/nix-support + echo "$system" > $out/nix-support/system + + if test -z "${toString doCoverageAnalysis}"; then + echo "nix-build none $out" >> $out/nix-support/hydra-build-products + fi + + # If `src' is the result of a call to `makeSourceTarball', then it + # has a subdirectory containing the actual tarball(s). If there are + # multiple tarballs, just pick the first one. + echo $src + if test -d $src/tarballs; then + src=$(ls $src/tarballs/*.tar.bz2 $src/tarballs/*.tar.gz | sort | head -1) + fi + + # Hack to compress log files. Prevents (by pointer hiding!) + # unnecessary dependencies. + startLogWrite() { + # Use process substitution to send the FIFO output to both + # stdout and bzip2. + bash -c "tee >(bzip2 > \"$1\".bz2) < \"$2\"" & + logWriterPid=$! + } + + # Set GCC flags for coverage analysis, if desired. + if test -n "${toString doCoverageAnalysis}"; then + export NIX_CFLAGS_COMPILE="-O0 -fprofile-arcs -ftest-coverage $NIX_CFLAGS_COMPILE" + export CFLAGS="-O0" + export CXXFLAGS="-O0" + fi + + ''; # */ + + + # In the report phase, create a coverage analysis report. + coverageReportPhase = if doCoverageAnalysis then '' + ${args.lcov}/bin/lcov --directory . --capture --output-file app.info + set -o noglob + ${args.lcov}/bin/lcov --remove app.info $lcovFilter > app2.info + set +o noglob + mv app2.info app.info + mkdir $out/coverage + ${args.lcov}/bin/genhtml app.info -o $out/coverage > log + + # Grab the overall coverage percentage for use in release overviews. + grep "Overall coverage rate" log | sed 's/^.*(\(.*\)%).*$/\1/' > $out/nix-support/coverage-rate + + echo "report coverage $out/coverage" >> $out/nix-support/hydra-build-products + '' else ""; + + + meta = { + description = if doCoverageAnalysis then "Coverage analysis" else "Native Nix build"; + }; + + } +) diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 4ba22e2b872..50819014d09 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -470,6 +470,10 @@ let inherit pkgs; }; + releaseTools = import ../build-support/release/default.nix { + inherit pkgs; + }; + ### TOOLS