[CMake] How to define datafiles?

Michael Hertling mhertling at online.de
Mon Apr 25 11:03:26 EDT 2011


On 04/25/2011 01:53 PM, Michael Wild wrote:
> 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

Indeed, a quite interesting approach, but does it work on Windows if an
executable's installation directory resides on a different drive than
its data directory, or in other words: Is there a relative path which
leads from C: to D:, e.g.? At the first try, I haven't been successful.

Regards,

Michael


More information about the CMake mailing list