[CMake] How to define datafiles?

Michael Wild themiwi at gmail.com
Mon Apr 25 07:53:29 EDT 2011


On 04/25/2011 12:48 PM, Michael Hertling wrote:
> On 04/24/2011 04:56 PM, Campbell Barton wrote:
>> 2011/4/23 YangXi <jiandingzhe at msn.com>:
>>> In my program, I have several pictures and plain-text data files. Usually in
>>> a unix system, they should be placed on /usr/share/my_program/some_place.
>>> How could I define those files in CMakeLists, and make their location known
>>> by the program?
>>> Thanks!
>>
>> first define the prefix in CMake so you can use it in your C program.
>> add_definitions(-DPREFIX="${CMAKE_INSTALL_PREFIX}")
>>
>> the C program can then add the rest of the path "share/my_program/some_place"
>>
>> You'll also want to install this file so its copied on "make install"
> 
> Alternatively, you might use configurable headers or even configurable
> sources and have CMake write the afore-noted paths to them when your
> project is configured. Suppose you have a config.h.in template in
> CMAKE_CURRENT_SOURCE_DIR with the line:
> 
> #define DATDIR @DATDIR@
> 
> Now, your CMakeLists.txt might contain
> 
> SET(DATDIR "${CMAKE_INSTALL_PREFIX}/share/..." CACHE PATH "...")
> CONFIGURE_FILE(config.h.in config.h @ONLY)
> SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/config.h
>     PROPERTIES GENERATED TRUE)
> 
> to turn the ${CMAKE_CURRENT_SOURCE_DIR}/config.h.in template into the
> ${CMAKE_CURRENT_BINARY_DIR}/config.h header with the DATDIR definition
> set to "${CMAKE_INSTALL_PREFIX}/share/..." or whatever you've possibly
> assigned to DATDIR on CMake's command line or GUI. E.g., an invocation
> as "cmake -DDATDIR=/var/lib ..." would result in DATDIR being set to
> /var/lib regardless of the CMAKE_INSTALL_PREFIX variable's value.
> 
> However, with both methods, your project's binaries will incorporate
> DATDIR or PREFIX as hard coded paths, so they might not run before the
> entire package is installed; in particular, they might fail to run from
> the build tree, e.g. for testing purposes. For this reason, you should
> consider to provide an additional way for the binaries to learn of the
> data directory, e.g. by examining an environment variable DATDIR, and
> use the hard coded paths just as a fallback.
> 
> Regards,
> 
> Michael

Or alternatively, hard-code the _relative_ path from the binary to the
data directory and make sure in the build-tree and the install-tree you
use the same relative path. Of course, then you would need a reliable
way of figuring out the applications absolute path at runtime, which can
be quite tricky on some platforms. Often it is a convention that argv[0]
contains the applications full path, but that is only a convention and
the calling program could set it to anything. On Linux systems
interrogating /proc/* is more reliable, other *Nix systems have similar
facilities, Mac OS X and Windows have dedicated functions. See [1] for a
rather comprehensive overview. If you are using Qt anyways, you can use
QCoreApplication::applicationDirPath() or
QCoreApplication::applicationFilePath() [2] to do obtain this
information a rather portable way.

HTH

Michael

[1]
http://stackoverflow.com/questions/1023306/finding-current-executables-path-without-proc-self-exe/1024937#1024937

[2] http://doc.trolltech.com/4.7/qcoreapplication.html#applicationDirPath



More information about the CMake mailing list