I am pretty new to CMake and tried to write a simple static library that does some image manipulation using Qt4.
cmake_minimum_required(VERSION 2.8)
project(timage)
find_package(Qt4 REQUIRED)
include(${QT_USE_FILE})
add_definitions(${QT_DEFINITIONS})
include_directories(
"${PROJECT_SOURCE_DIR}/include"
)
add_library(
timage
${PROJECT_SOURCE_DIR}/source/timage.cpp
)
target_link_libraries(
timage
${QT_LIBRARIES}
)
I can configure, and generate it, and it even successfully builds libtimage.a
. Now I want to include it into my main project, and here is where the trouble begins.
I started off with some unit tests, but already I get linker errors (undefined reference
for every single function call of the TImage
class). I built my unit tests with g++ -Wall -Wextra -std=c++11 -I../include -L../bin -ltimage -o test spec.cpp
I personally do not see the difference between what I am doing to the beginner's tutorial besides the Qt4 work. I would appreciate if someone could give me a hint in the right direction here.
Update I just found out that if I build my test with this CMake file:
link_directories(
${PROJECT_BINARY_DIR}
)
add_definitions("-std=c++11")
add_executable(
test
spec.cpp
)
target_link_libraries(
test
timage
)
Everything works just as expected. I am currently trying to find out what CMake is doing that I am not.
Your problem is that libtimage.a is probably not in ../bin
, but will by default be in ${PROJECT_BINARY_DIR}
- your build directory.
In your g++ command, you're adding ../bin
to your libraries search paths, but you need to be adding wherever ${PROJECT_BINARY_DIR}
is.
This is achieved in your second CMakeLists file in the link_directories
command. However, it's generally better to avoid using this command (the documentation explains why).
If timage
is available in your test's CMakeLists.txt as a CMake target, then there's no need to use link_directories
- CMake already knows where to find the built library and will pass the appropriate -L
flags automatically. By "CMake target" I mean it's defined in that file or a parent CMakeLists.txt using the add_library
command.
If timage
isn't an actual CMake target in the test CMakeLists.txt (i.e. it's a totally separate project which isn't invoked from a common parent CMakeLists.txt), then you have a couple of options.
You can export
your timage
project so that the test project can import it using include
, or you can build the library separately, and then have the test find it using find_library
. This will yield the full path to libtimage.a if it's found.
All of these options would avoid you having to use link_directories
.
Another point is that you can see exactly what build command CMake is invoking by doing
make VERBOSE=1
so when you build your test, you can compare the CMake-generated command to your own.