14

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?

6
  • 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. Commented Nov 7, 2014 at 18:10
  • If I add the .so extension, it then gives me the error: cannot find -lmylibrary Commented Nov 7, 2014 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. Commented Nov 7, 2014 at 18:27
  • 4
    Doesn't add_library build a new library from source? I have already been given the compiled mylibrary.so file... Commented Nov 7, 2014 at 18:31
  • 1
    Possible duplicate of CMake link to external library Commented Apr 20, 2016 at 13:03

2 Answers 2

8

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.

Sign up to request clarification or add additional context in comments.

1 Comment

@astronomerdave The IMPORTED_LOCATION 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.
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/*

5 Comments

Use find_file and friends instead.
@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.
That's not your suggestion.
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.
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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.