[CMake] How to define datafiles?

Michael Wild themiwi at gmail.com
Tue Apr 26 00:20:58 EDT 2011


On 04/25/2011 05:03 PM, Michael Hertling wrote:
> 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

No, that wouldn't work, unless you mount the other partition using
volume mount points. But usually the binary and data files are much
closer together and share a common directory in %ProgramW6432% or
%ProgramFiles(x86)%.

Michael


More information about the CMake mailing list