2012-06-19 30 views
25

我創建使用的文件列表:如何使用cmake安裝文件的層次結構?

file(GLOB_RECURSE DEPLOY_FILES "${PROJECT_SOURCE_DIR}/install/*") 

我想安裝所有在/ usr/myproject的這些文件中的/但我要保持在安裝文件夾中的文件樹:

install/junk 
install/other/junk2 
install/other/junk3 

如果我使用:

install(FILES ${DEPLOY_FILES} DESTINATION "usr/myproject") 

所有文件在/ usr/myproject的作爲結束

/usr/myproject/junk 
/usr/myproject/junk2 
/usr/myproject/junk3 

如何使安裝命令可以跟蹤相對路徑?

我已經做手工在for循環中解決這個問題的工作:

set(BASE "${PROJECT_SOURCE_DIR}/install") 
foreach(ITEM ${DEPLOY_FILES}) 
    get_filename_component(ITEM_PATH ${ITEM} PATH) 
    string(REPLACE ${BASE} "" ITEM_PATH ${ITEM_PATH}) 
    install(FILES ${ITEM} DESTINATION "usr/myproject${ITEM_PATH}") 
endforeach() 

...但是這很煩人的事情。當然有更簡單的方法?

(廣東話看到安裝文檔任何東西,雖然...)

+1

簡單有趣的是,他們難以做出簡單的**'cp -r' **操作。 – ulidtko

回答

23

用途:

INSTALL(DIRECTORY <directory> DESTINATION usr/myproject) 

(見此處查看詳情:http://www.cmake.org/cmake/help/v2.8.8/cmake.html#command:install

INSTALL(DIRECTORY .... )保留目錄結構。但是,如果您使用install作爲<directory>,那麼最終會得到usr/myproject/install/....,這不是您想要的。

有兩種方法可以做到這一點:

  1. 使用INSTALL(FILES .... DESTINATION usr/myproject)安裝直接躺在install/文件,然後使用INSTALL(DIRECTORY .... DESTINATION usr/myproject),手工列出的目錄進行安裝。

  2. 在原來的崗位使用您的通配符的命令,然後確定哪些項目是文件,這些文件的目錄,'move目錄項到一個單獨的列表,並分別喂名單INSTALL(FILES ...)INSTALL(DIRECTORY ...)

    file(GLOB DEPLOY_FILES_AND_DIRS "${PROJECT_SOURCE_DIR}/install/*") 
    foreach(ITEM ${DEPLOY_FILES_AND_DIRS}) 
        IF(IS_DIRECTORY "${ITEM}") 
         LIST(APPEND DIRS_TO_DEPLOY "${ITEM}") 
        ELSE() 
         LIST(APPEND FILES_TO_DEPLOY "${ITEM}") 
        ENDIF() 
    endforeach() 
    INSTALL(FILES ${FILES_TO_DEPLOY} DESTINATION usr/myproject) 
    INSTALL(DIRECTORY ${DIRS_TO_DEPLOY} DESTINATION usr/myproject) 
    

注:根據您安裝文件的類型,其他INSTALL(...)命令可能更合適(如INSTALL(TARGETS ....)安裝您的庫/可執行文件

+0

@Fraser感謝編輯,我完全錯過了錯誤的格式。 –

40

安裝最簡單的方法。一切從給定的目錄是:

install(DIRECTORY mydir/ DESTINATION dir/newname) 

尾隨'/'很重要。 沒有它mydir將被安裝到newname/mydir

從cmake的文檔:

每個目錄名的最後一個組件被附加到目標 目錄,但一個斜線可以用來避免這種情況,因爲它 留下的最後一個組件空。

+0

這是一個更簡單的解決方案,通過globbing等謝謝。 –

+4

感謝「跟蹤」/「很重要」。 – fechidal89

18

如果你有文件的列表,你可以簡單地遍歷它們,並使用get_filename_component()解壓目錄部分:

foreach (file ${INCLUDE_FILES}) 
    get_filename_component(dir ${file} DIRECTORY) 
    install(FILES ${file} DESTINATION include/${dir}) 
endforeach() 

完成。 ;-)

+0

這是一個非常好的和簡單的答案。除了解析文件列表並逐個安裝它們之外,不需要執行其他技巧。 +1 – bartgol

+0

非常簡單。 – Gallaecio