[CMake] Best way to handle application data path for local run vs. installation
Ruslan Baratov
ruslan_baratov at yahoo.com
Wed Dec 2 00:27:42 EST 2015
On 02-Dec-15 05:13, Alexander Neundorf wrote:
>
> On Tuesday, December 01, 2015 07:17:35 Ruslan Baratov wrote:
>
> > On 01-Dec-15 03:51, Alexander Neundorf wrote:
>
> > > On Monday, November 30, 2015 16:13:03 Ruslan Baratov via CMake wrote:
>
> > > > On 30-Nov-15 09:10, Dmitry Marakasov wrote:
>
> > > > > Hi!
>
> > >
>
> > > ...
>
> > >
>
> > > > > 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
>
> > >
>
> > > Not really. CMake has extra code to make sure the build rpath is as
>
> > > long as the install rpath will be, so it can be patched in later.
>
> >
>
> > Well, that's exactly what I said - RPATH can be patched.
>
> well, the RPATH entry was not designed to be patched,
>
RPATH designed to be patched. And since it's a third time I'm making
this statement please provide any arguments if you don't agree.
Here is mine (comes from wikipedia, https://en.wikipedia.org/wiki/Rpath):
The rpath of an executable or shared library is an optional entry
in the
.dynamic section of the ELF executable or shared libraries, with
the type
DT_RPATH, called the DT_RPATH attribute. It can be stored there at
link time by
the linker. Tools such as chrpath and patchelf can create or MODIFY
the entry
later.
Man chrpath (http://linux.die.net/man/1/chrpath):
-r <path> | --replace <path>
Replace current rpath or runpath setting with the path given
> any other string in an executable could be patched too:
>
RPATH and C++ string literals have not the same nature. E.g. on my Linux
machine RPATH string goes to ".dynstr" section and C++ literal to
".rodata" section.
The difference is quite huge. By parsing ELF headers you can figure out
RPATH offset and be 100% sure that patching is totally correct and
doesn't affect other binary or general executable logic. RPATH is just a
hint for linker.
Changing bytes in .rodata is much trickier. E.g. how do you distinguish
two strings:
void print_some_info() {
const char* path = "/usr/local"; // must not be changed
std::cout << "General note: user specific packages usually installed
to " << path << std::endl;
}
void parse_resources() {
const char* resources_path = "/usr/local"; // want to change it in future
std::string myresource = resources_path + "/foo/some.file";
}
What if compiler merge them?
(Just a general note, not related to how you want to implement resources
trick)
> const char* my_builddir_flag = "$$$$_I_M_NOT_INSTALLED_$$$$";
>
> ...
>
> if (*my_builddir_flag)
>
> {
>
> ... code when not installed
>
> }
>
> else
>
> {
>
> ... code for the installed version
>
> }
>
> Just search for that string in the executable and replace the first
> byte with a '\0'.
>
Still can violates logic. What if I want to print string to resources in
next format:
1. "-" x size of path to resources (compiler can figure out it at
compile time!)
2. path to resources
3. "-" x size of path to resources
If you pass "/usr/local" output will be (nice):
--------------
/usr/local
--------------
If you pass "/home/username", output will be (nice):
------------------------
/home/username
------------------------
If you pass "$$$$_I_M_NOT_INSTALLED_$$$$" then change string to
"/usr/local" after install (ugly, not what I expect!):
---------------------------
/usr/local
---------------------------
> Not sure there is a simple tool to do that, but writing one shouldn't
> be hard.
>
sed? :)
> Maybe it would even be accepted as an option into cmake.
>
Note that even if you solve all the issues above and make peace with
violation logic you still will not able to create relocatable package.
And just to be clear by relocation I mean packing application to
*.tar.gz archive so user can install it just by doing "tar xf" to any
place, like CMake do: https://cmake.org/download/
Out of curiosity can somebody show me cross-platform application
(Windows, Linux, OSX) that expect resources in hard-coded location?
Cheers, Ruslo
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/cmake/attachments/20151202/d9091047/attachment-0001.html>
More information about the CMake
mailing list