Cannot get tiny test with an extrenal static library to run

I’m trying to use an (Project) external static libary, but end up with undefined references regardless of what I do.

My cmake file looks as follows

cmake_minimum_required(VERSION 2.8.12) # first version with add_compile_options()

find_library(SQLITECPPLIB "libSQLiteCpp.a" "/home/llist/kdedev/lib/x86_64-linux-gnu/")
find_path(SQLITEINC "include" "/home/llist/kdedev/")
message (STATUS "LibFound: ${SQLITECPPLIB}")
message (STATUS "IncFound: ${SQLITEINC}")

# add main.cpp example source code
set(SOURCE_FILES src/main.cpp)

add_executable(My_SQLiteCpp_Example ${SOURCE_FILES})
target_include_directories(My_SQLiteCpp_Example PUBLIC BEFORE /home/llist/kdedev/include)

# Link SQLiteCpp_example1 with SQLiteCpp and sqlite3
target_link_libraries(My_SQLiteCpp_Example sqlite3 )

My main.cpp is even simpler

#include <iostream>
#include <cstdio>
#include <cstdlib>

#include <SQLiteCpp/SQLiteCpp.h>

int main ()
    std::cout << "SQlite3 version " << SQLite::VERSION << " (" << SQLite::getLibVersion() << ")" << std::endl;
    std::cout << "SQliteC++ version " << SQLITECPP_VERSION << std::endl;

    std::cout << SQLite::getLibVersion();

    return EXIT_SUCCESS;

Appreciate your help

First up, if setting your minimum CMake version to 3.14 is an option, a much simpler path is to make use of the SQLite3 find module:

cmake_minimum_required(VERSION 3.14)

# Augment the search path before calling find_package(), but you'd typically leave this
# for the user to do rather than hard-code it directly in the project like this. You might
# also need to do some extra work to account for the architecture subdir below lib.
list(APPEND CMAKE_PREFIX_PATH /home/llist/kdedev)

add_executable(My_SQLiteCpp_Example src/main.cpp)
target_link_libraries(My_SQLiteCpp_Example PRIVATE SQLite::SQLite3)

If you can’t make 3.14 your minimum CMake version, then I guess we’re stuck with having to do it manually like your original method.

This will leave finding the sqlite3 library to the linker instead of using the library you found earlier in the call to find_library().You need to replace sqlite3 with EXTLIB and the way the imported library is defined is also incorrect. It should look more like this (untested):

set_target_properties(EXTLIB PROPERTIES
target_link_libraries(My_SQLiteCpp_Example PRIVATE EXTLIB)

Thanks for the quick reply. If I understand your answer correctly I realized that I didn’t provide enough info.

I using an external product (SQLiteCpp) that wraps sqlite calls for c++. The product has its own cmake file and has been built and tested ok.
For the time being, there is no intention to (re)build SQLiteCpp as part of my small test project. All I need right now is the libSQLiteCpp.a which is currently in a non standard folder /home/llist/kdedev/lib/x86_64-linux-gnu and the .h files, currently in /home/llist/kdedev/include.
The sqlite development files are installed as part of my Ubuntu install.

The output for make (from my original cmake) shows the the static library is not included (anywhere)

llist@llist-VirtualBox-2:~/tmp/LL_SQLiteCpp_Example/build$ make
/usr/bin/cmake -S/home/llist/tmp/LL_SQLiteCpp_Example -B/home/llist/tmp/LL_SQLiteCpp_Example/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/llist/tmp/LL_SQLiteCpp_Example/build/CMakeFiles /home/llist/tmp/LL_SQLiteCpp_Example/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory ‘/home/llist/tmp/LL_SQLiteCpp_Example/build’
make -f CMakeFiles/My_SQLiteCpp_Example.dir/build.make CMakeFiles/My_SQLiteCpp_Example.dir/depend
make[2]: Entering directory ‘/home/llist/tmp/LL_SQLiteCpp_Example/build’
cd /home/llist/tmp/LL_SQLiteCpp_Example/build && /usr/bin/cmake -E cmake_depends “Unix Makefiles” /home/llist/tmp/LL_SQLiteCpp_Example /home/llist/tmp/LL_SQLiteCpp_Example /home/llist/tmp/LL_SQLiteCpp_Example/build /home/llist/tmp/LL_SQLiteCpp_Example/build /home/llist/tmp/LL_SQLiteCpp_Example/build/CMakeFiles/My_SQLiteCpp_Example.dir/DependInfo.cmake --color=
make[2]: Leaving directory ‘/home/llist/tmp/LL_SQLiteCpp_Example/build’
make -f CMakeFiles/My_SQLiteCpp_Example.dir/build.make CMakeFiles/My_SQLiteCpp_Example.dir/build
make[2]: Entering directory ‘/home/llist/tmp/LL_SQLiteCpp_Example/build’
[ 50%] Building CXX object CMakeFiles/My_SQLiteCpp_Example.dir/src/main.cpp.o
/usr/lib/ccache/c++ -I/home/llist/tmp/LL_SQLiteCpp_Example/BEFORE -I/home/llist/kdedev/include -g -o CMakeFiles/My_SQLiteCpp_Example.dir/src/main.cpp.o -c /home/llist/tmp/LL_SQLiteCpp_Example/src/main.cpp
[100%] Linking CXX executable My_SQLiteCpp_Example
/usr/bin/cmake -E cmake_link_script CMakeFiles/My_SQLiteCpp_Example.dir/link.txt --verbose=1
/usr/lib/ccache/c++ -g CMakeFiles/My_SQLiteCpp_Example.dir/src/main.cpp.o -o My_SQLiteCpp_Example -lsqlite3
/usr/bin/ld: CMakeFiles/My_SQLiteCpp_Example.dir/src/main.cpp.o: in function main': /home/llist/tmp/LL_SQLiteCpp_Example/src/main.cpp:22: undefined reference to SQLite::VERSION’
/usr/bin/ld: /home/llist/tmp/LL_SQLiteCpp_Example/src/main.cpp:22: undefined reference to SQLite::getLibVersion()' /usr/bin/ld: /home/llist/tmp/LL_SQLiteCpp_Example/src/main.cpp:25: undefined reference to SQLite::getLibVersion()’
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/My_SQLiteCpp_Example.dir/build.make:87: My_SQLiteCpp_Example] Error 1
make[2]: Leaving directory ‘/home/llist/tmp/LL_SQLiteCpp_Example/build’
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/My_SQLiteCpp_Example.dir/all] Error 2
make[1]: Leaving directory ‘/home/llist/tmp/LL_SQLiteCpp_Example/build’
make: *** [Makefile:87: all] Error 2

That build output shows a couple of things:

Note that BEFORE is being added as a header search path. This is because BEFORE has to be placed before the PUBLIC keyword in the call to target_include_directories(), not after it. This won’t have caused any build errors though.

Note the -lsqlite3 here. As I mentioned earlier, that is asking the linker to find a sqlite3 library somewhere on its library search path. There is also nothing on this link line asking the linker to link in the libSQLiteCpp.a library. If you want that on your link line, you need to call target_link_libraries() to tell it to do that. If I’m understanding your situation correctly now, you need this:

target_link_libraries(My_SQLiteCpp_Example PRIVATE EXTLIB sqlite3)

Nothing I tried so far works, so I went back to basics and linked the code from the command line.
The following works

/usr/lib/ccache/c++ -g CMakeFiles/My_SQLiteCpp_Example.dir/src/main.cpp.o -o My_SQLiteCpp_Example -L/home/llist/kdedev/lib/ -lsqlite3 -lSQLiteCpp

So by the look of it I just need a way to define the search library (Flag -L) and the two libraries (Flag -l) sqlite3 and SQLiteCpp in cmake.


Assuming the external libraries are in a standard place, the following does what I need.
cmake_minimum_required(VERSION 3.10)

set the project name and version

project(SQLiteCpp_Test VERSION 1.0)

specify the C++ standard


add the executable

add_executable(SQLiteCpp_test main.cpp)

find_library(sqlite_cpp libSQLiteCpp.a)
add_library(sqlite_cpp STATIC IMPORTED)
set_target_properties(sqlite_cpp PROPERTIES IMPORTED_LOCATION ${sqlite_cpp})

find_library(sqlite3 libsqlite3.a)
add_library(sqlite3 STATIC IMPORTED)
set_target_properties(sqlite3 PROPERTIES IMPORTED_LOCATION ${sqlite3})
target_link_libraries(sqlite3 INTERFACE pthread dl)

message (STATUS “SQLite: ${sqlite3}”)
message (STATUS “SQLiteCpp: ${sqlite_cpp}”)

target_link_libraries(SQLiteCpp_test sqlite_cpp sqlite3)