Wednesday, May 21, 2014

configure fails with "No package 'foo' found" - and how to fix it

A common error when building from source is something like the error below:

configure: error: Package requirements (foo) were not met:

No package 'foo' found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
Seeing that can be quite discouraging, but luckily, in many cases it's not too difficult to fix. As usual, there are many ways to get to a successful result, I'll describe what I consider the simplest.

What does it mean?

pkg-config is a tool that provides compiler flags, library dependencies and a couple of other things to correctly link to external libraries. For more details on it see Dan Nicholson's guide. If a build system requires a package foo, pkg-config searches for a file foo.pc in the following directories: /usr/lib/pkgconfig, /usr/lib64/pkgconfig, /usr/share/pkgconfig, /usr/local/lib/pkgconfig, /usr/local/share/pkgconfig. The error message simply means pkg-config couldn't find the file and you need to install the matching package from your distribution or from source.

What package provides the foo.pc file?

In many cases the package is the development version of the package name. Try foo-devel (Fedora, RHEL, SuSE, ...) or foo-dev (Debian, Ubuntu, ...). yum provides a great shortcut to install any pkg-config dependency:

$> yum install "pkgconfig(foo)"
will automatically search and install the right package, including its dependencies.
apt-get requires a bit more effort:
$> apt-get install apt-file
$> apt-file update
$> apt-file search --package-only foo.pc
foo-dev
$> apt-get install foo-dev
For those running Arch and pacman, the sequence is:
$> pacman -S pkgfile
$> pkgfile -u
$> pkgfile foo.pc
extra/foo
$> pacman -S extra/foo
zypper is the same as yum:
$> zypper in 'pkgconfig(foo)'
Once that's done you can re-run configure and see if all dependencies have been met. If more packages are missing, follow the same process for the next file.

Any users of other distributions - let me know how to do this on yours and I'll update the post

Where does the dependency come from?

In most projects using autotools the dependency is specified in the file configure.ac and looks roughly like one of these:

PKG_CHECK_MODULES(FOO, [foo])
PKG_CHECK_MODULES(DEPENDENCIES, foo [bar >= 1.4] banana)
The first argument is simple a name that is used in the build system, you can ingore it. After the comma is the list of space-separated dependencies. In this case this means we need foo.pc, bar.pc and banana.pc, and more specifically we need a bar.pc that is equal or newer to version 1.4 of the package. To install all three follow the above steps and you're good.

My version is wrong!

It's not uncommon to see the following error after installing the right package:

configure: error: Package requirements (foo >= 1.9) were not met:

Requested 'foo >= 1.9' but version of foo is 1.8

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
Now you're stuck and you have a problem. What this means is that the package version your distribution provides is not new enough to build your software. This is where the simple solutions and and it all gets a bit more complicated - with more potential errors. Unless you are willing to go into the deep end, I recommend moving on and accepting that you can't have the newest bits on an older distribution. Because now you have to build the dependencies from source and that may then require to build their dependencies from source and before you know you've built 30 packages. If you're willing read on, otherwise - sorry, you won't be able to run your software today.

Manually installing dependencies

Now you're in the deep end, so be aware that you may see more complicated errors in the process. First of all you need to figure out where to get the source from. I'll now use cairo as example instead of foo so you see actual data. On rpm-based distributions like Fedora run:

$> yum info cairo-devel    
Loaded plugins: auto-update-debuginfo, langpacks
Skipping unreadable repository '///etc/yum.repos.d/SpiderOak-stable.repo'
Installed Packages
Name        : cairo-devel
Arch        : x86_64
Version     : 1.13.1
Release     : 0.1.git337ab1f.fc20
Size        : 2.4 M
Repo        : installed
From repo   : fedora
Summary     : Development files for cairo
URL         : http://cairographics.org
License     : LGPLv2 or MPLv1.1
Description : Cairo is a 2D graphics library designed to provide high-quality
            : display and print output.
            : 
            : This package contains libraries, header files and developer
            : documentation needed for developing software which uses the cairo
            : graphics library.
The important field here is the URL line - got to that and you'll find the source tarballs. That should be true for most projects but you may need to google for the package name and hope. Search for the tarball with the right version number and download it. On Debian and related distributions, cairo is provided by the libcairo2-dev package. Run apt-cache show on that package:
$> apt-cache show libcairo2-dev
Package: libcairo2-dev
Source: cairo
Version: 1.12.2-3
Installed-Size: 2766
Maintainer: Dave Beckett 
Architecture: amd64
Provides: libcairo-dev
Depends: libcairo2 (= 1.12.2-3), libcairo-gobject2 (= 1.12.2-3),[...]
Suggests: libcairo2-doc
Description-en: Development files for the Cairo 2D graphics library
 Cairo is a multi-platform library providing anti-aliased
 vector-based rendering for multiple target backends.
 .
 This package contains the development libraries, header files needed by
 programs that want to compile with Cairo.
Homepage: http://cairographics.org/
Description-md5: 07fe86d11452aa2efc887db335b46f58
Tag: devel::library, role::devel-lib, uitoolkit::gtk
Section: libdevel
Priority: optional
Filename: pool/main/c/cairo/libcairo2-dev_1.12.2-3_amd64.deb
Size: 1160286
MD5sum: e29852ae8e8e5510b00b13dbc201ce66
SHA1: 2ed3534d02c01b8d10b13748c3a02820d10962cf
SHA256: a6099cfbcc6bd891e347dd9abc57b7f137e0fd619deaff39606fd58f0cc60d27
In this case it's the Homepage line that matters, but the process of downloading tarballs is the same as above. For Arch users, the interesting line is URL as well:
$> pacman -Si cairo | grep URL
Repository      : extra
Name            : cairo
Version         : 1.12.16-1
Description     : Cairo vector graphics library
Architecture    : x86_64
URL             : http://cairographics.org/
Licenses        : LGPL MPL
....
zypper (Tizen, SailfishOS, Meego and others) doesn't have an interface for this, but you can run rpm on the package that you installed.
$> rpm -qi cairo-devel
Name        : cairo-devel
[...]
URL         : http://cairographics.org/
This command would obviously work on other rpm-based distributions too (Fedora, RHEL, ...). Unlike yum, it does require the package to be installed but by the time you get here you've already installed it anyway :)

Now to the complicated bit: In most cases, you shouldn't install the new version over the system version because you may break other things. You're better off installing the dependency into a custom folder ("prefix") and point pkg-config to it. So let's say you downloaded the cairo tarball, now you need to run:

$> mkdir $HOME/dependencies/
$> tar xf cairo-someversion.tar.xz
$> cd cairo-someversion
$> autoreconf -ivf
$> ./configure --prefix=$HOME/dependencies
$> make && make install
$> export PKG_CONFIG_PATH=$HOME/dependencies/lib/pkgconfig:$HOME/dependencies/share/pkgconfig
# now go back to original project and run configure again
So you create a directory called dependencies, install cairo there. This will install cairo.pc as $HOME/dependencies/lib/cairo.pc. Now all you need to do is tell pkg-config that you want it to look there as well - so you set PKG_CONFIG_PATH. If you re-run configure in the original project, pkg-config will find the new version and configure should succeed. If you have multiple packages that all require a newer version, install them into the same path and you only need to set PKG_CONFIG_PATH once. Remember you need to set PKG_CONFIG_PATH in the same shell as you are running configure from.

If you keep seeing the version error the most common problem is that PKG_CONFIG_PATH isn't set in your shell, or doesn't point to the new cairo.pc file. A simple way to check is:

$> pkg-config --modversion cairo
1.13.1
Is the version number the one you installed or the system one? If it is the system one, you have a typo in PKG_CONFIG_PATH, just re-set it. If it still doesn't work do this:
$> cat $HOME/dependencies/lib/pkgconfig/cairo.pc
prefix=/usr
exec_prefix=/usr
libdir=/usr/lib64
includedir=/usr/include

Name: cairo
Description: Multi-platform 2D graphics library
Version: 1.13.1

Requires.private:   gobject-2.0 glib-2.0 >= 2.14 [...]
Libs: -L${libdir} -lcairo
Libs.private:            -lz -lz    -lGL        
Cflags: -I${includedir}/cairo
If the Version field matches what pkg-config returns, then you're set. If not, keep adjusting PKG_CONFIG_PATH until it works. There is a rare case where the Version field in the installed library doesn't match what the tarball said. That's a defective tarball and you should report this to the project, but don't worry, this hardly ever happens. In almost all cases, the cause is simply PKG_CONFIG_PATH not being set correctly. Keep trying :)

Let's assume you've managed to build the dependencies and want to run the newly built project. The only problem is: because you built against a newer library than the one on your system, you need to point it to use the new libraries.

$> export LD_LIBRARY_PATH=$HOME/dependencies/lib
and now you can, in the same shell, run your project.

Good luck!

5 comments:

  1. Arch Linux:

    # pacman -S pkgfile
    # pkgfile -u
    # pkgfile systemd.pc
    core/systemd
    # pkgfile -v systemd.pc
    core/systemd 204-3 /usr/share/pkgconfig/systemd.pc

    ReplyDelete
  2. thanks mate, much appreciated! Updated to add the Arch info.

    ReplyDelete
  3. Don't forget $HOME/dependencies/share/pkgconfig or might be mightily confused for a long time. I know this from experience. :)

    ReplyDelete
  4. Hah, thanks Aaron, you're right. that's one annoying thing to forget :) I added this now

    ReplyDelete
  5. You have a few gotchas here. First, you must set (and export) LIBRARY_PATH to "$HOME/dependencies/lib" (or add that directory if your LIBRARY_PATH is already set to something), otherwise if your dependency is a library, your software will not build even if you have the dependency already installed in $HOME/dependencies. This is due to a bug in autoconf, where folks forgot to explain to gcc to add $PREFIX/lib into the library search path when $PREFIX is something other than the default. Not that setting LD_LIBRARY_PATH is not sufficient because "ld" will ignore that variable :P (LD_LIBRARY_PATH is used by ld.so.1, the runtime linker, to search for shared libraries; to add library search directories to the compile time linker's path you need to put them into "LIBRARY_PATH" (note the missing "LD_" prefix) instead).

    Second is that you must also set "CPPFLAGS" to "-I$HOME/dependencies/include", otherwise your software compilation will fail cause it can't find the header files belonging to the dependency library. This is another bug in autoconf where folks forgot to add this directory into the GCC include search path.

    And third, all these variables, including LD_LIBRARY_PATH must be set and exported at the same time as PKG_CONFIG_PATH instead of after you (tried) to build everything and are ready to run as you stated in the post. This is because the software you are trying to build may want to build a custom tool to be used during the build process and if that custom build tool needs some of the dependencies installed in $HOME/dependencies, the tool will fail to run without the LD_LIBRARY_PATH configured.

    And I also recommend adding $HOME/bin into your PATH because some of these build scripts are or may be broken and will fail to search for tools installed in $HOME/dependencies/bin even if you say "--prefix=$HOME/dependencies" to ./configure.

    As an example of the need for the LIBRARY_PATH and CPPFLAGS try installing "cairo" from sources on stock ubuntu, using the "deep end" method, including all its dependencies. The dependencies are "zlib" and "libpng". An example of software that needs LD_LIBRARY_PATH and PATH configured correctly during build see anything that uses the Qt framework with Qt installed in $HOME/dependencies (Qt software uses "moc" to compile their GUI parts which is a preprocessor utility installed with Qt).

    ReplyDelete

Comments are moderated thanks to spammers