<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Cross-Platform on kenji.blog</title><link>http://kenji.blog/hi/tags/cross-platform/</link><description>Recent content in Cross-Platform on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>hi</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 12 Sep 2026 09:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/hi/tags/cross-platform/index.xml" rel="self" type="application/rss+xml"/><item><title>CMake का उपयोग करके क्रॉस-प्लेटफ़ॉर्म C++ बिल्ड वातावरण स्थापित करने के लिए गाइड</title><link>http://kenji.blog/hi/p/cmake-cross-platform-build-environment-guide/</link><pubDate>Sat, 12 Sep 2026 09:00:00 +0900</pubDate><guid>http://kenji.blog/hi/p/cmake-cross-platform-build-environment-guide/</guid><description>&lt;img src="http://kenji.blog/p/cmake-cross-platform-build-environment-guide/img/eyecatch.jpg" alt="Featured image of post CMake का उपयोग करके क्रॉस-प्लेटफ़ॉर्म C++ बिल्ड वातावरण स्थापित करने के लिए गाइड" />&lt;p>C++ सॉफ़्टवेयर विकास में, कई वर्षों से अधिकांश डेवलपर्स को परेशान करने वाली चीज़ &amp;ldquo;बिल्ड सिस्टम&amp;rdquo; का चयन और सेटअप रहा है। चूंकि C++ में कोई आधिकारिक मानक पैकेज मैनेजर या बिल्ड सिस्टम नहीं है, इसलिए प्रत्येक प्लेटफ़ॉर्म (Windows, Linux, macOS) के लिए अलग-अलग कंपाइलर और बिल्ड टूल (MSVC, GCC, Clang, Make, Ninja, आदि) का उपयोग करना आवश्यक था।&lt;/p>
&lt;p>हालाँकि, वर्तमान में &lt;strong>CMake&lt;/strong> वास्तविक उद्योग मानक (डि-फैक्टो स्टैंडर्ड) के रूप में स्थापित हो गया है, और CMake का सही उपयोग करके, आप एकल &lt;code>CMakeLists.txt&lt;/code> से एक क्रॉस-प्लेटफ़ॉर्म बिल्ड वातावरण को खूबसूरती से स्थापित कर सकते हैं।&lt;/p>
&lt;p>इस लेख में, हम CMake (आधुनिक CMake) का उपयोग करके एक क्रॉस-प्लेटफ़ॉर्म C++ बिल्ड वातावरण स्थापित करने की प्रक्रिया के बारे में, बुनियादी से लेकर उन्नत तकनीकों तक, पूरी तरह से और विस्तार से चर्चा करेंगे।&lt;/p>
&lt;h2 id="1-cmake-कय-ह-मट-बलड-ससटम-क-अवधरण">1. CMake क्या है? (मेटा-बिल्ड सिस्टम की अवधारणा)
&lt;/h2>&lt;p>CMake अपने आप में सीधे सोर्स कोड को कंपाइल करने वाला टूल नहीं है। CMake &amp;ldquo;बिल्ड सिस्टम उत्पन्न करने वाला सिस्टम&amp;rdquo; है, अर्थात &lt;strong>मेटा-बिल्ड सिस्टम (Meta-Build System)&lt;/strong>।&lt;/p>
&lt;p>CMake की मुख्य भूमिका प्लेटफ़ॉर्म- और कंपाइलर-स्वतंत्र अमूर्त कॉन्फ़िगरेशन फ़ाइलों (&lt;code>CMakeLists.txt&lt;/code>) को पढ़ना है, और स्वचालित रूप से प्रत्येक वातावरण के लिए उपयुक्त नेटिव बिल्ड स्क्रिप्ट (उदाहरण: Linux के लिए &lt;code>Makefile&lt;/code>, Windows के लिए Visual Studio &lt;code>.sln&lt;/code> प्रोजेक्ट फ़ाइलें, या तेज़ &lt;code>build.ninja&lt;/code>) उत्पन्न करना है।&lt;/p>
&lt;p>नीचे दिया गया आरेख CMake की जनरेशन प्रक्रिया को दर्शाता है।&lt;/p>
&lt;div class="mermaid">graph TD
A["CMakeLists.txt (अमूर्त बिल्ड परिभाषा)"] --> B["CMake (कॉन्फ़िगर और जनरेट करें)"]
B --> C["Unix Makefiles"]
B --> D["Ninja Build Files"]
B --> E["Visual Studio Solutions"]
B --> F["Xcode Projects"]
C --> G["नेटिव बिल्ड टूल (make, ninja, MSBuild, xcodebuild)"]
D --> G
E --> G
F --> G
G --> H["एक्ज़ीक्यूटेबल / शेयर्ड लाइब्रेरी / स्टैटिक लाइब्रेरी"]&lt;/div>
&lt;p>इस तरह, बीच में CMake को रखकर, डेवलपर्स OS-विशिष्ट कमांड में छोटे अंतरों की चिंता किए बिना C++ प्रोजेक्ट्स को प्रबंधित कर सकते हैं।&lt;/p>
&lt;h2 id="2-आधनक-cmake-क-मल-बत-चर-स-लकषय-target-तक">2. आधुनिक CMake की मूल बातें: चर से लक्ष्य (Target) तक
&lt;/h2>&lt;p>CMake 3.0 और उसके बाद के सिंटैक्स को &amp;ldquo;आधुनिक CMake&amp;rdquo; कहा जाता है, और इसकी डिज़ाइन फिलॉसफी इसके पूर्ववर्ती (लिगेसी CMake) से मौलिक रूप से भिन्न है। लिगेसी CMake में, डायरेक्टरी स्तर पर ग्लोबल चरों को फिर से लिखने का दृष्टिकोण (जैसे &lt;code>include_directories()&lt;/code> या &lt;code>link_libraries()&lt;/code> का उपयोग करना) मुख्यधारा था, लेकिन इसके परिणामस्वरूप अक्सर गंभीर दुष्प्रभाव होते थे जहाँ सेटिंग्स अनजाने में अन्य मॉड्यूल को प्रभावित करती थीं।&lt;/p>
&lt;p>आधुनिक CMake में, हर चीज़ को &lt;strong>लक्ष्य (Target)&lt;/strong> और &lt;strong>संपत्ति (Property)&lt;/strong> के रूप में माना जाता है। यह ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग में क्लास और मेंबर वेरिएबल्स के बीच के संबंध के समान है।&lt;/p>
&lt;ul>
&lt;li>&lt;strong>लक्ष्य (Target)&lt;/strong>: एक्ज़ीक्यूटेबल (Executable) या लाइब्रेरी (Library)।&lt;/li>
&lt;li>&lt;strong>संपत्ति (Property)&lt;/strong>: उस लक्ष्य को बनाने के लिए आवश्यक सोर्स फ़ाइलें, इंक्लूड डायरेक्टरीज़, कंपाइल विकल्प, लिंक करने के लिए अन्य लाइब्रेरीज़ आदि।&lt;/li>
&lt;/ul>
&lt;p>सेटिंग्स को केवल विशिष्ट लक्ष्यों के लिए एनकैप्सुलेट (सीमित) करके, बड़े प्रोजेक्ट्स के लिए भी एक सुरक्षित बिल्ड परिभाषा संभव हो जाती है जो टूटती नहीं है।&lt;/p>
&lt;h3 id="नयनतम-cmakeliststxt">न्यूनतम &lt;code>CMakeLists.txt&lt;/code>
&lt;/h3>&lt;p>सबसे पहले, आइए सबसे बुनियादी &lt;code>CMakeLists.txt&lt;/code> देखें।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cmake" data-lang="cmake">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># CMake की न्यूनतम आवश्यक संस्करण निर्दिष्ट करें
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">cmake_minimum_required&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">VERSION&lt;/span> &lt;span class="s">3.20&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># प्रोजेक्ट का नाम और उपयोग की जाने वाली भाषा निर्दिष्ट करें
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">project&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">MyAwesomeApp&lt;/span> &lt;span class="s">VERSION&lt;/span> &lt;span class="s">1.0.0&lt;/span> &lt;span class="s">LANGUAGES&lt;/span> &lt;span class="s">CXX&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># C++ मानक (C++20) का अनुरोध करें
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CMAKE_CXX_STANDARD&lt;/span> &lt;span class="s">20&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CMAKE_CXX_STANDARD_REQUIRED&lt;/span> &lt;span class="s">ON&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CMAKE_CXX_EXTENSIONS&lt;/span> &lt;span class="s">OFF&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="c"># कंपाइलर-विशिष्ट एक्सटेंशन अक्षम करें
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># एक्ज़ीक्यूटेबल लक्ष्य की परिभाषा
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">add_executable&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">MyAwesomeApp&lt;/span> &lt;span class="s">main.cpp&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>केवल इन कुछ पंक्तियों के साथ, C++20 की आवश्यकता वाली और कंपाइलर एक्सटेंशन को अक्षम करने वाली पोर्टेबल एक्ज़ीक्यूटेबल फ़ाइल के लिए बिल्ड सेटिंग पूरी हो जाती है।&lt;/p>
&lt;h2 id="3-नरभरत-और-सकप-scope-public--private--interface">3. निर्भरता और स्कोप (Scope): PUBLIC / PRIVATE / INTERFACE
&lt;/h2>&lt;p>आधुनिक CMake में महारत हासिल करने के लिए सबसे महत्वपूर्ण और कठिन अवधारणा &lt;strong>&lt;code>PUBLIC&lt;/code>, &lt;code>PRIVATE&lt;/code>, &lt;code>INTERFACE&lt;/code>&lt;/strong> नामक तीन एक्सेस मॉडिफायर (स्कोप) हैं, जिनका उपयोग &lt;code>target_include_directories&lt;/code> और &lt;code>target_link_libraries&lt;/code> आदि में किया जाता है।&lt;/p>
&lt;p>ये लक्ष्य की संपत्तियों (इंक्लूड पाथ और निर्भर लाइब्रेरीज़) को नियंत्रित करने के लिए उपयोग किए जाते हैं: &amp;ldquo;क्या यह मेरे स्वयं के बिल्ड के लिए आवश्यक है?&amp;rdquo; और &amp;ldquo;क्या इसे मुझ पर निर्भर अन्य लक्ष्यों तक भी फैलाया जाना चाहिए?&amp;rdquo;&lt;/p>
&lt;ol>
&lt;li>&lt;strong>&lt;code>PRIVATE&lt;/code>&lt;/strong>: केवल उस लक्ष्य के स्वयं के बिल्ड के लिए आवश्यक है। यह निर्भर लक्ष्यों तक &lt;strong>प्रसारित नहीं&lt;/strong> होता है।&lt;/li>
&lt;li>&lt;strong>&lt;code>INTERFACE&lt;/code>&lt;/strong>: उस लक्ष्य के स्वयं के बिल्ड के लिए आवश्यक नहीं है, लेकिन निर्भर लक्ष्यों के बिल्ड में &lt;strong>प्रसारित होता&lt;/strong> है (जैसे कि हेडर-ओनली लाइब्रेरीज़ में उपयोग किया जाता है)।&lt;/li>
&lt;li>&lt;strong>&lt;code>PUBLIC&lt;/code>&lt;/strong>: उस लक्ष्य के स्वयं के बिल्ड के लिए आवश्यक है और निर्भर लक्ष्यों में भी &lt;strong>प्रसारित होता&lt;/strong> है (&lt;code>PRIVATE&lt;/code> + &lt;code>INTERFACE&lt;/code>)।&lt;/li>
&lt;/ol>
&lt;p>आइए नीचे दिए गए आरेख में निर्भरताओं के प्रसार (उपयोग आवश्यकताओं का प्रसार) की कल्पना करें।&lt;/p>
&lt;div class="mermaid">graph TD
subgraph "Libraries"
MathLib["MathLib (स्टैटिक लाइब्रेरी)"]
NetworkLib["NetworkLib (शेयर्ड लाइब्रेरी)"]
HeaderLib["HeaderLib (हेडर ओनली)"]
end
subgraph "Application"
App["मुख्य एप्लिकेशन"]
end
App -- "target_link_libraries(App PRIVATE MathLib)" --> MathLib
App -- "target_link_libraries(App PUBLIC NetworkLib)" --> NetworkLib
NetworkLib -- "target_link_libraries(NetworkLib INTERFACE HeaderLib)" --> HeaderLib
note1["App MathLib के कार्यान्वयन पर निर्भर है, लेकिन इसे बाहर प्रदर्शित नहीं करता है"]
note2["NetworkLib HeaderLib के इंटरफ़ेस को सार्वजनिक करता है"]&lt;/div>
&lt;h3 id="सकप-क-वशषट-उपयग-क-उदहरण">स्कोप के विशिष्ट उपयोग के उदाहरण
&lt;/h3>&lt;p>मान लीजिए कि एक लाइब्रेरी &lt;code>MyLib&lt;/code> आंतरिक कार्यान्वयन के रूप में &lt;code>nlohmann/json&lt;/code> का उपयोग करती है, और सार्वजनिक रूप से उपलब्ध हेडर फ़ाइल &lt;code>MyLib.hpp&lt;/code> में &lt;code>nlohmann/json&lt;/code> को शामिल (include) नहीं करती है। इस स्थिति में, &lt;code>MyLib&lt;/code> का उपयोग करने वाले पक्ष (एप्लिकेशन) को JSON लाइब्रेरी के अस्तित्व को जानने की आवश्यकता नहीं है।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cmake" data-lang="cmake">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># लाइब्रेरी की परिभाषा
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">add_library&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">MyLib&lt;/span> &lt;span class="s">src/MyLib.cpp&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># अपने प्रोजेक्ट के इंक्लूड डायरेक्टरीज़ निर्दिष्ट करना
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># include डायरेक्टरी MyLib का उपयोग करने वालों के लिए भी आवश्यक है, इसलिए PUBLIC का उपयोग करें
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c"># src डायरेक्टरी केवल MyLib के कार्यान्वयन में उपयोग की जाती है, इसलिए PRIVATE का उपयोग करें
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">target_include_directories&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">MyLib&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">PUBLIC&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">$&amp;lt;&lt;/span>&lt;span class="nv">BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">$&amp;lt;&lt;/span>&lt;span class="nv">INSTALL_INTERFACE:include&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">PRIVATE&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">${&lt;/span>&lt;span class="nv">CMAKE_CURRENT_SOURCE_DIR&lt;/span>&lt;span class="o">}&lt;/span>&lt;span class="s">/src&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># json लाइब्रेरी का उपयोग केवल आंतरिक कार्यान्वयन के लिए किया जाता है, इसलिए इसे PRIVATE के साथ लिंक करें
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">target_link_libraries&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">MyLib&lt;/span> &lt;span class="s">PRIVATE&lt;/span> &lt;span class="s">nlohmann_json::nlohmann_json&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>इसके विपरीत, यदि &lt;code>MyLib.hpp&lt;/code> में &lt;code>#include &amp;lt;nlohmann/json.hpp&amp;gt;&lt;/code> लिखा गया है, तो &lt;code>MyLib&lt;/code> का उपयोग करने वाले पक्ष को भी JSON का हेडर पाथ पता होना चाहिए, अन्यथा कंपाइल एरर होगा, इसलिए इसे &lt;code>PUBLIC&lt;/code> के रूप में लिंक करने की आवश्यकता है। इन स्कोप्स को उचित रूप से सेट करके, आप बिल्ड समय को कम कर सकते हैं और अनावश्यक निर्भरता के रिसाव (Repackaging/Poisoning) को रोक सकते हैं।&lt;/p>
&lt;h2 id="4-आउट-ऑफ-सरस-बलड-out-of-source-build">4. आउट-ऑफ़-सोर्स बिल्ड (Out-of-source Build)
&lt;/h2>&lt;p>CMake का उपयोग करते समय सबसे महत्वपूर्ण सर्वोत्तम अभ्यास जिसका हमेशा पालन किया जाना चाहिए, वह है &lt;strong>आउट-ऑफ़-सोर्स बिल्ड&lt;/strong>।&lt;/p>
&lt;p>यह एक ऐसी विधि है जहाँ कोई भी बिल्ड आर्टिफैक्ट (ऑब्जेक्ट फ़ाइलें या एक्ज़ीक्यूटेबल फ़ाइलें) उस डायरेक्टरी (सोर्स ट्री) में आउटपुट नहीं होते हैं जहाँ सोर्स कोड स्थित है, बल्कि बिल्ड को एक अलग समर्पित डायरेक्टरी (आमतौर पर &lt;code>build/&lt;/code>) में अलग से निष्पादित किया जाता है।&lt;/p>
&lt;div class="mermaid">graph TD
Root["प्रोजेक्ट रूट (Git रिपॉजिटरी)"]
Root --> Src["src/"]
Root --> Inc["include/"]
Root --> CMake["CMakeLists.txt"]
Root -. "बिल्ड डायरेक्टरी बनाएं" .-> Build["build/ (आउट-ऑफ़-सोर्स)"]
Build --> Obj["CMakeFiles/ (ऑब्जेक्ट फ़ाइलें, कैश)"]
Build --> Bin["बाइनरीज़ (MyApp.exe)"]
Build --> Gen["जनरेटेड Makefile / build.ninja"]&lt;/div>
&lt;p>इस कॉन्फ़िगरेशन के साथ, यदि आप बिल्ड वातावरण को रीसेट करना चाहते हैं, तो आपको केवल &lt;code>build&lt;/code> डायरेक्टरी को पूरी तरह से हटाना होगा। चूंकि सोर्स ट्री प्रदूषित नहीं होता है, इसलिए Git के साथ प्रबंधन भी आसान हो जाता है (आपको बस &lt;code>.gitignore&lt;/code> में &lt;code>build/&lt;/code> जोड़ना होगा)।&lt;/p>
&lt;h3 id="बलड-नषपदन-परकरय">बिल्ड निष्पादन प्रक्रिया
&lt;/h3>&lt;p>आधुनिक CMake में, आप OS या बिल्ड टूल की परवाह किए बिना सामान्य कमांड का उपयोग करके बिल्ड चला सकते हैं।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 1. कॉन्फ़िगरेशन और जनरेशन (बिल्ड डायरेक्टरी बनाते समय सेटिंग)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cmake -S . -B build
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 2. वास्तविक बिल्ड (कंपाइल और लिंक)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cmake --build build --config Release
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># (वैकल्पिक) मल्टीथ्रेडेड बिल्ड के लिए -j विकल्प का उपयोग करें&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">cmake --build build --config Release -j &lt;span class="m">8&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>यहाँ &lt;code>cmake -S . -B build&lt;/code> का अर्थ है &amp;ldquo;वर्तमान डायरेक्टरी (&lt;code>.&lt;/code>) को सोर्स डायरेक्टरी के रूप में सेट करें और &lt;code>build&lt;/code> को बिल्ड डायरेक्टरी के रूप में सेट करें।&amp;rdquo;&lt;/p>
&lt;h2 id="5-थरड-परट-लइबररज-कस-शमल-कर">5. थर्ड-पार्टी लाइब्रेरीज़ कैसे शामिल करें
&lt;/h2>&lt;p>C++ विकास में, बाहरी लाइब्रेरीज़ (थर्ड-पार्टी लाइब्रेरीज़) को शामिल करना हमेशा से एक कठिन काम रहा है। हालाँकि, वर्तमान में, निम्नलिखित तीन दृष्टिकोण मुख्य रूप से मानक हैं।&lt;/p>
&lt;h3 id="51-find_package-ससटम-म-इसटल-क-गई-लइबररज-खज">5.1. find_package (सिस्टम में इंस्टॉल की गई लाइब्रेरीज़ खोजें)
&lt;/h3>&lt;p>सिस्टम में पहले से इंस्टॉल की गई लाइब्रेरीज़ (जैसे OpenSSL या Zlib) को खोजने और लिंक करने का यह सबसे पारंपरिक तरीका है।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cmake" data-lang="cmake">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">find_package&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">ZLIB&lt;/span> &lt;span class="s">REQUIRED&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">if&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">ZLIB_FOUND&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="nb">target_link_libraries&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">MyAwesomeApp&lt;/span> &lt;span class="s">PRIVATE&lt;/span> &lt;span class="s">ZLIB::ZLIB&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">endif&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="52-fetchcontent-सरत-स-डउनलड-और-एककरण">5.2. FetchContent (स्रोत से डाउनलोड और एकीकरण)
&lt;/h3>&lt;p>यह मॉड्यूल CMake 3.11 में पेश किया गया था और 3.14 के बाद से शक्तिशाली बन गया है। बिल्ड समय पर, यह सीधे बाहरी Git रिपॉजिटरी या URL से सोर्स कोड डाउनलोड करता है और इसे प्रोजेक्ट के हिस्से के रूप में एक साथ बनाता है। चूँकि निर्भरताओं को केंद्रीय रूप से प्रबंधित किया जा सकता है, क्रॉस-प्लेटफ़ॉर्म प्रतिलिपि प्रस्तुत करने योग्यता (reproducibility) अत्यधिक उच्च हो जाती है।&lt;/p>
&lt;p>नीचे GoogleTest को FetchContent के साथ शामिल करने का एक उदाहरण दिया गया है।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cmake" data-lang="cmake">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">include&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">FetchContent&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">FetchContent_Declare&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">googletest&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">GIT_REPOSITORY&lt;/span> &lt;span class="s">https://github.com/google/googletest.git&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">GIT_TAG&lt;/span> &lt;span class="s">v1.14.0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># लाइब्रेरी को प्रोजेक्ट में उपलब्ध कराएं
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">FetchContent_MakeAvailable&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">googletest&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># परीक्षण के लिए एक्ज़ीक्यूटेबल फ़ाइल बनाना और लिंक करना
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">add_executable&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">MyTests&lt;/span> &lt;span class="s">test/main.cpp&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">target_link_libraries&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">MyTests&lt;/span> &lt;span class="s">PRIVATE&lt;/span> &lt;span class="s">gtest_main&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="53-vcpkg-क-सथ-एककरण">5.3. vcpkg के साथ एकीकरण
&lt;/h3>&lt;p>Microsoft के नेतृत्व वाले C++ पैकेज मैनेजर &lt;strong>vcpkg&lt;/strong> का उपयोग करके, आप आसानी से हजारों लाइब्रेरीज़ शामिल कर सकते हैं। vcpkg को CMake के साथ मूल रूप से काम करने के लिए डिज़ाइन किया गया है।&lt;/p>
&lt;p>CMake चलाते समय, केवल vcpkg टूलचेन फ़ाइल निर्दिष्ट करके, &lt;code>find_package&lt;/code> स्वचालित रूप से vcpkg के भीतर लाइब्रेरीज़ की खोज करेगा।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE&lt;span class="o">=&lt;/span>/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>इसके अतिरिक्त, प्रोजेक्ट रूट में &lt;code>vcpkg.json&lt;/code> (मेनिफेस्ट मोड) रखकर, आप आवश्यक लाइब्रेरीज़ के संस्करण नियंत्रण को पूरी तरह से स्वचालित कर सकते हैं।&lt;/p>
&lt;h2 id="6-करस-पलटफरम-सपरट-क-लए-कपइलर-फलग">6. क्रॉस-प्लेटफ़ॉर्म सपोर्ट के लिए कंपाइलर फ़्लैग
&lt;/h2>&lt;p>Windows (MSVC), Linux (GCC/Clang), या macOS (Apple Clang) में से किसी भी वातावरण में सफलतापूर्वक निर्माण करने के लिए, आपको उचित कंपाइलर-विशिष्ट फ़्लैग सेट करने होंगे।&lt;/p>
&lt;p>CMake के &lt;strong>जेनरेटर एक्सप्रेशन (Generator Expressions)&lt;/strong> का उपयोग करके, आप &amp;ldquo;यदि कंपाइलर MSVC है तो यह फ़्लैग, अन्यथा वह फ़्लैग&amp;rdquo; जैसी सशर्त शाखाओं (conditional branches) को घोषणात्मक रूप से लिख सकते हैं। जेनरेटर एक्सप्रेशन &lt;code>$&amp;lt;...&amp;gt;&lt;/code> सिंटैक्स का उपयोग करते हैं और बिल्ड सिस्टम जनरेशन (Generate phase) के दौरान मूल्यांकित किए जाते हैं।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cmake" data-lang="cmake">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># सभी प्लेटफ़ॉर्म पर उच्चतम स्तर की चेतावनियों को सक्षम करने का उदाहरण
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">target_compile_options&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">MyAwesomeApp&lt;/span> &lt;span class="s">PRIVATE&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c"># MSVC के मामले में
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span> &lt;span class="o">$&amp;lt;&lt;/span>&lt;span class="nv">$&amp;lt;CXX_COMPILER_ID:MSVC&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="s">:/W4&lt;/span> &lt;span class="s">/WX&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c"># GCC या Clang के मामले में
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span> &lt;span class="o">$&amp;lt;&lt;/span>&lt;span class="nv">$&amp;lt;OR:$&amp;lt;CXX_COMPILER_ID:GNU&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="s">,&lt;/span>&lt;span class="o">$&amp;lt;&lt;/span>&lt;span class="nv">CXX_COMPILER_ID:Clang&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="s">,&lt;/span>&lt;span class="o">$&amp;lt;&lt;/span>&lt;span class="nv">CXX_COMPILER_ID:AppleClang&lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="s">&amp;gt;:-Wall&lt;/span> &lt;span class="s">-Wextra&lt;/span> &lt;span class="s">-Wpedantic&lt;/span> &lt;span class="s">-Werror&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>इस पद्धति का उपयोग करके, आप &lt;code>if(MSVC)&lt;/code> जैसी सशर्त शाखाओं के अत्यधिक उपयोग को रोक सकते हैं जो &lt;code>CMakeLists.txt&lt;/code> को पढ़ने में कठिन बनाते हैं, और प्रति-लक्ष्य लचीली सेटिंग्स को सक्षम करते हैं।&lt;/p>
&lt;h2 id="7-परकषण-वतवरण-सथपत-करन-ctest">7. परीक्षण वातावरण स्थापित करना (CTest)
&lt;/h2>&lt;p>क्रॉस-प्लेटफ़ॉर्म वातावरण में गुणवत्ता आश्वासन (Quality Assurance) के लिए स्वचालित परीक्षण शुरू करना आवश्यक है। CMake डिफ़ॉल्ट रूप से &lt;strong>CTest&lt;/strong> नामक एक टेस्ट रनर के साथ आता है।&lt;/p>
&lt;p>ऊपर बताए गए &lt;code>FetchContent&lt;/code> का उपयोग करके शामिल किए गए GoogleTest को CTest के साथ एकीकृत करने की प्रक्रिया निम्नलिखित है:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;span class="lnt">9
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cmake" data-lang="cmake">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># परीक्षण सुविधाएँ सक्षम करें (रूट CMakeLists.txt में केवल एक बार लिखा गया)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">enable_testing&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">add_executable&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">MyMathTests&lt;/span> &lt;span class="s">test/math_test.cpp&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">target_link_libraries&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">MyMathTests&lt;/span> &lt;span class="s">PRIVATE&lt;/span> &lt;span class="s">gtest_main&lt;/span> &lt;span class="s">MyLib&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># CTest में परीक्षण के रूप में पंजीकृत करें
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">include&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">GoogleTest&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">gtest_discover_tests&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">MyMathTests&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>बिल्ड के बाद, बस बिल्ड डायरेक्टरी में &lt;code>ctest&lt;/code> कमांड चलाएं, और सभी परीक्षण निष्पादित किए जाएंगे और परिणामों की रिपोर्ट की जाएगी।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd&lt;/span> build
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">ctest --output-on-failure -C Release
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="8-बलड-ससटम-क-सदधत-और-गणतय-मडल">8. बिल्ड सिस्टम का सिद्धांत और गणितीय मॉडल
&lt;/h2>&lt;p>यहाँ दृष्टिकोण को थोड़ा बदलते हैं और एक गणितीय मॉडल का उपयोग करके बड़े पैमाने की परियोजनाओं में बिल्ड सिस्टम और समानांतर संकलन (parallel compilation) की दक्षता पर विचार करते हैं।&lt;/p>
&lt;p>बिल्ड समय (संकलन समय) को कम करना C++ विकास में एक शाश्वत चुनौती है। आप सोर्स कोड को विभाजित करके और इसे समानांतर में कंपाइल करके बिल्ड समय को कम कर सकते हैं। इस समानांतरकरण द्वारा गति में वृद्धि (Speedup) को &lt;strong>एमडाहल के नियम (Amdahl&amp;rsquo;s Law)&lt;/strong> द्वारा प्रतिरूपित (modeled) किया गया है।&lt;/p>
&lt;p>यदि प्रोग्राम में समानांतरकरण योग्य भाग का अनुपात $P$ है, और क्रमिक रूप से निष्पादित किए जाने वाले (समानांतरकरण योग्य नहीं) भाग का अनुपात $1-P$ है, और उपयोग किए जाने वाले प्रोसेसर की संख्या $N$ है, तो समग्र सैद्धांतिक अधिकतम गति वृद्धि दर $S(N)$ निम्नलिखित सूत्र द्वारा व्यक्त की जाती है:&lt;/p>
$$ S(N) = \frac{1}{(1 - P) + \frac{P}{N}} $$
&lt;p>C++ बिल्ड प्रक्रिया में, &amp;ldquo;प्रत्येक &lt;code>.cpp&lt;/code> फ़ाइल को &lt;code>.o&lt;/code> या &lt;code>.obj&lt;/code> में कंपाइल करना&amp;rdquo; स्वतंत्र है और समानांतरकरण योग्य है ($P$ का भाग), लेकिन &amp;ldquo;अंतिम लिंकर (Linker) द्वारा संयोजन प्रक्रिया&amp;rdquo; मूल रूप से क्रमिक रूप से की जाती है ($1-P$ का भाग)।&lt;/p>
&lt;p>इसलिए, भले ही आप कितने भी कोर वाले CPU ($N \to \infty$) तैयार कर लें, जब तक लिंक समय नामक अड़चन (bottleneck) मौजूद है, अधिकतम गति वृद्धि दर निम्नलिखित समीकरण के समान हो जाएगी (asymptotic)।&lt;/p>
$$ \lim_{N \to \infty} S(N) = \frac{1}{1 - P} $$
&lt;p>यह सूत्र बताता है कि &amp;ldquo;बिल्ड समय को कम करने के लिए केवल CPU कोर बढ़ाना एक सीमा तक ही सीमित है।&amp;rdquo; आधुनिक CMake में &lt;code>PRIVATE&lt;/code> और &lt;code>INTERFACE&lt;/code> का उचित उपयोग करके, और हेडर फ़ाइलों की निर्भरता को न्यूनतम करके (जैसे फ़ॉरवर्ड डिक्लेरेशन का उपयोग करना), $P$ के अनुपात को बढ़ाना और इंक्रीमेंटल बिल्ड के दौरान रीकंपाइल लक्ष्य को कम करना व्यावहारिक रूप से सबसे प्रभावी बिल्ड गतिवर्धन रणनीति है।&lt;/p>
&lt;p>इसके अतिरिक्त, लिंक समय को कम करने में, स्टैटिक लाइब्रेरीज़ से शेयर्ड लाइब्रेरीज़ / DLLs पर स्विच करना, या LLD / Mold जैसे तेज़ लिंकर को अपनाना महत्वपूर्ण है।&lt;/p>
&lt;p>CMake में, आप आसानी से लिंकर को निम्नानुसार निर्दिष्ट कर सकते हैं:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cmake" data-lang="cmake">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># Clang/GCC वातावरण में lld लिंकर का उपयोग करने के लिए सेट करें
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">if&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">UNIX&lt;/span> &lt;span class="s">AND&lt;/span> &lt;span class="s">NOT&lt;/span> &lt;span class="s">APPLE&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span> &lt;span class="nb">target_link_options&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">MyAwesomeApp&lt;/span> &lt;span class="s">PRIVATE&lt;/span> &lt;span class="s2">&amp;#34;-fuse-ld=lld&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">endif&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="9-जटल-डयरकटर-सरचन-क-वयवहरक-उदहरण">9. जटिल डायरेक्टरी संरचना का व्यावहारिक उदाहरण
&lt;/h2>&lt;p>वास्तविक एप्लिकेशन विकास में, आपके पास एक डायरेक्टरी संरचना होगी जिसमें कई मॉड्यूल संयोजित होंगे। अंत में, हम एक आदर्श मध्यम आकार के प्रोजेक्ट की डायरेक्टरी संरचना और माता-पिता/बच्चे &lt;code>CMakeLists.txt&lt;/code> के बीच संबंध दिखाते हैं।&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">ProjectRoot/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── CMakeLists.txt (Root: पूरे प्रोजेक्ट की परिभाषा)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── vcpkg.json (निर्भर लाइब्रेरीज़ की परिभाषा)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── external/ (बाहरी मॉड्यूल)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── include/ (सार्वजनिक हेडर)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">│ └── myapp/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── src/ (सोर्स कोड और आंतरिक बिल्ड परिभाषा)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">│ ├── CMakeLists.txt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">│ ├── main.cpp
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">│ ├── math/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">│ │ ├── CMakeLists.txt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">│ │ ├── Vector3.hpp
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">│ │ └── Vector3.cpp
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">│ └── network/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">│ ├── CMakeLists.txt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">│ └── NetworkManager.cpp
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">└── tests/ (परीक्षण कोड)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ├── CMakeLists.txt
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> └── math_test.cpp
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>रूट &lt;code>CMakeLists.txt&lt;/code> केवल पर्यावरण सेटिंग्स और समग्र विकल्प परिभाषाएँ निष्पादित करता है, और सबडायरेक्टरीज़ को &lt;code>add_subdirectory()&lt;/code> का उपयोग करके जोड़ता है।&lt;/p>
&lt;p>&lt;strong>Root &lt;code>CMakeLists.txt&lt;/code>&lt;/strong>:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cmake" data-lang="cmake">&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cmake_minimum_required&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">VERSION&lt;/span> &lt;span class="s">3.20&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">project&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">ComplexApp&lt;/span> &lt;span class="s">LANGUAGES&lt;/span> &lt;span class="s">CXX&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># ग्लोबल सेटिंग्स
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CMAKE_CXX_STANDARD&lt;/span> &lt;span class="s">20&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">set&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">CMAKE_CXX_STANDARD_REQUIRED&lt;/span> &lt;span class="s">ON&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># परीक्षण सक्षम करना
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">enable_testing&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># सबडायरेक्टरीज़ जोड़ना
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">add_subdirectory&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">src&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">add_subdirectory&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">tests&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>&lt;code>src/CMakeLists.txt&lt;/code>&lt;/strong>:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-cmake" data-lang="cmake">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># प्रत्येक मॉड्यूल जोड़ें
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">add_subdirectory&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">math&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="nb">add_subdirectory&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">network&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># अंतिम एक्ज़ीक्यूटेबल फ़ाइल
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">add_executable&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">ComplexApp&lt;/span> &lt;span class="s">main.cpp&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">&lt;/span>&lt;span class="c"># मॉड्यूल्स को लिंक करना
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&lt;/span>&lt;span class="nb">target_link_libraries&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">ComplexApp&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">PRIVATE&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">MathLib&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">NetworkLib&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">)&lt;/span>&lt;span class="err">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>इस तरह डायरेक्टरी द्वारा &lt;code>CMakeLists.txt&lt;/code> को विभाजित करके और लक्ष्यों के बीच निर्भरता को परिभाषित करके, मॉड्यूल की पुन: प्रयोज्यता बढ़ जाती है और बिल्ड समानता (parallelism) में भी सुधार होता है। यही आधुनिक CMake द्वारा प्रस्तावित &amp;ldquo;मॉड्यूलर बिल्ड वातावरण&amp;rdquo; का असली सार है।&lt;/p>
&lt;h2 id="10-नषकरष">10. निष्कर्ष
&lt;/h2>&lt;p>हमने CMake का उपयोग करके क्रॉस-प्लेटफ़ॉर्म C++ बिल्ड वातावरण स्थापित करने की प्रक्रिया के बारे में बताया।
आइए मुख्य बिंदुओं की समीक्षा करें:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>मेटा-बिल्ड सिस्टम को समझना&lt;/strong>: CMake एक टूल है जो बिल्ड स्क्रिप्ट उत्पन्न करता है।&lt;/li>
&lt;li>&lt;strong>आधुनिक CMake का पूर्ण उपयोग&lt;/strong>: चर (variables) का उपयोग न करें, बल्कि &lt;code>add_executable&lt;/code>, &lt;code>target_link_libraries&lt;/code>, &lt;code>target_include_directories&lt;/code> आदि जैसे &lt;strong>लक्ष्य-उन्मुख (Target-oriented)&lt;/strong> सेटिंग्स को एनकैप्सुलेट करें।&lt;/li>
&lt;li>&lt;strong>उचित स्कोप सेटिंग&lt;/strong>: निर्भरताओं के प्रसार को नियंत्रित करने के लिए &lt;code>PUBLIC&lt;/code>, &lt;code>PRIVATE&lt;/code>, और &lt;code>INTERFACE&lt;/code> का सही ढंग से उपयोग करें।&lt;/li>
&lt;li>&lt;strong>आउट-ऑफ़-सोर्स बिल्ड को पूरी तरह लागू करना&lt;/strong>: &lt;code>build/&lt;/code> डायरेक्टरी के भीतर निर्माण करें ताकि सोर्स ट्री प्रदूषित न हो।&lt;/li>
&lt;li>&lt;strong>थर्ड-पार्टी एकीकरण&lt;/strong>: निर्भर लाइब्रेरीज़ के समाधान को स्वचालित करने के लिए &lt;code>FetchContent&lt;/code> और &lt;code>vcpkg&lt;/code> का पूरा उपयोग करें।&lt;/li>
&lt;li>&lt;strong>जेनरेटर एक्सप्रेशन्स का लाभ उठाएं&lt;/strong>: विभिन्न कंपाइलरों के बीच फ़्लैग के अंतर को स्मार्ट तरीके से संभालें।&lt;/li>
&lt;li>&lt;strong>गणितीय दृष्टिकोण&lt;/strong>: एमडाहल के नियम के बारे में जागरूक रहें, और समानांतर संकलन की दक्षता बढ़ाने के लिए निर्भरता को कम करें।&lt;/li>
&lt;/ol>
&lt;p>हालाँकि CMake शुरू में समझना मुश्किल लग सकता है, लेकिन एक बार जब आप लक्ष्य (Target) और संपत्ति (Property) की अवधारणा को समझ लेते हैं, तो आप एक सुव्यवस्थित बिल्ड वातावरण बनाए रख सकते हैं, चाहे C++ प्रोजेक्ट कितना भी जटिल या विशाल क्यों न हो। कृपया इस लेख को एक संदर्भ के रूप में उपयोग करें और नवीनतम आधुनिक CMake सिंटैक्स के साथ C++ विकास वातावरण स्थापित करने का प्रयास करें।&lt;/p></description></item></channel></rss>