Cross-compiling cairo for x86_64-w64 with mingw - linker

I have an application that links again SDL and cairo that I would like to cross-compile on ubuntu for win64. I used this excellent blog post to get SDL cross compiling and I've used another blog post to cross-compile zlib, libpng and libpixman.
However, I now get a linker error trying to compile my minimal test program:
$ make cairotest.exe
x86_64-w64-mingw32-gcc -o cairotest.o -c cairotest.c -I/usr/x86_64-w64-mingw32/include/SDL2 -Dmain=SDL_main -I/home/jshaw/x86_64-w64/include/cairo -I/home/jshaw/x86_64-w64/include/pixman-1 -I/home/jshaw/x86_64-w64/include/libpng16
x86_64-w64-mingw32-gcc -o cairotest.exe cairotest.o -L/usr/x86_64-w64-mingw32/lib -lmingw32 -lSDL2main -lSDL2 -mwindows -L/home/jshaw/x86_64-w64/lib -lcairo
collect2: error: ld returned 1 exit status
Makefile:13: recipe for target 'cairotest.exe' failed
I should mention that this test program works correctly if I just use SDL2 without any cairo code, so I suspect something is wrong with the cairo library that I cross-compiled. How should I go about diagnosing the problem?

Looking at your Makefile it appears as though your are using normal pkg-config for discovering your Cairo libs. CAIRO_LDFLAGS := $(shell $(PKG_CONFIG) cairo --libs). This will find the path to your host libraries, which is presumably a different architecture than the target. An architecture mismatch like that can really cause strange problems with the linker. I believe you should be looking for something like usr/x86_64-w64-mingw32/bin/pkg-config.
Other things to try;
Run the compilation commands manually, as the makefile could be suppressing output.
Also, when running the command, add the -v flag to the command line to get the verbose output to better figure out where the issue is.

Related

glib in cross compiling for raspberry pi c

I'm trying to compile a program with glib. I set up all the include paths so compilation goes through without errors but linker can't find glib.
Invoking: Cross GCC Linker
arm-linux-gnueabihf-gcc -L/home/ja/raspberrypi/rootfs/usr/local/lib -L/home/ja/raspberrypi/rootfs/lib/arm-linux-gnueabihf -o "daemon_test" ./src/gpio/gpio.o ./src/can/can_stuff.o ./src/can/libsocketcan.o ./src/daemon_test.o -lglib-2.0 -lwiringPi
/home/ja/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../lib/gcc/arm-linux-gnueabihf/4.8.3/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lglib-2.0
makefile:32: recipe for target 'daemon_test' failed
collect2: error: ld returned 1 exit status
make: *** [daemon_test] Error 1
I have a cross compiler set up for my raspberry pi. it's composed of eclipse and a gcc compiler running on debian.
it seems obvious that the linker can't find the proper file.
On my target raspberry pi I've installed libglib2.0-dev and a test program builds fine. So I used rsync to update my cross compiler's rootfs
rsync -rl --delete-after --safe-links pi#192.168.2.160:/{lib,usr,opt} $HOME/raspberrypi/rootfs
my include paths are set to the same values as come out from pkg-config on my rpi(adjusted for rootfs location)
pkg-config --libs --cflags glib-2.0
as I was writing this I did a search for "libglib" on both rpi and my cross compiler. there's a libglib-2.0.so on my rpi, but in my crosscompiler it's a libglib-2.0.so.0, they are both same size.
I removed the ".0" and got a new error
warning: libpcre.so.3, needed by /home/ja/raspberrypi/rootfs/lib/arm-linux-gnueabihf/libglib-2.0.so, not found (try using -rpath or -rpath-link)
and a bunch of undefined refferences. the thing is, that file exists in the same location as libglib-2.0.so(renamed form libglib-2.0.so.0)
-L/home/ja/raspberrypi/rootfs/lib/arm-linux-gnueabihf
anyone has any ideas what to do? I spent my whole day on this..

How do I make the MinGW cross compiler use the same libraries as gcc?

My program uses the GNU Multiple Precision Arithmetic Library to deal with numbers of an arbitrary size. I successfully compile it using GCC with:
gcc main.c -o diff -g -lgmp
However, when I try to use the MinGW crosscompiler compiler, I get the following error:
i686-w64-mingw32-gcc main.c -o diff.exe -g -lgmp
main.c:3:46: fatal error: gmp.h: No such file or directory
#include <gmp.h>//For files of arbitrary size
I then tried to tell it exactly where the header file was:
i686-w64-mingw32-gcc main.c -o diff.exe -I/usr/include -g -lgmp
/usr/lib/gcc/i686-w64-mingw32/4.9.2/../../../../i686-w64-mingw32/bin/ld: cannot find -lgmp
collect2: error: ld returned 1 exit status
Ok, so I figure now it successfully found the header, but cant find the library. So I tried again:
i686-w64-mingw32-gcc main.c -o diff.exe -I/usr/include -g -L/usr/lib -lgmp
/usr/lib/gcc/i686-w64-mingw32/4.9.2/../../../../i686-w64-mingw32/bin/ld: cannot find -lgmp
collect2: error: ld returned 1 exit status
I guess I need to specify the exact files to use, so I tried this:
i686-w64-mingw32-gcc main.c -o diff.exe -I/usr/include -g /usr/lib/libgmp.so
/usr/lib/libgmp.so: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
So, I honestly don't know what to do and I'd really really appreciate your help.
First, a disclaimer: the cross-compiler you are using is neither distributed by, nor supported by MinGW.org, whom I represent; if you are looking for a pre-compiled solution, you should seek it from the distributor of the specific cross-compiler itself.
That said, I can offer the following insight, (which will apply, in general, to any cross-compiler): the headers you find in /usr/include, or in /usr/local/include, and the libgmp.so which you find in /usr/lib, or in /usr/local/lib, are intended for use with your native platform compiler. They are not suitable for, and cannot be used with your MinGW cross-compiler; attempting to do so will surely never work. Thus, you have two options:
Ask your cross-compiler distributor to provide a pre-compiled copy of gmp.dll, (or at the very least, a compatible import library, although you may need the gmp.dll to distribute with your own application anyway), and any associated header files, and/or equivalent statically linkable library, for use with your cross-compiler.
Use your cross-compiler to build gmp.dll yourself, then install it, its associated headers, and perhaps also its associated import library and/or equivalent statically linkable library, into the same prefix-path as the cross-compiler itself.

PJSIP Application linking error

I'm trying to write a very small, very simple project using PJSIP. But I'm already stuck on the first step, incorporating PJSIP in my project. I'm trying to build and compile on a Ubuntu 14.04 system using an arm-linux-gnueabihf-gcc cross compiler. For the coding itself I'm using Eclipse CDT, but the crosscompiling part is working in a normal order.
I downloaded de pjproject-2.3 folder to my system, configured it with this command:
./configure --host=arm-linux-gnueabihf CFLAGS='--sysroot=/home/david/rpi/rootfs' LDFLAGS='--sysroot=/home/david/rpi/rootfs'
The /home/david/rpi/rootfs folder is where I copied the rootsystem of my Pi. I then ran 'make dep' and 'make'. I copied all the static libraries *.a to my Eclipse project folder and added the libraries to the linker (-l).
But when I want to build I get the following error:
Invoking: Cross G++ Linker
arm-linux-gnueabihf-g++ -L"/home/david/workspace/VoIPBenchmark" -L/home/david/rpi/rootfs/usr/lib -L/home/david/rpi/rootfs/usr/lib/arm-linux-gnueabihf --sysroot=/home/david/rpi/rootfs/ -o "VoIPBenchmark" ./src/SipImplemantation.o ./src/SipImplementationPJ.o ./src/Timer.o ./main.o -lpjsua2-arm-unknown-linux-gnueabihf -lpjsua-arm-unknown-linux-gnueabihf -lpjsip-ua-arm-unknown-linux-gnueabihf -lpjsip-simple-arm-unknown-linux-gnueabihf -lpjsip-arm-unknown-linux-gnueabihf -lpjsdp-arm-unknown-linux-gnueabihf -lpjmedia-audiodev-arm-unknown-linux-gnueabihf -lportaudio-arm-unknown-linux-gnueabihf -lpjmedia-codec-arm-unknown-linux-gnueabihf -lpjmedia-arm-unknown-linux-gnueabihf -lspeex-arm-unknown-linux-gnueabihf -lgsmcodec-arm-unknown-linux-gnueabihf -lsrtp-arm-unknown-linux-gnueabihf -lilbccodec-arm-unknown-linux-gnueabihf -lresample-arm-unknown-linux-gnueabihf -lpjnath-arm-unknown-linux-gnueabihf -lpjlib-util-arm-unknown-linux-gnueabihf -lpj-arm-unknown-linux-gnueabihf -lpthread -lm -lrt -lasound -llinphone
/home/david/rpi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../lib/gcc/arm-linux-gnueabihf/4.8.3/../../../../arm-linux-gnueabihf/bin/ld: /home/david/workspace/VoIPBenchmark/libsrtp-arm-unknown-linux-gnueabihf.a(ctr_prng.o)(.text+0x8c): unresolvable R_ARM_ABS32 relocation against symbol `ctr_prng'
/home/david/rpi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/../lib/gcc/arm-linux-gnueabihf/4.8.3/../../../../arm-linux-gnueabihf/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
make: *** [VoIPBenchmark] Error 1
I googled some and tried to add -fPIC in the ./configure step above, recopied the libraries, but without result. Does anyone know what this message is saying me, and better yet, knows a solution?
This problem has been resolved. I was using a library that also linked to the srtp library, this evidently conflicted. So I am now not using the library that causes the problem.

How do I link GLFW

I am trying to link GLFW to my C program.
The docs seem to suggest #include<GLFW/glfw3.h> however I have installed 2.7.2 (from my distro's repository) and don't have that header file:
find / -name *glfw* 2> /dev/null
/usr/lib/libglfw.so.2.6
/usr/lib/libglfw.a
/usr/lib/libglfw.so
/usr/lib/pkgconfig/libglfw.pc
/usr/lib/libglfw.so.2
/usr/include/GL/glfw.h
/usr/share/doc/libglfw-dev
/usr/share/doc/libglfw2
/var/cache/apt/archives/libglfw2_2.7.2-1_i386.deb
/var/cache/apt/archives/libglfw-dev_2.7.2-1_i386.deb
/var/lib/dpkg/info/libglfw2.list
/var/lib/dpkg/info/libglfw2.postinst
/var/lib/dpkg/info/libglfw-dev.md5sums
/var/lib/dpkg/info/libglfw2.postrm
/var/lib/dpkg/info/libglfw2.md5sums
/var/lib/dpkg/info/libglfw2.shlibs
/var/lib/dpkg/info/libglfw-dev.list
I tried #include<GL/glfw.h> but I still get undefined reference to 'glfwLoadTexture2D'
How do I link to GLFW and use glfwLoadTexture2D()?
An #include does nothing for the linker; it just brings in declarations, not the actual functions.
The documentation indicates that GLFW uses pkg-config (not surprising; #elmindreda knows her stuff), so your compilation line should be something like:
$ cc `pkg-config --cflags glfw3` -o foo foo.c `pkg-config --static --libs glfw3`
Also note that since the library uses pkg-config, you're not supposed to "care" about details such as where the header and library files are located on your particular installation. Just ask using the --cflags and --libs modes, and you will get the proper locations returned, as the example above indicates.
You are mixing up compilation and linking. If you were missing headers, you would probably have errors a lot sooner than the linking stage.
"Undefined reference" results from symbols not being found by the linker. The most likely cause is you not telling gcc that it should link to the GLFW libraries:
gcc myfile.c -lglfw
When I am on Linux, I compile opengl/glfw projects like this:
gcc main.c -lGL -lglfw
When I am on windows, I compile them by writing:
gcc main.c libglfw3.a -lopengl32 -lgdi32
and I put libglfw3.a file in the same directory where main.c is. I have read people say that they couldn't link properly before writing
-lopengl32 -lgdi32 -luser32 -lkernel32 -lws2_32.
Another thing which may be worth mentioning is that I couldn't link glfw libraries when I downloaded 32bit glfw binaries. When I downloaded 64bit glfw binaries everything worked fine. I have a 64 bit machine and a x86_64-w64-mingw32. I have read comments from people with the opposite experience, where they weren't able to link glfw libraries when they downloaded 64bit binaries, but they were able to link them after downloading 32bit binaries. My advice would be to try both.

Clang link-time optimization doesn't work properly on Fedora 18

I'm a newcomer to clang, so it's likely I'm doing something silly. But I've spent several hours looking for solutions, including searching here, where I haven't found questions addressing -flto with distro-provided packages. The detail of this description are specific to Fedora 18, but I'm having similar problems on Ubuntu 13.04, so the problem isn't specific to Fedora. It's either me or clang.
Problem: I'm trying to compile a simple hello-world program using clang++ -flto to get the benefits of link-time-optimization. Without -flto it works fine. With -flto it fails to link. Invoking as clang -flto -o hello hello.o -v to see the full linker command line, I get:
$ clang++ -flto -o hello hello.o -v
clang version 3.2 (tags/RELEASE_32/final)
Target: x86_64-redhat-linux-gnu
Thread model: posix
"/usr/bin/ld" --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o hello /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.7.2/crtbegin.o -L/usr/lib/gcc/x86_64-redhat-linux/4.7.2 -L/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../.. -L/lib -L/usr/lib -plugin /usr/bin/../lib/LLVMgold.so hello.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-redhat-linux/4.7.2/crtend.o /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib64/crtn.o
/usr/bin/ld: /usr/bin/../lib/LLVMgold.so: error loading plugin
/usr/bin/ld: /usr/bin/../lib/LLVMgold.so: error in plugin cleanup (ignored)
clang: error: linker command failed with exit code 1 (use -v to see invocation)
There seem to be two problems:
clang++ invokes the linker as /usr/bin/ld, and that's not the gold linker. Fedora18 installs gold as /usr/bin/ld.gold. I've tried creating a symlink from /usr/local/bin/ld to /usr/bin/ld.gold, verified that which ld says /usr/local/bin/ld, but clang++ doesn't use that. It seems to be hardwired to /usr/bin/ld.
clang++ invoked the linker with -plugin /usr/bin/../lib/LLVMgold.so. That's wrong, as the Fedora distribution of clang places it at /usr/lib64/llvm/LLVMgold.so.
I have tried manually invoking that linker line above with the following tweaks:
Replace -plugin /usr/bin/../lib/LLVMgold.so with -plugin /usr/lib64/llvm/LLVMgold.so. This yields the error message hello.o: file not recognized: File format not recognized. So the non-gold linker seems to know about plugins but wont take the .o's which contain LLVM bitcode.
Replace /usr/bin/ld with /usr/bin/ld.gold. This works, generates an executable that runs as expected.
Both of the above with --plugin instead of -plugin. This change makes no difference.
So what's the best way for somebody who prefers to stick to the system-provided packages to use clang -flto? I'm hoping there is a config file, or undocumented options or environment variables that will let me override these. Or better, that I'm missing a package and a "yum install ..." will fix it.
I would prefer not to invoke the linker directly, as then my makefiles need to know system objects and libraries that they should be ignorant of (e.g. crt1.o, crtbegin.o, crtend.o). I could also build clang myself, but I'm not seeing anything in its configure script that lets me configure the path of the linker and plugin.
I'm running Fedora 18. The only non-distro packages on the computer are google chrome and VMware Tools (it's a guest inside VMWare Fusion). Versions of relevant Fedora packages (the whole computer is "yum updated" as of today, 29-Apr-2013):
$ yum list --noplugins installed binutils* clang* llvm* gcc*
Installed Packages
binutils.x86_64 2.23.51.0.1-6.fc18 #updates
binutils-devel.x86_64 2.23.51.0.1-6.fc18 #updates
clang.x86_64 3.2-2.fc18 #updates
clang-devel.x86_64 3.2-2.fc18 #updates
clang-doc.noarch 3.2-2.fc18 #updates
gcc.x86_64 4.7.2-8.fc18 #fedora
gcc-c++.x86_64 4.7.2-8.fc18 #fedora
llvm.x86_64 3.2-2.fc18 #updates
llvm-libs.x86_64 3.2-2.fc18 #updates
There is an utility alternatives in Fedora - it allows to subtitute one linker with another on system level:
$ sudo alternatives --display ld
ld - status is auto.
link currently points to /usr/bin/ld.bfd
/usr/bin/ld.bfd - priority 50
/usr/bin/ld.gold - priority 30
Current `best' version is /usr/bin/ld.bfd.
$ sudo alternatives --set ld /usr/bin/ld.gold
About LLVMgold.so location you can only report a bug in Fedora Bugzilla, since the path is built-in in clang sources:
lib/Driver/Tools.cpp: std::string Plugin = ToolChain.getDriver().Dir + "/../lib/LLVMgold.so";
Fedora guys may apply a patch to the Clang's source package, or create a symlink to LLVMgold.so.
There is no changes even in Fedora 20 yet.

Resources