[CMake] Best way to handle application data path for local run vs. installation

Ruslan Baratov ruslan_baratov at yahoo.com
Mon Nov 30 04:13:03 EST 2015


On 30-Nov-15 09:10, Dmitry Marakasov wrote:
> Hi!
>
> This question bugs me for a long time so I though maybe someone has
> a solution. I have a project which includes an application and some
> data for it. An application needs to know path to its data files, so
> I pass it via compiler definition: ADD_DEFINITIONS(-DDATADIR="...")
>
> The problem is that this path is different based on whether I want to
> run the application from build directory:
>
> ADD_DEFINITIONS(-DDATADIR="${PROJECT_SOURCE_DIR}/data")
>
> or want to install it systemwide:
>
> ADD_DEFINITIONS(-DDATADIR="${CMAKE_INSTALL_PREFIX}/share/myapp")
>
> I want my project to both run from build directory and to be
> installable systemwide, without the need to rebuild or specify extra
> options.
>
> - I don't want to make an applications search for its data relative
>    to executable path
>    - There's no cross-platform way to get an executable path
It's tricky but not impossible. Might be helpful:
* http://stackoverflow.com/a/1024937/2288008
* 
https://github.com/Kitware/CMake/blob/31b013b14ad3bf4838f4ba327b5392018f4853b6/Source/cmSystemTools.cxx#L2227 
(see exe_dir)

>    - This will break when executable is moved or hardlinked
> - I don't want to try both paths, as this is error prone, as installed
>    executable may pick data files from repository or vice versa
> - I don't want to make user specify additional cmake flags like
>    -DSYSTEMWIDE_INSTALLATION or -DRUN_LOCALLY.
> - I don't want to use any wrapper scripts
> - I don't want to build two executables
...

> The best solution would be for cmake to fix path in executable file
> right after installation, something similar to what cmake does with
> rpaths.
I doubt there is a general way to patch data section with string in 
executable. At least with different size and in safe manner. For example 
Clang is smart enough to figure out 'strlen' of literal string at 
compile time, so changing string affects logic and hence is dangerous. 
And rpaths unlike data is designed to be modifiable (e.g. see 
install_name_tool for OS X) so it's okay to hack it back and forth.

Second thought is that when you hardcode path in executable you make it 
non-relocatable. E.g. it's not possible to pack it to .dmg installer so 
user can unpack it wherever he wants.

>   Or there could be a cross-platform way for executable to know
> whether it was installed which I've missed.
>
> Any ideas?
>
...

Ruslo


More information about the CMake mailing list