unclear about how to correctly run scan-build through make

If I run scan-build on one file manually I get a report directory created as expected:

cat t.C

int * foo(){ int x ; return &x ;}

scan-build -o $HOME/scan-build --use-analyzer=which clang clang++ t.C -c

scan-build: Using ‘/home/peeterj/clang/optimized/bin/clang’ for static analysis
t.C:1:30: warning: address of stack memory associated with local variable ‘x’ returned [-Wreturn-stack-address]
int * foo(){ int x ; return &x ;}
^
1 warning generated.
t.C:1:22: warning: Address of stack memory associated with local variable ‘x’ returned to caller
int * foo(){ int x ; return &x ;}

1 warning generated.
scan-build: 1 bugs found.
scan-build: Run 'scan-view /home/peeterj/scan-build/2012-12-12-3' to examine bug reports.

However, if I run this using a make rule, I see scan-build invoke make, but get the "contains no reports" message:

# rm *.o

# cat makefile
t.o : t.C
clang++ t.C -c

# scan-build -o $HOME/scan-build --use-analyzer=`which clang` make

scan-build: Using '/home/peeterj/clang/optimized/bin/clang' for static analysis
clang++ t.C -c
t.C:1:30: warning: address of stack memory associated with local variable 'x' returned [-Wreturn-stack-address]
int * foo(){ int x ; return &x ;}
^
1 warning generated.
scan-build: Removing directory '/home/peeterj/scan-build/2012-12-12-4' because it contains no reports.

From the scan-build man page, it appears that this is how to use this utility, but doing so just results in make being called as is. In what way is the makefile for the project supposed to be modified to use scan-build?

scan-build works by substituting a dummy CC and CXX to interpose on your build system. Your makefile needs to either use these variables, or you need to reconfigure through scan-build. From http://clang-analyzer.llvm.org/scan-build.html:

The reason configure also needs to be run through scan-build is because scan-build scans your source files by interposing on the compiler. This interposition is currently done by scan-build temporarily setting the environment variable CC to ccc-analyzer. The program ccc-analyzer acts like a fake compiler, forwarding its command line arguments over to the compiler to perform regular compilation and clang to perform static analysis.

By default, scan-build will use GCC to compile things on non-Darwin platforms. To override this, you can use the --use-cc and --use-c++ options (same as --use-analyzer).

Does that fix your problem?
Jordan

IIRC, scan-build works by setting CC, CXX etc. environment variables.
Since your Makefile does not use these, static analyzer is not being
run.

Dmitri

Thanks, that’s the key. Could this be added to the scan-build docs?

Clarification. This info is in the web page docs (that I didn't think of
looking at), but not in scan-build.1, nor the output of scan-build -h. It
would be good to consolidate the three of these.

It’s there on the analyzer site, under “Command Line Usage”:

scan-build has little or no knowledge about how you build your code. It works by overriding the CC and CXX environment variables to (hopefully) change your build to use a “fake” compiler instead of the one that would normally build your project. This fake compiler executes either clang or gcc (depending on the platform) to compile your code and then executes the static analyzer to analyze your code.

The reason configure also needs to be run through scan-build is because scan-build scans your source files by interposing on the compiler. This interposition is currently done by scan-build temporarily setting the environment variable CC to ccc-analyzer. The programccc-analyzer acts like a fake compiler, forwarding its command line arguments over to the compiler to perform regular compilation andclang to perform static analysis.

I guess we should throw a link to that page into the downloadable “checker” package, and possibly into scan-build itself.

Jordan

Oh right, we do have a man page. Yes, we should update that.