Trying to use CLang / CLang Static Analyzer under Windows XP SP3 32-bit

I'm trying to get CLang to run so that I can try out the CLang Static Analyzer.

I followed the instructions given in the "Using Visual Studio" section
of http://clang.llvm.org/get_started.html.

The ALL_BUILD Project built fine in Visual Studio 2008.

But when I try the first example I get:

clang t.c

clang: error: unable to execute command: program not executable
clang: error: assembler command failed due to signal 1 (use -v to see
invocation)

clang -v t.c

clang version 1.5 (trunk 100852)
Target: i686-pc-win32
Thread model: posix
"C:/llvm/bin/Debug/clang.exe" -cc1 -triple i686-pc-win32
-S -disable-free -main-file-name t.c -mrelocation-model static
-mdisable-fp-elim -mconstructor-aliases -v -resource-dir
C:/llvm/bin/lib/clang/1.5 -ferror-limit 19 -fmessage-length 80
-fms-extensions -fgnu-runtime -fdiagnostics-show-option
-fcolor-diagnostics -o C:/Temp/cc-000000.s -x c t.c
clang -cc1 version 1.5 based upon llvm 2.7svn hosted on i686-pc-win32
ignoring nonexistent directory "/usr/local/include"
ignoring nonexistent directory "/usr/include"
#include "..." search starts here:
#include <...> search starts here:
C:/llvm/bin/lib/clang/1.5/include
C:\Program Files\Microsoft Visual Studio 9.0\VC\include
C:\Program Files\Microsoft SDKs\Windows\v6.0A
End of search list.
"gcc" -v -c -o C:/Temp/cc-000001.o -x assembler C:/Temp/cc-000000.s
clang: error: unable to execute command: program not executable
clang: error: assembler command failed due to signal 1 (use -v to see
invocation)

I don't really want to use gcc (I happen to have cygwin installed, but
gcc is called gcc-3.exe or gcc-4.exe in cygwin\bin.)

I notice that the examples use the -cc1 option so I tried that:

clang -cc1 t.c

In file included from t.c:1:
In file included from C:\Program Files\Microsoft Visual Studio
9.0\VC\include/stdio.h:22:
C:\Program Files\Microsoft Visual Studio
9.0\VC\include/crtdefs.h:574:9: error: unknown type name '__int64'
typedef __int64 __time64_t; /* 64-bit time value */
        ^
In file included from t.c:1:
C:\Program Files\Microsoft Visual Studio
9.0\VC\include/stdio.h:268:77: error: unknown type name '__int64'
_Check_return_opt_ _CRTIMP int __cdecl _fseeki64(_Inout_ FILE * _File,
_In_ __int64 _Offset, _In_ int _Origin);
                                                                            ^
C:\Program Files\Microsoft Visual Studio
9.0\VC\include/stdio.h:269:24: error: unknown type name '__int64'
_Check_return_ _CRTIMP __int64 __cdecl _ftelli64(_Inout_ FILE * _File);
                       ^
C:\Program Files\Microsoft Visual Studio
9.0\VC\include/stdio.h:683:84: error: unknown type name '__int64'
_Check_return_opt_ _CRTIMP int __cdecl _fseeki64_nolock(_Inout_ FILE *
_File, _In_ __int64 _Offset, _In_ int _Origin);

   ^
C:\Program Files\Microsoft Visual Studio
9.0\VC\include/stdio.h:684:24: error: unknown type name '__int64'
_Check_return_ _CRTIMP __int64 __cdecl _ftelli64_nolock(_Inout_ FILE * _File);
                       ^
5 errors generated.

__int64 is a builtin VC++ keyword so it's not surprising that CLang
doesn't understand it.

but:

clang -cc1 -D__int64=int t.c

doesn't produce any output?

clang -cc1 -D__int64=int -v t.c

clang -cc1 version 1.5 based upon llvm 2.7svn hosted on i686-pc-win32
ignoring nonexistent directory "/usr/local/include"
ignoring nonexistent directory "/usr/include"
#include "..." search starts here:
#include <...> search starts here:
C:/llvm/bin/lib/clang/1.5/include
C:\Program Files\Microsoft Visual Studio 9.0\VC\include
C:\Program Files\Microsoft SDKs\Windows\v6.0A
End of search list.

No .exe is produced?

Taking a look at C:\llvm\tools\clang\tools\scan-build\scan-build

I gather that it's a perl script. Any chance this is going to work
with cygwin perl (or better yet ActiveState Perl), assuming I figure
out the clang issues?

Hello

I don't really want to use gcc

You should. clang calls gcc for assembling & linking.

I notice that the examples use the -cc1 option so I tried that:

-cc1 is an internal interface, you should not use it

Taking a look at C:\llvm\tools\clang\tools\scan-build\scan-build

I gather that it's a perl script. Any chance this is going to work
with cygwin perl (or better yet ActiveState Perl), assuming I figure
out the clang issues?

No, there are some changes wrt process spawning & stuff to make it
work at least with msys perl (and, I assume, for cygwin as well). No
idea for activestate perl, but it's safe to assume that more invasive
changes will be needed.

I'm trying to get CLang to run so that I can try out the CLang Static Analyzer.

I followed the instructions given in the "Using Visual Studio" section
of http://clang.llvm.org/get_started.html.

The ALL_BUILD Project built fine in Visual Studio 2008.

But when I try the first example I get:

clang t.c

clang: error: unable to execute command: program not executable
clang: error: assembler command failed due to signal 1 (use -v to see
invocation)

clang -v t.c

clang version 1.5 (trunk 100852)
Target: i686-pc-win32
Thread model: posix
"C:/llvm/bin/Debug/clang.exe" -cc1 -triple i686-pc-win32
-S -disable-free -main-file-name t.c -mrelocation-model static
-mdisable-fp-elim -mconstructor-aliases -v -resource-dir
C:/llvm/bin/lib/clang/1.5 -ferror-limit 19 -fmessage-length 80
-fms-extensions -fgnu-runtime -fdiagnostics-show-option
-fcolor-diagnostics -o C:/Temp/cc-000000.s -x c t.c
clang -cc1 version 1.5 based upon llvm 2.7svn hosted on i686-pc-win32
ignoring nonexistent directory "/usr/local/include"
ignoring nonexistent directory "/usr/include"
#include "..." search starts here:
#include <...> search starts here:
C:/llvm/bin/lib/clang/1.5/include
C:\Program Files\Microsoft Visual Studio 9.0\VC\include
C:\Program Files\Microsoft SDKs\Windows\v6.0A
End of search list.
"gcc" -v -c -o C:/Temp/cc-000001.o -x assembler C:/Temp/cc-000000.s
clang: error: unable to execute command: program not executable
clang: error: assembler command failed due to signal 1 (use -v to see
invocation)

I don't really want to use gcc (I happen to have cygwin installed, but
gcc is called gcc-3.exe or gcc-4.exe in cygwin\bin.)

That's the only way clang knows to assemble and link programs on
Windows at the moment. If you want to use some alternate way of
assembling/linking the output, pass -S to clang. Or you can use
something like -ccc-gcc-name gcc-4 as the first command-line option.
Or you can patch clang to support cygwin and/or mingw as and ld
directly. I'm not sure what "I don't really want to use gcc" means.

I notice that the examples use the -cc1 option so I tried that:

-cc1 is an internal interface; if you don't pass a very similar set of
options to what you see from clang -v, you're likely to run into
issues for general compilation. (On Windows in particular, I think
you need to pass -fms-extensions if clang is using MSVC headers.)

Taking a look at C:\llvm\tools\clang\tools\scan-build\scan-build

I gather that it's a perl script. Any chance this is going to work
with cygwin perl (or better yet ActiveState Perl), assuming I figure
out the clang issues?

I'm not familiar with the details, but there's no fundamental reason
why it shouldn't work.

-Eli

I've managed to get scan-build working on Windows XP Pro SP3 using a
Visual Studio 2008 built version of clang.exe. This post describes
what I had to do.

As others mentioned to my initial post, you have to use gcc (I was
under the mistaken impression that clang was a *replacement* for gcc).

First some things to note about trying to run the scan-build perl
script on Windows XP Pro SP3.

1). ActiveState perl doesn't work with scan-build.

The getpwuid function is unimplemented. Easy to get around by just faking it.
List form of pipe open not implemented, so it can't handle:

# Query clang for analysis options.
open(PIPE, "-|", $Clang, "-cc1", "-help") or
   DieDiag("Cannot execute '$Clang'\n");

Once I saw that error I gave up on trying to use ActiveState perl.

2). You can't run cygwin perl using the normal Windows XP command
prompt window (or JP Software's enhanced shell 4NT for that matter).
Things like `uname` or "system 'mkdir','-p',$NewDir;" don't work. You
have to use the cygwin bash shell.

3). In order to debug the perl fork() command (used inside
ccc-analyzer), you need to run perl -d inside an xterm window. This
means that you not only need xterm, but also X11. See
http://x.cygwin.com/ for installation instructions. Use the created
Start -> Cygwin-X -> XWin Server shortcut to start a resizable XTerm
window.

Then you can do the following:

perl /cygdrive/c/llvm/tools/clang/tools/scan-build/scan-build gcc t.c

or:

perl /cygdrive/c/llvm/tools/clang/tools/scan-build/scan-build gcc -v -v -v t.c

to get a bit more info on what's going on.

Once you get all that sorted out, you then will hit some bugs in
scan-build and ccc-analyzer.

First of all, it turns out that the following is *normal* for clean .c files:

ANALYZE: t.c main
scan-build: Removing directory '/tmp/scan-build-2010-04-15-3' because
it contains no reports.

So if there are no warnings or errors you see *nothing*. Therefore,
when first testing scan-build, make sure your small test file actually
has an error or two. Then you should see something like this:

ANALYZE: t.c main
t.c(7) : warning: Value stored to 'c' is never read
   c = a + b;
   ^ ~~~~~
t.c(7) : warning: The left operand of '+' is a garbage value
   c = a + b;
       ~ ^
2 warnings generated.
scan-build: 2 bugs found.
scan-build: Run 'scan-view /tmp/scan-build-2010-04-15-1' to examine
bug reports.

(where /tmp is actually c:\cygwin\tmp). I don't bother with scan-view,
I just open the index.html directly.

There are a number of problems in scan-build since it doesn't seem to
be in the place where it used to be (or maybe there's a symbolic link
that doesn't show up on Windows XP)?

Change:

my $ClangSB = Cwd::realpath("$RealBin/bin/clang");

to:

my $ClangSB = Cwd::realpath("$RealBin/../../../../bin/Debug/clang.exe");

(assuming you built a Debug version of clang with Visual Studio 2008)

Change:

my $AbsRealBin = Cwd::realpath($RealBin);
my $Cmd = "$AbsRealBin/libexec/ccc-analyzer";
my $CmdCXX = "$AbsRealBin/libexec/c++-analyzer";

To:

my $AbsRealBin = Cwd::realpath($RealBin);
my $Cmd = "$AbsRealBin/ccc-analyzer";
my $CmdCXX = "$AbsRealBin/c++-analyzer";

Change:

my $ScanView = Cwd::realpath("$RealBin/scan-view");

To:

my $ScanView = Cwd::realpath("$RealBin/../scan-view/scan-view");

in ccc-analyzer:

in sub GetCCArgs()

  chomp $line;
  $line =~ s/^\s+//;
  my @items = quotewords('\s+', 0, $line);

should be changed to:

  chomp $line;
  $line =~ s/^\s+//;
  $line =~ s/\cM//; #%%%% remove trailing carriage return
  my @items = quotewords('\s+', 0, $line);

Otherwise you get the following error:

Use of uninitialized value $CmdArgs[25] in exec at
/cygdrive/c/llvm/tools/clang/tools/scan-build/ccc-analyzer line 238.

The remaining problem is caused by sending cygwin style filenames to a
clang.exe built with Visual Studio 2008 (which doesn't understand such
things):

  if ($RunAnalyzer) {
    if (defined $ResultFile) {
      push @CmdArgs,'-o';
      push @CmdArgs, $ResultFile;
    }
    elsif (defined $HtmlDir) {
      push @CmdArgs,'-o';
      push @CmdArgs, $HtmlDir;
    }
  }

should be changed to:

  if ($RunAnalyzer) {
    if (defined $ResultFile) {
      push @CmdArgs,'-o';
      if ($ResultFile =~ m!^/cygdrive!) {
  $ResultFile =~ s!/cygdrive/(.)!$1:!i;
  }
      else {
  $ResultFile = "c:/cygwin$ResultFile";
  }

      push @CmdArgs, $ResultFile;
    }
    elsif (defined $HtmlDir) {
      push @CmdArgs,'-o';
      if ($HtmlDir =~ m!^/cygdrive!) {
  $HtmlDir =~ s!/cygdrive/(.)!$1:!i;
  }
      else {
  $HtmlDir = "c:/cygwin$HtmlDir";
  }
      push @CmdArgs, $HtmlDir;
    }
  }

Finally. I found that in order to debug ccc-analyzer, in scan-build's
RunBuildCommand(), I had to change:

    shift @$Args;
    unshift @$Args, $CCAnalyzer;

to:

    shift @$Args;
    unshift @$Args, $CCAnalyzer;
    unshift @$Args, "-d";
    unshift @$Args, "perl";

Then:

$DB::single = 1;

will break wherever I want in ccc-analyzer. Without the above change,
perl -d scan-build will debug scan-build, but *doesn't* stop at
$DB::single=1; statements inside ccc-analyzer. This is presumably
because ccc-analyzer is started via:

  return (system(@$Args) >> 8);

so the debugger doesn't know to also debug it unless explicitly told to?