【问题标题】:CMake: What is the difference between `include_directories` versus `target_link_libraries`CMake:“include_directories”与“target_link_libraries”有什么区别
【发布时间】:2017-04-17 18:11:10
【问题描述】:

我正在构建一个中等大小的 C++ 库,并从一堆不同的示例等中拼凑出我的 CMakeLists.txt 文件。我试图了解 include_directoriestarget_link_libraries 指令之间的区别。

我在下面列出了我的一些代码,但只是想在前面加上评论。我使用Boost 库来构建我的一些代码。所以我有一个指示INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS}) 在构建过程中包含 Boost 源目录。所以我假设 Cmake 将在构建任何可执行文件时包含这些 Boost Source 文件——无需任何额外的显式指令。

但后来我在构建可执行文件时有一个TARGET_LINK_LIBRARIES( gd_validator ${Boost_LIBRARIES} )。所以这表明我不仅需要包含 Boost 目录,还需要明确地将其与可执行文件链接。

所以我不确定我是否真的需要这两个步骤,或者我是否只需要 INCLUDE_DIRECTORIES 指令,仅此而已。

cmake_minimum_required(VERSION 3.7)
project(XXX) 
find_package(Boost 1.58.0 REQUIRED COMPONENTS system filesystem program_options chrono timer date_time REQUIRED)
if(NOT Boost_FOUND)
    message(FATAL_ERROR "NOTICE: This demo requires Boost and will not be compiled.")
endif()
set(Boost_USE_STATIC_LIBS        ON)
set(Boost_USE_MULTITHREADED      ON)
set(Boost_USE_STATIC_RUNTIME    OFF)

INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})

file(GLOB lib_SRC RELATIVE "lib/" "*.h" "*.cpp")
file(GLOB test_SRC RELATIVE "tests/" "*.h" "*.cpp")

# need to fix the instruction below to reference library
set(SOURCE_FILES ${lib_SRC} tests/testComplexCreator.cpp tests/testDataFormatter.cpp tests/testComplexAnalysis.cpp tests/testFascadeClass.cpp)
add_library(libXXX SHARED ${SOURCE_FILES})    
add_executable(${PROJECT_NAME} main.cpp random_mat_vector_generator.h random_mat_vector_generator.cpp)
add_executable(gd_validator gudhi_validator.cpp)
TARGET_LINK_LIBRARIES( gd_validator ${Boost_LIBRARIES} )

【问题讨论】:

    标签: c++ cmake


    【解决方案1】:

    是的,两者都需要。

    include_directories 将告诉编译器在哪里寻找头文件,在这种情况下,是 boost 库的头文件。

    target_link_libraries 将告诉链接器您要链接哪些库与您的可执行文件。

    虽然头文件(大多数情况下)仅提供访问库的接口,但库本身已预编译并链接到您的应用程序。

    【讨论】:

    • 好吧好吧。因此,据我了解,target_link_libraries 将预编译目标库的头文件/源代码,然后将其链接到我的应用程序。对吗?
    • 其实这个库已经预编译了。所以编译器会在你的代码中寻找库的使用,然后调用它(共享库)或用实际的库代码(静态库)替换使用。使用库的全部意义在于避免不必要的编译。仅当库是仅标头时,您才需要添加 target_link_libraries
    • 好的,太好了。是的,这就是我想知道的。非常感谢您的澄清。
    【解决方案2】:

    include_directories 指定要搜索包含文件(头文件)的目录。 target_link_libraries 指定要链接到目标的库(可执行文件或库)。 两个完全不同的东西。

    【讨论】:

    • 是的,这就是我想知道的。那么target_link_libraries 是否仅指已编译的库?通常我指向一个包含所有 Boost 头文件和源文件的目录,然后编译器将针对这些文件进行构建。那么如果我指向已编译的库,我是否只需要target_link_libraries
    • target_link_libraries 不仅仅做链接。例如,它会查找包含目录。
    • 编译期间使用包含文件。图书馆稍后链接。有什么困惑?您需要将编译器指向查找包含的位置。您还需要将链接器指向要链接的库。这些是完全不同的事情,取决于你想做什么,你需要做一个或另一个或两者兼而有之。
    • @juanchopanza 谢谢。看到这就是我问的原因。如果target_link_libraries 会找到包含目录,那么我是否需要为include_directories 提供单独的指令?或者,target_link_libraries 是否依赖于 include_directories 指令标识的文件夹?
    • @krishnab 这取决于“链接”的库是如何定义的,但如果做得正确,target_link_libraries 也会让您获得该库导出的标头。这是一个命名错误的函数。
    猜你喜欢
    • 2015-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-26
    相关资源
    最近更新 更多