The LLVM static code analyzer
scan-build is easy to use, right? All you do is prepend
scan-build in front of your
make command. Well, there a certain circumstances where it will not work. For example, if your
Makefile was generated by Eclipse for your cross-compile, scan-build will output some error messages and report zero bugs. You may be wondering, why does scan-build work with other
Makefiles? To understand that, one must understand the inner workings of
scan-build. When one runs
make, it defines a bunch of rules and environmental variables. One such variable is the
CC variable, which is for defining the C-Compiler. It is good practice to define the
CC variable to the compiler (
CC := gcc) in the Makefile and use
$(CC) for the compile command. The
scan-build program works by inserting itself between the compile command, which is done by replacing the
CC variable with the clang analyzer.
First we should determine what targets supported by LLVM with the following command.
Since ARM is a supported target, we’ll assume we are cross-compiling for an embedded system without an OS.
If you run the following command, it will tell you what make sets
CC to. It will return
cc, which is really just
gcc—for the host machine. Therefore, we’ll need to set CC to the ARM cross-compiler in the Makefile.
make --print-data-base | grep '^CC ='
Anything clang doesn’t support will need to be changed. The following script converts the Eclipse generated Makefiles and source to ones that agree with
clang, which serves as an example of some of the changes needed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
#!/bin/bash echo "Setting CC variable to arm-none-eabi-gcc..." sed -i 's/RM := .*/&\nCC := arm-none-eabi-gcc/g' Debug/makefile echo "Replacing compiler with CC variable..." for mkfile in $(grep -rl --exclude=makefile arm-none-eabi-gcc Debug) do sed -i 's/arm-none-eabi-gcc/$(CC)/g' $mkfile done echo "replacing -Og with one clang recognizes..." for mkfile in $(grep -rl '\-Og' Debug) do sed -i 's/-Og/-O2/g' $mkfile done FIND='\([ \t]*\)\(.*:[ ]"r"[ ](\)\([a-zA-Z0-9_]*\)\()[ ]:[ ]"vfpcc");\)' REPLACE='#ifdef __clang__\n\1__builtin_arm_set_fpscr(\3);\n#else\n&\n#endif' echo "replacing vfpcc with clang builtin" for srcfile in $(grep -rl vfpcc .) do if [[ $srcfile != *$0 ]] then echo "add clang builtin for vfpcc $srcfile" sed -i 's/'"$FIND"'/'"$REPLACE"'/g' $srcfile fi done echo -e "you can use scan-build for analysis.\n\n"
Assuming you’re in the Eclipse project directory, you should be able to run the analyzer with the following command—after you’ve run the script above. If you run into errors, you’ll need to resolve them and eventually add the fixes to the script. For example, you might run to an ASM goto issue.
scan-build --use-cc=/usr/bin/arm-none-eabi-gcc --analyzer-target=arm-none-eabi make -C Debug