rizsotto / scan-build

Clang's scan-build re-implementation in python

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can't run scan-build on Windwos

fbs2016 opened this issue · comments

Install the scan-build on Windows.
Run command "scan-build make" on a make project, it report that "perl' is not recognize as a command".
It needs perl to run?
After I install perl on my host, run the command "scan-build make"
#user>perl -S scan-build make
scan-build: error: Cannot find an executable 'clang' relative to scan-build. Consider using --use-analyzer to pick a version of 'clang' to use for static analysis

The project is based on clang and can build it success.

For another command "intercept-build make" or "analyze-build"
It report err: failed to create process.

Could you help give me some advice? Thanks

.

Thanks for your message. It's an interesting case you've described... There are two tools called scan-build: one is in Clang, and the other one is this. (The name collision is intended, because I wanted to rewrite the Clang perl implementation into a python one and push to Clang upstream repo. The push failed. :) But the name remained the same.)

So, it sounds that you running the perl version. (Probably got installed with Clang on your computer.) And this tool is also got into your PATH, and it's not clear to me which one is got executed.

If you want to use the Clang version, and got problem with it, please report it in the Clang project. If you have problem with this tools, you are at the right place. :)

I don't have a Windows machine to reproduce the problem, but can help you. First I would recommend to ensure you execute this tool. (Either remove the Perl version. Or just review the PATH environment. Or rename this project artifact.) Then try to run it as intercept-build -vvvv make to produce the compilation database. (If you have that, analyze-build will run the static analyzer. That's easy to do and less likely will fail.) So, focus on the intercept part first and attach the verbose output to see where it fails.

Thanks.
The scan-build I have run before is under the llvm compiler path not the one we want.
I update the PATH to remove the perl path, and try to run the command "intercept-build make", it report the err "failed to create process.". Do you know the reason of this err? Thanks

Thanks to coming back. As far as I know, the "failed to create process: comes from the Python's subprocess library. On Linux, there is no difference between make or bear make, because Bear calls the subprocess.call, which calls an execvp, which checks the PATH environment and the execution goes well. So, I guess the problem now will be how Windows implementation treat the PATH variables.
The python subprocess docs (same link) mentions the it calls CreateProcess to execute the given program. This docs claims that CreateProcess will ignore the search path.
So, can you give the full path to make when you execute with Bear?

The make I use on my Windows host is generated by make source file not like mingw or others. And the make command can be recognized by the shell, and I can get the path by "which make" on my product shell on Windows host, like "D:/myProduct/bin/make.EXE".

Ok, then could you execute scan-build -vvvv D:/myProduct/bin/make.EXE and attach the output?

Thanks.
I re-install the scan-build by pip3.7 install which based on python 3.7, and I install it by pip install before. The err "failed to create process" has disappeared. But it can't generate the right *.json file, it's empty:

intercept-build -vvvv make all

{'ALLUSERSPROFILE': 'C:\ProgramData',
'APPDATA': 'C:\Users\xxx\AppData\Roaming',
...
environment variables
...
build command

It will generate the output file, but the database file is empty.
Is there any key points which I can check it? Thanks

Thanks to coming back. And glad to hear that the execution problem gone... Now it looks like that the Makefile does not respect the CC and CXX environment variables. In windows scan-build runs a compiler wrapper (which calls the real compiler plus doing something to record the execution). So, your make should execute the wrapper and not the compiler... The Makefile has to written in a way that it consider the CC environment when it calls the C compiler. For example, if you execute the CC=false make it should break the compilation when it tries to call the C compiler... Some Makefile are generated. That case you shall run the Makefile generator with scan-build too. Like scan-build ./configure and then call scan-build make.
If your project is open source, you can send me link to it, and I can hint you with more concrete advices what to try.

Thanks.
I just try a test project, and want to get the database file by command intercept-build.

D:\xxx\testPrj>intercept-build -vvvv make all
intercept-build: DEBUG: parse_args_for_intercept_build: Raw arguments ['D:\Program Files\python3.7\Scripts\intercept-build', '-vvvv', 'make', 'all']
intercept-build: DEBUG: parse_args_for_intercept_build: Parsed arguments: Namespace(append=False, build=['make', 'all'], cc='cc', cdb='compile_commands.json', cxx='c++
', override_compiler=False, verbose=4)
intercept-build: DEBUG: run_build: run build ['make', 'all'], in environment:
{'...

}

D:/xxxbin/clang -gdwarf-3 -m64 -mcmodel=large -fno-omit-frame-pointer -mno-red-zone -fno-strict-aliasing -fno-builtin -o test.o -c
"test.c"
make: built targets of D:/xxx/testPrj
intercept-build: DEBUG: run_build: build finished with exit code: 0

The project just includes a test.c file and the make file is like the following:
test.o :
D:/xxx/bin/clang -gdwarf-3 -m64 -mcmodel=large -fno-omit-frame-pointer -mno-red-zone -fno-strict-aliasing -fno-builtin -o test.o -c "test.c"
all : test.o
@echo "make: built targets of pwd"

The Makefile shall not call the clang directly. It should use CC instead of the compiler name.

test.o: test.c
  $(CC) -c $(CFLAGS) -o test.o test.c

all: test.o

Thanks a lot.
I set the CC and CFLAGS as environment variable, it works for the test project on Windows..
It generates the database:
[
{
"arguments": [
"cc",
"-c",
"-gdwarf-3",
"-m64",
"-mcmodel=large",
"-fno-omit-frame-pointer",
"-mno-red-zone",
"-fno-strict-aliasing",
"-fno-builtin",
"-o",
"test.o",
"test.c"
],
"directory": "D:\xxx\testPrj",
"file": "test.c"
}
]

And for my application project, it's more complex, and the compiler is " $(TOOL_PATH)/clang" in the makefile, not the variable $CC.
For generating the database, the compiler must be the variable $CC ? Thanks.

I try your another tool "Bear", it works well on Linux, which use the same project on Windows.

That's a good news! 😄 Yes, it will work only with the CC and CXX variables.

This is a kind of traditional way to call the compilers in Makefiles. Then you can replace it with a simple environment override. (That comes handy if you want to try a new compiler, or use ccache or distcc or analyzer wrappers like purify.) So, it's always recommended to define your C compiler as CC.

Closing this ticket now.

Thank you very much again.