CMAKE_INSTALL_PREFIX: relative to absolute path strange behavior
I'm experiencing a behavior on how relative paths are expanded to absolute, that looks strange to me (just for reference I'm using 3.15.5).
CMakeLists.txt
Reference Let's take this reference example
project(relative_vs_absolute)
cmake_minimum_required(VERSION 3.15)
message(STATUS ${CMAKE_INSTALL_PREFIX})
message(STATUS ${other_var})
cmake
First attempt
$ cmake -DCMAKE_INSTALL_PREFIX="here" -Dother_var="there" ..
... (not relevant output) ...
-- /Users/ialberto/workspace/tmp/cmake_expand_install_prefix/build/here
-- there
$ egrep "(CMAKE_INSTALL_PREFIX|other_var)" CMakeCache.txt
CMAKE_INSTALL_PREFIX:PATH=/Users/ialberto/workspace/tmp/cmake_expand_install_prefix/build/here
other_var:UNINITIALIZED=there
CMAKE_INSTALL_PREFIX
is automatically translated to absolute path, while other_var
not. So, I thought it was a matter of variable type. But,
$ cmake -DCMAKE_INSTALL_PREFIX:PATH="here" -Dother_var:PATH="there" ..
-- here
-- there
$ egrep "(CMAKE_INSTALL_PREFIX|other_var)" CMakeCache.txt
CMAKE_INSTALL_PREFIX:PATH=here
other_var:PATH=there
Specifying both as PATH
variables, no one gets translated to absolute path.
I may agree with you that automatically translating a PATH that is relative to its absolute path would be a too strong assumption and constraint.
But, from set() documentation
Furthermore, if the is PATH or FILEPATH and the provided on the command line is a relative path, then the set command will treat the path as relative to the current working directory and convert it to an absolute path.
So, IMHO I would expect that specifying PATH
as variable type, both of them would get translated to absolute path.
ccmake
Then, with this in mind, I started experimenting with ccmake
.
At first sight, it behaves exactly as cmake
. (I changed from message(STATUS)
to message(WARNING)
for convenience)
$ ccmake -DCMAKE_INSTALL_PREFIX="here" -Dother_var="there" ..
CMake Warning at CMakeLists.txt:4 (message):
/Users/ialberto/workspace/tmp/cmake_expand_install_prefix/build/here
CMake Warning at CMakeLists.txt:5 (message):
there
$ egrep "(CMAKE_INSTALL_PREFIX|other_var)" CMakeCache.txt
CMAKE_INSTALL_PREFIX:PATH=/Users/ialberto/workspace/tmp/cmake_expand_install_prefix/build/here
other_var:UNINITIALIZED=there
$ ccmake -DCMAKE_INSTALL_PREFIX:PATH="here" -Dother_var:PATH="there" ..
CMake Warning at CMakeLists.txt:4 (message):
here
CMake Warning at CMakeLists.txt:5 (message):
there
$ egrep "(CMAKE_INSTALL_PREFIX|other_var)" CMakeCache.txt
CMAKE_INSTALL_PREFIX:PATH=here
other_var:PATH=there
But, if I set one of them from the user-interface, the variables are set to the exact value I set into. I can explain this to me with the fact that it just do a string-replacement of values, without any additional logic like when specified from the command line.
Conclusion
Everything started because I'm using a project that assumes that CMAKE_INSTALL_PREFIX
is an absolute path, but I used to set it through ccmake
user interface, and I was installing it (for testing reason) in a directory nested in the build-dir, specifying a relative path (e.g. install_here
).
- IMHO the
cmake
behavior is not coherent with the documentation (or I'm missing something from the documentation); - I don't know if I can expect that setting variables from
ccmake
user-interface would have the same behavior as setting them from the command line.