summary refs log tree commit diff
path: root/pkgs/build-support/release
diff options
context:
space:
mode:
authorAustin Seipp <aseipp@pobox.com>2014-05-02 13:26:41 -0500
committerAustin Seipp <aseipp@pobox.com>2014-05-02 14:07:37 -0500
commit76b05b163001a26807f3d2f52434b482777967c1 (patch)
tree50ada937f3ead2bfa27f09738daa7d4987053733 /pkgs/build-support/release
parent59528d9f0e7bef27acafe7cb6eaf5273aef2dcfa (diff)
downloadnixpkgs-76b05b163001a26807f3d2f52434b482777967c1.tar
nixpkgs-76b05b163001a26807f3d2f52434b482777967c1.tar.gz
nixpkgs-76b05b163001a26807f3d2f52434b482777967c1.tar.bz2
nixpkgs-76b05b163001a26807f3d2f52434b482777967c1.tar.lz
nixpkgs-76b05b163001a26807f3d2f52434b482777967c1.tar.xz
nixpkgs-76b05b163001a26807f3d2f52434b482777967c1.tar.zst
nixpkgs-76b05b163001a26807f3d2f52434b482777967c1.zip
releaseTools: add {clang,coverity}Analysis tools
These two expressions greatly simplify using the clang-analyzer or
Coverity static analyzer on your C/C++ projects. In fact, they are
identical to nixBuild in every way out of the box, and should 'Just
Work' providing your code can be compiled with Clang already.

The trick is that when running 'make', we actually just alias it to the
appropriate scan build tool, and add a post-build hook that will bundle
up the results appropriately and unalias it.

For Clang, we put the results in $out/analysis and add an 'analysis'
report to $out/nix-support/hydra-build-products pointing to the result
HTML - this means that if the analyzer finds any bugs, the HTML results
will automatically show up Hydra for easy viewing.

For Coverity, it's slightly different. Instead we run the build tool and
after we're done, we tar up the results in a format that Coverity Scan's
service understands. We put the tarball in $out/tarballs under the name
'foo-cov-int.xz' and add an entry for the file to hydra-build-products
as well for easy viewing.

Of course for Coverity you must then upload the build. A Hydra plugin to
do this is on the way, and it will automatically pick up the
cov-int.tar.xz for uploading.

Note that coverityAnalysis requires allowUnfree = true;, as well as the
cov-build tools, which you can download from https://scan.coverity.com -
they're not linked to your account or anything, it's just an annoying
registration wall.

Note this is a first draft. In particular, scan-build fixes the C/C++
compiler to be Clang, and it's perfectly reasonable to want to use Clang
for the analyzer but have scan-build invoke GCC instead.

Signed-off-by: Austin Seipp <aseipp@pobox.com>
Diffstat (limited to 'pkgs/build-support/release')
-rw-r--r--pkgs/build-support/release/default.nix10
-rw-r--r--pkgs/build-support/release/nix-build.nix63
2 files changed, 69 insertions, 4 deletions
diff --git a/pkgs/build-support/release/default.nix b/pkgs/build-support/release/default.nix
index 6288935ec2a..d36707dc60f 100644
--- a/pkgs/build-support/release/default.nix
+++ b/pkgs/build-support/release/default.nix
@@ -31,6 +31,16 @@ rec {
       doCoverageAnalysis = true;
     } // args);
 
+  clangAnalysis = args: nixBuild (
+    { inherit clangAnalyzer;
+      doClangAnalysis = true;
+    } // args);
+
+  coverityAnalysis = args: nixBuild (
+    { inherit cov-build xz;
+      doCoverityAnalysis = true;
+    } // args);
+
   gcovReport = args: import ./gcov-report.nix (
     { inherit runCommand lcov rsync;
     } // args);
diff --git a/pkgs/build-support/release/nix-build.nix b/pkgs/build-support/release/nix-build.nix
index 8ebae24c673..b80c9242ed2 100644
--- a/pkgs/build-support/release/nix-build.nix
+++ b/pkgs/build-support/release/nix-build.nix
@@ -8,6 +8,8 @@
 { buildOutOfSourceTree ? false
 , preConfigure ? null
 , doCoverageAnalysis ? false
+, doClangAnalysis ? false
+, doCoverityAnalysis ? false
 , lcovFilter ? []
 , lcovExtraTraceFiles ? []
 , src, stdenv
@@ -18,6 +20,9 @@
 , buildInputs ? []
 , ... } @ args:
 
+let
+  doingAnalysis = doCoverageAnalysis || doClangAnalysis || doCoverityAnalysis;
+in
 stdenv.mkDerivation (
 
   {
@@ -25,8 +30,8 @@ stdenv.mkDerivation (
     doCheck = true;
 
     # When doing coverage analysis, we don't care about the result.
-    dontInstall = doCoverageAnalysis;
-    useTempPrefix = doCoverageAnalysis;
+    dontInstall = doingAnalysis;
+    useTempPrefix = doingAnalysis;
 
     showBuildStats = true;
 
@@ -37,6 +42,29 @@ stdenv.mkDerivation (
         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 = (stdenv.lib.optionalString (failureHook != null) failureHook) +
@@ -64,11 +92,33 @@ stdenv.mkDerivation (
       src=$(findTarballs $src | head -1)
     '';
 
+    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
+    '';
+
+    # 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 doCoverageAnalysis}" ]; then
+      if [ -z "${toString doingAnalysis}" ]; then
           for i in $outputs; do
               if [ "$i" = out ]; then j=none; else j="$i"; fi
               mkdir -p ''${!i}/nix-support
@@ -79,7 +129,12 @@ stdenv.mkDerivation (
 
     prePhases = ["initPhase"] ++ prePhases;
 
-    buildInputs = buildInputs ++ stdenv.lib.optional doCoverageAnalysis args.makeGCOVReport;
+    buildInputs =
+      buildInputs ++
+      (stdenv.lib.optional doCoverageAnalysis args.makeGCOVReport) ++
+      (stdenv.lib.optional doClangAnalysis args.clangAnalyzer) ++
+      (stdenv.lib.optional doCoverityAnalysis args.cov-build) ++
+      (stdenv.lib.optional doCoverityAnalysis args.xz);
 
     lcovFilter = ["/nix/store/*"] ++ lcovFilter;