我有一个框架,它取决于多个第三方库。我想轻松分享我的框架。例如,用户只需要我的包含并添加我的lib来使用我的框架,而不是所有依赖项。
我使用CMake创建我的库,但我仍然试图了解它是如何工作的。
项目的层次结构
test
├── CMakeLists.txt
├── libA
│ ├── CMakeLists.txt
│ ├── libA.cpp
│ ├── libA.hpp
├── libB
│ ├── CMakeLists.txt
│ ├── libB.cpp
│ ├── libB.hpp
└── test
├── CMakeLists.txt
└── main.cpp
libB依赖于libA,我想只添加libB以使项目有效。
位于 test / 中的主要CMakeLists.txt的内容:
cmake_minimum_required (VERSION 2.8.11)
project (C CXX)
include(CheckCXXCompilerFlag)
add_subdirectory("libA")
add_subdirectory("libB")
add_subdirectory("test")
位于 test / libA 中的主CMakeLists.txt的内容:
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})
位于 test / libB 中的主CMakeLists.txt的内容:
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)
位于测试/测试中的主CMakeLists.txt的内容:
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)
如果我运行主CMake一切正常,独立生成良好。 但是如果我想通过进入测试/测试并运行“cmake。&& make”来创建exe,我有一个未定义的addL(int,int)引用。为了使它工作,我必须在CMakeLists的末尾添加target_link_libraries(C A)。这是正常的吗?是否可以只添加主库而不依赖它?
答案 0 :(得分:1)
命令调用
target_link_libraries(C B)
在您的用例中具有不同含义。
在“所有”用例中,“B”(先前)被定义为CMake 目标,因此CMake知道库的位置(在这种情况下不使用link_directories
) ,并自动将库'B'的所有依赖项传播到可执行文件'C'。
在“仅测试”用例中,没有名为“B”的CMake目标,因此它只是转换为链接器选项-lB
。链接器在链接目录下搜索适当的库文件(在这种情况下需要link_directories
)。但是有关'B'依赖关系的信息会丢失,因此不会执行与A的自动链接。
您的项目可能会提供独立的 CMake脚本,该脚本可以包含在您的库中。 脚本应定义所有必需的依赖项。此类脚本的常见“类型”是FindXXX.cmake
和XXXConfig.cmake
,可以通过find_package(XXX)命令包含这些类型。