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

Dmitry Marakasov amdmi3 at amdmi3.ru
Mon Nov 30 06:53:50 EST 2015


* Ruslan Baratov (ruslan_baratov at yahoo.com) wrote:

> > - 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)

I know how it is done - I've patched numberless applications which
only used /proc to work on FreeBSD, and that's why I absolutely
don't want to go this way.

Also this doesn't solve the problem of moving binary around without
moving data.

> >    - 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. 

I know that changing data is tricky, but I though more of something
like having both paths compiled in and switching by changing a
constant length data.

> 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.

Hmm, I didn't think of that, probably some other systems may need
this as well.

Though I just understood that this problem is different than the one
of making cmake produce executable suitable for both inplace run
and installation: even if I produce a relocatable binary, I /still/
needs different (relative) paths to data for inplace/systemwide
cases.

Anyway for now, I did some research and solved the problem of inplace
vs. systemwide compilation in a way that I find acceptable.

I check for CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT to basically
know whether a user has explicitly specified CMAKE_INSTALL_PREFIX.
If user specified install prefix, I prepare for systemwide install,
otherwise I prepare for inplace run.

https://github.com/AMDmi3/hoverboard-sdl/blob/0.4.0/CMakeLists.txt

This doesn't support inplace and systemwide /at the same time/, but
still supports either of them cleanly, doesn't require extra actions
from user and behaves sensibly by default.

-- 
Dmitry Marakasov   .   55B5 0596 FF1E 8D84 5F56  9510 D35A 80DD F9D2 F77D
amdmi3 at amdmi3.ru  ..:  jabber: amdmi3 at jabber.ru      http://amdmi3.ru


More information about the CMake mailing list