Michael Hertling wrote: > On 06/14/2010 12:09 PM, Biddiscombe, John A. wrote: >> 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. [snip] > To make things more convenient, would it be possible to > automatically protect the imported targets' definitions in the targets > file generated by INSTALL(EXPORT ...) using IF(NOT TARGET ...) along > with the associated properties in the configuration-specific files?
The targets.cmake files are supposed to be included through a <pkg>-config.cmake file as discussed in this thread. The outer config file would need blockers for its settings to handle the use case under discussion, so doing it in the targets file is redundant. I want to keep the targets file as simple as possible, providing only information that developers cannot get reliably. This means there should be minimal logic. Using "if(NOT TARGET)" could cause silent failure when one of the targets accidentally conflicts with a target defined by the including project. One might end up with some of the imported targets configured properly and others confused by target name collisions. > Currently, as far as I can see, a parent > directory and its subdirectories have no possibility to load the same > package involving imported targets independently. It works if the subdirectory is added before the parent directory loads the targets: ... add_subdirectory(dir-using-Foo) find_package(Foo) ... The add_subdirectory command initializes processing in the subdirectory with the state of the parent directory, including currently imported targets. However, in a single project the inner directory should know that the targets were imported by an ancestor and not bother loading the package. The trouble comes when the inner directory is a project that can also build stand-alone. In this case it is probably a third-party dependency which should be configured before the rest of the project anyway. > to ask if it would be feasible to make imported targets really scoped, > i.e. the latest definition hides - but doesn't touch - the previous > one and remains valid until hidden by a descendant's definition. This would be cool, but I do not think it would work well. First, it can cause mixing of targets from different versions of imported package. For example: # finds version 1, but parent already loaded version 2 find_package(Foo) if(TARGET target_from_version_2) # ... uses target from wrong Foo endif() Second, the lazy evaluation of link dependencies makes the scope hard to define. The names passed to target_link_libraries() are not processed until generation time. This allows code like # lib_from_Foo not yet defined target_link_libraries(mylib1 lib_from_Foo) find_package(Foo) # loads lib_from_Foo target_link_libraries(mylib2 lib_from_Foo) to work. (The delayed evaluation allows things like circular dependencies among static libraries to work.) Now consider the scoped replacement case: # ...parent already loaded package Foo target_link_libraries(mylib1 lib_from_Foo) # ...finds different Foo than parent find_package(Foo) target_link_libraries(mylib2 lib_from_Foo) By the time CMake looks for an imported target "lib_from_Foo" to link to mylib1, it has been replaced by the one from a different version of Foo. This may be what the author intended, or it may not. -Brad _______________________________________________ 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