mingw build problems

I'm trying to cross-compile LLVM with build=, host=target=. I'm using
the following packages from Debian lenny:

mingw32 4.2.1.dfsg-1
mingw32-binutils 2.18.50-20080109-1
mingw32-runtime 3.13-1

The first problem I hit was when I configured with CC, CXX, AR and
RANLIB set to mingw cross-tools, but forgot to specify NM as well.
This resulted in a load of warnings that scrolled off the screen:

nm: AliasAnalysis.o: File format not recognized
nm: AliasAnalysisCounter.o: File format not recognized
nm: AliasAnalysisEvaluator.o: File format not recognized
nm: AliasDebugger.o: File format not recognized
nm: AliasSetTracker.o: File format not recognized
nm: Analysis.o: File format not recognized
...

followed by millions of undefined symbols when linking any executable:

llvm[2]: Linking Debug executable opt
/home/foad/llvm/objdir-mingw/tools/opt/Debug/AnalysisWrappers.o: In
function `~CallGraphPrinter':
/home/foad/svn/llvm-project/llvm/trunk/tools/opt/AnalysisWrappers.cpp:71:
undefined reference to `llvm::ModulePass::~ModulePass()'
/home/foad/svn/llvm-project/llvm/trunk/tools/opt/AnalysisWrappers.cpp:71:
undefined reference to `llvm::ModulePass::~ModulePass()'
/home/foad/llvm/objdir-mingw/tools/opt/Debug/AnalysisWrappers.o: In
function `~ExternalFunctionsPassedConstants':
/home/foad/svn/llvm-project/llvm/trunk/tools/opt/AnalysisWrappers.cpp:32:
undefined reference to `llvm::ModulePass::~ModulePass()'
/home/foad/svn/llvm-project/llvm/trunk/tools/opt/AnalysisWrappers.cpp:32:
undefined reference to `llvm::ModulePass::~ModulePass()'
/home/foad/llvm/objdir-mingw/tools/opt/Debug/AnalysisWrappers.o:AnalysisWrappers.cpp:(.debug_info+0x1ba6):
undefined reference to `llvm::CallGraphLinkVar'
...

The attached patch makes GenLibDeps.pl notice that nm has failed, so
that the build fails immediately rather than giving more obscure
errors later on.

Thanks,
Jay.

patch.die (892 Bytes)

The next problem I have is:

llvm[2]: Linking Debug executable opt
/home/foad/llvm/objdir-mingw/Debug/lib/libLLVMSystem.a(DynamicLibrary.o):/home/foad/svn/llvm-project/llvm/trunk/lib/System/Win32/DynamicLibrary.inc:179:
undefined reference to `___eprintf'
collect2: ld returned 1 exit status

I can work around this by removing the two references to __eprintf
from lib/System/Win32/DynamicLibrary.inc, but... why are they there in
the first place, and why don't I have __eprintf on my system?

I see that these references were introduced here:

http://llvm.org/viewvc/llvm-project?view=rev&revision=52037

but I don't understand what they are for. Do they let lli execute
programs in which the compiler has hard-coded calls to __eprintf? Does
that mean that __eprintf ought to be found in libgcc?

Thanks,
Jay.

Another observation: GettingStarted.html still gives these
instructions for cross-compiling LLVM:

   1. Configure and build LLVM as a native compiler. You will need
just TableGen from that build.
          * If you have $LLVM_OBJ_ROOT=$LLVM_SRC_ROOT just execute
make -C utils/TableGen after configuring.
          * Otherwise you will need to monitor building process and
terminate it just after TableGen was built.
   2. Copy the TableGen binary to somewhere safe (out of your build tree).
   3. Configure LLVM to build with a cross-compiler. To do this,
supply the configure script with --build and --host options that are
different. The values of these options must be legal target triples
that your GCC compiler supports.
   4. Put the saved TableGen executable into the into
$LLVM_OBJ_ROOT/{BUILD_TYPE}/bin directory (e.g. into .../Release/bin
for a Release build).
   5. Build LLVM as usual.

... but all this messing about with tblgen seems to be completely
unnecessary now, presumably since this commit:

http://llvm.org/viewvc/llvm-project?view=rev&revision=58981

Thanks,
Jay.

I can work around this by removing the two references to __eprintf
from lib/System/Win32/DynamicLibrary.inc, but... why are they there in
the first place, and why don't I have __eprintf on my system?

I see that these references were introduced here:

http://llvm.org/viewvc/llvm-project?view=rev&revision=52037

but I don't understand what they are for. Do they let lli execute
programs in which the compiler has hard-coded calls to __eprintf? Does
that mean that __eprintf ought to be found in libgcc?

Does it perhaps relate to the old
runtime/GCCLibraries/libgcc/eprintf.c, which was removed here:

http://llvm.org/viewvc/llvm-project?view=rev&revision=41257

?

Thanks,
Jay.

The next problem I have is:

llvm[2]: Linking Debug executable llc
/usr/lib/gcc/i586-mingw32msvc/4.2.1-sjlj/libstdc++.a(stubs.o):(.text+0x160):
multiple definition of `_powf'
/home/foad/llvm/objdir-mingw/Debug/lib/libLLVMCodeGen.a(RegAllocLinearScan.o):/usr/lib/gcc/i586-mingw32msvc/4.2.1-sjlj/../../../../i586-mingw32msvc/include/math.h:576:
first defined here
collect2: ld returned 1 exit status

math.h:576 says:

__CRT_INLINE float __cdecl powf (float x, float y)
  {return (float) pow (x, y);}

The definition of _powf in RegAllocLinearScan.o seems to be marked
with some LINK_ONCE_DISCARD and COMDAT stuff, so I assume multiple
such definitions shouldn't cause linker errors.

I don't know what libstdc++'s stubs.o is for. If I create a bodged
version of libstdc++ that doesn't include stubs.o, then llc links
successfully!

I've tried coming up with a small C++ app that gives the same linker
error, but so far without success.

Can anyone help?

Thanks,
Jay.

Jay Foad <jay.foad@gmail.com> writes:

Another observation: GettingStarted.html still gives these
instructions for cross-compiling LLVM:

[snip]

... but all this messing about with tblgen seems to be completely
unnecessary now, presumably since this commit:

http://llvm.org/viewvc/llvm-project?view=rev&revision=58981

The CMake build system also supports cross-compiling using the usual
cmake process. Time ago, while testing the cmake build, I found the same
problems as you. Anton indicated to me that there are issues with recent
mingw support on debian.

Hello, Jay

The first problem I hit was when I configured with CC, CXX, AR and
RANLIB set to mingw cross-tools, but forgot to specify NM as well.
This resulted in a load of warnings that scrolled off the screen:

Pretty strange I did not notice this problem before... Maybe because I have all-in-one binutils bult, which can recognize all variety of object formats.

Hello, Jay

The first problem I hit was when I configured with CC, CXX, AR and
RANLIB set to mingw cross-tools, but forgot to specify NM as well.
This resulted in a load of warnings that scrolled off the screen:

Why don't just set normal --host/--build/--target options? It will pick the proper tools for you.

Hello, Jay

but I don't understand what they are for. Do they let lli execute
programs in which the compiler has hard-coded calls to __eprintf? Does
that mean that __eprintf ought to be found in libgcc?

Yes. And I believe it was there, at least for "official mingw gcc", which is 3.4.5. Could you please investigate why you don't have this in your libgcc? Is it gcc v3 vs v4 issue?

Does it perhaps relate to the old
runtime/GCCLibraries/libgcc/eprintf.c, which was removed here:

http://llvm.org/viewvc/llvm-project?view=rev&revision=41257

Absolutely not.

Hello, Jay

I don't know what libstdc++'s stubs.o is for. If I create a bodged
version of libstdc++ that doesn't include stubs.o, then llc links
successfully!

I've tried coming up with a small C++ app that gives the same linker
error, but so far without success.

Sounds like broken compiler and/or mingw runtime. This perfectly explains, why mingw gcc 4.2.x is still considered as 'experimental'. What if you just try 3.4.6 instead?

Quite right. Fixed. Thanks for pointing that out!

-Jim

The first problem I hit was when I configured with CC, CXX, AR and
RANLIB set to mingw cross-tools, but forgot to specify NM as well.
This resulted in a load of warnings that scrolled off the screen:

Why don't just set normal --host/--build/--target options? It will
pick the proper tools for you.

Good point - thanks! I was using --host=mingw32, and I didn't know
that it would find the cross-tools automatically if I used
--host=i586-mingw32msvc.

Thanks,
Jay.

but I don't understand what they are for. Do they let lli execute
programs in which the compiler has hard-coded calls to __eprintf? Does
that mean that __eprintf ought to be found in libgcc?

Yes. And I believe it was there, at least for "official mingw gcc",
which is 3.4.5. Could you please investigate why you don't have this
in your libgcc? Is it gcc v3 vs v4 issue?

Debian's mingw32 libgcc.a doesn't have __eprintf in either of these versions:

3.4.5.20060117.1.dfsg-2
4.2.1.dfsg-1

These were the only versions I could find.

The official mingw32 libgcc.a does have __eprintf, in both of these versions:

gcc-3.4.5-20060117-3
gcc-4.3.0-20080502-mingw32-alpha

Thanks,
Jay.

but I don't understand what they are for. Do they let lli execute
programs in which the compiler has hard-coded calls to __eprintf? Does
that mean that __eprintf ought to be found in libgcc?

Yes. And I believe it was there, at least for "official mingw gcc",
which is 3.4.5. Could you please investigate why you don't have this
in your libgcc? Is it gcc v3 vs v4 issue?

GCC's gcc/configure has this logic:

# If this is using newlib, without having the headers available now,
# then define inhibit_libc in LIBGCC2_CFLAGS.
# This prevents libgcc2 from containing any code which requires libc
# support.
inhibit_libc=false
if { { test x$host != x$target && test "x$with_sysroot" = x ; } ||
       test x$with_newlib = xyes ; } &&
     { test "x$with_headers" = x || test "x$with_headers" = xno ; } ; then
       inhibit_libc=true
fi

Debian's mingw32 package is built with host != target, and without the
--with-sysroot and --with-headers options. So this logic kicks in, and
prevents __eprintf from being built in libgcc.a, since it calls into
libc.

From this discussion:

http://gcc.gnu.org/ml/gcc-patches/2001-05/msg00780.html

it sounds like only code built with GCC 2.x will refer to __eprintf.

Thanks,
Jay.

From this discussion:

Fergus Henderson - Re: Undefined "_eprintf"

it sounds like only code built with GCC 2.x will refer to __eprintf.

Also, the official MinGW gcc-2.95.3 package doesn't include an
assert.h, so it seems like MinGW has probably always used its own
assert.h, not the version GCC used to provide, so no code built with
MinGW would ever have referred to __eprintf. But I'm not 100% sure
about this and I can't actually test it.

Anyway, I'd vote for removing all references to __eprintf from
lib/System/Win32/DynamicLibrary.inc.

Thanks,
Jay.

Hello, Jay

Also, the official MinGW gcc-2.95.3 package doesn't include an
assert.h, so it seems like MinGW has probably always used its own
assert.h, not the version GCC used to provide, so no code built with
MinGW would ever have referred to __eprintf. But I'm not 100% sure
about this and I can't actually test it.

Thanks for tracking, this!

Anyway, I'd vote for removing all references to __eprintf from
lib/System/Win32/DynamicLibrary.inc.

Agree. Julien, what do you think?

The attached patch makes GenLibDeps.pl notice that nm has failed, so
that the build fails immediately rather than giving more obscure
errors later on.

Would you mind applying the patch?

Thanks,
Jay.

patch.die (892 Bytes)

Sure. But could you add a message to the "die" commands? Something like:

close DEFS or die "Could not close: $!";

?

-bw

That's fine with me. I'll test it once the change is made.

Thanks,
Julien