[CMake] How to define datafiles?

Michael Wild themiwi at gmail.com
Tue Apr 26 09:44:39 EDT 2011


On 04/26/2011 03:09 PM, Michael Hertling wrote:
> On 04/26/2011 06:20 AM, Michael Wild wrote:
>> 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
> 
> Yes, that's true, indeed. OTOH, I wouldn't like to inhibit such a
> configuration a priori, and people have the weirdest set-ups and
> requirements. In the end, the incorporation of hard coded paths -
> relative or absolute - is particularly critical w.r.t. a compiled
> package's relocation capability.
> 
> Regards,
> 
> Michael

Either you make it configurable in your CMakeLists.txt, and/or (and IMHO
one should always do this) make the data and configuration paths
configurable via environment variables, and also possibly with command
line switches.

Michael



More information about the CMake mailing list