2

I am trying to include this C++ library with CMake. As I understood, the file that I need to include is located at lib/libbinacpp/lib/libbinacpp.so (relative to the library root folder).

So, I created a new folder, with two subfolders

  • src, which only contains one file: src/main.cpp (a simple Hello, World)
  • lib, which contains a folder binacpp, the result of cloning the library

On the top level, I have my CMakeLists.txt. First, I tried to write the following:

cmake_minimum_required(VERSION 3.20)
project(RebalancerBot)

set(CMAKE_CXX_STANDARD 20)

#Include binacpp
add_library(binacpp SHARED IMPORTED)
set_target_properties(binacpp PROPERTIES IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/lib/binacpp/lib/libbinacpp/lib/libbinacpp.so)

add_executable(RebalancerBot src/main.cpp)

#Link everything after adding the executable
target_link_libraries(RebalancerBot PRIVATE binacpp)

Which resulted in the error

make[3]: *** No rule to make target 'lib/binacpp/lib/libbinacpp/lib/libbinacpp.so', needed by 'RebalancerBot'.  Stop.

To my surprise, I got a different error after replacing ${CMAKE_BINARY_DIR} with the actual root path of my folder (i.e /home/actual_path/). I found this surprising since I thought that ${CMAKE_BINARY_DIR}$ should exactly be the path to the root CMakeLists.txt file. Anyway, after the replacement, I got the following new errors:

/usr/bin/ld: warning: libcrypto.so.1.0.0, needed by ../lib/binacpp/lib/libbinacpp/lib/libbinacpp.so, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libwebsockets.so.11, needed by ../lib/binacpp/lib/libbinacpp/lib/libbinacpp.so, not found (try using -rpath or -rpath-link)
/usr/bin/ld: ../lib/binacpp/lib/libbinacpp/lib/libbinacpp.so: undefined reference to `lws_client_connect_via_info'
/usr/bin/ld: ../lib/binacpp/lib/libbinacpp/lib/libbinacpp.so: undefined reference to `lws_callback_on_writable'
... (the list goes on)

If I understand correctly, these errors are due to the dependencies of libbinacpp.so. How can fix them?

PS: It should be noted that, if I cd into lib/binacpp/src and make inside of this directory, everything runs without errors.

EDIT: Thanks to @AlanBirtles comment, I found that the error with CMAKE_BINARY_DIR was due to the fact that it unfolds to the directory I run cmake in. What I needed was CMAKE_SOURCE_DIR: the directory containing my cmake file.

Philippe
  • 299
  • 2
  • 3
  • 13
  • "the file that I need to include is located at `lib/libbinacpp/lib/libbinacpp.so`" - Then why do you use path prefix `lib/binacpp/lib/libbinacpp/lib/libbinacpp.so` when set `IMPORTED_LOCATION` property? – Tsyvarev Jan 16 '22 at 16:33
  • @Tsyvarev Sorry for the confusion here. The first path is relative to the `binacpp` folder, which I copied into my own `lib/binacpp` – Philippe Jan 16 '22 at 16:36
  • 1
    `CMAKE_BINARY_DIR` is the directory you run cmake in `CMAKE_SOURCE_DIR` is the directory containing your cmake file – Alan Birtles Jan 16 '22 at 16:47
  • CMake add_library doesn't not include existing library, it builds new from sources: https://cmake.org/cmake/help/latest/command/add_library.html – Yaroslav Stetsyk Jan 16 '22 at 16:49
  • @AlanBirtles Thank you for that. Let me edit this into the question, as it solved the issue – Philippe Jan 16 '22 at 16:51
  • @YaroslavStetsyk Are you sure? From what I understood from this question, you can also just pass the `.so` file https://stackoverflow.com/questions/26807329/no-rule-to-make-target-error-in-cmake-when-linking-to-shared-library – Philippe Jan 16 '22 at 16:52
  • 1
    @YaroslavStetsyk see https://cmake.org/cmake/help/latest/command/add_library.html#imported-libraries – Alan Birtles Jan 16 '22 at 18:01
  • Correction: unless you set IMPORTED target property – Yaroslav Stetsyk Jan 17 '22 at 16:36
  • `${CMAKE_BINARY_DIR}` refers to the build directory corresponding to the toplevel `CMakeLists.txt`. There are 2 issues with this: a) you're referring to the build dir, but the libs are located in the source tree; build and source directory need not match (and in fact it's a good idea, if they don't) b) If you ever add your current project to a larger project using `add_subdirectory`, the path will be set relative to a different directory. You need use `CMAKE_CURRENT_SOURCE_DIR` instead to avoid these issues. – fabian Jan 17 '22 at 17:53

1 Answers1

0

CMake offers the possibility to have a build directory which differs from the source directory. A offer we should gladly accept, because it keeps our build system from messing with our source and we can have different build directories, depending on build type, compiler, target system, etc.

  • ${CMAKE_BINARY_DIR} is a shortcut to your top-level build directory. CMake will generate all files here during the build.
  • ${CMAKE_SOURCE_DIR} is where CMake is looking for your sources. CMake is not intended to make changes in your source directory.

If you copied the library to your source directory, you need to reference it with the right shortcut.

By the way, are you sure, you want to copy the library to the source directory? Because you don't need to. You can use find_file (https://cmake.org/cmake/help/latest/command/find_file.html), find_library (https://cmake.org/cmake/help/latest/command/find_library.html), find_path (https://cmake.org/cmake/help/latest/command/find_path.html) or find_program (https://cmake.org/cmake/help/latest/command/find_program.html) to checkout the location of the item you need and use this path to define your imported library.