[cmake-developers] [Review Request] Topic CMakePackageConfigHelpers_build_tree

Daniele E. Domenichelli daniele.domenichelli at gmail.com
Tue Jul 22 06:48:44 EDT 2014


On 22/07/14 10:53, Stephen Kelly wrote:
> Daniele E. Domenichelli wrote:
> 
>> The first case is a folder that is appended to CMAKE_MODULE_PATH, and
>> that containing CMake files that can optionally be included by projects
>> using this package.
> 
> I still find this an odd user interface.
> 
> You provide a variable FOO_MODULE_PATH or something and document that users 
> should add that to their CMAKE_MODULE_PATH after invoking find_package? Then 
> what? The user needs to know which files they can include(). Do you leave 
> the user to run ls to find out what's there or do you document them for your 
> package?

Not exactly, the folder is appended to CMAKE_MODULE_PATH in the config
file... The user can include one of the modules in the folder, but he
does not need to do it, since the modules enable some extra feature that
the user might not want. He just needs to know the name of the module,
so it's not different from knowing the name of a variable...



> Instead of all that, you could provide and document variables (ala 
> QT_USE_FILE) which the users pass directly to include(). I would find that a 
> better user interface and less fragile.

Sorry, I'm still not convinced by this... The "QT_USE_FILE" variable
will have the same issue with relative paths and will have to be passed
as absolute path to configure_package_config_file(), or am I missing
something?



>> The second case is a path to a folder containing "data" files installed
>> by the library (that usually go in <prefix>/share/<something>), and that
>> other projects should be able to use.
> 
> I guess if you have a particular structure in the source tree, you might not 
> want to symlink/replicate it to the build tree. That arises for qml files 
> for example. However, usually I have chosen the symlink/copy route.

Symlinks are not really an option, because it works on unix only, and we
need to support windows as well.

Also I think that in one of our cases copy might be not the best
options, since some of these files are large binary blobs, and therefore
a copy is quite expensive, but I'll have to check if that is necessary...

Another issue with copying the file is that the file is copied at CMake
time, not a build time, and cmake is not triggered and therefore the
copy is not performed at build time if the file is modified and the user
just runs make (or "build" for visual studio and other IDEs).



<off-topic>

By the way, is there a reason why file(COPY) does not have an option to
copy the file only if the file(s) is(are) different. I had a few cases
where I had to use "execute_process(COMMAND ${CMAKE_COMMAND} -E
copy_if_different" because file(COPY) would trigger an unnecessary rebuild.

Since you were asking if CMake misses some important feature, I believe
that a very useful feature to have would be to be able to have an option
for the install(FILES/PROGRAMS/DIRECTORY) command that reproduces the
install tree in the binary directory, but at build time, and only if the
destination file is missing or is different from the source.

Or maybe, using the export(FILES/PROGRAMS/DIRECTORY), like for the new
export(EXPORT) command...

</off-topic>



> As you can see here, the CMakePackageConfigHelpers is only needed for 
> 'backward compatibility' provision of the INCLUDE_DIRS variable, which 
> wouldn't be added in new code:

Backwards compatibility is, in my opinion, another valid use case...
Of course you could get the INCLUDE_DIRS using get_property inside the
config file, but there is still some case uncovered, i.e. if you don't
have libraries in your package (for example for a header only library).



>> and the
>> relative path is different, since for the build tree the cmake config
>> files are in ${CMAKE_BINARY_DIR} (as expected for example by the package
>> registry)
> 
> Some other places you can have the cmake config file for the build tree:
> 
>  ${CMAKE_BINARY_DIR}/cmake
>  ${CMAKE_BINARY_DIR}/<project-name>
>  ${CMAKE_BINARY_DIR}/<project-name>/cmake
>  ${CMAKE_BINARY_DIR}/cmake/<project-name>
>  ${CMAKE_BINARY_DIR}/lib/cmake/<project-name>
>  ${CMAKE_BINARY_DIR}/lib/cmake
> 
> Depending on whether you're going for 'cleanliness' or similarity to the 
> installed layout etc.

I wasn't aware of this, thanks for pointing it out... Maybe this needs
some more documentation...

I couldn't find anything about in export[1] and cmake-packages.7[2], and
find_package[3] says:

 CMake constructs a set of possible installation prefixes for the
 package. Under each prefix several directories are searched for a
 configuration file.

The build directory is unlikely to be constructed as an "installation
prefix", therefore I thought that these paths were not checked for a
build tree.

Does this mean that if I set the <PACKAGE>_DIR environment variable to
the CMAKE_BINARY_DIR of my package, CMake will look into these folders
as well? This is what our users are used to do and it will not be easy
to change their behaviour, also because this is quite useful for testing
different builds.


[1]http://www.cmake.org/cmake/help/git-master/command/export.html
[2]http://www.cmake.org/cmake/help/git-master/manual/cmake-packages.7.html
[3]http://www.cmake.org/cmake/help/git-master/command/find_package.htm



>> Does this mean that configure_package_config_file is going to be
>> deprecated and should not be used for new packages?
> 
> No, it does not mean that. It means I was trying to find out why you need 
> it. My current understanding is that the things it does can also be done 
> other ways (and better ways I think as with the variables for include() 
> above).


Anyway, conceptually one should recreate the install tree inside the
build tree, and then generate just one config file using
configure_package_config_file and use it both for build and install, is
this correct?



Cheers,
 Daniele



More information about the cmake-developers mailing list