[cfe-dev] using scan-build on osx 10.9 command line

Ted Kremenek kremenek at apple.com
Tue Dec 30 21:22:36 PST 2014


> On Dec 30, 2014, at 12:41 PM, James Burgess <jamesrburgess at mac.com> wrote:
> 
> Hi Ted,
> Thanks for the reply
> 
> (1) Yes, I can compile normally with gcc/g++. I use the command line tools for building a pretty sizable code base that is mostly c++. This is a very stock Mac, it had 10.9 when I tried this the first time but I’ve now updated to 10.10.1 and I get the same error. After upgrading to 10.10 I ran Xcode to see if it wanted to update, it did install something but it looks like the gcc/g++ report the same versions with a slight bump in the build number (clang-600.0.56)

Ok, this is what I thought.

> 
> 2) using -isysroot fixes the problem, success!
> 
> Now I’d like to integrate this into my own build system. I read that if I was using make/autoconf (which I am not) I could just set CC and CXX and the right thing would happen?
> 
> I can see scan-build doing the same but most of the script seems to be about building the report html, I’m guessing I’m going to need some of that script after my build is done. Does anyone know what would be the recipe if for doing that if I had a large pile of makefiles and I’d set CC and CXX before building?

The "-isysroot" option points the compiler to an SDK.  Normally when you run gcc (which really is 'clang' on newer OS X installations) it is a shim to run "xcrun clang", which in turns invokes clang with the proper SDK path.  scan-build is interposing on the Makefile's compiler, and invoking clang to run static analysis.  The clang it is using, however, is the clang that came with the checker tar file, and you're not getting the automatic SDK inference that happens when you run the system clang with no SDK option.

When Xcode (and xcodebuild) invokes clang it always passes an explicit "-isysroot" option, which is probably why nobody using the checker builds with Xcode projects has reported a problem.

I think you could hack your Makefile to include an explicit "-isysroot" for OTHER_CFLAGS, but I think this is unnecessary.  You are really working around a limitation in scan-build.

I think one of the following two things should happen:

(1) ccc-analyzer (which is the fake compiler driver invoked by scan-build) should add an implicit -isysroot when running clang when no -isysroot is provided.

(2) We change how scan-build does interposition of the compiler during build time to use a different method that doesn't guess what the host compiler would do, but observes it directly and replicates that logic.  Right now we interpose essentially at the build system level, which doesn't get all the implicit logic that the host compiler has.

I've hacked up a solution for #2.  Could you try copying the attached ccc-analyzer file into the 'libexec' directory of your untarred checker directory and see if that solves the problem.



Full disclosure:

$ git diff
diff --git a/tools/scan-build/ccc-analyzer b/tools/scan-build/ccc-analyzer
index 4c8f648..c993282 100755
--- a/tools/scan-build/ccc-analyzer
+++ b/tools/scan-build/ccc-analyzer
@@ -41,10 +41,14 @@ my $Clang;
 my $DefaultCCompiler;
 my $DefaultCXXCompiler;
 my $IsCXX;
+my $UseXCRUN = 0;

 if (`uname -a` =~ m/Darwin/) {
   $DefaultCCompiler = 'clang';
   $DefaultCXXCompiler = 'clang++';
+  if (-x "/usr/bin/xcrun") {
+    $UseXCRUN = 1;
+  }
 } else {
   $DefaultCCompiler = 'gcc';
   $DefaultCXXCompiler = 'g++';
@@ -478,6 +482,7 @@ my $HtmlDir = $ENV{'CCC_ANALYZER_HTML'};
 my %DisabledArchs = ('ppc' => 1, 'ppc64' => 1);
 my %ArchsSeen;
 my $HadArch = 0;
+my $HasSDK = 0;

 # Process the arguments.
 foreach (my $i = 0; $i < scalar(@ARGV); ++$i) {
@@ -500,6 +505,12 @@ foreach (my $i = 0; $i < scalar(@ARGV); ++$i) {
     next;
   }

+  # On OSX/iOS, record if an SDK path was specified.  This
+  # is innocuous for other platforms, so the check just happens.
+  if ($Arg =~ /^-isysroot/) {
+    $HasSDK = 1;
+  }
+
   # Options with possible arguments that should pass through to compiler.
   if (defined $CompileOptionMap{$ArgKey}) {
     my $Cnt = $CompileOptionMap{$ArgKey};
@@ -644,6 +655,15 @@ foreach (my $i = 0; $i < scalar(@ARGV); ++$i) {
   }
 }

+# If we are on OSX and have an installation where the
+# default SDK is inferred by xcrun use xcrun to infer
+# the SDK.
+if (not $HasSDK and $UseXCRUN) {
+  my $sdk = `/usr/bin/xcrun --show-sdk-path -sdk macosx`;
+  chomp $sdk;
+  push @CompileOpts, "-isysroot", $sdk;
+}
+
 if ($Action eq 'compile' or $Action eq 'link') {
   my @Archs = keys %ArchsSeen;
   # Skip the file if we don't support the architectures specified.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20141230/631587a8/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: ccc-analyzer
Type: application/octet-stream
Size: 19691 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20141230/631587a8/attachment.obj>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20141230/631587a8/attachment-0001.html>


More information about the cfe-dev mailing list