我正在学习使用CMake构建一个库。构建库的代码结构如下:
include:
Test.hpp
ITest.hpp // interface
src:
Test.cpp
ITest.cpp
在CMakeLists.txt中,我用来建库的句子是:
file(GLOB SRC_LIST "src/iTest.cpp" "src/Test.cpp" "include/Test.hpp"
"include/iTest.hpp" "include/deadreckoning.hpp")
add_library(test SHARED ${SRC_LIST})
target_link_libraries( test ${OpenCV_LIBS}) // link opencv libs to libtest.so
然后我写了另一个测试文件(main.cpp),将库复制并粘贴到同一目录下,链接库并调用库内的函数。此CMakeLists.txt是
cmake_minimum_required(VERSION 2.8)
project(myapp)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread -O3 -Wall -ftree-vectorize -ffast-math -funroll-loops")
add_executable(myapp main.cpp)
target_link_libraries(myapp "/home/labUser/test_lib/libtest.so")
如果我没有在库中包含头文件,main.cpp可以成功编译和运行:
#include <iostream>
using namespace std;
int main(){
cout << "hello world" << endl;
return -1;
}
但是当我包含头文件#include "ITest.hpp"
时,它有错误:
fatal error: iTest.hpp: No such file or directory
#include "iTest.hpp"
compilation terminated.
我不明白为什么会这样。我想我已经成功地链接了库,因为当我运行main.cpp而不包括头文件时,它不会给予任何“链接”错误。我认为头文件显然在库中。为什么我不能包括它?有人能帮我弄明白吗?
1条答案
按热度按时间x9ybnkn61#
你这里有几个问题。
向目标用户传播头部:
当你已经将包含文件添加到你的库目标中时,你需要让你的库目标的消费者知道如何找到头文件。
因此,当你的应用
myapp
链接到你的库目标test
时,你需要告诉cmake将./include
添加到myapp's
包含搜索路径。有一个特殊的cmake变量
${CMAKE_CURRENT_LIST_DIR}
,它解析当前正在处理的CMakeLists.txt
所在的目录的路径。在您的示例中,它是
src
和include
的父文件夹。为了告诉cmake在其包含搜索路径中添加一个路径,您可以使用
target_include_directories
为此,路径将为
${CMAKE_CURRENT_LIST_DIR}/include
所以你要找的语法是:
请注意,这意味着您不必将
"include/iTest.hpp"
和"include/Test.hpp"
添加到SRC_LIST
glob中,因为编译器将能够从上面的target_include_directories
中找到它们。链接到您的测试库:
现在,您已经创建了库并添加了include目录,要在应用中实际 * 使用它 *,您应该再次使用
target_link_libraries
,但不要指定生成的.so
文件的路径,而是引用您创建的库目标的名称test
现在,
myapp
将知道如何找到Test.hpp
,因为它将从您在myapp
和test
之间创建的“依赖关系链接”中获取该信息因此,假设以下目录结构,则以下CMakeLists.txt文件可以工作
src/CMakeLists.txt
src/library/CMakeLists.txt
src/app/CMakeLists.txt