diff --git a/pkgs/build-support/release/default.nix b/pkgs/build-support/release/default.nix index 3d593f0b6bb7..acad3487dad2 100644 --- a/pkgs/build-support/release/default.nix +++ b/pkgs/build-support/release/default.nix @@ -27,7 +27,7 @@ rec { } // args); coverageAnalysis = args: nixBuild ( - { inherit lcov; + { inherit lcov enableCoverageInstrumentation makeCoverageAnalysisReport; doCoverageAnalysis = true; } // args); diff --git a/pkgs/build-support/release/nix-build.nix b/pkgs/build-support/release/nix-build.nix index 88bafd84faa3..42533b0094aa 100644 --- a/pkgs/build-support/release/nix-build.nix +++ b/pkgs/build-support/release/nix-build.nix @@ -15,6 +15,7 @@ , failureHook ? null , prePhases ? [] , postPhases ? [] +, buildInputs ? [] , ... } @ args: stdenv.mkDerivation ( @@ -61,13 +62,6 @@ stdenv.mkDerivation ( . ${./functions.sh} origSrc=$src src=$(findTarballs $src | head -1) - - # Set GCC flags for coverage analysis, if desired. - if test -n "${toString doCoverageAnalysis}"; then - export NIX_CFLAGS_COMPILE="-O0 --coverage $NIX_CFLAGS_COMPILE" - export CFLAGS="-O0" - export CXXFLAGS="-O0" - fi ''; initPhase = '' @@ -85,30 +79,13 @@ stdenv.mkDerivation ( prePhases = ["initPhase"] ++ prePhases; - # 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 $lcovExtraTraceFiles -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 ""; - + buildInputs = buildInputs ++ [ args.makeCoverageAnalysisReport ]; lcovFilter = ["/nix/store/*"] ++ lcovFilter; inherit lcovExtraTraceFiles; - postPhases = postPhases ++ - (stdenv.lib.optional doCoverageAnalysis "coverageReportPhase") ++ ["finalPhase"]; + postPhases = postPhases ++ ["finalPhase"]; meta = (if args ? meta then args.meta else {}) // { description = if doCoverageAnalysis then "Coverage analysis" else "Nix package for ${stdenv.system}"; diff --git a/pkgs/build-support/setup-hooks/enable-coverage-instrumentation.sh b/pkgs/build-support/setup-hooks/enable-coverage-instrumentation.sh new file mode 100644 index 000000000000..08ef490e2447 --- /dev/null +++ b/pkgs/build-support/setup-hooks/enable-coverage-instrumentation.sh @@ -0,0 +1,14 @@ +# Force GCC to build with coverage instrumentation. Also disable +# optimisation, since it may confuse things. +export NIX_CFLAGS_COMPILE="$NIX_CFLAGS_COMPILE -O0 --coverage" + +# FIXME: Handle the case where postUnpack is already set. +postUnpack() { + # This is an uberhack to prevent libtool from remoaving gcno + # files. This has been fixed in libtool, but there are packages + # out there with old ltmain.sh scripts. See + # http://www.mail-archive.com/libtool@gnu.org/msg10725.html + for i in $(find -name ltmain.sh); do + substituteInPlace $i --replace '*.$objext)' '*.$objext | *.gcno)' + done +} diff --git a/pkgs/build-support/setup-hooks/make-coverage-analysis-report.sh b/pkgs/build-support/setup-hooks/make-coverage-analysis-report.sh new file mode 100644 index 000000000000..2951666651c6 --- /dev/null +++ b/pkgs/build-support/setup-hooks/make-coverage-analysis-report.sh @@ -0,0 +1,18 @@ +postPhases+=" coverageReportPhase" + +coverageReportPhase() { + lcov --directory . --capture --output-file app.info + set -o noglob + lcov --remove app.info $lcovFilter > app2.info + set +o noglob + mv app2.info app.info + + mkdir -p $out/coverage + genhtml app.info $lcovExtraTraceFiles -o $out/coverage > log + + # Grab the overall coverage percentage for use in release overviews. + mkdir -p $out/nix-support + grep "Overall coverage rate" log | sed 's/^.*(\(.*\)%).*$/\1/' > $out/nix-support/coverage-rate + + echo "report coverage $out/coverage" >> $out/nix-support/hydra-build-products +} diff --git a/pkgs/stdenv/adapters.nix b/pkgs/stdenv/adapters.nix index 3bac53411549..cb7e3ba925f5 100644 --- a/pkgs/stdenv/adapters.nix +++ b/pkgs/stdenv/adapters.nix @@ -231,29 +231,7 @@ rec { programs like lcov to produce pretty-printed reports. */ addCoverageInstrumentation = stdenv: - # Object files instrumented with coverage analysis write runtime - # coverage data to /.gcda, where is the - # location where gcc originally created the object file. That - # would be /tmp/nix-build-, which will be long gone by - # the time we run the program. Furthermore, the .gcno - # files created at compile time are also written there. And to - # make nice coverage reports with lcov, we need the source code. - # So we have to use the `keepBuildTree' adapter as well. - let stdenv' = cleanupBuildTree (keepBuildTree stdenv); in - { mkDerivation = args: stdenv'.mkDerivation (args // { - NIX_CFLAGS_COMPILE = toString (args.NIX_CFLAGS_COMPILE or "") + " -O0 --coverage"; - postUnpack = - '' - # This is an uberhack to prevent libtool from removing gcno - # files. This has been fixed in libtool, but there are - # packages out there with old ltmain.sh scripts. - # See http://www.mail-archive.com/libtool@gnu.org/msg10725.html - for i in $(find -name ltmain.sh); do - substituteInPlace $i --replace '*.$objext)' '*.$objext | *.gcno)' - done - '' + args.postUnpack or ""; - }); - }; + cleanupBuildTree (keepBuildTree (overrideInStdenv stdenv [ pkgs.enableCoverageInstrumentation ])); /* Replace the meta.maintainers field of a derivation. This is useful diff --git a/pkgs/stdenv/generic/default.nix b/pkgs/stdenv/generic/default.nix index 457eb29ee14b..6e74af5fce52 100644 --- a/pkgs/stdenv/generic/default.nix +++ b/pkgs/stdenv/generic/default.nix @@ -87,10 +87,10 @@ let userHook = config.stdenv.userHook or null; # Inputs built by the cross compiler. - buildInputs = lib.optionals (crossConfig != null) buildInputs ++ extraBuildInputs; + buildInputs = lib.optionals (crossConfig != null) (buildInputs ++ extraBuildInputs); propagatedBuildInputs = lib.optionals (crossConfig != null) propagatedBuildInputs; # Inputs built by the usual native compiler. - nativeBuildInputs = nativeBuildInputs ++ lib.optionals (crossConfig == null) buildInputs; + nativeBuildInputs = nativeBuildInputs ++ lib.optionals (crossConfig == null) (buildInputs ++ extraBuildInputs); propagatedNativeBuildInputs = propagatedNativeBuildInputs ++ lib.optionals (crossConfig == null) propagatedBuildInputs; }))) ( diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 1495372f6dac..bbc14656e8eb 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -396,6 +396,12 @@ let fixDarwinDylibNames = makeSetupHook { } ../build-support/setup-hooks/fix-darwin-dylib-names.sh; + enableCoverageInstrumentation = makeSetupHook { } ../build-support/setup-hooks/enable-coverage-instrumentation.sh; + + makeCoverageAnalysisReport = makeSetupHook + { deps = [ pkgs.lcov pkgs.enableCoverageInstrumentation ]; } + ../build-support/setup-hooks/make-coverage-analysis-report.sh; + ### TOOLS