Rebuilding LLVM libraries with LLVM-GCC on Windows

Hello again,

In order to avoid the set jump/long jump dependency of DLLs built under Visual C++, we're trying to build the libraries and tools under LLVM-GCC so it will use DWARF exception handling instead of SJ/LJ. The problem we're running into is that the libraries that we just finished creating cannot be found later in the build process when OPT tries to build. My partner has MinGW and MSYS installed on his system and we're trying to build version 2.5 of LLVM using CMake. Can anybody make recommendations on how to get this to work?

The basic reason we're doing this rather than taking the easy way out with MinGW's implementation of G++ for linking is that we want to be able to create a build script that can be called from an installer. The LLC command, the libraries it calls, the GAS assembler and LD linker and any other parts of the Binutils package used should be the only requirements for the solution. The bitcode we are trying to compile has already been linked by llvm-link but contains code that is written in C++.

--Sam Crow

Hello

In order to avoid the set jump/long jump dependency of DLLs built under Visual C++, we're trying to build the libraries and tools under LLVM-GCC so it will use DWARF exception handling instead of SJ/LJ. The problem we're running into is that the libraries that we just finished creating cannot be found later in the build process when OPT tries to build. My partner has MinGW and MSYS installed on his system and we're trying to build version 2.5 of LLVM using CMake. Can anybody make recommendations on how to get this to work?

There are two things to try:
1. Use 2.6 release (I believe mingw build with cmake definitely worked there)
2. Do not use cmake. Use normal configure + make process (this worked
since LLVM pre 1.8 iirc).

Some additional information about the setup may be of interest:

I'm using CMake to generate the make files for MSYS. All appears to go well until the tools are compiled.

The undefined references seem to be coming from the libraries that were just compiled:

../../lib/libLLVMBitReader.a(BitcodeReader.cpp.obj):fake:(.rdata$linkonce_ZTVN4llvm8ConstantE+0x10): undefined reference to `llvm::Value::dump() const'

Apparently it's not being linked with libLLVMCore.a among other libs.

The command line it's using is:

cd /C/Development/llvm-2.5/tools/opt && /C/Development/llvm-gcc/bin/llvm-g++.exe "CMakeFiles/opt.dir/AnalysisWrappers.cpp.obj" "CMakeFiles/opt.dir/GraphPrinters.cpp.obj" "CMakeFiles/opt.dir/PrintSCC.cpp.obj" "CMakeFiles/opt.dir/opt.cpp.obj" -o ../../bin/opt.exe -Wl,--out-implib,../../lib/libopt.dll.a -Wl,--major-image-version,0,--minor-image-version,0 ../../lib/libLLVMipo.a ../../lib/libLLVMScalarOpts.a ../../lib/libLLVMInstrumentation.a ../../lib/libLLVMBitWriter.a ../../lib/libLLVMBitReader.a -limagehlp -lpsapi -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32

Which clearly doesn't link against LLVMCore.

--Mike Ness

Is it consistent to have a Pass instance's run method's implementation use getAnalysisIfAvailable<AnalysisType>() (vs just using getAnalysis< AnalysisType >) when that same instance's getAnalysisUsage(AnalysisUsage &au) implementation invokes au.addRequired<AnalysisType>()?

For example in the implementation of SelectionDAGISel::runOnMachineFunction(...) (called from MachineFunctionPass::runOnFunction(...)):

DwarfWriter *DW = getAnalysisIfAvailable<DwarfWriter>();

is used vs:

DwarfWriter &DW = getAnalysis<DwarfWriter>();

even though SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) sets:

AU.addRequired<DwarfWriter>();

Since this occurs in 2.6 and trunk, and this pattern is repeated with other analysis passes, I'm wondering if I'm not understanding something.

Thanks in advance

Garrison

"Michael Ness" <mike@liquido2.com> writes:

Some additional information about the setup may be of interest:

I'm using CMake to generate the make files for MSYS. All appears to go well
until the tools are compiled.

The undefined references seem to be coming from the libraries that were just
compiled:

../../lib/libLLVMBitReader.a(BitcodeReader.cpp.obj):fake:(.rdata$linkonce_ZTVN4llvm8ConstantE+0x10):
undefined reference to `llvm::Value::dump() const'

Apparently it's not being linked with libLLVMCore.a among other libs.

What's the output of this command:

bin/llvm-config --libs "bitreader asmparser bitwriter instrumentation scalaropts ipo"

(executed from the root of your build directory)

Does it mention libLLVMCore ? From your command line it seems that CMake
was unable to determine the library dependencies. Either the
dependencies are wrong (hence the llvm-config check above) or the CMake
build is misinterpreting the output of llvm-config.

I don't know how well the LLVM cmake build worked for 2.5. In theory, it
should work the same way as for a unix host. In practice...

Hi!

If a pass is required then it makes sense to
getAnalysis<DwarfWriter>(). getAnalysisIfAvailable<>() is used for
cases where a pass want to take advantage of (or fix up) info only
*if* it is available.

If you prepare a patch to fix getAnalysisifAvailable<>() uses (e.g.
DwarfWriter requests you mention below) then I'll apply it.

Ok, I'll target this, if is not done by then, once I get a better understanding of the LLVM infrastructure. I currently seem to be spending most of my limited time reading LLVM source. Thanks for the clarification.

Garrison

Thanks Óscar,

I decided to forget 2.5 and move on to 2.6 which built fine with CMake. However, I continue to have problems with llvm-config when using the following command:

$ llvm-g++ out.s -o out `llvm-config --ldflags --libs core support system x86`

I consistently get undefined reference errors that are from libraries that should've been linked already. The errors change depending on the order of the components. There is obviously dependency issues--references to libs that have already been linked. How do I resolve these dependency problems?

Also, I'm unable to use "llvm-config --libs all" because I receive the error: "llvm-config: unknown component name: pic16codegen" llvm-config --components doesn't list pic16codegen, so I'm confused why it's included with --libs all.

--Mike Ness

"Michael Ness" <mike@liquido2.com> writes:

I decided to forget 2.5 and move on to 2.6 which built fine with CMake.
However, I continue to have problems with llvm-config when using the
following command:

$ llvm-g++ out.s -o out `llvm-config --ldflags --libs core support system
x86`

I consistently get undefined reference errors that are from libraries that
should've been linked already. The errors change depending on the order of
the components. There is obviously dependency issues--references to libs
that have already been linked. How do I resolve these dependency problems?

What's the output of

llvm-config --libs x86

?

Take a look at the $LLVM_BUILD_ROOT/bin/llvm-deps script and see if the
library dependencies listed at the end looks normal, i.e. every library
depends on other libraries, with Support and System on almost every
dependency list.

Also, I'm unable to use "llvm-config --libs all" because I receive the
error: "llvm-config: unknown component name: pic16codegen"
llvm-config --components doesn't list pic16codegen, so I'm confused why
it's included with --libs all.

Maybe there is a bug on the generation of library dependencies. This may
due to a faulty binutils or perl. Maybe there is a problem with the name
of some components too, they changed names on the last months.

What command line options do you pass to cmake? (variables, switches,
etc).

Ok, more recent developments follow. I updated my MSYS and MinGW install to use binutils 2.20 and gcc 4.4.0. With this I was able to build LLVM 2.6 with the following CMake configuration:

cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PIC=NO -DLLVM_ENABLE_THREADS=NO -G "MSYS Makefiles" ~/llvm-2.6-src

I also downloaded the llvm-gcc 4.2 binaries from llvm.org and used them to build an alternate llvm system using the following configuration:

cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PIC=NO -DLLVM_ENABLE_THREADS=NO -DCMAKE_C_COMPILER=llvm-gcc -DCMAKE_CXX_COMPILER=llvm-g++ -G "MSYS Makefiles" ~/llvm-2.6-src

llvm-config seems to work better in both builds (at least listing more dependencies). Using the gcc version:

$ llvm-config --libs x86
-lLLVMX86AsmParser -lLLVMX86AsmPrinter -lLLVMX86CodeGen -lLLVMSelectionDAG -lLLVMAsmPrinter
-lLLVMCodeGen -lLLVMScalarOpts -lLLVMTransformUtils -lLLVMipa -lLLVMAnalysis -lLLVMTarget -lLLVMMC
-lLLVMCore -lLLVMX86Info -lLLVMSupport -lLLVMSystem

and using the llvm-gcc version:

$ ~/llvm-2.6-gcc/bin/llvm-config --libs x86
-lLLVMX86AsmParser -lLLVMX86AsmPrinter -lLLVMX86CodeGen -lLLVMSelectionDAG -lLLVMAsmPrinter
-lLLVMCodeGen -lLLVMScalarOpts -lLLVMTransformUtils -lLLVMipa -lLLVMAnalysis -lLLVMTarget -lLLVMMC
-lLLVMCore -lLLVMX86Info -lLLVMSupport -lLLVMSystem

I then used both of these builds to attempt to assemble and link my project with llvm-g++:

$ llvm-g++ out.s -o out.exe `llvm-config --ldflags --libs x86 core system support`

gave me the errors found in the attached file "errors_gcc.txt". And

$ llvm-g++ out.s -o out.exe `~/llvm-2.6-gcc/bin/llvm-config --ldflags --libs x86 core system support`

gave me the errors found in the attached file "errors_llvm-gcc.txt".

I found it interesting that the attempt to link with the LLVM libs built with gcc caused several "multiple definition" errors, whereas the attempt to link with the libs built by llvm-gcc cause no multiple definitions but many more stdcall-fixup warnings.

Both attempts failed to link, citing llvm::Type::Int32Ty as unresolved among other things. Isn't llvm::Type in Core?

I appears I'm closer using the llvm-gcc build, but still unable to link everything correctly. Any other ideas?

Thanks,

--Mike

errors_gcc.txt (11 KB)

errors_llvm-gcc.txt (5.18 KB)

"Michael Ness" <mike@liquido2.com> writes:

[snip]

I then used both of these builds to attempt to assemble and link my
project with llvm-g++:

$ llvm-g++ out.s -o out.exe `llvm-config --ldflags --libs x86 core
system support`

gave me the errors found in the attached file "errors_gcc.txt". And

$ llvm-g++ out.s -o out.exe `~/llvm-2.6-gcc/bin/llvm-config --ldflags
--libs x86 core system support`

gave me the errors found in the attached file "errors_llvm-gcc.txt".

You are working with an assembler file. Why?

You don't need to enumerate the base libraries. Something like

llvm-config --ldflags --libs x86

should suffice. In the next message, please show the output of that
command. Maybe the `--ldflags' is adding stuff to the command line that
causes the problem. Try removing it.

I found it interesting that the attempt to link with the LLVM libs
built with gcc caused several "multiple definition" errors, whereas
the attempt to link with the libs built by llvm-gcc cause no multiple
definitions but many more stdcall-fixup warnings.

Was the assembler file generated by the same g++ you are using for
linking it and, previously, for building LLVM?

Both attempts failed to link, citing llvm::Type::Int32Ty as unresolved
among other things. Isn't llvm::Type in Core?

Yes.

I appears I'm closer using the llvm-gcc build, but still unable to
link everything correctly. Any other ideas?

As the LLVM tools builds file, I think that the problem is in how you
handle the build of your project. Or you are hitting a problem with
MinGW's binutils.

Have you access to other toolset for building your project (VC++, g++ on
Linux, etc.)? Have you tried using LLVM libraries created with
configure&make, as Anton suggested?

Hello, Everyone

Have you access to other toolset for building your project (VC++, g++ on
Linux, etc.)? Have you tried using LLVM libraries created with
configure&make, as Anton suggested?

One side note: ignore all "stdcall fixup" stuff - this is bug in the
backend I'm planning to fix for 2.7

"Michael Ness" <mike@liquido2.com> writes:

You are working with an assembler file. Why?

Here is the build process I'm using for my project: I have a program
written in LLVM assembly that is converted to bit code using llvm-as. I
have anther file written in C that is compiled to bit code using
llvm-gcc --emit-llvm. These two bit code files are then linked with
llvm-link and the resulting bit code is assembled with llc to yield the
assembly file I'm using.

You don't need to enumerate the base libraries. Something like

llvm-config --ldflags --libs x86

should suffice. In the next message, please show the output of that
command. Maybe the `--ldflags' is adding stuff to the command line that
causes the problem. Try removing it.

$ llvm-config --ldflags --libs x86
-L/home/Michael/llvm-2.6/lib -limagehlp -lpsapi -lLLVMX86AsmParser -lLLVMX86AsmPrinter
-lLLVMX86CodeGen
-lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMCodeGen -lLLVMScalarOpts -lLLVMTransformUtils
-lLLVMipa
-lLLVMAnalysis -lLLVMTarget -lLLVMMC -lLLVMCore -lLLVMX86Info -lLLVMSupport
-lLLVMSystem

Okay, try this command (after joining all the lines together):

llvm-g++ out.s -o out.exe -L/home/Michael/llvm-2.6/lib
-lLLVMX86AsmParser -lLLVMX86AsmPrinter -lLLVMX86CodeGen
-lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMCodeGen -lLLVMScalarOpts
-lLLVMTransformUtils -lLLVMipa -lLLVMAnalysis -lLLVMTarget -lLLVMMC
-lLLVMCore -lLLVMX86Info -lLLVMSupport -lLLVMSystem -lLLVMX86AsmParser
-lLLVMX86AsmPrinter -lLLVMX86CodeGen -lLLVMSelectionDAG -lLLVMAsmPrinter
-lLLVMCodeGen -lLLVMScalarOpts -lLLVMTransformUtils -lLLVMipa
-lLLVMAnalysis -lLLVMTarget -lLLVMMC -lLLVMCore -lLLVMX86Info
-lLLVMSupport -lLLVMSystem -limagehlp -lpsapi

Yes, the LLVM libraries are listed twice. And the system libraries are
moved to the end (this is required for avoiding an undefined reference).

Was the assembler file generated by the same g++ you are using for
linking it and, previously, for building LLVM?

No, the assembler file was generated by llvm-as. I did use the same
llvm-g++ to compile the C source file to bit code though.

Have you access to other toolset for building your project (VC++, g++ on
Linux, etc.)? Have you tried using LLVM libraries created with
configure&make, as Anton suggested?

I do have access to VC++ and Linux g++ and will attempt to build using these
tools.

Using VC++ with llvm-gcc may be tricky, but doable. Try Linux first.