[CMake] [RFC] How to use pkg-config under Windows (... and OSX)?

Alexander Neundorf a.neundorf-work at gmx.net
Thu Nov 17 12:26:08 EST 2011


On Thursday 17 November 2011, Alan W. Irwin wrote:
> Hi Alex:
> 
> On 2011-11-15 18:07+0100 Alexander Neundorf wrote:
> > Hi,
> > 
> > cmake ships with a FindPkgConfig.cmake file, which is used by some Find-
> > modules.
> > Also in KDE, we have quite a lot of Find-modules which use
> > FindPkgConfig.cmake.
> > 
> > Now, some of them put a
> > 
> > if(UNIX)
> > 
> >  find_package(PkgConfig)
> > 
> > endif()
> > 
> > around it, some use it on all platforms.
> > 
> > In theory it works also on Windows, and also on OSX, so that this if()
> > would not be necessary.
> > 
> > But our (KDEs) Windows developer team says that even if pkg-config is
> > found under Windows, and even if it reports something, they actively
> > want to ignore it.
> > 
> > The reason for this is that for those packages under Windows the user
> > decides at install-time where the package will be installed, while the
> > pc-files for pkg-config have been generated at build-time with the
> > install directory the developer chose at build-time.
> > This directory chosen by the developer and hardcoded into the pc-files
> > and the actual install directory chosen by the user can very well be
> > different.
> > 
> > If this is the case, then pkg-config reports wrong include and wrong link
> > directories, and the build will work worse than without pkg-config.
> > 
> > Similar issues may exist under OSX, for libraries which are installed as
> > a package where the user can decide at install time where to put them.
> > 
> > 
> > So, I am looking for a, if possible, generic solution to his problem.
> > 
> > Options I see:
> > 
> > 1) exclude it from being used under Windows in the Find-modules:
> > if(UNIX)
> > 
> >  find_package(PkgConfig)
> > 
> > endif()
> > 
> > 2) completely exclude it under Windows by putting something like the
> > following into FindPkgConfig.cmake:
> > if(WIN32)
> > 
> >  return()
> > 
> > endif()
> > 
> > 3) don't exclude it, but hope it reports good results (our Windows
> > developers disagree)
> > 
> > 4) add cache option whether pkg-config should be used under Windows, so
> > something like the following would be in FindPkgConfig.cmake:
> > 
> > if (NOT CMAKE_USE_PKGCONFIG_UNDER_WIN32)
> > 
> >  return()
> > 
> > endif()
> > 
> > 
> > 5) something else...
> 
> The Linux (also Unix?) tradition is to allow some flexibility with
> install location by allowing the user to specify at least the install
> prefix at configuration (i.e. cmake) time.  For relative install
> paths, CMake supports this idea with CMAKE_INSTALL_PREFIX.  For
> absolute install paths, it is the responsibility of the developer of
> the CMake-based build system to prefix the absolute install paths with
> CMAKE_INSTALL_PREFIX. For example, that is the approach we take with
> PLplot.
> 
> Anyhow, if the developer of a CMake-based build system has been
> careful to support CMAKE_INSTALL_PREFIX (either with relative install
> paths or absolute ones that have ${CMAKE_INSTALL_PREFIX} prefixed),
> that generally gives users all the installation location control they
> need.  For example, in PLplot all generated pkg-config files are
> installed in an absolute location that is automatically prefixed by
> ${CMAKE_INSTALL_PREFIX}.
> 
> I don't completely understand the use case that you have described for
> the KDE windows developers. If they just want their users to be able
> to control the installation prefix, why don't they advise those users
> to use CMAKE_INSTALL_PREFIX?


No, this is not the issue.
The issue is the following:

Let's say package Foo (unrelated to KDE, and unrelated to cmake) has been 
ported from UNIX to Windows, and installs a pkgconfig file.
This pkgconfig file is generated at the time when the binary package for Foo 
is generated.

Now a user downloads and installs the binary package of Foo, along with the 
included pkgconfig file, which contains the install path from build time.
But the user can now decide where he will install this binary package.
This may differ from what is recorded in the pkgconfig file in the binary 
package of Foo.
So the Foo.pc file is installed, and contains e.g. "C:/Foo/include", but the 
user decides to install it to "D:/MyStuff/", so the include dir would be 
"D:/MyStuff/include".


Now cmake comes into play.
Let's say there is a project Bar, which uses Foo, so it does
find_package(Foo).

Now FindFoo.cmake uses pkgconfig:

find_package(PkgConfig)
pkg_check_modules(Foo ...)

Now this will report C:/Foo/include (because this is what the pkgconfig-file 
contains), instead of D:/MyStuff/include, where the user decided to install 
it.

Alex


More information about the CMake mailing list