Bug 130

Summary: cross-compilation RFE
Product: pkg-config Reporter: J.H.M. Dassen (Ray) <jdassen>
Component: srcAssignee: Dan Nicholson <dbn.lists>
Status: RESOLVED FIXED QA Contact:
Severity: enhancement    
Priority: high CC: dberkholz, info, jwilk, keithp, otaylor
Version: unspecified   
Hardware: All   
OS: All   
Whiteboard:
i915 platform: i915 features:
Attachments: Proposed patch
updated patch
upupdated patch

Description J.H.M. Dassen (Ray) 2003-10-29 10:20:41 UTC
[Originally reported as http://bugs.debian.org/217902]

From: =?iso-8859-1?Q?R=FCdiger?= Kuhlmann
<debian-bugs-RIYqiGiwFZpr=spam@ruediger-kuhlmann.de>
Subject: cross-compilation with pkg-config
Message-ID: <20031028014805.GG15353@o112.hadiko.de>

Package: pkg-config
Version: 0.15.0-2
Severity: wishlist
Tags: patch

The provided patch enables the easy use of pkg-config when cross-compiling.
The previous .m4 macro would end up finding the build's pkg-config, which in
turn would find the flags and includes for the build's libraries - which is
obviously not desired. Instead, the .m4 macro is changed to find the cross
pkg-config, namely <host>-pkg-config, which should be just a symlink to
pkg-config. Then, pkg-config will detect having been called as
<host>-pkg-config, will extract the <host>, and change the package search
directory to "/usr/<host>/lib/pkgconfig" (which is where libraries for
cross-compilation should install their .pc files). Precisely,
/usr/<host>/lib/pkgconfig is a compile-time-defined constant format string
that defaults to "${prefix}/%s/lib/pkgconfig".
Comment 1 J.H.M. Dassen (Ray) 2003-10-29 10:21:18 UTC
Created attachment 64 [details] [review]
Proposed patch
Comment 2 Havoc Pennington 2003-10-29 12:38:19 UTC
There's been prior discussion of cross-compilation on xdg-list and on
gtk-devel-list I think.
Comment 3 Rüdiger Kuhlmann 2003-11-01 06:47:01 UTC
Created attachment 67 [details] [review]
updated patch

I checked on the mentioned list you refered to, however, the topic at least on
one of the lists wasn't about where pkgconfig searches for .pc files (which can
be done manually by using $PKG_CONFIG_LIBDIR, but my patch makes that
automatic), but about how to re-use .pc files both for native and for cross
compiling. So I updated my patch:

* it now checks $PKG_CONFIG_X_LIBDIR when cross-compilation is detected, and
doesn't use $PKG_CONFIG_LIBDIR in this case
* updated configure.in and Makefile.am to current syntax and require current
autotools versions
* in case of cross-compilation, override the $prefix variable with
$prefix/<host> (--enable-xprefix configure option, $PKG_CONFIG_XPREFIX env var)
* disable prefix override with empty $PKG_CONFIG_XPREFIX

This way, .pc files can be re-used from a native Windows install.
Comment 4 Owen Taylor 2003-11-01 08:31:34 UTC
(I don't see why the current macro would end up finding the build's
pkg-config ... it doesn't make any sense to have the build bin
directory in PATH.)

This patch seems to be adding a lot of assumptions about the directory
setup for cross-compilation that aren't necessarily universal.

While you've allowed changing these assumptions when building pkg-config, that
doesn't really do a lot of good, since presumably the native pkg-config on the
system is simply the pkg-config provided with the system built with
native options.

Frankly, setting PKG_CONFIG_LIBDIR doesn't seem any harder to me 
than creating a symlink to <host>-pkg-config. And much easier to
understand.

So, I'm not sure anything is needed at all. But if you want an automated
system, here's what I'd suggest:

 - Add support for building pkg-config with --target=; the only effect
   of which would be to install the binary as <target>-pkg-config
   (this might be close to working already?)

 - Add another configure option which sets the default value of  
   PKGCONFIG_LIB_DIR.

 - Change pkgconfig.m4 as you suggest.

Then, when building a cross-compilation environment, you just need to 
build another copy of pkg-config pointed at the correct place and 
install it along with your other cross tools, and it will be found
automatically. While there is some "inefficiency" in this, it's
pretty small.

Or, even simpler, we just change pkgconfig.m4 and tell people to
create a wrapper script:

 #!/bin/sh
 export PKG_CONFIG_LIBDIR=/cross-prefix/lib/pkgconfig
 pkgconfig $@

One could also argue that one should try to address the big problem -
sharing .pc files between cross compilation on the host and 
native compilation on the build - first and then perhaps the 
right solution little problem (finding the right .pc files for 
cross compilation) will fall out of that.
Comment 5 Rüdiger Kuhlmann 2003-11-01 09:22:05 UTC
> (I don't see why the current macro would end up finding the build's 
> pkg-config ... it doesn't make any sense to have the build bin 
> directory in PATH.) 
 
Huh? pkg-config is usually installed in /usr/bin. That's usually in your 
$PATH. Having to change the $PATH for cross-compiling is tedious and 
error-prone. You nowadays never do that. 
 
> This patch seems to be adding a lot of assumptions about the directory 
> setup for cross-compilation that aren't necessarily universal. 
 
Which? They just assume that you install pkg-config and the host's in the same 
place, which is reasonable. And, as you see, you can override them with 
environment variable to match your layout. 
 
> Frankly, setting PKG_CONFIG_LIBDIR doesn't seem any harder to me  
> than creating a symlink to <host>-pkg-config. And much easier to 
> understand. 
 
No, it's not easier to understand. Have all your build's .pc files in a wierd 
place - just set PKG_CONFIG_LIBDIR. Have all yout cross-compile .pc files in a 
wierd place - just set PKG_CONFIG_X_LIBDIR. This way you adapt them to your 
layout, while otherwise you need to set them according to what you 
cross-compile just now. My approach means: configure your layout (with sane 
defaults given). Your approach: set an env var each time you cross-compile. 
See the difference? Your approach is basically manual intervention into the 
build process. Which is what you want to avoid. 
 
Of course, it works as well. In the same way that hacking a Makefile after a 
configure run works as well. 
 
> - Add support for building pkg-config with --target=; the only effect 
>   of which would be to install the binary as <target>-pkg-config 
>   (this might be close to working already?) 
 
Then you have basically one binary for each possible host platform. In my case 
you have a binary that fits all, and you just need to add a symlink. 
 
If there is an AC_ARG_PROGRAM, then that can be used, and you have --prefix 
anyway. OTOH, one could indeed do a specific configure option instead. 
 
It just depends on whether you want pkg-config to be able to do the right 
thing in the default install or whether you will require cross-compiler users 
to install their own copy of it. 
 
> - Change pkgconfig.m4 as you suggest. 
 
It would be nice if at least that would be in the next version because it 
needs endless time till the new .m4 is used everywhere anyway... 
 
> One could also argue that one should try to address the big problem - 
> sharing .pc files between cross compilation on the host and  
> native compilation on the build - first and then perhaps the  
> right solution little problem (finding the right .pc files for  
> cross compilation) will fall out of that. 
 
Well, that's what the prefix override solves. Of course you can argue that you 
could do that with a seperate copy of <host>-pkg-config as well. 
 
 
Comment 6 Owen Taylor 2003-11-01 10:58:00 UTC
(This discussion might be better on xdg-list really)

> (I don't see why the current macro would end up finding the build's 
> > pkg-config ... it doesn't make any sense to have the build bin 
> > directory in PATH.) 
>  
> Huh? pkg-config is usually installed in /usr/bin. That's usually in your 
> $PATH. Having to change the $PATH for cross-compiling is tedious and 
> error-prone. You nowadays never do that. 
> 
Sorry, I was confusing host/build here. 
 
> This patch seems to be adding a lot of assumptions about the directory 
> > setup for cross-compilation that aren't necessarily universal. 
>  
> Which? They just assume that you install pkg-config and the host's in the same 
> place, which is reasonable. And, as you see, you can override them with 
> environment variable to match your layout. 
> 
You patch assumes an installation with prefix /usr/<host>/, which
while not unheard of, is likely uncommon ... most people don't want
to install custom builds into /usr. Yes, you can override that 
with an envvar, but I don't see the advantage of that over 
just setting PKG_CONFIG_LIBDIR for the usual case.
 
> Frankly, setting PKG_CONFIG_LIBDIR doesn't seem any harder to me  
> > than creating a symlink to <host>-pkg-config. And much easier to 
> > understand. 
>  
> No, it's not easier to understand. Have all your build's .pc files in a wierd 
> place - just set PKG_CONFIG_LIBDIR. Have all yout cross-compile .pc files in a 
> wierd place - just set PKG_CONFIG_X_LIBDIR. This way you adapt them to your 
> layout, while otherwise you need to set them according to what you 
> cross-compile just now. My approach means: configure your layout (with sane 
> defaults given). Your approach: set an env var each time you cross-compile. 
> See the difference? Your approach is basically manual intervention into the 
> build process. Which is what you want to avoid. 
 
If you are cross-compiling to half-a-dozen different architectures regularly
with a uniform directory layout, then I guess that might be true. How many
people do that? If we can keep the general use case
(one cross-compilation target at a time) simpler, I don't think asking
such people to have some shell scripts to set up their environment
is unreasonable.

Here's a possible compromise: instead of adding another environment
variable with an unclear interaction with PKG_CONFIG_LIBDIR, why don't
we simply allow variable substitutions of $PLATFORM into PKG_CONFIG_LIBDIR. (I
suggest that token because it's supported by RPATH in the linux dynamic loader,
but $HOST might make more sense) I think that's cleaner.

There is some issue there with native builds there, so perhaps a 
separate envvar PKG_CONFIG_CROSS_LIBDIR does makes sense (I really dislike the
X_LIBDIR naming ... it's abbreviation at the expense
of clarity.) But a variable substitution would IMO be much cleaner
in any case then a format string.

> Of course, it works as well. In the same way that hacking a Makefile after a 
> configure run works as well. 

That's an entirely unjustified comparison.
 
> - Add support for building pkg-config with --target=; the only effect 
> >   of which would be to install the binary as <target>-pkg-config 
> >   (this might be close to working already?) 
>  
> Then you have basically one binary for each possible host platform. In my case 
> you have a binary that fits all, and you just need to add a symlink. 
 
And figure out a printf-formatted envvar and get that into your environment...
Since you need a separate binary for all the other tools,
I don't see having one for pkg-config as much of an issue. As soon
as you have to do anything (create a symlink even), that's the majority
of the conceptual complexity. But sure, if we can avoid it in some
simple way, that's great.
 
[...]

> - Change pkgconfig.m4 as you suggest. 
>  
> It would be nice if at least that would be in the next version because it 
> needs endless time till the new .m4 is used everywhere anyway... 
 
I don't see any problem with making that change. (I don't have access
to pkg-config CVS at the moment, so Havoc will have to do it.) Most packages can
easily enough be autoreconf'ed.
 
> One could also argue that one should try to address the big problem - 
> > sharing .pc files between cross compilation on the host and  
> > native compilation on the build - first and then perhaps the  
> > right solution little problem (finding the right .pc files for  
> > cross compilation) will fall out of that. 
>  
> Well, that's what the prefix override solves. Of course you can argue that you 
> could do that with a seperate copy of <host>-pkg-config as well. 
 
I don't see how the prefix override really solves things, because you
the different-from-install path on the host system, not on the build system. 

Also, overriding the "prefix" variable is likely a bad idea, because the
prefix variable is just a convention that we happened to start using
in the config files. (The basic reason it's there, truth be told, is
because it avoids really nasty shell substitution untangling in the
configure file.) It also doesn't work if the user explicitely specified
--libdir on their configure line, because then libdir=@libdir@
will look like libdir=/usr/lib not libdir=${prefix}/lib.

It seems that a solution here would need to involve DESTDIR in some fashion so
that the correct host paths get put into the .pc files.

We could add a new special internal variable (not allowed to set it in the .pc
file) $_destdir say, so that in gtk+-2.0.pc we would write:

Libs: -L${_destdir}${libdir} -lgtk-${target}-@GTK_API_VERSION@ @GTK_EXTRA_LIBS@
Cflags: -I${_destdir}${includedir}/gtk-2.0 @GTK_EXTRA_CFLAGS@

Then you would set 

 PKG_CONFIG_DESTDIR=/mnt/build/$PLATFORM

(Considerations for adding PKG_CONFIG_CROSS_DESTDIR as well and $HOST vs.
$PLATFORM as above.)

If you did that, then setting DESTDIR to /mnt/build/arm-pc-gnu-linux
or whatever on your install would then work. 

It's unfortunate that this requires modification of every .pc
file, but I don't really see a good alternative.
Comment 7 Rüdiger Kuhlmann 2004-02-09 08:43:55 UTC
Created attachment 86 [details] [review]
upupdated patch

Updated patch to be 2.13-safe. Also changed environment cariables to those
proposed by hp.
Comment 8 Rüdiger Kuhlmann 2004-02-09 16:03:59 UTC
Darn, I'm blind. Make that "ifdef" instead of "m4_ifelse". 
Comment 9 Benjamin Close 2007-12-13 16:29:12 UTC
Howdy, just chasing up old bugs. Ray, does pkg-config still suffer from the symptoms you mention in this bug?
Comment 10 J.H.M. Dassen (Ray) 2007-12-15 04:06:41 UTC
(In reply to comment #9)
> Howdy, just chasing up old bugs. Ray, does pkg-config still suffer from
> the symptoms you mention in this bug?

As I haven't been involved with Debian's pkg-config package for a long time
and the proposed patches here are Rüdiger's, he is probably the right person
to ask.
Comment 11 Dan Nicholson 2012-08-15 00:32:00 UTC
Most of what's in attachment 86 [details] [review] is now supported by the PKG_CONFIG_SYSROOT_DIR variable. See pkg-config(1) for more description. As I understand things, sysroot style cross compiling is the standard way to do things nowadays. I think this removes the need for the separate PKG_CONFIG_CROSS_LIBDIR and PKG_CONFIG_CROSSPREFIX environment variables as it provides a cross specific variable to use. I tend to agree with comment 6 the extra variables are not needed in the common case and people seem to be getting along fine without them all these years.

The part I do like is the support for $host-pkg-config in pkg.m4 so that you can have an arch-specific pkg-config invoked automatically. I'll work that part into the next version and maybe try to make the pkg-config build support installing $host-pkg-config easily.
Comment 12 Dan Nicholson 2012-10-13 15:37:28 UTC
I've committed the change to install $host-pkg-config in commit 6b072969. Since that has been supported by PKG_PROG_PKG_CONFIG for a long time, even current packages will pick up arch-specific pkg-configs.

That combined with PKG_CONFIG_SYSROOT_DIR gives (I believe) complete functionality for cross-compiling scenarios. There are a couple things I'd like to make better such as adding a --sysroot command line arg and automatically adding the sysroot directory to the path like gcc, but those are just nice to have.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.