A1A2A3A4
A1A2A3A4

Reputation: 453

CMake cannot resolve runtime directory path

After running cmake CMakeLists.txt

I get the following warning

CMake Warning at src/CMakeLists.txt:32 (add_executable):
  Cannot generate a safe runtime search path for target MMPEditor because
  files in some directories may conflict with libraries in implicit
  directories:

runtime library [libQt5Widgets.so.5] in /usr/lib/x86_64-linux-gnu may be hidden by files in:
  /home/ch/Qt/5.2.1/gcc_64/lib
runtime library [libQt5Core.so.5] in /usr/lib/x86_64-linux-gnu may be hidden by files in:
  /home/ch/Qt/5.2.1/gcc_64/lib
runtime library [libQt5Gui.so.5] in /usr/lib/x86_64-linux-gnu may be hidden by files in:
  /home/ch/Qt/5.2.1/gcc_64/lib
runtime library [libQt5OpenGL.so.5] in /usr/lib/x86_64-linux-gnu may be hidden by files in:
  /home/ch/Qt/5.2.1/gcc_64/lib

Some of these libraries may not be found correctly.

What does it mean for one file to be hidden by another and how can I allow CMake to determine which is the right folder to link to?

Upvotes: 25

Views: 38956

Answers (3)

Tsyvarev
Tsyvarev

Reputation: 66118

What the warning actually implies:

  1. The project requests linking with the shared library, which is contained in two directories. That is, both these directories have the file named like foo.so.x.y.
  2. CMake perfectly understands which library file is chosen for linking. That is, it may pass the "right" directory to the runtime loader, so the loader will search the library there.
  3. For some reason, CMake cannot prevent the loader to search under the "wrong" directory too. E.g. that directory is searched by default, or it contains other libraries needed for the same executable.
  4. As a result, CMake cannot guarantee that, when you run the executable, the loader will find the proper library.

For examples, the message

runtime library [libQt5Widgets.so.5] in /usr/lib/x86_64-linux-gnu may be hidden by files in:
  /home/ch/Qt/5.2.1/gcc_64/lib

means, that the project requests to link with the library libQt5Widgets.so.5 located in the directory /usr/lib/x86_64-linux-gnu.

But library with the same name exists also in the directory /home/ch/Qt/5.2.1/gcc_64/lib, which CMake treats as "implicit directory", where the loader will search in any case. (Probably, because this directory is listed in the variable LD_LIBRARY_PATH).

The consequences of the warning:

  1. The project can be configured without the errors.
  2. The project can be built without errors.
  3. But when run the executable, the loaded may load wrong library. And that could lead to unpredictable results.

Because unpredictable results on running are rarely acceptable, it is better to fix the warning. Possible ways include the following:

  1. Make sure that CMake chooses the library which you are actually intended to use.

    E.g. you could actually intend to use the custom installation of QT under /home/ch/Qt/5.2.1/gcc_64. In that case you need to hint CMake about your intentions. E.g. by setting CMAKE_PREFIX_PATH variable.

  2. Uninstall the library located in the "wrong" directory.

    E.g. if you have newer version of the library and never intend to use the older one, then for avoid confusion it is better to uninstall the later.

  3. If the "wrong" directory is searched by the loader because it is included into the variable LD_LIBRARY_PATH, then set this variable to not contain that directory.

    CMake is able to correctly build projects for run without LD_LIBRARY_PATH settings.

  4. If "wrong" directory is searched by the loader because it contains some other libraries, eliminate usage of that libraries in your executable.

    If you have two "repositories" of libraries on your PC, then compatibility between libraries is guaranteed only within a single repo. Mixed usage of libraries could lead to incompatibility problems at runtime.

Upvotes: 28

Asalle
Asalle

Reputation: 1337

If you're dealing with find_library

find_library(LIBRARY_NAME PATHS "/usr/lib/x86_64-linux-gnu" NO_DEFAULT_PATH) where

  • PATHS stands for the exact path to the libs
  • NO_DEFAULT_PATH means, that cmake will not search anywhere else

check the values of lib and include paths with message(status, ${LIBRARY_NAME})


If you're dealing with find_package:

It's a bit more complicated than the previous example, but it's essentially the same.

For each package you have to run find_package for:

  1. Create file with name Find<Packagename>.cmake, e. g. if you're looking for cppunit, you'll have to create FindCPPUNIT.cmake.

  2. In that file, you'll have to run find_path on include files and find_library on lib files, like in "If you're dealing with find_library".

    find_path(CPPUNIT_INCLUDE_DIR PATHS "/usr/include/x86_64-linux-gnu" NO_DEFAULT_PATH)       
    find_library(CPPUNIT_LIBRARY PATHS "/usr/lib/x86_64-linux-gnu" NO_DEFAULT_PATH)
    

    And then you have to add the path to the file to CMAKE_MODULE_PATH.

Upvotes: 10

Abhishek Bansal
Abhishek Bansal

Reputation: 5345

Your system libraries are conflicting with your local custom build Qt libraries. Its a warning but you might not get expected results in your application because of this. You need to tell CMake that it should exclude system path while searching for libraries in your CMakeModule. From this documentation

If NO_DEFAULT_PATH is specified, then no additional paths are added to the search.

Also in same documentation one more flag is mentioned NO_CMAKE_SYSTEM_PATH which only include platform specific default paths.

Upvotes: 5

Related Questions