अंतिम अद्यतन:2026-10-12
Meson से C++ प्रोजेक्ट बिल्ड करना¶
हाल ही में कुछ open source projects उपयोग करते समय पाया कि उन सभी ने meson+ninja के build तरीके को अपनाया है और CMake, Makefile के तरीके को छोड़ दिया है, इस लेख में हम Meson का परिचय कराएँगे, इंस्टॉलेशन से लेकर एक पूरे meson प्रोजेक्ट के लेखन तक।
आइए, अब मुख्य विषय में आते हैं।
1. Meson इंस्टॉल करना¶
Meson को PyPi से प्राप्त किया जा सकता है, इसलिए pip3 install meson से इंस्टॉल किया जा सकता है। अलग-अलग systems में सही pip command का उपयोग सुनिश्चित करें, और Python 3 version वाला pip ही ज़रूर उपयोग करें।
अगर चाहें, तो standard Python command से locally भी इंस्टॉल किया जा सकता है:
Ninja से build करने की स्थिति में, Ninja को सीधे उसके GitHub release page से या PyPi के ज़रिए download किया जा सकता है:
Meson build के इंस्टॉलेशन के बारे में अधिक जानकारी के लिए, नीचे दी गई Meson की official website पढ़ें।
2. Meson Vs Cmake¶
जब सभी CMake उपयोग करते हैं, तो Meson क्यों उपयोग करें, इन दोनों के अपने-अपने फ़ायदे और नुकसान क्या हैं?
Performance की दृष्टि से, Meson अपनी तेज़ build speed के लिए जाना जाता है। Meson का design build speed को optimize करने के लिए किया गया है, और incremental builds में यह विशेष रूप से उत्कृष्ट प्रदर्शन करता है। Meson, Ninja build system को डिफ़ॉल्ट backend के रूप में उपयोग करता है, और Ninja खुद भी तेज़ और efficient होने के लिए जाना जाता है।
इसकी तुलना में, CMake की build speed project के size से प्रभावित हो सकती है, खासकर बड़े projects में। CMake विभिन्न generators (जैसे Makefile) उपयोग करता है, और अलग-अलग generators की performance भी भिन्न हो सकती है।
बेशक compilation speed बढ़ाने के लिए CMake + Ninja का उपयोग भी किया जा सकता है।
Open source project के नज़रिए से देखें तो Meson के उपयोग के दृश्य भी बहुत हैं, उदाहरण के लिए: PostgreSQL, QEMU, GNOME Software, GTK+, आदि
2.1 Meson के फ़ायदे और नुकसान¶
1.फ़ायदे
- Python आधारित, उपयोग में सरल
- cross compilation का समर्थन
- सभी objects strongly typed हैं: objects 'dependency', 'include directory' जैसी entities हैं, इसलिए string replacement की गलतियाँ होना बहुत मुश्किल है।
- थर्ड-पार्टी लाइब्रेरीज़ reference करना बहुत सुविधाजनक
- बहुत बहुत तेज़, खासकर incremental build के समय।
- documentation, cmake से n गुना बेहतर।
2.नुकसान
- शायद CMake जितना mature नहीं
- Python3 + Ninja की dependency
- project generators, IDE समर्थन में Meson, CMake जितना नहीं
- vscode समर्थन
- https://github.com/mesonbuild/vscode-meson
- उपलब्ध modules सीमित
- non-meson projects को खुद wrapdb पर submit करना पड़ता है
- https://mesonbuild.com/Wrapdb-projects.html
2.2 CMake के फ़ायदे और नुकसान¶
1.फ़ायदे
- IDE समर्थन friendly, team collaboration के लिए काफी अच्छा
- mature, लगभग C++ projects का standard बन चुका है
2.कमियाँ
- cross compilation कठिन
- compilation speed तुलनात्मक रूप से धीमी
3. Meson WrapDB¶
चूंकि googletest एक meson project नहीं है, तो meson से इसे dependency के रूप में कैसे उपयोग करें?
इसी तरह, grpc, abseil-cpp के उपयोग का तरीका भी समान है।
यहाँ पहले WrapDB का परिचय देना ज़रूरी है, Meson WrapDB, Meson build system का एक component है, जो थर्ड-पार्टी projects की build description files को manage और provide करता है, जिन्हें आमतौर पर "wrap" files कहा जाता है। इन wrap files में थर्ड-पार्टी project को configure और build करने के लिए ज़रूरी जानकारी होती है, ताकि उन्हें Meson build system उपयोग करने वाले अन्य projects में आसानी से integrate किया जा सके।
search command या नीचे दी गई website से थर्ड-पार्टी लाइब्रेरीज़ की खोज की जा सकती है।
https://mesonbuild.com/Wrapdb-projects.html#meson-wrapdb-packages
हम gtest के उपयोग का उदाहरण लेते हैं:
- gtest search करें
अगर यह command wrap किए गए project का नाम return करती है, तो अगला step लिया जा सकता है:
- अपने project में subprojects directory बनाएँ, install से gtest इंस्टॉल करें
इस समय आपके project की सभी dependencies subprojects directory में इंस्टॉल हो चुकी हैं।
इससे gtest.wrap generate होगा, इसकी सामग्री में निम्नलिखित शामिल होगा।
ध्यान दें: यह फ़ाइल ऊपर install के बाद बनी फ़ाइल है, इसे बदलने की सलाह नहीं दी जाती।
[wrap-file]
directory = googletest-1.14.0
source_url = https://github.com/google/googletest/archive/refs/tags/v1.14.0.tar.gz
source_filename = gtest-1.14.0.tar.gz
source_hash = 8ad598c73ad796e0d8280b082cebd82a630d73e73cd3c70057938a6501bba5d7
patch_filename = gtest_1.14.0-1_patch.zip
patch_url = https://wrapdb.mesonbuild.com/v2/gtest_1.14.0-1/get_patch
patch_hash = 2e693c7d3f9370a7aa6dac802bada0874d3198ad4cfdf75647b818f691182b50
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/gtest_1.14.0-1/gtest-1.14.0.tar.gz
wrapdb_version = 1.14.0-1
[provide]
gtest = gtest_dep
gtest_main = gtest_main_dep
gmock = gmock_dep
gmock_main = gmock_main_dep
4. एक meson प्रोजेक्ट कैसे लिखें?¶
आगे बढ़ते हुए practice के चरण में आते हैं, एक meson project कैसे लिखें?
नीचे a/b division test का उदाहरण है, gtest से unit testing करने वाला एक छोटा project।
4.1 कोड लिखना¶
.h और .cc को src directory में रखें:
इसके बाद same level पर test directory बनाएँ।
4.2 meson प्रोजेक्ट प्रबंधन¶
project के root path पर meson.build फ़ाइल जोड़ें, इसकी सामग्री इस प्रकार है:
project('gtest_div', 'cpp')
gtest_proj = subproject('gtest')
gtest_dep = gtest_proj.get_variable('gtest_main_dep')
div_src = files('src/division.cc')
tests_src = files('test/division_test.cc')
e = executable(
'division_test',
tests_src + div_src,
dependencies : [ gtest_dep],
override_options : ['cpp_std=c++14']
)
# https://mesonbuild.com/Unit-tests.html#testing-tool
test('this is a division test', e)
देखा जा सकता है कि यह सामग्री python के syntax से लगभग एक समान है, python से परिचित लोगों के लिए यह code समझना बहुत आसान है, यहाँ ऊपर दिए गए कुछ ज़रूरी हिस्सों पर ध्यान से बात करेंगे।
- थर्ड-पार्टी लाइब्रेरी import करना
उदाहरण के लिए: आपके import किए गए थर्ड-पार्टी लाइब्रेरी वाले project का नाम gtest है, जैसे:
तब subproject से इस project को प्राप्त किया जा सकता है, और फिर gtest_proj.get_variable से gtest की dependency जानकारी प्राप्त की जा सकती है, उदाहरण के लिए: googletest में इसे इस तरह declare किया गया है:
gtest_main_dep = declare_dependency(
include_directories : gtest_incdir,
sources : [gtest_libsources, gtest_mainsources],
dependencies : dependency('threads')
)
- executable
executable, cmake के add_executable से बहुत मिलता-जुलता है, यह executable फ़ाइल division_test बनाता है।
- test
Unit testing का syntax:
meson test या ninja test का उपयोग किया जा सकता है, run होने के बाद test log बनता है, जो यहाँ स्थित है:
4.3 Meson प्रोजेक्ट का निर्माण और चलाना¶
ऊपर के operations से एक meson project तैयार है। आगे, हम इस project को build और run करते हैं।
4.3.1 build directory कॉन्फ़िगर करना¶
यह cmake के mkdir build && cmake .. के समान है।
run का परिणाम:
➜ gtest_div meson setup build
The Meson build system
Version: 1.2.3
Source dir: /Users/light/work/practice/gtest_div
Build dir: /Users/light/work/practice/gtest_div/build
Build type: native build
Project name: gtest_div
Project version: undefined
C++ compiler for the host machine: c++ (clang 12.0.5 "Apple clang version 12.0.5 (clang-1205.0.22.11)")
C++ linker for the host machine: c++ ld64 650.9
Host machine cpu family: x86_64
Host machine cpu: x86_64
Downloading gtest source from https://github.com/google/googletest/archive/refs/tags/v1.14.0.tar.gz
Download size: 867764
Downloading: ..........
Downloading gtest patch from https://wrapdb.mesonbuild.com/v2/gtest_1.14.0-1/get_patch
Download size: 2440
Downloading: ..........
Executing subproject gtest
gtest| Project name: gtest
gtest| Project version: 1.14.0
gtest| C++ compiler for the host machine: c++ (clang 12.0.5 "Apple clang version 12.0.5 (clang-1205.0.22.11)")
gtest| C++ linker for the host machine: c++ ld64 650.9
gtest| Run-time dependency threads found: YES
gtest| Dependency threads found: YES unknown (cached)
gtest| Dependency threads found: YES unknown (cached)
gtest| Dependency threads found: YES unknown (cached)
gtest| Build targets in project: 0
gtest| Subproject gtest finished.
Build targets in project: 1
gtest_div undefined
Subprojects
gtest: YES
Found ninja-1.11.1 at /usr/local/bin/ninja
इस समय हम subprojects में cached gtest project देख सकते हैं।
4.3.2 संकलन¶
हम निम्न दो commands उपयोग कर सकते हैं, पहली:
run का log:
➜ gtest_div meson compile -C build/
INFO: autodetecting backend as ninja
INFO: calculating backend command to run: /usr/local/bin/ninja -C /Users/light/work/practice/gtest_div/build
ninja: Entering directory `/Users/light/work/practice/gtest_div/build'
[5/5] Linking target division_test
दूसरी:
ये दोनों commands अनिवार्यतः एक जैसी हैं, दोनों ninja से compile करेंगी, बेशक -C से directory specify न करने पर भी चलेगा, उस स्थिति में cd build && ninja या cd build && meson compile करना होगा।
4.3.3 चलाना और टेस्ट करना¶
इससे division_test executable program बनेगा, run करने पर:
➜ gtest_div ./build/division_test
Running main() from ../subprojects/googletest-1.14.0/googletest/src/gtest_main.cc
[==========] Running 2 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 2 tests from DivisionTest
[ RUN ] DivisionTest.Divide
[ OK ] DivisionTest.Divide (0 ms)
[ RUN ] DivisionTest.DivideByZero
[ OK ] DivisionTest.DivideByZero (0 ms)
[----------] 2 tests from DivisionTest (0 ms total)
[----------] Global test environment tear-down
[==========] 2 tests from 1 test suite ran. (0 ms total)
[ PASSED ] 2 tests.
चूंकि meson.build में unit test test जोड़ा गया है, इसलिए हम उपयोग कर सकते हैं
या:
अगर directory specify करनी हो:
run का log:
➜ gtest_div meson test -C build
ninja: Entering directory `/Users/light/work/practice/gtest_div/build'
ninja: no work to do.
1/1 this is a division test OK 0.01s
Ok: 1
Expected Fail: 0
Fail: 0
Unexpected Pass: 0
Skipped: 0
Timeout: 0
Full log written to /Users/light/work/practice/gtest_div/build/meson-logs/testlog.txt
संबंधित विषय¶
- Bazel से C++ प्रोजेक्ट बिल्ड करना | C++那些事
- Bazel और LLDB संयुक्त डिबगिंग | C++那些事
- CMake की शुरुआत और व्यवहार | C++那些事
- Conan C++ पैकेज मैनेजर की शुरुआत | C++那些事
- C++ Insights कंपाइल-टाइम अवलोकन | C++那些事
- C++ Jupyter Notebook इंटरैक्शन | C++那些事
- C++ string को int में बदलना | C++那些事
- C++ dbg-macro डीबगिंग मैक्रो | C++那些事
- GCC कंपाइलेशन विकल्पों की विस्तृत जानकारी | C++那些事
- GDB से C++ प्रोग्राम डीबग करना | C++那些事