0
votes

I am trying to link a prebuilt static library, leveldb, to a small c++ script however I am getting a file not found error when trying to include the .h file from the lib. I don't know CMake that well so any help is appreciated.

//script.cc
#include <iostream>
#include "leveldb/db.h" // <<<<<<<< " fatal error: leveldb/db.h: No such file or directory"

int main(int argc, char** argv){
  std::cout << "hello \n";
  return 0;
}

As per other stack overflow posts static linking is done with target_link_libraries(). This is my current cmake file
CMakeLists.txt

cmake_minimum_required(VERSION 3.13.4)
project(my_project)
link_directories(${CMAKE_SOURCE_DIR}/third_party/)
add_executable(runscript script.cc)
target_link_libraries(runscript ${CMAKE_SOURCE_DIR}/third_party/libleveldb.a)

this is essentially what my project directory looks like

.
├── CMakeLists.txt
├── script.cc
└── third_party
    └── libleveldb.a
2
So where is db.h file? - KamilCuk
it should be apart of the static lib right?, look at the first code snippet from the github link - arm.u
No. That is literally the whole repo. Why not just include the cmake config? - KamilCuk
I have no clue how to do that, do you know any stackoverflow posts for that? - arm.u
I believe just clone the repo, add_subdirectory the cmake config, and then only target_link_libraries(runscript PUBLIC leveldb). .a file are just object files, they do not contain headers. There is no reason in that linking with a static library should add a path to the search path of includes and spawn files in there. Static library is just an archive of object files. Header files need to be shipped separately. - KamilCuk

2 Answers

1
votes

To link with another cmake project, usually the way is to:

  • Clone the repo somewhere. For example, if your project is meant to be under git control, most people add the third_party repos as git submodules. Note: that is also ExternalProject_Add.
  • Then add add_subdirectory(the_dir_with_the_repo). This will source the third_party CMakeLists.txt file and include all the targets that are there.
  • After it, you can just target_link_libraries(runscript PUBLIC leveldb) use the targets from the third_party CMakeLists.txt like your own.

A static library, a file with .a extension, is just a archive of object files, that's all. Object files do not contain the information from header files, function declarations, external variables declarations, macros, etc. In C language headers are meant to be shipped separately, as entirely independent files.

1
votes

Solution. (Thanks to KamilCuk's comment above)
CMakeLists.txt

cmake_minimum_required(VERSION 3.13.4)
project(my_proj)
add_subdirectory(third_party/leveldb)
add_executable(runscript script.cc)
target_link_libraries(runscript PUBLIC leveldb)
.
├── CMakeLists.txt
├── script.cc
└── third_party
    └── [leveldb repo]