[CMake] How to make a ProjectConfig.cmake

Michael Wild themiwi at gmail.com
Fri Dec 31 05:18:56 EST 2010


On 12/31/2010 10:16 AM, Michael Hertling wrote:
> On 12/30/2010 06:59 PM, Ian Monroe wrote:
>> On Thu, Dec 30, 2010 at 09:42, Michael Wild <themiwi at gmail.com> wrote:
>>> On 12/30/2010 03:34 PM, Ian Monroe wrote:
>>>> On Thu, Dec 30, 2010 at 08:08, Michael Hertling <mhertling at online.de> wrote:
>>>>> On 12/30/2010 11:33 AM, Ian Monroe wrote:
>>>>>> To create my QyotoConfig.cmake I need to know the full path of a
>>>>>> library so that I can set a variable like QYOTO_LIBRARY.
>>>>>>
>>>>>> This is pretty standard requirement right? Its what we're supposed to
>>>>>> do in *Config.cmake's?
>>>>>
>>>>> Yes.
>>>>>
>>>>>> So anyways, how do I that? The only target property that hasn't
>>>>>> returned NOTFOUND is LOCATION, which unhelpfully returns the location
>>>>>> of the library in the build directory. I could parse this to get the
>>>>>> file name, and then append it to the library install location... but
>>>>>> that seems like such a hack. Feels like I'm doing something wrong if I
>>>>>> need to use a hack to do something standard.
>>>>>
>>>>> Usually, I'd have a template QyotoConfig.cmake.in which contains
>>>>>
>>>>> FIND_LIBRARY(QYOTO_LIBRARY qyoto
>>>>>    PATHS @CMAKE_INSTALL_PREFIX@/lib
>>>>>    NO_DEFAULT_PATH
>>>>> )
>>>>>
>>>>> and is processed by CONFIGURE_FILE(). If the library is installed with
>>>>>
>>>>> INSTALL(TARGETS qyoto
>>>>>    RUNTIME DESTINATION bin
>>>>>    LIBRARY DESTINATION lib
>>>>>    ARCHIVE DESTINATION lib
>>>>> )
>>>>>
>>>>> the FIND_LIBRARY() in the resulting QyotoConfig.cmake file will find
>>>>> the library right at the installation location but nowhere else, and
>>>>> the platform-dependent file names, e.g. libqyoto.so versus qyoto.dll,
>>>>> are also handled correctly.
>>>>>
>>>>>> I looked at install(EXPORT which could work, but it seems to include a
>>>>>> lot more information then is needed. I just want to set a variable
>>>>>> with the full path to a library.
>>>>>
>>>>> Nevertheless, the imported-targets approach, i.e. the combination of
>>>>> INSTALL(TARGETS ... EXPORT ...) and INSTALL(EXPORT ...) along with an
>>>>> appropriately set up config file, is much more powerful and should be
>>>>> preferred, IMO; see [1] for more information. BTW, as the export file
>>>>> defines the imported targets, its inclusion in the config file should
>>>>> possibly be protected in a suitable way to avoid fatal redefinitions.
>>>>
>>>> The context I'm coming from is that I'm developing stuff that is
>>>> distributed by Linux distributions. The export file has information
>>>> about what the target is dependent on, including full paths. That
>>>> feels like a bad thing to me. What was true about dependencies when a
>>>> package was being built on a build server might not be true later.
>>>
>>> If the paths on the build server don't match the ones on the destination
>>> system, then that distro is broken. Period. Here's what happens in the
>>> case of Debian/Ubuntu/...:
>>>
>>> - A minimal installation is unpacked from a tar-ball
>>> - The system chroots into the unpacked system
>>> - All dependencies are installed into the build environment
>>> - The package is built
>>> - The system exits the chroot, retrieves the package and discards the
>>> build environment
>>>
>>> This is to guarantee that the dependencies are set up correctly and that
>>> no strange interferences occur.
>>
>> Yes, I know how build systems work. But if some library that I depends
>> on changes where it is installed, that very well might not matter at
>> all to running my application. And mostly certainly not to building
>> it.
>>
>> ...yet the EXPORT-created cmake would still refer to this old file.
>> Maybe it doesn't really matter, just seems like bad practice to be
>> referring to files that aren't yours in these cmake files that get
>> installed.
> 
> This issue isn't limited to configuration files with imported targets
> or their usage in a Linux distribution. Even with the, say, classical
> approach, you have hardcoded paths of library/executable files or the
> like in the config file, so the latter is valid for the system's state
> at the very moment of the installation. When a package's prerequisites
> are changed later the config file is in danger to be broken. That's a
> fundamental difference to find modules which can search prerequisites
> dynamically and return with <PACKAGE>_FOUND==FALSE as the case may be.
> Anyway, I think we have to put up with this possible raw point, but a
> well administrated system - or a well organized distribution - should
> keep the risks small.
> 
> Regards,
> 
> Michael

I fully agree with Michael.

Further, in Linux distros libraries don't just move around, thanks to
the file hierarchy standard (FHS). If anything changes, it's their name,
and then you need to recompile anyway. Most likely such a change in
naming (or as you worry about, placing) will go along with a version
change, so again, you'd need to recompile.

Michael


More information about the CMake mailing list