CMake中使用get_target_property判斷Target是否存在

來源:互聯網
上載者:User

              使用Cmake的add_custom_target建立自訂的Target後,必須將這個Target加入all依賴,否則產生的Makefile不會執行這個Target的內容。這樣會有個問題,如果需要編譯如下目錄:

目錄下有N個目錄,這些目錄下或是目錄,或是檔案,那麼遞迴下去,就會有若干CMakeLists.txt,也就是說,會有若干個add_custom_target(all ...)的存在。進入單獨目錄編譯或許不要緊,但是如果我們在頂層或者中介層執行cmake產生Makefile,就會報重複Target的錯誤,這個重複的Target就是多次添加的all。錯誤如下:

add_custom_target cannot create target "all" because  another target with the same name already exists.  The existing target is a  custom target created in source directorySee documentation  for policy CMP0002 for more details.

只能在葉子編譯而不能在中上層編譯,這樣顯然不行。一個可行的解決方案是,在向all中添加Target前,先判斷Target‘是否存在,如果不存在,則使用add_custom_target添加依賴(add_custom_target的問題在於,它本身不判斷Target是否存在,每次都是建立);如果存在,則使用add_dependencies添加依賴(add_dependencies只是添加依賴,而不會建立Target)。在這裡,使用get_target_property判斷Target存在與否,原型如下:

get_target_property(VAR target property)
這裡的property和VAR相當於一個map索引值對,property是鍵,VAR是值,這個索引值對從屬於target,如果這個target沒有這個鍵,那麼VAR將返回OUTPUT_VALUE-NOTFOUND。

有get必有set,向一個Target添加索引值的方法是set_property,原型如下:

set_property(<GLOBAL                            |              DIRECTORY [dir]                   |              TARGET    [target1 [target2 ...]] |              SOURCE    [src1 [src2 ...]]       |              TEST      [test1 [test2 ...]]     |              CACHE     [entry1 [entry2 ...]]>             [APPEND] [APPEND_STRING]             PROPERTY <name> [value1 [value2 ...]])
這裡功能較多,我們只需要設定TARGET為指定的target名,PROPERTY設定為需要的索引值對即可。如此,判斷一個Target是否存在就可以這麼寫:

get_target_property(OUTPUT_VALUE all STATUS)if(${OUTPUT_VALUE} STREQUAL OUTPUT_VALUE-NOTFOUND)#Target all 不存在else()#Target all 存在endif()
在此基礎上,封裝一個自訂的函數append_dependencies,它向all中添加依賴,在all不存在的情況下,使用add_custom_target建立Target all並且增加依賴,對Target增加索引值對訊息,如果all存在,則使用add_dependencies添加依賴,代碼如下:

function(append_dependencies)    set(multiValueArgs DEPENDENCIES)    cmake_parse_arguments(APPEND_DEPENDENCIES "" "" "${multiValueArgs}" ${ARGN})        get_target_property(OUTPUT_VALUE all STATUS)    if(${OUTPUT_VALUE} STREQUAL OUTPUT_VALUE-NOTFOUND)        add_custom_target(all DEPENDS ${APPEND_DEPENDENCIES_DEPENDENCIES})        set_property(TARGET all PROPERTY STATUS AVAILABLE)    else()        add_dependencies(all DEPENDS ${APPEND_DEPENDENCIES_DEPENDENCIES})    endif()    endfunction()<pre name="code" class="plain">

 使用append_dependencies向all添加依賴,這樣就能有效解決在中上層目錄中Target衝突的現象。 


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.