<div bgcolor="#ffffff" text="#000000">
Not a problem - figured putting together some clean templates could probably help me and my colleagues out too, anyway.<br><br>Your comment about the syntax makes me understand a bit better... &quot;MyPackage&quot; isn&#39;t a name, it&#39;s a placeholder for one of the many general packages of third party functionality that you use.  I am guessing that you&#39;re putting the detection for every library that your app can/must use into one &quot;find&quot; 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&#39;ll probably find yourself hanging on to a repository of assorted find modules.<br>
<br>I&#39;ve pasted a simple example here, since it pretty well meshes with a common use case.<br>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.<br>
<br>-------------<br><br>cmake_minimum_required(VERSION 2.6)<br>project(minimal-vrjuggler-osg)<br><br># Locally-developed modules dist&#39;ed with this app<br>list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)<br><br>
# This should handle all dependencies, including OpenGL, GMTL, and so on<br>find_package(VRJuggler22 REQUIRED)<br><br>find_package(OpenSceneGraph REQUIRED osgUtil osgDB)<br><br># Search for includes in these directories<br>
include_directories(<br>    ${OPENSCENEGRAPH_INCLUDE_DIRS}<br>    ${VRJUGGLER22_INCLUDE_DIRS})<br><br># Build the project<br>set(SOURCES<br>    main.cpp<br>    theapp.cpp<br>    theapp.h)<br><br>add_executable(example ${SOURCES})<br>
target_link_libraries(example ${OPENSCENEGRAPH_LIBRARIES} ${VRJUGGLER22_LIBRARIES})<br><br>-----------<br><br>That&#39;s an entire functional CMakeLists.txt file - though behind the scenes we&#39;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 &quot;REQUIRED&quot; 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.)<br>
<br>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&#39;re writing a VR Juggler app, you&#39;re going to want a large chunk of the tree by default, I made a FindVRJuggler22.cmake &quot;meta-module&quot; sort of thing: means that for most folks, all that&#39;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&#39;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&#39;t just smush them all into one massive file.)<br>
<br>Here&#39;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)  : <br>
<br>digraph {<br>    // a module that, when included, provides a function definition that can remove duplicate<br>    // libraries from a _LIBRARIES list safely, without breaking the DEBUG RELEASE GENERAL annotations<br>    // I wrote this one, so it&#39;s in my project in a directory with the custom find modules<br>
    CleanLibraryList;<br><br>    subgraph cluster_bundled {<br>        label = &quot;Included with cmake 2.8.0&quot;;<br>        FindBoost;<br>        FindOpenSceneGraph -&gt; { FindOpenThreads; FindosgALL; }<br>    }<br>
<br>subgraph cluster_vrjuggler22 {<br>            label = &quot;VR Juggler 2.2 suite: All require CleanLibraryList and CleanDirectoryList, and recommend FindFlagpoll&quot;;<br>            FindTweek12 -&gt; FindVPR20;<br>            FindJCCL12 -&gt; FindVPR20;<br>
            FindGadgeteer12 -&gt; { FindJCCL12; FindVPR20; }<br>            FindSonix12 -&gt; FindVPR20;<br>            FindVRJ22 -&gt; { FindJCCL12; FindGadgeteer12; FindSonix12; FindVPR20; }<br>            FindVRJOGL22 -&gt; FindVRJ22;<br>
            FindVRJuggler22 -&gt; FindVRJOGL22;<br>        } // commented out to make the diagram easier to read -&gt; {FindFlagpoll; CleanLibraryList; CleanDirectoryList;}<br>        FindVPR20 -&gt; { FindBoost; FindCPPDOM; }<br>
        FindGadgeteer12 -&gt; FindGMTL;<br>        FindSonix12 -&gt; FindGMTL;<br>}<br><br>Hope this helps!<br><br>Ryan<br>
<br>
<br>
<br>
On 1/7/10 5:13 PM, Nico Schlömer wrote:
<blockquote type="cite">
  <pre>Wow, thanks for the elaborate answer!
I learn a lot just going through the examples.

One thing for me to understand first:

  </pre>
  <blockquote type="cite">
    <pre>Ah, so if those components are always necessary (that is, A always needs B,
and B always needs C), there&#39;s no need to use the &quot;components&quot; option.
    </pre>
  </blockquote>
  <pre>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&#39;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 &quot;b&quot; and &quot;c&quot; 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 &quot;a&quot; &quot;b&quot; &quot;c&quot; &quot;d&quot; [...] &quot;z&quot; )

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 &quot;Too bad, we need a.&quot; )
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 &quot;a&quot; &quot;g&quot; &quot;t&quot; )
# FATAL_ERRORing out if either of a, g, t hasn&#39;t been found,
# otherwise providing a slim ${MyPACKAGE_LIBRARIES} to be appended to
# TARGET_LINK_LIBRARIES or something.

].

Cheers,
Nico
  </pre>
</blockquote>
<br>
<br>
<pre cols="72">-- 
Ryan Pavlik
Human-Computer Interaction Graduate Student
Virtual Reality Applications Center
Iowa State University

<a href="mailto:rpavlik@iastate.edu" target="_blank">rpavlik@iastate.edu</a>
<a href="http://academic.cleardefinition.com/" target="_blank">http://academic.cleardefinition.com/</a></pre>
</div>