Skip to content

Commit 88e54ca

Browse files
authored
Work around CMake bug that mangles install dir
CMake has a long-standing bug/feature (see [here](https://cmake.org/pipermail/cmake/2015-March/060204.html) and reply [here](https://cmake.org/pipermail/cmake/2015-March/060209.html)) which can mangle certain path variables by attempting to make them into relative paths if you try to set them with CACHE PATH. Say you have your OpenCV download at `/path/on/my/computer/to/opencv/`. What actually happens is that if you try to set this variable by invoking CMAKE with `-DCMAKE_INSTALL_PREFIX=/my/desired/install/path`, what you end up is *not* `/usr/local/` and *not* `my/desired/install/path`, but instead, this monstrosity: `/path/on/my/computer/to/opencv/src/OpenCV-build//my/desired/install/path`. That is, CMake attempts, for some reason, to turn the path that you passed into a path relative to `${CMAKE_BINARY_DIR}`. See the links I posted above: this is a known (and apparently unfixable) issue with CMake. In OpenCV's case, among other potential issues, this leads to broken paths in `opencv_tests_config.hpp`, which can break the build or cause bizarre behaviour. The fix for this issue, as stated in my links above, is to test that the variable hasn't been set yet with an `if(NOT DEFINED ...)` before attempting to set it. This is what I've implemented here. I admit I don't know enough about OpenCV's internals to know whether you *really* need to force the install to be in `/usr/local`, but as it stands right now you get *neither* a clean `/usr/local` path *nor* a customized `/my/desired/install/path`, but a broken mess. This change at least allows the user to customize their install directory. In the meantime, there's a workaround for this, by explicitly defining the variable as a path with `-DCMAKE_INSTALL_PREFIX:PATH=my/desired/install/path`. But if this change can save anyone else the hours of headaches that I had today, I'll be happy.
1 parent 642e4d9 commit 88e54ca

File tree

1 file changed

+14
-12
lines changed

1 file changed

+14
-12
lines changed

CMakeLists.txt

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,21 @@ endif()
2525
# Following block can broke build in case of cross-compilng
2626
# but CMAKE_CROSSCOMPILING variable will be set only on project(OpenCV) command
2727
# so we will try to detect crosscompiling by presense of CMAKE_TOOLCHAIN_FILE
28-
if(NOT CMAKE_TOOLCHAIN_FILE)
29-
# it _must_ go before project(OpenCV) in order to work
30-
if(WIN32)
28+
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
29+
if(NOT CMAKE_TOOLCHAIN_FILE)
30+
# it _must_ go before project(OpenCV) in order to work
31+
if(WIN32)
32+
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "Installation Directory")
33+
else()
34+
set(CMAKE_INSTALL_PREFIX "/usr/local" CACHE PATH "Installation Directory")
35+
endif()
36+
else(NOT CMAKE_TOOLCHAIN_FILE)
37+
#Android: set output folder to ${CMAKE_BINARY_DIR}
38+
set( LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_BINARY_DIR} CACHE PATH "root for library output, set this to change where android libs are compiled to" )
39+
# any crosscompiling
3140
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "Installation Directory")
32-
else()
33-
set(CMAKE_INSTALL_PREFIX "/usr/local" CACHE PATH "Installation Directory")
34-
endif()
35-
else(NOT CMAKE_TOOLCHAIN_FILE)
36-
#Android: set output folder to ${CMAKE_BINARY_DIR}
37-
set( LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_BINARY_DIR} CACHE PATH "root for library output, set this to change where android libs are compiled to" )
38-
# any crosscompiling
39-
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "Installation Directory")
40-
endif(NOT CMAKE_TOOLCHAIN_FILE)
41+
endif(NOT CMAKE_TOOLCHAIN_FILE)
42+
endif()
4143

4244
if(CMAKE_SYSTEM_NAME MATCHES WindowsPhone OR CMAKE_SYSTEM_NAME MATCHES WindowsStore)
4345
set(WINRT TRUE)

0 commit comments

Comments
 (0)