簡體   English   中英

cmake - 何時在CMakeLists.txt文件中包含include_directories

[英]cmake - When to include include_directories in a CMakeLists.txt file

我有一個C ++項目,其中我有以下行:

#include <curl/curl.h>

我正在使用CURL庫從傳感器訪問IMU數據。 我准備了一個如下所示的CMakeLists.txt文件:

cmake_minimum_required(VERSION 3.5.1)
project(imu_data_access_cmake_test)
set(CMAKE_CXX_STANDARD 11)
find_package(CURL REQUIRED)
include_directories(${CURL_INCLUDE_DIRS})
set(SOURCES imu_data_access.cpp ${CURL_INCLUDE_DIRS}/curl/curl.h)
add_executable(imu_data_access_cmake_test ${SOURCES})
#add_executable(imu_data_access_cmake_test imu_data_access.cpp)
target_link_libraries(imu_data_access_cmake_test ${CURL_LIBRARIES})

這非常有效。 但是,如果我刪除include_directories行並修改add_executable行只是使用我的imu_data_access.cpp作為源, cmake不會拋出錯誤,一切仍然有效。 我假設這是由於target_link_libraries行。

如何知道是否應該使用include_directoriestarget_link_libraries包含庫? 如果包/庫有.so文件,我們可以簡單地忽略該包/庫的include_directories嗎?

編輯:如何知道是否應該使用include_directoriestarget_link_libraries包含庫?

如何知道是否應該使用include_directoriestarget_link_libraries包含庫?

除非庫是僅限標頭的庫,否則需要調用target_link_libraries才能使用它。

如果Find*腳本(由find_package()調用調用)使用include目錄設置變量(此信息可以從腳本的文檔中獲得),則它假定將包含這些目錄(通過include_directoriestarget_include_directories )。

IMPORTED目標的情況下,通過target_link_libraries傳播include目錄,通常命名為<namespace>::<name>


在您的特定情況下, include_directories不起作用,因為默認情況下編譯器搜索給定目錄,這通常是通過包管理器安裝庫時。 find_package即使在非系統安裝時也能工作。

我看到了一些可以幫助您改進代碼的事情。

避免過度指定最低版本

我通常希望確保我的CMake腳本不會過度指定版本。 在我看來,在這個腳本中,除了版本3.1之外的任何東西都可以工作。 所以我傾向於改變第一行:

cmake_minimum_required(VERSION 3.1)

始終如一地處理包裹

如您所知, find_package()通常為包設置package_INCLUDE_DIRSpackage_LIBRARIES 我發現一直使用這些變量對於簡化CMake腳本的維護比修剪到最低限度要好得多。 因此我不擔心他們是否需要並且這樣做:

find_package(CURL REQUIRED)
include_directories(${CURL_INCLUDE_DIRS})
add_executable(imu_data_access_cmake_test imu_data_access.cpp)
target_link_libraries(imu_data_access_cmake_test ${CURL_LIBRARIES})

不要將系統包含在源中

請注意,我省略了這一行:

set(SOURCES imu_data_access.cpp ${CURL_INCLUDE_DIRS}/curl/curl.h)

並非每個庫都包含文件需要或應該作為源列出。 作為一般規則,我只包括我的來源,這也是我對你的項目的建議。

一個好的做法是使用target_include_directories()而不是include_directories() 好處是您可以指示包含的可見性,例如,如果您使用以下內容配置庫:

add_library(foo foo.cpp)
target_include_directories(foo PUBLIC foo_include)
target_include_directories(foo PRIVATE private_include)

然后,如果將foo鏈接到可執行bar ,則bar將可以訪問foo_include目錄,但不能訪問private_include 命令include_directories()適用於CMakeLists.txt包含命令的目錄,因此它將應用於此目錄及其子目錄中聲明的任何庫/可執行文件。

對於target_link_libraries() ,行為會有所不同,因為它可以是庫列表,在這種情況下,沒有包含目錄的概念。 但它可以是一個IMPORTED庫,它可以包含更多信息,例如include目錄(例如,Boost和Qt這樣做)。

對於cURL, 文檔指出CURL_LIBRARIES包含庫列表。 在您的情況下,可能會找到cURL標頭,因為默認情況下,CMake將在標准位置搜索標頭,因此在這種情況下, target_link_libraries()對包含沒有影響。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM