Not a problem - figured putting together some clean templates could probably help me and my colleagues out too, anyway.
Your comment about the syntax makes me understand a bit better... "MyPackage" isn't a name, it's a placeholder for one of the many general packages of third party functionality that you use. I am guessing that you're putting the detection for every library that your app can/must use into one "find" module, when you actually probably should have a directory in your source tree added to your CMAKE_MODULE_PATH that contains a large number of find modules, some of which are interdependent (just like how the example I sent uses find_package(BLAS) - which is a module that comes bundled with cmake). Once you make enough cmake-based build systems, you'll probably find yourself hanging on to a repository of assorted find modules. I've pasted a simple example here, since it pretty well meshes with a common use case. The sample project uses OpenSceneGraph (plus its optional components osgDB and osgUtil), as well as a large suite of libraries with internal dependencies known as VR Juggler 2.2. OSG has modules that come with CMake, while I had to make my own for VR Juggler. ------------- cmake_minimum_required(VERSION 2.6) project(minimal-vrjuggler-osg) # Locally-developed modules dist'ed with this app list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) # This should handle all dependencies, including OpenGL, GMTL, and so on find_package(VRJuggler22 REQUIRED) find_package(OpenSceneGraph REQUIRED osgUtil osgDB) # Search for includes in these directories include_directories( ${OPENSCENEGRAPH_INCLUDE_DIRS} ${VRJUGGLER22_INCLUDE_DIRS}) # Build the project set(SOURCES main.cpp theapp.cpp theapp.h) add_executable(example ${SOURCES}) target_link_libraries(example ${OPENSCENEGRAPH_LIBRARIES} ${VRJUGGLER22_LIBRARIES}) ----------- That's an entire functional CMakeLists.txt file - though behind the scenes we're linking to a ton of libraries in a ton of different directories. (Read through the cmake docs online a few times - you got the imported target thing but missed the "REQUIRED" flag that you can pass to find_package... If you use the FindPackageHandleDefaultArgs call as suggested by the readme.txt, it takes care of handling QUIET and REQUIRED for you.) So, I made a separate FindWhatever.cmake file for each library that belongs to VR Juggler, and set it up like the examples from the last email, treating them each as a separately-usable library (since they are). Since most of the time, however, if you're writing a VR Juggler app, you're going to want a large chunk of the tree by default, I made a FindVRJuggler22.cmake "meta-module" sort of thing: means that for most folks, all that's needed in the cmakelists is find_package(VRJuggler22 REQUIRED) or at most find_package(VRJuggler22 COMPONENTS VRJOGL22 Tweek12). So, I have a whole bundle of find modules written (actually, in total, I have ~20 find modules in a directory I share between all my projects, with another ~20 modules that provide functions: some utilities for find scripts, some for use directly by a cmakelists) that I share between my projects, but because each find module knows its own dependencies, it works it out. In that sense, more files is better: it means you're keeping your find modules well-focused and modular. (If the library comes in a separate zip/targz file, it probably should have a separate find module - don't just smush them all into one massive file.) Here's the dependency tree for the VR Juggler find modules - each node is a separate .cmake file that goes in a directory in my source tree, and each of those find modules are set up just like the examples from the last email. (in graphviz/DOT format) : digraph { // a module that, when included, provides a function definition that can remove duplicate // libraries from a _LIBRARIES list safely, without breaking the DEBUG RELEASE GENERAL annotations // I wrote this one, so it's in my project in a directory with the custom find modules CleanLibraryList; subgraph cluster_bundled { label = "Included with cmake 2.8.0"; FindBoost; FindOpenSceneGraph -> { FindOpenThreads; FindosgALL; } } subgraph cluster_vrjuggler22 { label = "VR Juggler 2.2 suite: All require CleanLibraryList and CleanDirectoryList, and recommend FindFlagpoll"; FindTweek12 -> FindVPR20; FindJCCL12 -> FindVPR20; FindGadgeteer12 -> { FindJCCL12; FindVPR20; } FindSonix12 -> FindVPR20; FindVRJ22 -> { FindJCCL12; FindGadgeteer12; FindSonix12; FindVPR20; } FindVRJOGL22 -> FindVRJ22; FindVRJuggler22 -> FindVRJOGL22; } // commented out to make the diagram easier to read -> {FindFlagpoll; CleanLibraryList; CleanDirectoryList;} FindVPR20 -> { FindBoost; FindCPPDOM; } FindGadgeteer12 -> FindGMTL; FindSonix12 -> FindGMTL; } Hope this helps! Ryan On 1/7/10 5:13 PM, Nico Schlömer wrote: Wow, thanks for the elaborate answer! I learn a lot just going through the examples. One thing for me to understand first: Ah, so if those components are always necessary (that is, A always needs B, and B always needs C), there's no need to use the "components" option. Ah, I found the components thing neat for its syntax, as one can (quite semantically) say FIND_PACKAGE( MyPackage COMPONENTS coolCompOfMyPackage anotherOne ) # very much like done in FindBoost.cmake Of course there's not only a,b,c, but a whole set of libraries a,...,z under the roof of MyPackage with a more or less complicated dependency tree. Also, it would depend on the installation of MyPackage whether all the libraries are actually there; for example, and installation with only "b" and "c" would be possible. Anyway, instead of hardcoding a,b,c one could possible FOREACH through a (hardcoded) list of components, such as SET( ALL_LIBS "a" "b" "c" "d" [...] "z" ) I guess how one would do that with the above suggestion is to further define MYPACKAGE_{$LIB}_FOUND, and then in the CMakeLists.txt FIND_PACKAGE( MyPackage ) IF( MYPACKAGE_a_FOUND ) # add the necessary stuff to TARGET_LINK_LIBRARIES, for example ELSE() MESSAGE( FATAL_ERROR "Too bad, we need a." ) END() The disadvantage I see here is that FindMypackage.cmake had to be adapted every time a new library makes it into MyPackage. Also, the code in CMakeLists.txt would get longer than what I thought would be nice [being: FIND_PACKAGE( MyPackage COMPONENTS "a" "g" "t" ) # FATAL_ERRORing out if either of a, g, t hasn't been found, # otherwise providing a slim ${MyPACKAGE_LIBRARIES} to be appended to # TARGET_LINK_LIBRARIES or something. ]. Cheers, Nico -- Ryan Pavlik Human-Computer Interaction Graduate Student Virtual Reality Applications Center Iowa State University rpav...@iastate.eduhttp://academic.cleardefinition.com/
_______________________________________________ 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