Extra /usr in path in PackagConfig

Our build server (jenkins) is building gtest via cmake and it creates a package config.

We install it into a staging area to tar it up for upload to artifactory.
That gets installed to /opt/gtest/{version}/x64/{lib,include} like all of our dependencies.

I found -DCMAKE_INSTALL_PREFIX=/ in the build script. If I change that, it modifies the location of the final install. if I set it to DCMAKE_INSTALL_PREFIX=/opt/gtest/{version}/x64/ I get a directory like

/opt/gtest/{version}/x64/opt/gtest/{version}/x64/{lib,include}

But as it stands, the packageConfig files that are created are changing the paths and inserting “usr”

error:
CMake Error at /opt/gtest/1.12.1/x64/lib/cmake/GTest/GTestTargets.cmake:108 (message):
The imported target “GTest::gtest” references the file
“/opt/gtest/1.12.1/usr/lib/libgtest.a”
but this file does not exist. Possible reasons include:

  • The file was deleted, renamed, or moved to another location.
  • An install or uninstall procedure did not complete successfully.
  • The installation package was faulty and contained
    “/opt/gtest/1.12.1/x64/lib/cmake/GTest/GTestTargets.cmake”
    but not all the files it references.

Call Stack (most recent call first):
/opt/gtest/1.12.1/x64/lib/cmake/GTest/GTestConfig.cmake:32 (include)
CMakeLists.txt:85 (find_package)

How do I prevent Cmake from inserting “usr” in all the paths?

CMAKE_INSTALL_PREFIX should be the deployment destination. If you want to stage it somewhere, use DESTDIR=/path/to/staging cmake --build . --target install.

Thanks. While this basically is what we do as per the instructions, it does not address what is happening inside the generated config Target file.

The CMAKE_INSTALL_PREFIX is effecting the paths in this file in an unclear way.

It may be GTest’s COnfig file generation or CMake,i am not sure.

I found that if set it equal to . or ./ i end up with the current working directory name in the path
If =/ i get /usr in paths
if =/x64 i get /x64 in path
if =/usr I get nothing added to path which works perfectly. Like it cancels it out. There must be some prefix matching logic and default path detection going on.

Weird. I don’t know of any code doing that, but I’ve been surprised before. A small test case that shows the problem would be appreciated.

Thanks.
Weird is exactly the word myself and the build engineer used.
There is existing build infrastructure that predates us so we have some digging to do.

For example I see it build into /STAGING/usr/include when DESTDIR is set for /STAGING on some projects but directly into /STAGING for other projects with same DESTDIR. THe diff being one is passed to CMake and other directly to make.

FWIW, I generally recommend against building the install target as a way to install the project (I just noticed I need to update part of my book to make this clearer). It is fine if you want all the defaults as is, but as soon as you want to do something that departs from that, you’re better off calling cmake --install .... It is clearer and more flexible. The defaults install to a system location (unless you change the value of CMAKE_INSTALL_PREFIX), which requires elevated privileges, and building with elevated privileges is very questionable to me. Some of my consulting clients have had headaches because of that in the past.

Doing the install as a separate step to the build also decouples “have I built everything” from “now install things”. It means you are responsible for ensuring everything to be installed has been built, but I’d question doing a make install without a preceding `make" anyway (I’m using “make” generically here, replace that with whatever build tool invocation you are using).

I’m departing from the focus of this issue here, but it is at least tangentially relevant. CMAKE_INSTALL_PREFIX is the default install location, and it will typically be something like /usr/local for Unix platforms. The value given by that cache variable is hard-coded into the install scripts. You can override it at install time using:

cmake --install /path/to/build/dir --prefix /overridden/base/install/dir

Trying to get that behavior by building the install target is not as clear or reliable, in my opinion.

Getting back to the main focus of the original post, if you’re seeing things installed to the wrong path even when using the --prefix argument to cmake --install, then we have a genuine problem that needs investigation. If the config file generated by gtest specifies the wrong path when the install is relocated like that, then chances are their config file is malformed.