[CMake] ${PROJECT}-config.cmake

Biddiscombe, John A. biddisco at cscs.ch
Mon Jun 14 06:09:54 EDT 2010


Michael,

thanks for the feedback. Following the advice given, I've modified the project so that it generates an hdf5-config.cmake file, which checks for If(NOT target blah blah) and then loads the hdf5-targets.cmake file.

All seem to be clean and tidy.

I had one small problem which was generating one hdf5-config.cmake for the install directory, and  one for the build directory and getting paths correct, so that a user can use either the build version (testing etc) or the install (not users). Seemed like it was harder than it should be. Your point is noted that the time at which the targets files are created is not guaranteed, but for now all seems good.

Thanks - (anyone trying out the hdf5-1.8.5.x point releases will hopefully get these changes and can suggest fixes for stuff that does not work).

JB


> -----Original Message-----
> From: cmake-bounces at cmake.org [mailto:cmake-bounces at cmake.org] On Behalf Of
> Michael Hertling
> Sent: 08 June 2010 23:34
> To: cmake at cmake.org
> Subject: Re: [CMake] ${PROJECT}-config.cmake
> 
> On 06/07/2010 05:24 PM, Biddiscombe, John A. wrote:
> > When using the install target command as follows
> >
> >   INSTALL (
> >       TARGETS
> >           ${HDF5_LIB_TARGET}
> >       EXPORT
> >           ${HDF5_EXPORTED_TARGETS}
> >       LIBRARY DESTINATION lib COMPONENT libraries
> >       ARCHIVE DESTINATION lib COMPONENT libraries
> >       RUNTIME DESTINATION bin COMPONENT libraries
> >   )
> >
> > cmake very nicely generates an HDF5-config.cmake file in the build
> directory, and at install time, in the install directory. This is great.
> 
> AFAIK, those files generated by the INSTALL(TARGETS ... EXPORT ...)
> and INSTALL(EXPORT ...) commands concerning imported targets are not
> intended to be used as config files for a package; accordingly, they
> should not be named *-config.cmake as this has a special meaning for
> FIND_PACKAGE(). Preferably, they are named *-targets.cmake instead.
> 
> > However, I have project A(paraview) with two subdirectories B (hdf5) and C
> (mystuff), where C "uses" B. All is well except that if C includes the hdf5-
> config.cmake from the Build directory as generated by B (ADD_LIBRARY(vtkhdf5
> SHARED IMPORTED)) , cmake produces error messages along the lines of
> >
> > CMake Error at D:/cmakebuild/pv-shared/Utilities/hdf5-1.8/HDF5-
> config.cmake:16 (ADD_LIBRARY):
> > add_library cannot create imported target "vtkhdf5" because another target
> > with the same name already exists.
> 
> So, B and C are built within the same project A, right? In this case,
> you could refer directly to B's targets whereas imported targets are
> meant to be provided by outside projects. Btw, where do you get the
> hdf5-config.cmake from for its inclusion at CMake time, i.e. before
> installation? IIRC, the time it is generated at and the location it
> is written to are not mentioned in the docs, and can you be sure it
> is not changed during installation? Here, IMO, you're relying on
> undocumented behaviour.
> 
> > Naturally, when building C standalone using the install directory of
> standalone B, all works fine.
> 
> This means C could *also* be built using an already installed B, right?
> In this case, B should provide a config file, say b-config.cmake, that
> includes the targets file, say b-targets.cmake, and protects that
> inclusion to prevent multiple definitions of the targets, e.g.:
> 
> IF(NOT TARGET "vtkhdf5")
>     INCLUDE(<ThePathTo>/b-targets.cmake)
> ENDIF()
> SET(B_LIBRARIES "vtkhdf5")
> SET(B_INCLUDE_DIRS ...)
> SET(B_DEFINITIONS ...)
> 
> When building C, you can issue FIND_PACKAGE(B ...) to enable B, but you
> should not mix these cases, i.e. you should set up C to use either the
> "builtin" B or the externally installed B, e.g. in C's CMakeLists.txt:
> 
> IF(USE_BUILTIN_B)
>     LIST(APPEND LIBRARIES "vtkhdf5")
>     ADD_DEFINITIONS(<TheDefinitionsOfB>)
>     INCLUDE_DIRECTORIES(<ThePathToHeadersOfB>)
> ELSE()
>     FIND_PACKAGE(B REQUIRED ...)
>     LIST(APPEND LIBRARIES ${B_LIBRARIES})
>     ADD_DEFINITIONS(${B_DEFINITIONS})
>     INCLUDE_DIRECTORIES(${B_INCLUDE_DIRS})
> ENDIF()
> ...
> TARGET_LINK_LIBRARIES(... ${LIBRARIES})
> 
> Thus, you have an explicit distinction between the alternatives without
> relying on the availability of B's targets file in the build directory,
> and if B can be installed as a stand-alone package it should provide a
> config file for itself anyway.
> 
> > Everything would be simple, if cmake would simply skip the imported target
> from B the second time it is loaded when called from the subproject C, then
> a single set of config and cmakelists would work all the time, but as it is,
> extra logic needs to be added.
> >
> > Is there any easy way of telling project C, load the config file if B is
> not part of the same build so that I can reuse the same syntax between
> separate build or common builds. I'd like to use the generated hdf5-
> config.cmake files because they have all the necessary properties set
> correctly (like when target name is not the same as lib name etc etc, which
> makes things harder like below).
> >
> > # Import target "vtkhdf5" for configuration "Debug"
> > SET_PROPERTY(TARGET vtkhdf5 APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
> > SET_TARGET_PROPERTIES(vtkhdf5 PROPERTIES
> >   IMPORTED_IMPLIB_DEBUG "D:/cmakebuild/pv-
> shared/bin/Debug/vtkhdf5ddll.lib"
> >   IMPORTED_LINK_INTERFACE_LIBRARIES_DEBUG "ws2_32;wsock32;C:/Program
> Files/MPICH2/lib/mpi.lib;vtkzlib"
> >   IMPORTED_LOCATION_DEBUG "D:/cmakebuild/pv-
> shared/bin/Debug/vtkhdf5ddll.dll"
> >   )
> 
> If you really want to use the targets file of B internally during the
> build - which I would not recommend - you can protect each INCLUDE()
> of that file with "IF(NOT TARGET ...)" as shown above in order to
> reliably prevent multiple inclusions.
> 
> Regards,
> 
> Michael
> _______________________________________________
> Powered by www.kitware.com
> 
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
> 
> Please keep messages on-topic and check the CMake FAQ at:
> http://www.cmake.org/Wiki/CMake_FAQ
> 
> Follow this link to subscribe/unsubscribe:
> http://www.cmake.org/mailman/listinfo/cmake


More information about the CMake mailing list