13

In Ubuntu, I have downloaded a third-party shared library, mylibrary.so, which I have placed in the directory /home/karnivaurus/Libraries. I have also placed the associated header file, myheader.h, in the directory /home/karnivaurus/Headers. I now want to link to this library in my C++ code, using CMake. Here is my CMakeLists.txt file:

cmake_minimum_required(VERSION 2.0.0)

project(DemoProject)

include_directories(/home/karnivaurus/Headers)

add_executable(demo demo.cpp)

target_link_libraries(demo /home/karnivaurus/Libraries/mylibrary)

However, this gives me the error message:

:-1: error: No rule to make target `/home/karnivaurus/Libraries/mylibrary', needed by `demo'.  Stop.

What's going on?

Kevin
  • 16,549
  • 8
  • 60
  • 74
Karnivaurus
  • 22,823
  • 57
  • 147
  • 247
  • 6
    1. Do you really need to support CMake as **ancient** as 2.0? 2. Shouldn't the library's name on disk be `libmylibrary.so`? If it's not, you might try adding the `.so` extension to `target_link_libraries()`, it might help unconfuse it. – Angew is no longer proud of SO Nov 07 '14 at 18:10
  • If I add the `.so` extension, it then gives me the error: `cannot find -lmylibrary` – Karnivaurus Nov 07 '14 at 18:18
  • Can you link to the library manually, i.e. in a project not using CMake? If so, what command line achieves that? It might be possible to infer the CMake syntax from this. I still believe the library's name does not follow Linux conventions, though. – Angew is no longer proud of SO Nov 07 '14 at 18:27
  • Are you missing an add_library call? – Bill Campbell Nov 07 '14 at 18:30
  • 4
    Doesn't `add_library` build a new library from source? I have already been given the compiled `mylibrary.so` file... – Karnivaurus Nov 07 '14 at 18:31
  • 1
    Possible duplicate of [CMake link to external library](http://stackoverflow.com/questions/8774593/cmake-link-to-external-library) – Donal Lafferty Apr 20 '16 at 13:03

2 Answers2

6

While the other answer posted here is valid, it is out-dated. CMake now provides better solutions for using a pre-built external library in your code. In fact, CMake itself even discourages the use of link_directories() in its documentation.

The target_link_libraries() command takes very specific syntax for linking to an external library. A more modern solution is to create an IMPORTED CMake target for your external library:

add_library(MyExternalLib SHARED IMPORTED)

# Provide the full path to the library, so CMake knows where to find it.
set_target_properties(MyExternalLib PROPERTIES IMPORTED_LOCATION /home/karnivaurus/Libraries/mylibrary.so)

You can then use this imported CMake target later on in your code, and link it to your other targets:

target_link_libraries(demo PRIVATE MyExternalLib)

For other ways to use an external third-party library in your CMake code, see the responses here.

Kevin
  • 16,549
  • 8
  • 60
  • 74
  • @astronomerdave The [`IMPORTED_LOCATION`](https://cmake.org/cmake/help/latest/prop_tgt/IMPORTED_LOCATION.html) property should point to a single target. I believe you can set two *versions* of a library for one target, using `IMPORTED_LOCATION_Debug` and `IMPORTED_LOCATION_Release`, for example. – Kevin Jun 27 '20 at 00:04
0

You may use a full path to the static library. To link w/ dynamic one, better to use link_directories() like this:

cmake_minimum_required(VERSION 2.0.0)

project(DemoProject)

include_directories(/home/karnivaurus/Headers)
link_directories(/home/karnivaurus/Libraries)

add_executable(demo demo.cpp)

target_link_libraries(demo mylibrary)

and make sure mylibrary has prefix lib and suffix .so in file name (i.e. full name is /home/karnivaurus/Libraries/libmylibrary.so).

To make you project more flexible, you'd better to write a finder module and avoid hardcode paths like /home/karnivaurus/*

zaufi
  • 6,811
  • 26
  • 34
  • 1
    Use find_file and friends instead. – steveire Nov 08 '14 at 19:28
  • @steveire often just having some path to a file is not enough. for more serious projects it is better to learn finders and how to write them. – zaufi Nov 08 '14 at 19:31
  • That's not your suggestion. – steveire Nov 09 '14 at 12:07
  • 1
    This answer is very outdated. The current CMake documentation explicitly states that `link_directories` should be avoided. Refer to the documentation for more information on alternatives. – tjwrona1992 Jun 05 '19 at 14:15
  • 9
    I don't consider it a waste of time and I'm not trying to insult your answer. I'm not saying it was a bad answer when it was written, but people will stumble across this thread on Google looking for CMake advice. They should be made aware that although it may have been a good answer in the past it would be bad to take this advice today because there are better alternatives. – tjwrona1992 Jun 06 '19 at 22:42