[CMake] Correct handling of absolute/relative installation paths

Eric Noulard eric.noulard at gmail.com
Thu Jul 27 07:08:54 EDT 2017


2017-07-27 12:28 GMT+02:00 David Demelier <demelier.david at gmail.com>:

> Hello,
>
> I'm still trying to find a correct solution to handle user specified
> installation paths.
>
> Let's consider two kind of paths:
>
>   - WITH_BINDIR (default: bin/) where to install executables,
>   - WITH_DATADIR (default: share/project_name/) where to install extra
> data.
>
> I want to let the user configuring those paths because not all
> distributions use the same paths (e.g. bin vs usr/bin).
>
> Then, I also like to build the whole CMake project by creating the
> hierarchy as it would be installed like:
>
> <binarydir>/WITH_BINDIR/myapp
> <binarydir>/WITH_DATADIR/somestuff.txt
>

Do you mean here that you setup CMAKE_<XXXX>_OUTPUT_DIRECTORY (variable or
target property) to your favorite value
or
You build and then install with the <binarydir>/ prefix?


>
> Using relative paths makes the application relocatable, if I keep
> WITH_BINDIR set as "bin" I can get the executable path at runtime, going
> through its parent (bin/../) and then I can go share/project_name.
> Obviously this is only valid for relative paths.
>
> However, a very high number of package managers build programs by
> specifying absolute paths, it is not an issue: instead of getting the
> directories at runtime, I use directly the absolute ones.
>
> On unix it can still work because it will just be translated as:
>
> <binarydir>/usr/local/bin/myapp
> <binarydir>/usr/local/share/project_name/somestuff.txt
>
> This is much bigger an issue on Windows if the user set WITH_BINDIR to
> something like D:/alt/bin
>
> The path would be translated to
>
> <binarydir>D:/alt/bin
>
> which is invalid on Windows.
>
> I like very much having this kind of `fakeroot' directory where you can
> have a preview on how the project looks like but I don't know what to do if
> paths are absolute, especially on Windows.
>

My opinion is that you should never use absolute path (besides some very
specific case on unix where you want to put something in /etc/...)
You should ask your user for

   DATADIR
   BINDIR
   etc...

all those var should be relative path.

and an eventual
   INSTALL_PREFIX
which could be absolute.

In any case if you really want to tolerate absolute path given by the user,
but still want to mimic install location during the build
then you'll have to escape it.

For each path you expect from the user:

check the path with if(IS_ABSOLUTE path) and compute some relative path
  a) if you are on Windows remove the drive letter, i.e. D:/alt/bin becomes
alt/bin
          (or network drive share name //shairedisk/alt/bin  becomes
alt/bin)
  b) if you are on Unix


>
> What are your thoughts on that, recommandations?
>

I wouldn't try to mimic install tree during the build (if it is what you
are doing),
If I have a need to "verify" install tree structure then **after the
build** I would do a fake install with a particular
local prefix (as CPack does before packaging).

Note that for similar reason CPack has to track files installed with
absolute destination and
possibly error out when it cannot handle it, particularly on Windows
oriented generator:
see e.g.:
https://cmake.org/cmake/help/v3.7/variable/CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION.html

AFAIK, IFW and NSIS do not work with, absolute installed files.


-- 
Eric
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/cmake/attachments/20170727/1c6fc26c/attachment.html>


More information about the CMake mailing list