-->

Why does my cross-compiling fail?

2019-05-25 03:27发布

问题:

I'm new to Linux programming and I'm trying to compile a c file including the GTK+ library. My file is called test.c and it's supposed to run on Windows computers. I'm using the command:

i586-mingw32msvc-gcc `pkg-config --cflags gtk+-3.0` -o test test.c `pkg-config --libs gtk+-3.0`

I get an awful error, I tried to figure out what went wrong by myself but didn't manage to understand what's going on here.

This is the output:

回答1:

You're almost certainly running pkg-config with the host metadata files, such output will likely make your cross-compiler, erm, cross.

Try this tutorial, it explains how to do what you want starting with downloading the required GTK+-3.0 win32 binaries, and setting up your linux environment so that pkg-config picks up the target metadata files:

http://www.tarnyko.net/en/?q=node/45

The job of pkg-config is to provide a straightforward way for one program to determine the compiler and linker requirements, and any dependent libraries for a library it uses. It also makes it easier for autoconf (and the user) to determine the presence, version and dependencies of specific packages. Your examples are using:

pkg-config --cflags gtk+-3.0
pkg-config --libs gtk+-3.0

Those will output the compiler and library flags that a program using gtk+-3.0 needs. Assuming you have a native version installed on your system, the default output will be suitable only for your type of system (paths, library names, dependent libraries etc).

The trick with cross-compiling is to have a separate tree of source, .pc (pkg-config meta-data), libraries and header files (for each targeted architecture). When you run pkg-config during configure/compile, you can set PKG_CONFIG_PATH as in the tutorial above so it picks up the correct .pc files for the targeted architecture.

There's a little bear trap here though: PKG_CONFIG_PATH adds to the start of the search path, so it can still fall back to the wrong package details if you have not installed the required software into your target tree, but you have a "native" version installed. You should usually set PKG_CONFIG_LIBDIR instead, this replaces the default path (typically /usr/lib/pkgconfig). That way when you cross-compile something more elaborate that uses autoconf (configure scripts) you (hopefully) get a sensible diagnostic about missing packages, rather than having the wheels come off mid-way through the compile.

For example, I can use this to list just the OpenWRT MIPS packages I have in one cross-compile tree:

WRTROOT=/openwrt/staging_dir/target-mips_r2_uClibc-0.9.32/
PKG_CONFIG_PATH=  PKG_CONFIG_LIBDIR=${WRTROOT}/usr/lib/pkgconfig pkg-config --list-all

Unsetting PKG_CONFIG_PATH prevents it finding extra packages in my /usr/local, setting PKG_CONFIG_LIBDIR means it won't find the native system ones.



回答2:

In addition to setting the PKG_CONFIG_PATH and PKG_CONFIG_LIBDIR variables, it might be necessary to pass --define-prefix to pkg-config:

PKG_CONFIG_PATH= PKG_CONFIG_LIBDIR=/openwrt/staging_dir/target-mips_34kc_eglibc-2.19/usr/lib/pkgconfig pkg-config --define-prefix --cflags libmodbus
-I/openwrt/staging_dir/target-mips_34kc_eglibc-2.19/usr/include/modbus

Otherwise you get the include path on your host system:

PKG_CONFIG_PATH= PKG_CONFIG_LIBDIR=/openwrt/staging_dir/target-mips_34kc_eglibc-2.19/usr/lib/pkgconfig pkg-config --cflags libmodbus
-I/usr/include/modbus

which might work, provided the host system and the cross-compile environment have the same include files installed.