2011-12-08 10 views
13

CMakeには事前定義されたGettextカタログを含むフォルダがあります。作成時にフォルダにコピーしてから変更します。しかし問題は、ターゲットを実行するたびにローカルコピー(おそらく変更されている)にあらかじめ定義されたファイルがコピーされることです。ファイルが前の状態と異なる場合はコピーする方法はありますか?オリジナルファイルが変更された場合はCMakeコピー

私はまた、これを行う方法はCMake生成時にそれらをコピーすることだと考えていましたが、人々はフォルダを削除して物事をねじ込むかもしれないので、少し疲れました。また、ビルド時にのみ、生成時にコマンドを実行する方法もわかりません。

答えて

5

私はこれをしばらく前に修正することができましたが、この回答は忘れました。申し訳ありませんがこれをスキップして答えを持っていないすべての人々!

# ----- 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は(レポにコミットする場合を除く)編集したユーザであることを意味していないストックpoファイルを含むディレクトリです。 langDirは 'lang'のビルドディレクトリにあります。それは通過し、ファイルの年齢に基づいてそれをコピーまたは更新します。

+0

素晴らしい例!! – gone

20

ファイルに依存するカスタムコマンドを使用できるはずです。次のようなものがあります:

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) 

私には分かりません。現在使用しているCMakeコードを提供するのに役立つかもしれません。

また、 "$ {CMAKE_COMMAND} -E copy_if_different"を試してみることもできます。コマンドの依存関係を考えれば、これが違うのかどうかはわかりませんが、確かに何かが欠落している可能性があります。あるいは、makeの出力を使用していないと違うかもしれません。


あなたが「発生時刻」(あなたはcmakeの実行)でコピーをやってみたい場合は、このコマンドを使用することができます(私は私の構文が正しいことだと思うが、私はそれをテストしていない):

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

COPYの代わりにINSTALLを使用すると、動作が少し異なります。

生成時に任意のプロセスを実行する必要がある場合は、execute_processコマンドを試してください。

もちろん、詳細はthe CMake documentationを参照してください。

+1

"cp"はUNIX固有のものですが、私はそれを撃つでしょう。 – Jookia

+1

"cp"を使用するのではなく、単に "$ {CMAKE_COMMAND} -E copy"を使用して "cmake -E"を実行して、利用可能なcmake -Eクロスプラットフォームツールのようなコマンド実行することができます。 "copy_if_different"さえあります...このようなカスタムコマンドを使用することは完璧な解決策であり、私が与えた答えもそうです。 – DLRdave

+0

ああ、私はこれまでに一度もそれを使いましたが、それを完全に忘れました。ポインタありがとう。 –

7

もう1つの方法は、configure_fileCOPYONLY引数を使用することです。

configure_file(input_file output_file COPYONLY) 

これは、任意の変数置換を実行しないであろうと、あなたがmakeを実行したときに「INPUT_FILE」をコピーします。しかし、それはcmakeの実行を引き起こし、これは時間消費のために望ましくないかもしれません。

関連する問題