सीएमके का उपयोग करके स्रोत निर्देशिका से बाइनरी निर्देशिका में फाइल कॉपी करें


100

मैं क्लेयन पर एक सरल परियोजना बनाने की कोशिश कर रहा हूं। प्रोजेक्ट बनाने के लिए Makefiles (या किसी प्रकार का) बनाने के लिए यह CMake (मैं यहां नया हूं) का उपयोग करता हूं

जब भी मुझे अपना कोड चलाना होगा, मुझे हर बार बाइनरी डायरेक्टरी में कुछ नॉन-प्रोजेक्ट फाइल (कुछ प्रकार की रिसोर्स फाइल) ट्रांसफर करनी होगी।

उस फ़ाइल में परीक्षण डेटा होता है और अनुप्रयोग उन्हें पढ़ने के लिए खोल देता है। मैंने ऐसा करने के कई तरीके आजमाए:

  • के जरिए file(COPY ...

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

    अच्छी लग रही है, लेकिन यह सिर्फ एक बार काम करता है और अगले रन के बाद फ़ाइल को रिकॉपी नहीं करता है।

  • के जरिए add_custom_command

    • OUTPUT संस्करण

      add_custom_command(
              OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/input.txt
              COMMAND ${CMAKE_COMMAND} -E copy
                      ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
                      ${CMAKE_CURRENT_BINARY_DIR}/input.txt)
      
    • TARGET संस्करण

      add_custom_target(foo)
      add_custom_command(
              TARGET foo
              COMMAND ${CMAKE_COMMAND} copy
                      ${CMAKE_CURRENT_BINARY_DIR}/test/input.txt
                      ${CMAKE_SOURCE_DIR})
      

    लेकिन इसमें से कोई भी काम नहीं करता है।

मैं क्या गलत कर रहा हूं?

जवाबों:


127

आप का उपयोग पर विचार कर सकते configure_file साथ COPYONLYविकल्प:

configure_file(<input> <output> COPYONLY)

इसके विपरीत file(COPY ...)यह इनपुट और आउटपुट के बीच एक फ़ाइल-स्तरीय निर्भरता बनाता है, जो है:

यदि इनपुट फ़ाइल को संशोधित किया जाता है तो बिल्ड सिस्टम फाइल को फिर से कॉन्फ़िगर करने और बिल्ड सिस्टम को फिर से बनाने के लिए सीएमके को फिर से चलाएगा।


12
कृपया ध्यान दें कि configure_fileउप-निर्देशिकाओं के साथ काम नहीं करने जा रहा है, भले ही आप फ़ाइलों की सूची बनाने के लिए GLOB का उपयोग करें।
टारेंटयुला

63

दोनों विकल्प वैध हैं और आपके निर्माण के दो अलग-अलग चरणों को लक्षित कर रहे हैं:

  1. file(COPY ...कॉन्फ़िगरेशन चरण में फ़ाइल की प्रतिलिपि बनाता है और केवल इस चरण में। जब आप अपने cmake कॉन्फ़िगरेशन को बदले बिना अपनी परियोजना का पुनर्निर्माण करते हैं, तो यह कमांड निष्पादित नहीं होगी।
  2. add_custom_command जब आप प्रत्येक बिल्ड चरण पर फ़ाइल को कॉपी करना चाहते हैं तो पसंदीदा विकल्प है।

आपके कार्य का सही संस्करण होगा:

add_custom_command(
        TARGET foo POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy
                ${CMAKE_SOURCE_DIR}/test/input.txt
                ${CMAKE_CURRENT_BINARY_DIR}/input.txt)

आप के बीच चयन कर सकते हैं PRE_BUILD, PRE_LINK, POST_BUILD सबसे अच्छा आप के प्रलेखन पढ़ने के लिए है add_custom_command

पहले संस्करण का उपयोग करने के तरीके पर एक उदाहरण यहां पाया जा सकता है: किसी अन्य लक्ष्य के लिए स्रोत उत्पन्न करने के लिए CMake add_custom_command का उपयोग करें


1
क्या यह CMAKE_SOURCE_DIR या CMAKE_CURRENT_SOURCE_DIR है?
स्यात्फ़ुल निज़ाम याहया

1
CMAKE_CURRENT_SOURCE_DIRयदि test/input.txtफ़ाइल वर्तमान CMakeLists.txtफ़ाइल के सापेक्ष है, तो @SyaifulNizamYahya का उपयोग करें । यदि यह जड़ के सापेक्ष है CMakeLists.txt, तो उपयोग करें CMAKE_SOURCE_DIR
मार्क इनग्राम

16

आपके द्वारा आज़माया गया पहला विकल्प दो कारणों से काम नहीं करता है।

सबसे पहले, आप कोष्ठक को बंद करना भूल गए।

दूसरा, DESTINATIONएक निर्देशिका होनी चाहिए, एक फ़ाइल नाम नहीं। मान लें कि आपने कोष्ठक को बंद कर दिया है, तो फ़ाइल नामक फ़ोल्डर में समाप्त हो जाएगी input.txt

इसे काम करने के लिए, बस इसे बदलने के लिए

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

4

मैं यह सुझाव दूंगा कि TARGET_FILE_DIRक्या आप चाहते हैं कि फ़ाइल को आपके .exe फ़ाइल के समान फ़ोल्डर में कॉपी किया जाए।

$ मुख्य फ़ाइल की निर्देशिका (.exe, .so.1.2, .a)।

add_custom_command(
  TARGET ${PROJECT_NAME} POST_BUILD
  COMMAND ${CMAKE_COMMAND} -E copy 
    ${CMAKE_CURRENT_SOURCE_DIR}/input.txt 
    $<TARGET_FILE_DIR:${PROJECT_NAME}>)

VS में, यह cmake स्क्रिप्ट input.txt को उसी फाइल में कॉपी कर देगी, जो आपके अंतिम exe के रूप में है, फिर चाहे वह डिबग हो या रिलीज।


3

यह वही है जो मैंने कुछ संसाधन फ़ाइलों की प्रतिलिपि बनाने के लिए उपयोग किया था: कॉपी-फाइलें त्रुटियों को अनदेखा करने के लिए एक खाली लक्ष्य है

 add_custom_target(copy-files ALL
    COMMAND ${CMAKE_COMMAND} -E copy_directory
    ${CMAKE_BINARY_DIR}/SOURCEDIRECTORY
    ${CMAKE_BINARY_DIR}/DESTINATIONDIRECTORY
    )

मैं भी जोड़ना होगा add_dependencies(MainTarget copy-files)जब मैं MainTarget निर्माण यह स्वचालित रूप से चलाने बनाने के लिए
Herrgott

यह सबसे अच्छा उत्तर (+ हेरगोट की टिप्पणी) जैसा लगता है क्योंकि यह वास्तव में यह सुनिश्चित करता है कि स्रोत का वर्तमान संस्करण हमेशा गंतव्य के निर्माण में है। छोटे कॉपी नौकरियों के लिए यह अच्छी तरह से काम करता है, धन्यवाद। add_dependencies(MainTarget copy-files)रूट CMakeLists.txtफाइल में डालने का मतलब है कि इसे पूरे प्रोजेक्ट में इस्तेमाल किया जा सकता है।
शनि

1

यदि आप करंट डायरेक्टरी से बाइनरी (बिल्ड फ़ोल्डर) फ़ोल्डर में फ़ोल्डर कॉपी करना चाहते हैं

file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/yourFolder/ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/yourFolder/)

तब सिंटेक्स है:

file(COPY pathSource DESTINATION pathDistination)

0

सुझाया गया config_file शायद सबसे आसान समाधान है। हालाँकि, यदि आप मैन्युअल रूप से बिल्ड डायरेक्ट्री से फ़ाइल डिलीट करते हैं तो यह कॉपी कमांड को फिर से रन नहीं करेगा। इस मामले को संभालने के लिए, मेरे लिए निम्नलिखित कार्य:

add_custom_target(copy-test-makefile ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/input.txt)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/input.txt
                   COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
                                                    ${CMAKE_CURRENT_BINARY_DIR}/input.txt
                   DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/input.txt)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.