[英]CMake and FIND_PACKAGE
確保cmake僅從特定根目錄中查找庫和標頭的最佳方法是什么。
假如說:
我可以使用NO_DEFAULT_PATH並指定查找路徑來完成一半,但我對此沒有完整的證明解決方案,因為我始終依賴於FindXXX.cmake或xxxConfig.cmake的實現方式。 例如,如果調試/發布文件具有不同的名稱,例如,在我的/ mysdkroot /中,我僅具有調試文件,並且在系統中僅存在發布,則對於某些庫,它可能會首先找到該發布,而不是首先找到調試,這是因為我無法將搜索范圍縮小到該文件夾。
NO_DEFAULT_PATH
是一個好的開始。 但是,我將啟用一種查找包的方法,那就是使用CMAKE_PREFIX_PATH
:
NO_PACKAGE_ROOT_PATH
NO_CMAKE_ENVIRONMENT_PATH
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_PACKAGE_REGISTRY
NO_CMAKE_SYSTEM_PATH
NO_CMAKE_SYSTEM_PACKAGE_REGISTRY
這將禁用它們,除了CMAKE_PREFIX_PATH
指定的路徑。
然后將您的前綴路徑設置為您的SDK:
set(CMAKE_PREFIX_PATH "/mysdkroot")
然后,實際上,您仍然取決於如何實現這些findXXX.cmake
和那些XXX-config.cmake
。 幸運的是,您可以完全使用命令多態來更改其行為:
set(current-find-package "")
function(find_package)
set(current-find-package "${ARGV1}")
# The leading underscore mean the original command
_find_package(${ARGV})
endfunction()
# function usually used in findXX.cmake modules
function(find_library)
if("${current-find-package}" STREQUAL "SomePakage")
# TODO: remove unwanted paths in ARGV
_find_library(${ARGV} NO_DEFAULT_PATH)
endif()
endfunction()
盡管這可行,但我建議您不要濫用它,或者使用它時要非常小心 。 您不想引入令人驚訝的行為。
您主要關心的是XX-config.cmake
和findXX.cmake
, findXX.cmake
試圖在您的SDK路徑之外查找庫。
首先, XX-config.cmake
通常行為正確。 如果找到了XX-config.cmake
,它將不會嘗試在路徑之外查找庫。 它已經知道在哪里可以找到那些庫。
然后,您擁有的FindXX.cmake
可能會出現不正確的行為,因為它們主要是在不同的cmake時代用手寫的。
我的建議是替換行為不理想的模塊。 只需提供自己的自定義FindXX.cmake
模塊即可正常運行。 如果維護者提供的服務沒有按照您的意願進行,請不要使用它們,只需提供您自己的服務即可。
確保cmake僅從特定的根目錄中查找庫和標頭。
根據“根目錄”是真正的“根”的方式,您可以嘗試將CMAKE_FIND_ROOT_PATH變量設置為該目錄:
set(CMAKE_FIND_ROOT_PATH "/mysdkroot")
伴隨將CMAKE_FIND_ROOT_PATH_MODE_*
變量設置為ONLY,可以強制相應的find_*
命令僅在給定目錄下搜索:
# 'find_path' will search only under CMAKE_FIND_ROOT_PATH.
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE "ONLY")
# 'find_library' will search only under CMAKE_FIND_ROOT_PATH.
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY "ONLY")
# 'find_package' will search 'XXXConfig.cmake' (not 'FindXXX.cmake'!) only under CMAKE_FIND_ROOT_PATH.
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE "ONLY")
這種方法的局限性在於CMake將CMAKE_FIND_ROOT_PATH
目錄解釋為文件系統根目錄 ,而不是安裝前綴 。 也就是說,CMake假定(在Linux環境上)庫位於/mysdkroot/usr/lib
,標頭位於/mysdkroot/usr/include
。
您可以結合使用CMAKE_FIND_ROOT_PATH
和CMAKE_PREFIX_PATH
設置,以告知CMake 安裝目錄 :
set(CMAKE_FIND_ROOT_PATH /mysdk)
set(CMAKE_PREFIX_PATH /root) # Not sure whether setting prefix to `/` would work.
具有與
set(CMAKE_PREFIX_PATH /mysdk/root)
但是,如果CMake在給定前綴下找不到某些內容,那么它將不會搜索/usr/include
(將CMAKE_FIND_ROOT_PATH_MODE_INCLUDE
設置為ONLY
)。 相反,它將嘗試/mysdk/usr/include
。 如果您的系統上沒有給定的目錄,則在該目錄下找不到任何內容。
請注意,不能肯定100%CMake所找到的內容都不會位於特定根目錄之外。 您可能希望FindXXX.cmake
在一個“正常”的方式,即用寫入find_*
命令,但沒有什么能夠阻止以不同的方式寫這些腳本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.