[英]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_directories
或target_link_libraries
包含庫? 如果包/庫有.so
文件,我們可以簡單地忽略該包/庫的include_directories
嗎?
編輯:如何知道是否應該使用include_directories
和target_link_libraries
包含庫?
如何知道是否應該使用
include_directories
或target_link_libraries
包含庫?
除非庫是僅限標頭的庫,否則需要調用target_link_libraries
才能使用它。
如果Find*
腳本(由find_package()
調用調用)使用include目錄設置變量(此信息可以從腳本的文檔中獲得),則它假定將包含這些目錄(通過include_directories
或target_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_DIRS
和package_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.