2017-02-20 79 views
1

從CMake的FIND_PACKAGE獲取包含和庫路徑時,你知道一個技巧來獲得統一的輸出術語嗎?Unifying CMake的FIND_PACKAGE

有時它是FOO_INCLUDE。有時候它是FOO_INCLUDE_PATH。等

例如,我想找到一種方法來確保FOO_INCLUDE和FOO_LIB在FOO_FOUND設置爲TRUE後調用FIND_PACKAGE後總是定義。

+1

現代查找包的實現確實提供了像'Foo :: Foo'這樣的IMPORTED目標(以避免需要知道包含路徑,庫等依賴關係及其變量符號)。 – Florian

+0

謝謝你的回答弗洛裏安。你能給我一個這樣一個導入目標的例子嗎?據我瞭解CMake的FIND_PACKAGE函數的文檔,這些目標應該在FindFOO.cmake文件中定義,但並非總是如此(例如FindMPI)。因此,說通過輸入目標可以達到統一可能是真實的,但是現在認爲它是統一的是錯誤的。因此,它不能解決我的問題。 – Aleph

+1

除了'FOO_FOUND'和一些特殊的「查找」變量外,CMake **不強制執行'Find'腳本來設置特定的變量**。所以你的問題的答案是'不,沒有統一的方式。'然而,你可以編寫自己的函數/宏來處理'find_package'的後處理結果。在該函數中,您可以檢查常見模式(* FOO_INCLUDE *,* FOO_INCLUDE_PATH *,* FOO_INCLUDE_DIR *等)並將所需變量設置爲適當的值。 – Tsyvarev

回答

0

談到我的意見爲答案

爲了避免需要知道include路徑,圖書館等的依賴和他們的變量符號現代find_package的實施確實提供了像Foo::FooIMPORTED目標。但是,正如@Tsyvarev所評論的那樣 - 遠遠沒有通過所有CMake的find modules統一。

所以推廣的CMake's Sample Find Module implementation,你可以用一個覆蓋find_package()宏版本類似下面的統一你find_package()電話:

cmake_minimum_required(VERSION 3.2) 

project(UnifiedFindPackage) 

macro(unify_vars _result) 
    set(${_result} "") 
    foreach(_i IN ITEMS ${ARGN}) 
     if (${_i}) 
      list(APPEND ${_result} "${${_i}}") 
     endif() 
    endforeach() 
endmacro() 

macro(find_package _name) 
    _find_package(${_name} ${ARGN}) 
    if (${_name}_FOUND AND NOT TARGET ${_name}::${_name}) 
     add_library(${_name}::${_name} STATIC IMPORTED GLOBAL) 
     unify_vars(_var ${_name}_LIBRARY ${_name}_LIB) 
     if (_var) 
      set_target_properties(${_name}::${_name} PROPERTIES IMPORTED_LOCATION "${_var}") 
     endif() 
     if (${_name}_LIBRARY_RELEASE) 
      set_property(TARGET ${_name}::${_name} APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) 
      set_target_properties(${_name}::${_name} PROPERTIES IMPORTED_LOCATION_RELEASE "${${_name}_LIBRARY_RELEASE}") 
     endif() 
     if (${_name}_LIBRARY_DEBUG) 
      set_property(TARGET ${_name}::${_name} APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) 
      set_target_properties(${_name}::${_name} PROPERTIES IMPORTED_LOCATION_DEBUG "${${_name}_LIBRARY_DEBUG}") 
     endif()    
     if (${_name}_LIBRARIES) 
      set_property(TARGET ${_name}::${_name} APPEND PROPERTY INTERFACE_LINK_LIBRARIES "${${_name}_LIBRARIES}") 
     endif() 
     unify_vars(_var ${_name}_INCLUDE_DIRS ${_name}_INCLUDE_PATH) 
     if (_var) 
      set_property(TARGET ${_name}::${_name} APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${_var}") 
     endif() 
     unify_vars(_var ${_name}_COMPILE_FLAGS ${_name}_DEFINITIONS) 
     if (_var) 
      set_property(TARGET ${_name}::${_name} APPEND PROPERTY INTERFACE_COMPILE_OPTIONS "${_var}") 
     endif() 
    endif()    
endmacro() 

find_package(MPI REQUIRED) 

add_executable(${PROJECT_NAME} main.c) 
target_link_libraries(${PROJECT_NAME} MPI::MPI) 

這應該只展示一個可能的統一,可以按需要的基礎上延長。

編輯:把它變成社區維基答案。請隨時貢獻。

該代碼在本示例中用MPI查找模塊結果進行了測試。

+0

非常感謝!我會在今天測試您的解決方案並在此處作出回覆。 – Aleph