2012-06-19 7 views
25

He creado una lista de archivos usando:¿Cómo puedo instalar una jerarquía de archivos usando cmake?

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

Quiero instalar todos estos archivos en/usr/miproyecto/pero quiero mantener el árbol de archivos en la carpeta instalada:

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

si uso:

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

Todos los archivos terminan en/usr/miproyecto como:

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

¿Cómo puedo hacer que el comando de instalación realice un seguimiento de las rutas relativas?

he trabajado en torno al tema por hacerlo de forma manual en un bucle 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() 

... pero esto es molesto para hacerlo. Seguramente hay una manera más fácil?

(no puede ver nada en la documentación de instalación, aunque ...)

+1

Es simplemente divertido cómo es difícil hacer una operación trivial ** 'cp -r' **. – ulidtko

Respuesta

23

Uso:

INSTALL(DIRECTORY <directory> DESTINATION usr/myproject) 

(ver aquí para más detalles: http://www.cmake.org/cmake/help/v2.8.8/cmake.html#command:install)

INSTALL(DIRECTORY .... ) conserva la estructura de directorios. Pero, si usa install como <directory>, terminaría con usr/myproject/install/.... que no es lo que desea.

Hay dos maneras de hacer esto:

  1. Uso INSTALL(FILES .... DESTINATION usr/myproject) para instalar los archivos que se encuentran directamente en install/, a continuación, utilizar INSTALL(DIRECTORY .... DESTINATION usr/myproject) y manualmente una lista de los directorios de instalar.

  2. usar los comando globbing en su puesto original, a continuación, determinar cuáles son las entradas de archivos, que son directorios,'move las entradas de directorio a una lista separada y alimentar a las listas de INSTALL(FILES ...) y INSTALL(DIRECTORY ...) respectivamente.

    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) 
    

Nota: Dependiendo del tipo de archivos que instala, otros INSTALL(...) comandos podría ser más apropiado (por ejemplo INSTALL(TARGETS ....) para instalar sus bibliotecas/ejecutables

+0

@Fraser Gracias por la edición, me perdí totalmente el formato incorrecto. –

40

La forma más sencilla de instalar.. todo, desde un directorio dado es:

install(DIRECTORY mydir/ DESTINATION dir/newname) 

Arrastrando '/' es significante. Sin él, mydir se instalaría en newname/mydir.

a partir de documentos cmake:

El último componente del nombre de cada directorio se añade al directorio de destino sino una barra diagonal se puede utilizar para evitar esto porque deja el último componente vacía.

+0

Esta es una solución mucho más simple que engloba, etc. Gracias. –

+4

Gracias por "Trailing '/' es significativo." – fechidal89

18

Si usted tiene una lista de archivos, puede simplemente bucle sobre ellas y utilizar get_filename_component() para extraer la parte del directorio:

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

Done. ;-)

+0

Esta es una respuesta realmente buena y simple. No es necesario hacer más trucos que analizar la lista de archivos e instalarlos de uno en uno. +1 – bartgol

+0

Maravillosamente simple. – Gallaecio

Cuestiones relacionadas