CMake आउटपुट / बिल्ड डायरेक्टरी


116

मैं CMake के लिए बहुत नया हूँ, और इसे उपयोग करने के तरीके के बारे में कुछ ट्यूटोरियल पढ़ता हूं, और 3 अलग-अलग संकलक के लिए एक कार्यक्रम बनाने के लिए CMake स्क्रिप्ट की कुछ जटिल 50 पंक्तियाँ लिखी हैं। यह शायद सीएमके में मेरे सभी ज्ञान को समाप्त करता है।

अब मेरी समस्या यह है कि मेरे पास कुछ स्रोत कोड हैं, जिनके फ़ोल्डर को मैं प्रोग्राम बनाते समय स्पर्श / गड़बड़ नहीं करना चाहता। मैं चाहता हूं कि सभी सीएमके और makeआउटपुट फाइल और फोल्डर में जाएं ../Compile/, इसलिए मैंने अपनी सीएमके स्क्रिप्ट में कुछ चरों को बदल दिया, और यह कुछ समय के लिए काम किया जब मैंने अपने लैपटॉप पर कुछ ऐसा किया:

Compile$ cmake ../src
Compile$ make

जहाँ मेरे पास उस फ़ोल्डर में एक साफ आउटपुट था जो मैं अभी हूँ, जो कि मैं देख रहा हूँ।

अब मैं दूसरे कंप्यूटर में चला गया, और सीएमके को 2.8.11.2 पर फिर से जोड़ दिया, और मैं लगभग एक वर्ग में वापस आ गया! यह हमेशा उस srcफ़ोल्डर में चीज़ को संकलित करता है जहाँ मेरा CMakeLists.txtस्थित है।

जिस भाग को मैं अपनी सीएमके स्क्रिप्ट में निर्देशिका चुनता हूं वह यह है:

set(dir ${CMAKE_CURRENT_SOURCE_DIR}/../Compile/)
set(EXECUTABLE_OUTPUT_PATH ${dir} CACHE PATH "Build directory" FORCE)
set(LIBRARY_OUTPUT_PATH ${dir} CACHE PATH "Build directory" FORCE)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${dir})
set(CMAKE_BUILD_FILES_DIRECTORY ${dir})
set(CMAKE_BUILD_DIRECTORY ${dir})
set(CMAKE_BINARY_DIR  ${dir})
SET(EXECUTABLE_OUTPUT_PATH ${dir})
SET(LIBRARY_OUTPUT_PATH ${dir}lib)
SET(CMAKE_CACHEFILE_DIR ${dir})

और अब यह हमेशा समाप्त होता है:

-- Build files have been written to: /.../src

क्या मैं कुछ भूल रहा हूँ?


4
आपके द्वारा सेट किए जा रहे सभी चर सेट करने की बहुत कम आवश्यकता है। CMake उन्हें उचित चूक के लिए तैयार करता है। आपको निश्चित रूप से संशोधित या नहीं करना चाहिए । यदि आप इन सभी कॉल्स को हटाते हैं और बस करते हैं तो क्या होगा ? CMAKE_BINARY_DIRCMAKE_CACHEFILE_DIRset()cd Compile; rm -rf *; cmake ../src
Angew अब SO

5
मूल रूप से, जब तक आप सीएमके को चलाते हुए स्रोत निर्देशिका से बाहर हैं, तब तक यह स्रोत निर्देशिका को संशोधित नहीं करेगा, जब तक कि आपका सीएमकेलिस्ट स्पष्ट रूप से इसे नहीं बताता है।
Angew को अब SO

@Angew टिप के लिए धन्यवाद, जो आश्चर्य की बात है! मैंने उन सभी लाइनों को हटा दिया और सिर्फ cmake का उपयोग किया ../src और इसने एक आकर्षण की तरह काम किया! यह बहुत आश्चर्य की बात है क्योंकि मैंने इससे पहले जब मैं पहली बार सीएमके सीख रहा था तब यह कोशिश की और यह काम नहीं किया। कृपया अपना जवाब एक आधिकारिक उत्तर में दें ताकि आप मोटी चर्बी की जाँच कर सकें :)
क्वांटम भौतिक विज्ञानी

1
मुझे बचाने के लिए @Adam बोवेन की टिप्पणी थी कि "आप स्रोत स्रोत के साथ स्रोत निर्देशिका के लिए एक आउट-ऑफ-सोर्स बिल्ड नहीं बना सकते हैं"
और सराफ

जवाबों:


60

आपके द्वारा सेट किए जा रहे सभी चर सेट करने की बहुत कम आवश्यकता है। CMake उन्हें उचित चूक के लिए तैयार करता है। आपको निश्चित रूप से संशोधित या नहीं करना चाहिए । इन्हें केवल-पढ़ने योग्य मानें।CMAKE_BINARY_DIRCMAKE_CACHEFILE_DIR

पहले src निर्देशिका से मौजूदा समस्याग्रस्त कैश फ़ाइल को निकालें:

cd src
rm CMakeCache.txt
cd ..

फिर सभी set()कमांड निकालें और करें:

cd Compile
rm -rf *
cmake ../src

जब तक आप सीएमके को चलाते हुए स्रोत निर्देशिका से बाहर हैं, तब तक यह स्रोत निर्देशिका को संशोधित नहीं करेगा जब तक कि आपका सीएमकेलिस्ट स्पष्ट रूप से इसे नहीं बताता है।

एक बार जब आपके पास यह काम हो जाता है, तो आप यह देख सकते हैं कि सीएमके डिफ़ॉल्ट रूप से चीजें कहां डालता है, और केवल तब ही जब आप डिफ़ॉल्ट स्थानों (जैसे डिफ़ॉल्ट मान EXECUTABLE_OUTPUT_PATH) से संतुष्ट नहीं होते हैं , केवल उन लोगों को संशोधित करें जिनकी आपको आवश्यकता है। और उनमें के सापेक्ष व्यक्त करने के लिए कोशिश CMAKE_BINARY_DIR, CMAKE_CURRENT_BINARY_DIR, PROJECT_BINARY_DIRआदि

यदि आप CMake दस्तावेज़ीकरण को देखते हैं, तो आप वैरिएबल को शब्दार्थ खंडों में विभाजित देखेंगे। बहुत विशेष परिस्थितियों को छोड़कर , आपको "वैरिएबल्स कि सूचना प्रदान करने" के तहत सूचीबद्ध सभी लोगों को सीएमके लेल के अंदर केवल-पढ़ने के लिए इलाज करना चाहिए।


2
मैं src निर्देशिका में बनाता है के साथ cmake का उपयोग शुरू कर दिया ... यह तकनीक शुरू में विफल रही। एक बार जब मैंने src डायरेक्टरी में सभी cmake build files / caches को डिलीट कर दिया तो यह तकनीक काम कर गई। धन्यवाद!
एवी टेविट

18
शायद इसका इस्तेमाल न करने की सलाह देना बेहतर है rm -rf *cd Compileअसफल होने पर यह सुंदर नहीं है ...
रोमन

2
@ रमन मैं इस तरह के कमांड-लाइन उदाहरणों को बहुत अधिक छद्म कोड मानता हूं। यह कम वर्बोज़ और टाइपिंग से अधिक सटीक है "निर्देशिका में प्रवेश करें Compile, वहां सब कुछ हटा दें, और फिर सीएमके को स्रोत के मार्ग के साथ चलाएं।" मैं पाठक के हिस्से पर बुनियादी सामान्य ज्ञान और निर्णय मानता हूं।
एंग्यू को अब SO

@AviTevet: मुझे लगता है कि यह सही उत्तर है। यदि स्रोत निर्देशिका के अंदर पिछले cmake आह्वान से cmake कैश फ़ाइलें हैं, तो आप जनरेट की गई फ़ाइलों के लिए किसी अन्य निर्देशिका को लेने के लिए cmake प्राप्त नहीं करेंगे, जब तक कि आप स्रोत निर्देशिका से सभी पुराने हटा नहीं देते। मेरी राय में सीएमके द्वारा बहुत ही टूटा हुआ व्यवहार। आप दूसरा उत्तर क्यों नहीं लिखते?
जो सो

113

ऐसा लगता है कि आप स्रोत के निर्माण से बाहर चाहते हैं । ऐसे कुछ तरीके हैं जिनसे आप आउट ऑफ सोर्स बना सकते हैं।

  1. तुम जो कर रहे थे, करो

    cd /path/to/my/build/folder
    cmake /path/to/my/source/folder

    जो cmake एक उत्पन्न करने के लिए कारण होगा निर्माण पेड़ में /path/to/my/build/folderके लिए स्रोत पेड़ में /path/to/my/source/folder

    एक बार जब आप इसे बना लेते हैं, तो cmake याद रहता है कि स्रोत फ़ोल्डर कहां है - इसलिए आप बिल्ड ट्री पर cmake को फिर से जोड़ सकते हैं

    cmake /path/to/my/build/folder

    या और भी

    cmake .

    यदि आपकी वर्तमान निर्देशिका पहले से ही निर्मित फ़ोल्डर है।

  2. 3.13 या बाद के सीएमके के लिए, स्रोत को सेट करने और फ़ोल्डरों को बनाने के लिए इन विकल्पों का उपयोग करें

    cmake -B/path/to/my/build/folder -S/path/to/my/source/folder
  3. पुराने सीएमके के लिए, स्रोत को सेट करने और फ़ोल्डर बनाने के लिए कुछ अनजाने विकल्पों का उपयोग करें :

    cmake -B/path/to/my/build/folder -H/path/to/my/source/folder

    जो (1) के समान ही काम करेगा, लेकिन वर्तमान कार्य निर्देशिका पर निर्भरता के बिना।

CMake डिफ़ॉल्ट रूप से बिल्ड ट्री में अपने सभी आउटपुट डालता है , इसलिए जब तक आप उदारतापूर्वक ${CMAKE_SOURCE_DIR}या ${CMAKE_CURRENT_SOURCE_DIR}अपने cmake फ़ाइलों में उपयोग नहीं कर रहे हैं, तब तक यह आपके स्रोत पेड़ को नहीं छूना चाहिए ।

सबसे बड़ी बात जो गलत हो सकती है वह यह है कि अगर आपने पहले अपने स्रोत के पेड़ में एक बिल्ड ट्री जनरेट किया है (यानी आपके पास सोर्स बिल्ड में है)। एक बार जब आप इसे (1) के दूसरे भाग में kicks के ऊपर कर लेते हैं, और cmake स्रोत में कोई बदलाव नहीं करता है या स्थानों का निर्माण नहीं करता है। इस प्रकार, आप इन-सोर्स बिल्ड के साथ सोर्स डायरेक्टरी के लिए आउट-ऑफ-सोर्स बिल्ड नहीं बना सकते । आप CMakeCache.txtस्रोत निर्देशिका से (न्यूनतम पर) निकालकर इसे आसानी से ठीक कर सकते हैं । कुछ अन्य फाइलें (अधिकतर CMakeFilesनिर्देशिका में) हैं जो सीएमके उत्पन्न करती हैं कि आपको भी हटा देना चाहिए, लेकिन ये सीमेक को स्रोत वृक्ष का निर्माण पेड़ के रूप में नहीं करेंगे।

चूंकि आउट-ऑफ-सोर्स बिल्ड अक्सर इन-सोर्स बिल्ड की तुलना में अधिक वांछनीय होते हैं, आप सोर्स बिल्ड से बाहर की आवश्यकता के लिए अपने cmake को संशोधित करना चाह सकते हैं:

# Ensures that we do an out of source build

MACRO(MACRO_ENSURE_OUT_OF_SOURCE_BUILD MSG)
     STRING(COMPARE EQUAL "${CMAKE_SOURCE_DIR}"
     "${CMAKE_BINARY_DIR}" insource)
     GET_FILENAME_COMPONENT(PARENTDIR ${CMAKE_SOURCE_DIR} PATH)
     STRING(COMPARE EQUAL "${CMAKE_SOURCE_DIR}"
     "${PARENTDIR}" insourcesubdir)
    IF(insource OR insourcesubdir)
        MESSAGE(FATAL_ERROR "${MSG}")
    ENDIF(insource OR insourcesubdir)
ENDMACRO(MACRO_ENSURE_OUT_OF_SOURCE_BUILD)

MACRO_ENSURE_OUT_OF_SOURCE_BUILD(
    "${CMAKE_PROJECT_NAME} requires an out of source build."
)

उपरोक्त मैक्रो आमतौर पर उपयोग किए जाने वाले मॉड्यूल से आता है जिसे कहा जाता है MacroOutOfSourceBuildMacroOutOfSourceBuild.cmakeGoogle पर इसके लिए कई स्रोत हैं लेकिन मैं मूल को ढूंढ नहीं पा रहा हूं और यहां पूर्ण रूप से शामिल करना काफी कम है।

दुर्भाग्य से सीमेक ने आमतौर पर मैक्रो को लागू करने के समय तक कुछ फाइलें लिखी हैं, इसलिए हालांकि यह आपको वास्तव में निर्माण करने से रोक देगा, जिसे आपको अभी भी हटाना होगा CMakeCache.txtऔर CMakeFiles

आपको उन रास्तों को सेट करने के लिए उपयोगी हो सकता है जो बायनेरिज़, साझा और स्टैटिक लाइब्रेरीज़ को लिखे गए हैं - किस स्थिति में मैं एक 'बिन' डायर में सेमीकेक आउटपुट कैसे बनाऊँ? (अस्वीकरण, मेरे पास उस प्रश्न पर शीर्ष मतदान का उत्तर है ... लेकिन यह है कि मुझे इसके बारे में कैसे पता है)।


वास्तव में स्रोत फ़ोल्डर को सेट करने का विकल्प है -S, न कि-H
smac89

@ smac89 धन्यवाद! ऐसा लगता है कि उन्होंने 3.13 में उन्हें प्रलेखित किया है - मैंने आधुनिक सीएमके को प्रतिबिंबित करने के लिए उत्तर अपडेट किया है।
एडम बोवेन

8

मेरी टिप्पणी को एक उत्तर में बदलना:

मामले में किसी ने भी वही किया जो मैंने किया था, जो सभी निर्माण फ़ाइलों को स्रोत निर्देशिका में डालकर शुरू किया गया था:

cd src
cmake .

cmake निर्माण फ़ाइलें और कैश फ़ाइलें (का एक समूह डाल देंगे CMakeCache.txt, CMakeFiles, cmake_install.cmakeमें, आदि) srcdir।

स्रोत बिल्ड से बाहर बदलने के लिए, मुझे उन सभी फ़ाइलों को निकालना पड़ा। तब मैं कर सकता था जो @Angew ने उनके जवाब में सिफारिश की थी:

mkdir -p src/build
cd src/build
cmake ..

7

सीएमके विकी के रूप में :

CMAKE_BINARY_DIR यदि आप स्रोत बना रहे हैं, तो यह CMAKE_SOURCE_DIR के समान है, अन्यथा यह आपके बिल्ड ट्री की शीर्ष स्तर की निर्देशिका है

आउट-ऑफ-सोर्स निर्माण शुरू किया गया था, यह निर्धारित करने के लिए इन दो चर की तुलना करें


6

आपको अपनी स्क्रिप्ट में हार्ड कोडेड बिल्ड डीआईआर नाम पर भरोसा नहीं करना चाहिए, इसलिए लाइन के साथ ../Compile बदलना होगा।

यह इसलिए है क्योंकि यह उपयोगकर्ता के लिए होना चाहिए जहां संकलन करना है।

इसके बजाय पूर्वनिर्धारित चर में से एक का उपयोग करें: http://www.cmake.org/Wiki/CMake_Useful_Variables (देखें CMAKE_BINARY_DIRऔर CMAKE_CURRENT_BINARY_DIR)


2
यह वास्तव में मैं क्या देख रहा था - CMAKE_CURRENT_BINARY_DIRआमतौर पर वर्तमान बाइनरी बिल्ड पथ के बारे में बताऊंगा। संभवतया आश्रित लिबास / बिन बिल्ड की स्थापना के लिए उपयोग किया जा सकता है।
परसोिश
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.