[CMake] [CMAKE] Handling External Libraries and Resources

Patrik Gornicz gornicz_p at hotmail.com
Wed May 12 18:12:20 EDT 2010



I've been tasked with developing a new build system for projects at my work
place. We decided to use CMake and have been quite pleased thus far. However,
we've run into a requirement we haven't been able to satisfy to our satisfaction.

The requirement is with respect to handling external libraries and resources
when building.  By external libraries I mean libraries that the CMake system
itself does not build (ex. boost, third party libraries, etc.) but we want to
use without having to install them on the system (ie. keep them local to our
build tree).  By resources I mean anything else that our binaries require to
function normally (ex. images, music, audio clips, localized text files, etc.)

Essentially, we want a directory, say targetdir, were all our runtime required
files get built or copied into such that the program can execute in a developer
friendly way using both XCode and Visual Studio.

What is the best way to do this with CMake?


Requirements:
  * Must work well with XCode on the Mac, GNU Make on the Mac, and Visual
    Studio on Windows.
  * Updating resources and/or external libraries should cause their versions in
    the targetdir to get updated (ie. Dependency tracking)

Reasons for desiring a targetdir:
  * Our application loads resources (ex. images) using paths relative to the
    main executable. (rather common, no?)
  * On Windows there is no rpath option to tell Windows where to search for
    dlls (at least to the best of my knowledge there isn't), hence, dlls need
    to be side-by-side with our main executable.
  * Its nice to have everything required to run a program in one location so an
    installer can be created without having everything scattered around a build
    tree.

What we are currently doing:
  * Build all of our shared libraries and binaries into this target directory.
    * Ex. set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/targetdir")
    * Ex. set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/targetdir")
  * Manually keeping track of and copying external libraries and resources into
    this target directory.
    * CON: There doesn't seem to be a way to create custom commands and have a
           non custom target use/execute them.
      * Hence, we've created an addition target (called App-build-resources)
        which is a custom target and runs our custom copying code and the App
        target depends on this addition target.
    * CON: Currently we only have resources associated with applications
           (binaries), but it would be nice to have resources associated with
           libraries.
      * ie. It would be nice if a library copied resources it needs into the
            location it is being built. Currently this would require a
            Lib-build-resources target per library which is quite ugly.
    * PRO: A developer can select the App target (ex. Set As StartUp Project in
           Visual Studio) and simply build knowing that the custom target will
           run before the App target is considered up to data.
    * PRO: A developer can simply execute the App target after building
           directly because the App target creates the main executable.
    * CON: The CMake code is rather ugly due to the large amount of manual work going on.
      * Keeping track of what external file to link against and making targets
        link against it.
      * Keeping track of what external file and resources need to be copied
        into the targetdir.

Other things we've tried or considered:
  * Using an INSTALL target that copies all of the built binaries, libraries,
    external libraries and resources into a directory that is within the source
    tree.
    * CON: Both XCode and Visual Studio cannot easily execute the installed versions.
      * ex. The binary copied by INSTALL is not the target of the Visual Studio
            project, hence, trying to run it from within Visual Studio results
            in a "The system cannot find the path specified error".
  * Using the IMPORTED property for external libraries.
    * CON: Does not solve the issue with respect to resources.
      * Why shouldn't the ideal solution be able to handle resources just as easily?
    * CON: We seemed to run into a scoping issue where an IMPORTED library
           could only be referenced in the directory (and subdirectories) where
           a non IMPORTED library is global. (is this a bug?)
      * Due to the layout of our source tree this was problematic. (we worked
        around it by using includes instead of add_subdirectorys, though we
        didn't like that very much)
  * Instead of doing the copying at build time (ie. by XCode/Visual Studio) do
    the copying at build generation time (ie. by CMake)
    * CON: XCode and Visual Studio have per-configuration output directories,
           hence, CMake has to copy the files into each of these directories.
    * CON: Dependencies aren't really tracked.
      * If one developer updates an image another developer has to remember to
        manually run CMake when they sync to trigger the copy. (The ZERO_CHECK
        CMake run doesn't get triggered by such an update)
  * Custom target that always runs and executes a GNU Makefile to handle
    copying of resources and external libraries.
    * CON: Shouldn't really be necessary, and would require extra work.


Essentially, I'd like to hear your views on handling resource copying. Is
there an obvious method I've overlooked? What are other projects doing to
handle resources? Any ideas with respect to other methods of handling resources?

Thanks for your time,
Patrik Gornicz
 		 	   		  
_________________________________________________________________
30 days of prizes: Hotmail makes your day easier! Enter Now.
http://go.microsoft.com/?linkid=9729710


More information about the CMake mailing list