I have a framework which depends on multiple third party libraries. I would like to share my framework easily. For example the user needs only my includes and add my lib to use my framework, and not all the dependencies.
I use CMake to create my libs, but I am still trying to understand how it works.
The hierarchy of the project
test
├── CMakeLists.txt
├── libA
│ ├── CMakeLists.txt
│ ├── libA.cpp
│ ├── libA.hpp
├── libB
│ ├── CMakeLists.txt
│ ├── libB.cpp
│ ├── libB.hpp
└── test
├── CMakeLists.txt
└── main.cpp
The libB depends on the libA, and I would like to add only the libB to make the project works.
The content of the main CMakeLists.txt located in test/:
cmake_minimum_required (VERSION 2.8.11)
project (C CXX)
include(CheckCXXCompilerFlag)
add_subdirectory("libA")
add_subdirectory("libB")
add_subdirectory("test")
The content of the main CMakeLists.txt located in test/libA:
cmake_minimum_required (VERSION 2.8.11)
project (A CXX)
include(CheckCXXCompilerFlag)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++14")
file(GLOB SOURCES "*.cpp")
add_library(A STATIC ${SOURCES})
The content of the main CMakeLists.txt located in test/libB:
cmake_minimum_required (VERSION 2.8.11)
project (B CXX)
include(CheckCXXCompilerFlag)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++14")
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} "-static")
include_directories("../libA")
link_directories("../libA")
file(GLOB SOURCES "*.cpp")
add_library(B STATIC ${SOURCES})
target_link_libraries(B A)
The content of the main CMakeLists.txt located in test/test:
cmake_minimum_required (VERSION 2.8.11)
project (C CXX)
include(CheckCXXCompilerFlag)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++14")
include_directories(../libA)
include_directories(../libB)
link_directories(../build/libB)
link_directories(../build/libA)
add_executable(C main.cpp)
target_link_libraries(C B)
If I run the main CMake all works fine, the standalone is well generated. But if I want to create only the exe by going into test/test and running "cmake . && make", I have an undefined reference to addL(int, int). To make it works I have to add target_link_libraries(C A) at the end of the CMakeLists. Is it normal? Is it possible to add only the main library without its dependencies?
Command invocation
target_link_libraries(C B)
have different meanings in your use-cases.
In "all" use-case 'B' is (previously) defined as a CMake target, so CMake knows location of the library (link_directories
is not used in that case), and automatically propagates all dependencies of library 'B' to executable 'C'.
In "test-only" use case there is no CMake target named 'B', so it is just transformed to linker option -lB
. Linker searches appropriate library file under link directories (link_directories
is needed in that case). But information about 'B' dependencies is lost, so automatic linking with A isn't performed.
Your project may provide a standalone CMake script which can be included by a user of your library. The script should define all needed dependencies. Common "types" of such scripts are FindXXX.cmake
and XXXConfig.cmake
, which can be included via find_package(XXX) command.