On 02/24/2011 06:00 PM, L. A. Pritchett-Sheats wrote: > > I'm working on a software project that requires about a dozen external > packages to build our libraries. What is the correct way to define the > dependencies for our targets that depend on these external libraries? > > So far I have created FindXXX.cmake files for each external library. These > files set XXX_INCLUDE_DIRS and XXX_LIBRARY or XXX_LIBRARIES. Should I make > a target in our build for XXX? > > Example A: > in the root CMakeLists.txt file: > find_package(UnitTest) > add_library(unittest++ STATIC IMPORTED) > set_target_property(IMPORTED_LOCATION ${UnitTest_LIBRARY}) > > then in a subdirectory foo/CMakeLists.txt > add_executable(test_foo test/Main.cpp test/test_foo.cpp) > add_test(foo test_foo) > target_link_libraries(test_foo foo unittest++) > > or should each subdirectory that contains a CMakeLists.txt file that needs > this library to link to an executable explicitly define the library in the > target's target_link_libraries call? Like this.... > > Example B: > in foo/CMakeLists.txt: > find_package(UnitTest) > add_executable(test_foo test/Main.cpp test/test_foo.cpp) > add_test(foo test_foo) > target_link_libraries(test_foo foo ${UnitTest_LIBRARY}) > > > We've been following Example A, but have run into numerous link problems > because we are using NetCDF, HDF5, ExodusII and a mesh framework package > that depends on all 3. I've looked at two other projects that use CMake: > Trilinos and Yarp. Both follow Example B and since we are having so much > difficulty resolving links at run time, I wanted to know if we are > defining these dependencies correctly. > > Thanks for your time.
At first, your FindXXX.cmake files, provided XXX is a library, should define XXX_LIBRARIES in any case since this variable is meant to hold XXX_LIBRARY - usually the result of a FIND_LIBRARY() call - along with XXX's prerequisite libraries. In other words, XXX_LIBRARIES contains anything necessary to link against XXX. Mentioning UnitTest_LIBRARY instead of UnitTest_LIBRARIES in TARGET_LINK_LIBRARIES() might be a cause for the problems you report on. Furthermore, defining imported targets for external libraries should be the find module's job; it's intended as a more flexible alternative to the direct specification of a library's full path, e.g. The necessary prerequisites are specified appropriately enough by target properties IMPORTED_LINK_INTERFACE_LIBRARIES. As it were, dropping them might result in unresolved dependencies at link time. Finally, if the target "foo" is sufficiently independent, particularly if it can be configured and built by itself, I would tend to place the needed FIND_PACKAGE() calls in foo's CMakeLists.txt as in example B above, even if these calls appear in other CMakeLists.txt files, too. In that way, this part of the project becomes more self-contained and you do not need to rely on any FIND_PACKAGE() calls to be made before somewhere in the current scope. Additionally, well written find modules can be safely called multiple times and due to the cache, they do their work usually once. OTOH, if "foo" is tightly connected with other parts of the project, e.g. if it is a module which isn't useful on its own or doesn't make sense without a main program, it's probably appropriate to have a superordinate CMakeLists.txt call FIND_PACKAGE() and rely on the results. In summary, I'd recommend to write FindXXX.cmake files for external libraries which set up imported targets *with* their prerequisites, i.e. IMPORTED_LOCATION and IMPORTED_LINK_INTERFACE_LIBRARIES target properties. Note that the find modules need to protect the imported targets from being defined twice; this is important when the same FIND_PACKAGE() call is multiply issued within the same scope. The imported targets, however, should be conveyed to the caller via the XXX_LIBRARIES variables, so the calling CMakeLists.txt file can just say TARGET_LINK_LIBRARIES(... ${XXX_LIBRARIES}) regardless whether the FindXXX.cmake file uses imported targets or returns full paths directly. BTW, which link problems do you have exactly? You have also mentioned a "difficulty resolving links *at run time*", so are you sure these problems are caused by the find modules and the way you use them? 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