Cmake链接共享库:"没有这样的文件或目录"当包含来自库的头文件时

时间:2017-11-01 17:10:03

标签: c++ cmake shared-libraries

我正在学习使用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而不包含头文件时,它并没有给出任何&#34;链接&#34 ;错误。我认为显然头文件在库中。为什么我不能包括它?任何人都可以帮我解决这个问题吗?

非常感谢!

1 个答案:

答案 0 :(得分:2)

这里有几个问题。

将标头传播给目标用户:

虽然您已将包含文件添加到库目标,但您需要让库目标的使用者知道如何查找标题。

因此,当您的应用myapp链接到您的图书馆定位test时,您需要告诉cmake将./include添加到myapp's包含搜索路径。

有一个特殊的cmake变量${CMAKE_CURRENT_LIST_DIR},它解析为当前正在处理的CMakeLists.txt目录的路径。

在您的实例中,这是srcinclude的父文件夹。

./                    <-- ${CMAKE_CURRENT_LIST_DIR} is this directory
+--- CMakeLists.txt
+--- src/
|    +---Test.cpp
|    +---ITest.cpp
+--- include/
     +---Test.hpp
     +---ITest.hpp

为了告诉cmake添加其包含搜索路径的路径,请使用target_include_directories

为此,路径将为${CMAKE_CURRENT_LIST_DIR}/include

所以你要找的语法是:

target_include_directories(test PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)

请注意,这意味着您不必将"include/iTest.hpp""include/Test.hpp"添加到SRC_LIST glob,因为编译器可以从上面找到它们{{ 1}}

链接到您的测试库:

现在您已经创建了库并添加了包含目录,以便在您的应用中实际使用,您应该再次使用target_include_directories,但不要指定生成的target_link_libraries文件的路径,而不是引用您创建的库目标的名称,.so

test

现在target_link_libraries(myapp test) 将知道如何查找myapp,因为它将从&#34;依赖关系链接获取该信息&#34;您已在Test.hppmyapp

之间创建

因此,假设以下目录结构,可以使用以下CMakeLists.txt文件

test

<强> src/ +--- library/ | +--- < sources for your shared library > +--- app/ +--- < sources for your application >

src/CMakeLists.txt

<强> cmake_minimum_required(VERSION 3.0) project(myapp) add_subdirectory(library) add_subdirectory(app)

src/library/CMakeLists.txt

<强> set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread -O3 -Wall -ftree-vectorize -ffast-math -funroll-loops") find_package(OpenCV REQUIRED) add_library(test SHARED "src/iTest.cpp src/Test.cpp") target_link_libraries(test ${OpenCV_LIBS}) // link opencv libs to libtest.so target_include_directories(test ${CMAKE_CURRENT_LIST_DIR}/include)

src/app/CMakeLists.txt