CMake का उपयोग करके किसी फ़ोल्डर में सभी फ़ाइलों को स्वचालित रूप से एक लक्ष्य में जोड़ें?


163

मैं विजुअल C ++, XCode और makefiles से CMake में अलग-अलग बिल्ड मैनेजमेंट सिस्टम से क्रॉस प्लेटफॉर्म प्रोजेक्ट को बदलने पर विचार कर रहा हूं।

एक आवश्यक विशेषता मुझे एक निर्देशिका में सभी फ़ाइलों को एक लक्ष्य में स्वचालित रूप से जोड़ना है। हालांकि यह मेक के साथ करना आसान है, लेकिन विजुअल C ++ और XCode के साथ यह आसानी से संभव नहीं है (यदि मैं गलत हूं तो मुझे सही करें)। क्या यह सीधे सीएमके में करना संभव है? कैसे?


Btw। इन विजुअल स्टूडियो, कम से कम C # प्रोजेक्ट्स में, प्रोजेक्ट एक्स्प्लोरर में एक टूलबार बटन है, जिसका नाम सभी फाइलें दिखाता है। यह परियोजना के सभी उप-निर्देशिकाओं को दृश्यमान बनाता है, अगर वे इस परियोजना में तार्किक रूप से शामिल किसी भी फाइल को शामिल नहीं करते हैं। आप इन निर्देशिकाओं को संदर्भ मेनू के माध्यम से शामिल कर सकते हैं, जिसमें उनके अंदर सभी स्रोत फ़ाइलें शामिल हैं, पुनरावर्ती :)
तुर्क

जवाबों:


228

हो सकता है। जैसे file(GLOB:

cmake_minimum_required(VERSION 2.8)

file(GLOB helloworld_SRC
    "*.h"
    "*.cpp"
)

add_executable(helloworld ${helloworld_SRC})

ध्यान दें कि इसके लिए मैन्युअल री-रनिंग की आवश्यकता होती है cmakeयदि कोई स्रोत फ़ाइल जोड़ी जाती है या हटा दी जाती है, क्योंकि उत्पन्न बिल्ड सिस्टम को पता नहीं है कि सीमेक को फिर से तैयार करने के लिए कब कहा जाए, और हर बिल्ड पर ऐसा करने से बिल्ड समय बढ़ जाएगा।


11
Cmake को मैन्युअल रूप से री-रन करने का विकल्प CMakeLists.txt फाइल को रनिंग करने से पहले टच करना है।
सीमस कॉनर


8
> "हम आपके स्रोत पेड़ से स्रोत फ़ाइलों की सूची एकत्र करने के लिए GLOB का उपयोग करने की अनुशंसा नहीं करते हैं। यदि कोई स्रोत जोड़ा या हटाए जाने पर कोई CMakeLists.txt फ़ाइल परिवर्तित नहीं होती है, तो उत्पन्न बिल्ड सिस्टम को पता नहीं चल सकता है कि CMake को पुन: उत्पन्न करने के लिए कब कहा जाए।" यह अब सीएमकेई 3.7 डॉक्स के लिए अनुशंसित नहीं है जो कि हैंड 1 क्लॉड के बारे में जुड़ा हुआ है
ट्रिपल

4
फिर GLOB का विकल्प क्या है?
Shayne

13
V3.1 के बाद से एक बेहतर तरीका यहाँ सुझाया गया है: target_source () crascit.com/2016/01/31/…
Sheen

34

क्लेस्ट द्वारा उत्तर निश्चित रूप से काम करता है, लेकिन एक महत्वपूर्ण चेतावनी है:

जब आप Makefileमैन्युअल लिखते हैं , तो आप SRCSसभी .cppऔर .hफ़ाइलों का चयन करने के लिए फ़ंक्शन का उपयोग करके एक चर उत्पन्न कर सकते हैं । यदि कोई स्रोत फ़ाइल बाद में जोड़ी गई है, तो उसे फिर से चलाना makeशामिल होगा।

हालांकि, CMake (जैसे कमांड के साथ file(GLOB ...)) स्पष्ट रूप से एक फ़ाइल सूची उत्पन्न करेगा और इसे ऑटो-जनरेट में रखेगा Makefile। यदि आपके पास एक नया स्रोत फ़ाइल है, तो आपको Makefileफिर से चल रहे द्वारा फिर से उत्पन्न करने की आवश्यकता होगी cmake

संपादित करें: Makefile को हटाने की कोई आवश्यकता नहीं है।


4
क्या सीमेक को केवल फिर से नहीं चलाया जा सकता है, जो आउट-ऑफ-डेट मेकफाइल को हटा / संशोधित करना चाहिए?
एथन

25
यह कोई उत्तर नहीं है, यह @ क्लेस्ट के उत्तर के बारे में एक टिप्पणी है।
नेवॉल्ड

3
@ स्टोवओवरफ़्लो शब्दावली में नहीं।
कारा डेनिज़

1
यह टिप्पणी अच्छी है, लेकिन यह "मानक" है, है ना? पूछनेवाला पहले से ही सीमेक का उपयोग कर रहा है, इसलिए सुझाव देना "अधिक" हो सकता है जो कि सहायक नहीं है।
फ्रैंकलीआओ

तो क्या नए स्रोत फ़ाइलों को जोड़ने और फिर से चल रहे cmake के बिना निर्माण करने का कोई तरीका है?
आर्टिन

6

@ प्रश्न उत्तर के लिए एक्सटेंशन :

CMake के बाद से 3.12 अतिरिक्त विकल्प CONFIGURE_DEPENDS है समर्थित आदेशों से file(GLOB)और file(GLOB_RECURSE)। इस विकल्प के साथ निर्देशिका में स्रोत फ़ाइल को हटाने / हटाने के बाद सीएमके को मैन्युअल रूप से फिर से चलाने की कोई आवश्यकता नहीं है - प्रोजेक्ट के अगले निर्माण पर सीएमके स्वचालित रूप से फिर से चलाया जाएगा।

हालाँकि, विकल्प CONFIGURE_DEPENDS का तात्पर्य है कि संबंधित निर्देशिका को हर बार निर्माण का अनुरोध करने पर पुनः जाँच की जाएगी, इसलिए निर्माण प्रक्रिया CONFIGURE_DEPENDS की तुलना में अधिक समय का उपभोग करेगी ।

CONFIGURE_DEPENDS उपलब्ध विकल्प के साथ भी CMake प्रलेखन अभी भी स्रोतों का उपयोग करने या एकत्र करने की अनुशंसा नहीं करता है।file(GLOB)file(GLOB_RECURSE)


"सीएमके प्रलेखन अभी भी स्रोतों का उपयोग करने file(GLOB)या file(GLOB_RECURSE)इकट्ठा करने की अनुशंसा नहीं करता है" वे तब क्या सलाह देते हैं? स्रोतों को इकट्ठा करने के लिए या मैन्युअल रूप से हर एक स्रोत फ़ाइल को सूचीबद्ध करने के लिए कुछ और का उपयोग करना?
थॉमस

1
@ थोमस: वे मैन्युअल रूप से हर स्रोत फ़ाइल को सूचीबद्ध करने की सलाह देते हैं। यह उत्तर अनुशंसा की एक महान व्याख्या देता है।
त्सेवेरेव

-2

तो आपके लिए स्रोत फ़ाइलों की सूची बनाने के लिए पॉवरशेल का उपयोग क्यों न करें। इस लिपि पर एक नजर डालें

param (
    [Parameter(Mandatory=$True)]
    [string]$root 
)

if (-not (Test-Path  -Path $root)) {    
throw "Error directory does not exist"
}

#get the full path of the root
$rootDir = get-item -Path $root
$fp=$rootDir.FullName;


$files = Get-ChildItem -Path $root -Recurse -File | 
         Where-Object { ".cpp",".cxx",".cc",".h" -contains $_.Extension} | 
         Foreach {$_.FullName.replace("${fp}\","").replace("\","/")}

$CMakeExpr = "set(SOURCES "

foreach($file in $files){

    $CMakeExpr+= """$file"" " ;
}
$CMakeExpr+=")"
return $CMakeExpr;

मान लीजिए कि आपके पास इस संरचना वाला एक फ़ोल्डर है

C:\Workspace\A
--a.cpp
C:\Workspace\B 
--b.cpp

अब इस फ़ाइल को उदाहरण के लिए "GenerSourceList.ps1" के रूप में सहेजें, और स्क्रिप्ट को इस रूप में चलाएँ

~>./generateSourceList.ps1 -root "C:\Workspace" > out.txt

बाहरी फ़ाइल में समाहित किया जाएगा

set(SOURCE "A/a.cpp" "B/b.cpp")

प्रश्न को क्रॉस-प्लेटफ़ॉर्म पर टैग किया गया है - शक्तियां क्रॉस-प्लेटफ़ॉर्म नहीं है।
रीचर्ट

@reichhart powershell भी लिनक्स और मैक और पर काम करता है
कोई

मुझे पता है। लेकिन इसमें पॉवरशेल और "सीमेक" के लिए कोई टैग नहीं है, पहले से ही क्रॉसप्लेट रिकॉर्डर है। "पॉवर्सशेल" एक अतिरिक्त निर्भरता होगी और विंडोज की तुलना में अन्य ओएस पर बहुत कम उपयोग किया जाता है। आपको शक्तियां वाले लोगों की तुलना में लिनक्स पर और भी अधिक C # डेवलपर्स मिल सकते हैं। और सबसे महत्वपूर्ण तथ्य यह है कि सवाल: "क्या यह सीधे सीएमके में करना संभव है? कैसे?"
रीछार्ट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.