2011-12-08 6 views
13

En CMake tengo una carpeta que contiene catálogos de Gettext predefinidos, que en el momento de la compilación lo copio en una carpeta y luego los modifico. Pero el problema es que cada vez que ejecuto el objetivo, copio el archivo predefinido en la copia local (que probablemente esté modificada). ¿Hay alguna manera de copiar si el archivo es diferente a un estado anterior, de lo contrario, déjelo en blanco?CMake copy if original file changed

También pensaba que una forma de hacerlo sería copiarlos en el tiempo de generación de CMake, pero me siento un poco cansado de hacerlo ya que las personas pueden eliminar las carpetas y arruinar las cosas. Además, no sé cómo ejecutar comandos en tiempo de generación, solo en tiempo de compilación.

Respuesta

5

Muy bien, logré solucionar esto hace un tiempo, pero se me olvidó esta respuesta. Lo siento todas las personas que se saltearon esto y no tuvieron la respuesta!

# ----- Copy and merge across the po files that come with the source. 

message("Copying and updating stock translations...") 

file(GLOB poFiles "${stockDir}/*.po") 

foreach(file ${poFiles}) 
    # Get the language name, like en_US or zh_CN from the name of the po file, so 
    # 'en_US.po' or 'zh_CN.po' become 'en_US' or 'zh_CN.po' 
    get_filename_component(langName ${file} NAME_WE) 

    set(newFile "${langDir}/${langName}.po") 

    if(NOT EXISTS ${newFile}) 
    execute_process(COMMAND ${MSGMERGE_EXECUTABLE} 
     "--output-file" ${newFile} ${file} ${potFile} 
     OUTPUT_QUIET ERROR_VARIABLE error RESULT_VARIABLE ret) 

    if(ret) # Have to do this hack as msgmerge prints to stderr. 
     message(SEND_ERROR "${error}") 
    endif() 

    message(" '${langName}' copied.") 
    elseif(${file} IS_NEWER_THAN ${newFile}) 
    execute_process(COMMAND ${MSGMERGE_EXECUTABLE} 
     "--update" ${newFile} ${file} 
     OUTPUT_QUIET ERROR_VARIABLE error RESULT_VARIABLE ret) 

    if(ret) # Have to do this hack as msgmerge prints to stderr. 
     message(SEND_ERROR "${error}") 
    endif() 

    message(" '${langName}' merged.") 
    endif() 
endforeach() 

stockDir es el directorio que contiene los archivos almacenados po que no están destinados a ser editados por el usuario (a menos que comprometerse con el repositorio). langDir está en el directorio de compilación debajo de 'lang'. Se procesa y copia o actualiza según la edad de los archivos.

+0

¡Gran ejemplo! – gone

20

Creo que debería poder usar un comando personalizado que depende del archivo. Algo como:

add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/output.file 
    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/input.file ${CMAKE_CURRENT_BINARY_DIR}/output.file 
    MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/input.file) 

Avísame si eso no lo hace. Puede ser útil proporcionar el código CMake que está utilizando actualmente.

También podría probar "$ {CMAKE_COMMAND} -E copy_if_different"; no me queda claro si esto sería diferente dadas las dependencias del comando, pero sin duda podría estar pasando algo por alto, o podría ser diferente si no está usando la salida "hacer".


En caso de que quiera intentar hacer la copia en el "tiempo de generación" (cuando se ejecuta cmake), puede utilizar este comando (creo que mi sintaxis es correcta, pero no he probado es):

file(COPY 
    ${CMAKE_CURRENT_SOURCE_DIR}/input.file 
    DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/) 

El uso de INSTALL en lugar de COPY proporciona un comportamiento ligeramente diferente.

Si necesita ejecutar un proceso arbitrario en el momento de la generación, intente con el comando execute_process.

Por supuesto, para más detalles, vea the CMake documentation.

+1

"cp" es unix específico, pero lo intentaré. – Jookia

+1

En lugar de usar "cp", simplemente puede usar "$ {CMAKE_COMMAND} -E copy" - ejecutar "cmake -E" sin ningún otro argumento para ver la lista de comandos de herramienta compatibles con cmake -E disponibles en varias plataformas poder correr. Incluso hay un "copy_if_different" ... Usar un comando personalizado como este es la solución perfecta, y la respuesta que le habría dado también. – DLRdave

+0

Oh sí, lo usé al menos una vez pero me olvidé por completo. Gracias por el puntero. –

7

Otra opción es usar configure_file con el argumento COPYONLY.

configure_file(input_file output_file COPYONLY) 

Esto no realizará ninguna sustitución de variables y copiará "archivo_entrada" cuando ejecuta make. Pero desencadena una ejecución cmake y esto puede ser indeseable debido al consumo de tiempo.