2012-06-19 12 views
25

stworzyłem listę plików za pomocą:Jak mogę zainstalować hierarchię plików za pomocą cmake?

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

Chcę zainstalować wszystkie te pliki w/usr/myproject/Ale chcę, aby utrzymać drzewo plików zainstalowanego folderu:

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

Jeśli używam:

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

Wszystkie pliki kończy się w katalogu/usr/myproject jak:

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

Jak mogę uczynić polecenie instalacji śledź względne ścieżki?

Pracowałem wokół kwestii, wykonując go ręcznie w pętli 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() 

... ale to jest denerwujące zrobić. Z pewnością jest łatwiejszy sposób?

(mogę zobaczyć coś w docs instalują chociaż ...)

+1

To po prostu zabawne, w jaki sposób f * & ing trudne mogą wykonać trywialną operację ** 'cp -r' **. – ulidtko

Odpowiedz

23

Zastosowanie:

INSTALL(DIRECTORY <directory> DESTINATION usr/myproject) 

(zobacz tutaj szczegóły: http://www.cmake.org/cmake/help/v2.8.8/cmake.html#command:install)

INSTALL(DIRECTORY .... ) zachowuje strukturę katalogów. Ale jeśli użyjesz install jako <directory>, skończysz z usr/myproject/install/...., co nie jest tym, czego potrzebujesz.

Istnieją dwa sposoby, aby to zrobić:

  1. Zastosowanie INSTALL(FILES .... DESTINATION usr/myproject) Aby zainstalować pliki, które leżą bezpośrednio w install/, a następnie użyć INSTALL(DIRECTORY .... DESTINATION usr/myproject) i ręcznie listy katalogów do zainstalowania.

  2. Użyj polecenia uogólniające w swoim pierwotnym stanowisku, a następnie określić, które wpisy są pliki, które są katalogi,'move wpisów katalog na oddzielnej liście i paszy list do INSTALL(FILES ...) i INSTALL(DIRECTORY ...) odpowiednio.

    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) 
    

Uwaga: W zależności od rodzaju plików instalowanych inne INSTALL(...) polecenia może być bardziej odpowiednie (np INSTALL(TARGETS ....) zainstalowanie bibliotek/wykonywalne

+0

@Fraser Dzięki za edycję, całkowicie pominąłem niewłaściwe formatowanie. –

40

Najprostszym sposobem zainstalowania.. wszystko z podanego katalogu:

install(DIRECTORY mydir/ DESTINATION dir/newname) 

Końcowe "/" jest znaczące. Bez niego mydir zostanie zainstalowany pod numerem .

Od docs CUpewnij:

Ostatnim elementem każdej nazwy katalogu jest dodawane do katalogu docelowego ale końcowy ukośnik mogą być wykorzystane, aby tego uniknąć, ponieważ opuszcza ostatni składnik pusty.

+0

To jest o wiele prostsze rozwiązanie niż globbing itp. Dzięki. –

+4

Podziękowania dla "Trailing"/"są znaczące." – fechidal89

18

Jeśli masz listę plików, można po prostu pętla nad nimi i wykorzystywać get_filename_component() wyodrębnić część katalogów:

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

zrobić. ;-)

+0

To jest naprawdę dobra i prosta odpowiedź. Nie trzeba robić sztuczek innych niż analizowanie listy plików i instalowanie ich pojedynczo. +1 – bartgol

+0

Pięknie proste. – Gallaecio

Powiązane problemy