syheliel
syheliel

Reputation: 181

autoconf: `PKG_CONFIG_PATH` not working in `configure.ac` when using `PKG_CHECK_EXISTS`

I want to check whether gmodule exists in my custom PKG_CONFIG_PATH

// configure.ac
AC_SUBST([PKG_CONFIG_PATH],"./glib/lib/x86_64-linux-gnu/pkgconfig/")
PKG_PROG_PKG_CONFIG
PKG_CHECK_EXISTS([gmodule-2.0],[],[
    AC_MSG_ERROR(can't find gmodule in glib-2.0)
])

But I have the following error:

checking for libunwind.h... yes
checking for pkg-config... /usr/bin/pkg-config
checking pkg-config is at least version 0.9.0... yes
configure: error: can't find gmodule in glib-2.0

I'm 100 percent sure that gmodule-2.0.pc is in my custom path:

> ls ./glib/lib/x86_64-linux-gnu/pkgconfig/                            
gio-2.0.pc  gio-unix-2.0.pc  glib-2.0.pc  gmodule-2.0.pc  gmodule-export-2.0.pc  gmodule-no-export-2.0.pc  gobject-2.0.pc  gthread-2.0.pc

And I can also use pkg-config to find gmodule-2.0:

> PKG_CONFIG_PATH="./glib/lib/x86_64-linux-gnu/pkgconfig/" pkg-config gmodule-2.0 --cflags 
-pthread -I/home/xxx/fuzz/test/StochFuzz/glib/include -I/home/xxx/fuzz/test/StochFuzz/glib/include/glib-2.0 -I/home/xxx/fuzz/test/StochFuzz/glib/lib/x86_64-linux-gnu/glib-2.0/include

Do I miss something?

Upvotes: 1

Views: 1287

Answers (2)

FeRD
FeRD

Reputation: 2084

If you're doing some sort of superbuild, and want whatever you're configuring to use a local glib that you've already built and installed into ./glib/, then the right way to do that is not to do anything weird in your configure.ac, it's to run configure with your custom PKG_CONFIG_PATH:

$ PKG_CONFIG_PATH="./glib/lib/x86_64-linux-gnu/pkgconfig/" ./configure ...

HOWEVER, if you're building something used shared libraries, then building it this way is going to cause you headaches since you've effectively made that local glib/ directory tree a runtime dependency. You're going to need to set a RUNPATH (aka RPATH) on your binary outputs, so they can actually find their libraries, and even then the runtimes will be fragile and not easily moved.

I'd feel a lot better if you were doing something like,

$ cd ~/superbuild
$ mkdir runtime
$ cd glib_src
$ ./configure --prefix=$(realpath $(pwd)/../runtime) ...
$ make
$ make install
$ cd ../mypkg_src
$ PKG_CONFIG_PATH="$(realpath $(pwd)/../runtime/lib/x86_64-linux-gnu/pkgconfig)" \
  ./configure --prefix=$(realpath $(pwd)/../runtime) ...
$ make
$ make install

...that indicated you were installing your superbuild outputs all to the same place (the runtime/ tree below the top-level superbuild directory), rather than (seemingly) having a different install tree for each dependency.

You'd still need a RUNPATH on everything built against libraries in ~/superbuild/runtime/lib/x86_64-linux-gnu/, but you can just set it to $ORIGIN/../lib/x86_64-linux-gnu/ for binaries you install into ~/superbuild/runtime/bin/, and $ORIGIN for other shared libraries installed into ~/superbuild/runtime/lib/x86_64-linux-gnu/.

Then, you'd at least be able to move the contents of ~/superbuild/runtime/ after the fact, as long as they're all kept in the same place relative to each other.

But this sort of thing shouldn't be hardcoded into a configure.ac. PKG_CONFIG_PATH, at least, should always be set outside of configure — you can script the superbuild steps in a build.sh if you want, but don't cripple your configure script with bad, fragile assumptions.

(And better yet, don't use autotools for this. It's spectacularly ill-suited. CMake, for example, will automatically set RUNPATHs on binaries it generates in the build directory, so you don't even have to worry about any of that until install time. And its FetchContent module can make quick work of incorporating dependent packages, even autotools-based ones, into a superbuild.)

Upvotes: 1

John Bollinger
John Bollinger

Reputation: 180048

Do I miss something?

It looks like you are expecting this ...

AC_SUBST([PKG_CONFIG_PATH],"./glib/lib/x86_64-linux-gnu/pkgconfig/")

... to cause configure to use ./glib/lib/x86_64-linux-gnu/pkgconfig/ as the PKG_CONFIG_PATH when it runs pkg-config. In that case, you are at least missing that

  • the purpose of AC_SUBST() is to create an output variable. You want an output variable if you want to convey the pkg-config path to your Makefiles, but that is not directly relevant to your configure script.

  • although AC_SUBST does set the value of the specified shell variable if you designate a value for it,

    1. It does not necessarily export that variable.
    2. The assignment does not necessarily appear in the configure script at a place corresponding to the macro's location in configure.ac.
  • if you are trying to use components that are bundled with your project (and surely that's what you are doing if the wanted details are provided by pkg-config data from within your own source tree) then pkg-config is way overkill. Just put the needed paths and flags in your Makefile.am file(s), or if you're not using Automake then directly in your Makefile.in file(s).

If you insist on doing it with pkg-config anyway, then this variation will likely induce the behavior you want from the PKG_CHECK_EXISTS macro:

# configure.ac
PKG_CONFIG_PATH=./glib/lib/x86_64-linux-gnu/pkgconfig/
export PKG_CONFIG_PATH
PKG_PROG_PKG_CONFIG
PKG_CHECK_EXISTS([gmodule-2.0],[],[
    AC_MSG_ERROR(can't find gmodule in glib-2.0)
])

If you also need to convey your custom PKG_CONFIG_PATH to your makefiles then you can add ...

AC_SUBST([PKG_CONFIG_PATH])

... but you shouldn't. Notwithstanding the fact that you shouldn't be using pkg-config at all in this case (see above), when you do use pkg-config in an Autotools build system, the best way to use it is entirely within configure. Extract the needed paths and flags there, and convey those to your makefiles via output variables.

Upvotes: 3

Related Questions