इस सेटअप में WebAssembly को कैसे इंटिग्रेट किया जाता है? इस लेख में, हम C/C++ और Emscripten का इस्तेमाल करके, इस समस्या को हल करेंगे.
WebAssembly (wasm) को अक्सर परफ़ॉर्मेंस प्रिमिटिव या वेब पर अपने मौजूदा C++ कोडबेस को चलाने के तरीके के तौर पर फ़्रेम किया जाता है. squoosh.app के ज़रिए, हम यह दिखाना चाहते थे कि wasm के लिए कम से कम एक तीसरा नज़रिया है: अन्य प्रोग्रामिंग भाषाओं के बड़े-बड़े इकोसिस्टम का इस्तेमाल करना. Emscripten की मदद से, C/C++ कोड का इस्तेमाल किया जा सकता है. Rust में wasm का सपोर्ट पहले से मौजूद है. साथ ही, Go टीम इस पर काम कर रही है. हमें उम्मीद है कि जल्द ही यह सुविधा अन्य भाषाओं में भी उपलब्ध होगी.
इन स्थितियों में, wasm आपके ऐप्लिकेशन का मुख्य हिस्सा नहीं होता, बल्कि एक पज़ल पीस होता है: एक और मॉड्यूल. आपके ऐप्लिकेशन में पहले से ही JavaScript, CSS, इमेज ऐसेट, वेब पर आधारित बिल्ड सिस्टम, और React जैसा फ़्रेमवर्क मौजूद है. इस सेटअप में WebAssembly को कैसे इंटिग्रेट किया जाता है? इस लेख में, हम C/C++ और Emscripten का इस्तेमाल करके इस समस्या को हल करेंगे.
Docker
Emscripten के साथ काम करते समय, मुझे Docker बहुत मददगार लगा. C/C++ लाइब्रेरी को अक्सर उस ऑपरेटिंग सिस्टम के साथ काम करने के लिए लिखा जाता है जिस पर उन्हें बनाया गया है. एक जैसा एनवायरमेंट होना बहुत ज़रूरी है. Docker की मदद से, आपको वर्चुअलाइज़ किया गया Linux सिस्टम मिलता है. यह Emscripten के साथ काम करने के लिए पहले से ही सेट अप होता है. साथ ही, इसमें सभी टूल और डिपेंडेंसी इंस्टॉल होती हैं. अगर कोई चीज़ मौजूद नहीं है, तो उसे सिर्फ़ इंस्टॉल किया जा सकता है. इसके लिए, आपको यह चिंता करने की ज़रूरत नहीं है कि इससे आपकी मशीन या आपके अन्य प्रोजेक्ट पर क्या असर पड़ेगा. अगर कोई गड़बड़ी होती है, तो कंटेनर को हटा दें और फिर से शुरू करें. अगर यह एक बार काम करता है, तो इसका मतलब है कि यह आगे भी काम करता रहेगा और एक जैसे नतीजे देगा.
Docker Registry में trzeci की Emscripten इमेज मौजूद है. मैं इसका काफ़ी समय से इस्तेमाल कर रहा हूं.
npm के साथ इंटिग्रेशन
ज़्यादातर मामलों में, किसी वेब प्रोजेक्ट का एंट्री पॉइंट npm का package.json
होता है. आम तौर पर, ज़्यादातर प्रोजेक्ट npm install &&
npm run build
की मदद से बनाए जा सकते हैं.
आम तौर पर, Emscripten से बनाए गए बिल्ड आर्टफ़ैक्ट (एक .js
और एक .wasm
फ़ाइल) को सिर्फ़ एक और JavaScript मॉड्यूल और सिर्फ़ एक और ऐसेट के तौर पर माना जाना चाहिए. JavaScript फ़ाइल को webpack या rollup जैसे बंडलर से मैनेज किया जा सकता है. साथ ही, wasm फ़ाइल को किसी अन्य बड़ी बाइनरी ऐसेट की तरह माना जाना चाहिए. जैसे, इमेज.
इसलिए, Emscripten के बिल्ड आर्टफ़ैक्ट को "सामान्य" बिल्ड प्रोसेस शुरू होने से पहले बनाना होगा:
{
"name": "my-worldchanging-project",
"scripts": {
"build:emscripten": "docker run --rm -v $(pwd):/src trzeci/emscripten
./build.sh",
"build:app": "<the old build command>",
"build": "npm run build:emscripten && npm run build:app",
// ...
},
// ...
}
नया build:emscripten
टास्क, Emscripten को सीधे तौर पर चालू कर सकता है. हालांकि, जैसा कि पहले बताया गया है, मेरा सुझाव है कि Docker का इस्तेमाल करें, ताकि यह पक्का किया जा सके कि बिल्ड एनवायरमेंट एक जैसा हो.
docker run ... trzeci/emscripten ./build.sh
, Docker को trzeci/emscripten
इमेज का इस्तेमाल करके नया कंटेनर बनाने और ./build.sh
कमांड चलाने के लिए कहता है.
build.sh
एक शेल स्क्रिप्ट है, जिसे आपको आगे लिखना है! --rm
Docker को बताता है कि कंटेनर के चलने के बाद उसे मिटा दिया जाए. इस तरह, समय के साथ पुरानी मशीन इमेज का कलेक्शन नहीं बनता. -v $(pwd):/src
का मतलब है कि आपको Docker से मौजूदा डायरेक्ट्री ($(pwd)
) को कंटेनर के अंदर /src
में "मिरर" करने के लिए कहना है. कंटेनर में मौजूद /src
डायरेक्ट्री में मौजूद फ़ाइलों में किए गए बदलाव, आपके असली प्रोजेक्ट में भी दिखेंगे. इन मिरर की गई डायरेक्ट्री को "बाइंड माउंट" कहा जाता है.
आइए, build.sh
पर एक नज़र डालें:
#!/bin/bash
set -e
export OPTIMIZE="-Os"
export LDFLAGS="${OPTIMIZE}"
export CFLAGS="${OPTIMIZE}"
export CXXFLAGS="${OPTIMIZE}"
echo "============================================="
echo "Compiling wasm bindings"
echo "============================================="
(
# Compile C/C++ code
emcc \
${OPTIMIZE} \
--bind \
-s STRICT=1 \
-s ALLOW_MEMORY_GROWTH=1 \
-s MALLOC=emmalloc \
-s MODULARIZE=1 \
-s EXPORT_ES6=1 \
-o ./my-module.js \
src/my-module.cpp
# Create output folder
mkdir -p dist
# Move artifacts
mv my-module.{js,wasm} dist
)
echo "============================================="
echo "Compiling wasm bindings done"
echo "============================================="
यहां बहुत कुछ समझने लायक़ है!
set -e
शेल को "fail fast" मोड में डालता है. अगर स्क्रिप्ट में मौजूद किसी भी निर्देश से गड़बड़ी होती है, तो पूरी स्क्रिप्ट तुरंत बंद हो जाती है. यह बहुत मददगार हो सकता है, क्योंकि स्क्रिप्ट का आखिरी आउटपुट हमेशा एक सफलता का मैसेज या वह गड़बड़ी होगी जिसकी वजह से बिल्ड नहीं हो सका.
export
स्टेटमेंट की मदद से, कुछ एनवायरमेंट वैरिएबल की वैल्यू तय की जाती हैं. इनकी मदद से, C कंपाइलर (CFLAGS
), C++ कंपाइलर (CXXFLAGS
), और लिंकर (LDFLAGS
) को अतिरिक्त कमांड-लाइन पैरामीटर पास किए जा सकते हैं.
ये सभी, ऑप्टिमाइज़र की सेटिंग OPTIMIZE
के ज़रिए पाते हैं, ताकि यह पक्का किया जा सके कि सभी को एक ही तरीके से ऑप्टिमाइज़ किया गया है. OPTIMIZE
वैरिएबल के लिए, ये वैल्यू इस्तेमाल की जा सकती हैं:
-O0
: कोई ऑप्टिमाइज़ेशन न करें. इसमें किसी भी डेड कोड को हटाया नहीं जाता. साथ ही, Emscripten, जनरेट किए गए JavaScript कोड को छोटा नहीं करता. डीबग करने के लिए अच्छा है.-O3
: परफ़ॉर्मेंस के लिए, ज़्यादा से ज़्यादा ऑप्टिमाइज़ करें.-Os
: परफ़ॉर्मेंस के लिए ज़्यादा से ज़्यादा ऑप्टिमाइज़ करें. साथ ही, साइज़ को दूसरे मानदंड के तौर पर इस्तेमाल करें.-Oz
: साइज़ को कम करने के लिए, इमेज को ज़्यादा से ज़्यादा ऑप्टिमाइज़ करें. अगर ज़रूरी हो, तो परफ़ॉर्मेंस को कम करें.
वेब के लिए, मैं ज़्यादातर -Os
का सुझाव देता/देती हूं.
emcc
कमांड में कई विकल्प होते हैं. ध्यान दें कि emcc को "GCC या clang जैसे कंपाइलर के लिए ड्रॉप-इन रिप्लेसमेंट" के तौर पर इस्तेमाल किया जाना चाहिए. इसलिए, GCC में इस्तेमाल किए जाने वाले सभी फ़्लैग, EMCC में भी इस्तेमाल किए जा सकते हैं. -s
फ़्लैग खास है, क्योंकि इसकी मदद से हम खास तौर पर Emscripten को कॉन्फ़िगर कर सकते हैं. उपलब्ध सभी विकल्प, Emscripten के settings.js
में देखे जा सकते हैं. हालांकि, यह फ़ाइल काफ़ी बड़ी हो सकती है. यहां Emscripten के उन फ़्लैग की सूची दी गई है जो मेरे हिसाब से वेब डेवलपर के लिए सबसे ज़रूरी हैं:
--bind
, embind को चालू करता है.-s STRICT=1
में, बंद किए गए सभी बिल्ड विकल्पों के लिए सहायता बंद कर दी गई है. इससे यह पक्का होता है कि आपका कोड, आने वाले समय में काम करने वाले तरीके से बनाया गया है.-s ALLOW_MEMORY_GROWTH=1
की मदद से, ज़रूरत पड़ने पर मेमोरी को अपने-आप बढ़ाया जा सकता है. लिखते समय, Emscripten शुरुआत में 16 एमबी मेमोरी असाइन करेगा. आपका कोड मेमोरी के कुछ हिस्सों को असाइन करता है. यह विकल्प तय करता है कि मेमोरी खत्म होने पर, इन कार्रवाइयों से पूरा Wasm मॉड्यूल काम करना बंद कर देगा या ग्लू कोड को असाइनमेंट को पूरा करने के लिए, कुल मेमोरी को बढ़ाने की अनुमति दी जाएगी.-s MALLOC=...
यह तय करता है किmalloc()
को लागू करने के लिए कौनसा तरीका इस्तेमाल करना है.emmalloc
, Emscripten के लिए खास तौर पर बनाया गयाmalloc()
का छोटा और तेज़ वर्शन है. इसके अलावा,dlmalloc
का इस्तेमाल किया जा सकता है. यहmalloc()
को पूरी तरह से लागू करने का तरीका है. आपको सिर्फ़ तबdlmalloc
पर स्विच करना चाहिए, जब आपको बार-बार कई छोटे ऑब्जेक्ट असाइन करने हों या थ्रेडिंग का इस्तेमाल करना हो.-s EXPORT_ES6=1
, JavaScript कोड को ES6 मॉड्यूल में बदल देगा. इसमें एक डिफ़ॉल्ट एक्सपोर्ट होगा, जो किसी भी बंडलर के साथ काम करेगा. इसके लिए,-s MODULARIZE=1
को भी सेट करना ज़रूरी है.
यहां दिए गए फ़्लैग हमेशा ज़रूरी नहीं होते या सिर्फ़ डीबग करने के लिए मददगार होते हैं:
-s FILESYSTEM=0
एक फ़्लैग है, जो Emscripten से जुड़ा है. यह फ़्लैग, आपके C/C++ कोड में फ़ाइल सिस्टम के ऑपरेशन इस्तेमाल करने पर, आपके लिए फ़ाइल सिस्टम को एम्युलेट करने की सुविधा देता है. यह कंपाइल किए गए कोड का विश्लेषण करता है, ताकि यह तय किया जा सके कि फ़ाइल सिस्टम इम्यूलेशन को ग्लू कोड में शामिल करना है या नहीं. हालांकि, कभी-कभी यह विश्लेषण गलत हो सकता है. ऐसे में, आपको फ़ाइल सिस्टम के इम्यूलेशन के लिए 70 केबी का अतिरिक्त ग्लू कोड देना पड़ सकता है, जिसकी आपको शायद ज़रूरत न हो.-s FILESYSTEM=0
की मदद से, Emscripten को इस कोड को शामिल न करने के लिए मजबूर किया जा सकता है.-g4
से Emscripten,.wasm
में डीबग करने से जुड़ी जानकारी शामिल करेगा. साथ ही, wasm मॉड्यूल के लिए सोर्स मैप फ़ाइल भी जारी करेगा. Emscripten की मदद से डीबग करने के बारे में ज़्यादा जानने के लिए, उनके डीबग करने से जुड़े सेक्शन पर जाएं.
बस हो गया! इस सेटअप को टेस्ट करने के लिए, आइए एक छोटा सा my-module.cpp
बनाएं:
#include <emscripten/bind.h>
using namespace emscripten;
int say_hello() {
printf("Hello from your wasm module\n");
return 0;
}
EMSCRIPTEN_BINDINGS(my_module) {
function("sayHello", &say_hello);
}
और एक index.html
:
<!doctype html>
<title>Emscripten + npm example</title>
Open the console to see the output from the wasm module.
<script type="module">
import wasmModule from "./my-module.js";
const instance = wasmModule({
onRuntimeInitialized() {
instance.sayHello();
}
});
</script>
(यहां एक gist दी गई है, जिसमें सभी फ़ाइलें शामिल हैं.)
सब कुछ बनाने के लिए, यह कमांड चलाएं
$ npm install
$ npm run build
$ npm run serve
localhost:8080 पर जाने से, आपको DevTools कंसोल में यह आउटपुट दिखेगा:

C/C++ कोड को डिपेंडेंसी के तौर पर जोड़ना
अगर आपको अपने वेब ऐप्लिकेशन के लिए C/C++ लाइब्रेरी बनानी है, तो आपको उसके कोड को अपने प्रोजेक्ट में शामिल करना होगा. अपने प्रोजेक्ट की रिपॉज़िटरी में कोड को मैन्युअल तरीके से जोड़ा जा सकता है. इसके अलावा, इस तरह की डिपेंडेंसी को मैनेज करने के लिए, npm का इस्तेमाल किया जा सकता है. मान लें कि मुझे अपने वेब ऐप्लिकेशन में libvpx का इस्तेमाल करना है. libvpx, C++ लाइब्रेरी है. इसका इस्तेमाल VP8 फ़ॉर्मैट में इमेज को एन्कोड करने के लिए किया जाता है. VP8, .webm
फ़ाइलों में इस्तेमाल किया जाने वाला कोडेक है.
हालांकि, libvpx npm पर उपलब्ध नहीं है और इसमें package.json
भी नहीं है. इसलिए, मैं इसे सीधे तौर पर npm का इस्तेमाल करके इंस्टॉल नहीं कर सकता.
इस समस्या से बचने के लिए, napa का इस्तेमाल करें. napa की मदद से, किसी भी git रिपॉज़िटरी यूआरएल को अपने node_modules
फ़ोल्डर में डिपेंडेंसी के तौर पर इंस्टॉल किया जा सकता है.
napa को डिपेंडेंसी के तौर पर इंस्टॉल करें:
$ npm install --save napa
साथ ही, पक्का करें कि napa
को इंस्टॉल स्क्रिप्ट के तौर पर चलाया गया हो:
{
// ...
"scripts": {
"install": "napa",
// ...
},
"napa": {
"libvpx": "git+https://github.com/webmproject/libvpx"
}
// ...
}
npm install
चलाने पर, napa, libvpx GitHub रिपॉज़िटरी को आपके node_modules
में libvpx
नाम से क्लोन कर देता है.
अब libvpx बनाने के लिए, अपनी बिल्ड स्क्रिप्ट को बढ़ाया जा सकता है. libvpx को बनाने के लिए, configure
और make
का इस्तेमाल किया जाता है. अच्छी बात यह है कि Emscripten यह पक्का करने में मदद कर सकता है कि configure
और make
, Emscripten के कंपाइलर का इस्तेमाल करें. इसके लिए, रैपर कमांड emconfigure
और emmake
उपलब्ध हैं:
# ... above is unchanged ...
echo "============================================="
echo "Compiling libvpx"
echo "============================================="
(
rm -rf build-vpx || true
mkdir build-vpx
cd build-vpx
emconfigure ../node_modules/libvpx/configure \
--target=generic-gnu
emmake make
)
echo "============================================="
echo "Compiling libvpx done"
echo "============================================="
echo "============================================="
echo "Compiling wasm bindings"
echo "============================================="
# ... below is unchanged ...
C/C++ लाइब्रेरी को दो हिस्सों में बांटा जाता है: हेडर (आम तौर पर .h
या .hpp
फ़ाइलें), जो लाइब्रेरी के डेटा स्ट्रक्चर, क्लास, कॉन्स्टेंट वगैरह को तय करते हैं. दूसरा हिस्सा, असल लाइब्रेरी (आम तौर पर .so
या .a
फ़ाइलें) होती है. अपने कोड में लाइब्रेरी के VPX_CODEC_ABI_VERSION
कॉन्स्टेंट का इस्तेमाल करने के लिए, आपको #include
स्टेटमेंट का इस्तेमाल करके लाइब्रेरी की हेडर फ़ाइलें शामिल करनी होंगी:
#include "vpxenc.h"
#include <emscripten/bind.h>
int say_hello() {
printf("Hello from your wasm module with libvpx %d\n", VPX_CODEC_ABI_VERSION);
return 0;
}
समस्या यह है कि कंपाइलर को यह नहीं पता कि vpxenc.h
को कहाँ ढूंढना है.
-I
फ़्लैग का इस्तेमाल इसी काम के लिए किया जाता है. इससे कंपाइलर को पता चलता है कि हेडर फ़ाइलों के लिए किन डायरेक्ट्री की जांच करनी है. इसके अलावा, आपको कंपाइलर को लाइब्रेरी की असली फ़ाइल भी देनी होगी:
# ... above is unchanged ...
echo "============================================="
echo "Compiling wasm bindings"
echo "============================================="
(
# Compile C/C++ code
emcc \
${OPTIMIZE} \
--bind \
-s STRICT=1 \
-s ALLOW_MEMORY_GROWTH=1 \
-s ASSERTIONS=0 \
-s MALLOC=emmalloc \
-s MODULARIZE=1 \
-s EXPORT_ES6=1 \
-o ./my-module.js \
-I ./node_modules/libvpx \
src/my-module.cpp \
build-vpx/libvpx.a
# ... below is unchanged ...
अगर अब npm run build
चलाया जाता है, तो आपको दिखेगा कि प्रोसेस एक नई .js
और एक नई .wasm
फ़ाइल बनाती है. साथ ही, डेमो पेज में वाकई में यह कॉन्स्टेंट दिखेगा:

आपको यह भी दिखेगा कि बिल्ड प्रोसेस में ज़्यादा समय लगता है. बिल्ड होने में ज़्यादा समय लगने की वजह अलग-अलग हो सकती है. libvpx के मामले में, इसमें ज़्यादा समय लगता है. ऐसा इसलिए होता है, क्योंकि यह हर बार आपकी बिल्ड कमांड चलाने पर, VP8 और VP9 दोनों के लिए एक एन्कोडर और एक डिकोडर कंपाइल करता है. भले ही, सोर्स फ़ाइलें न बदली हों. आपके my-module.cpp
में छोटा सा बदलाव करने में भी काफ़ी समय लगेगा. libvpx के बिल्ड आर्टफ़ैक्ट को सेव करके रखना बहुत फ़ायदेमंद होगा. ऐसा तब किया जा सकता है, जब उन्हें पहली बार बनाया गया हो.
इसके लिए, एनवायरमेंट वैरिएबल का इस्तेमाल किया जा सकता है.
# ... above is unchanged ...
eval $@
echo "============================================="
echo "Compiling libvpx"
echo "============================================="
test -n "$SKIP_LIBVPX" || (
rm -rf build-vpx || true
mkdir build-vpx
cd build-vpx
emconfigure ../node_modules/libvpx/configure \
--target=generic-gnu
emmake make
)
echo "============================================="
echo "Compiling libvpx done"
echo "============================================="
# ... below is unchanged ...
(यहां gist दिया गया है, जिसमें सभी फ़ाइलें शामिल हैं.)
eval
कमांड की मदद से, एनवायरमेंट वैरिएबल सेट किए जा सकते हैं. इसके लिए, बिल्ड स्क्रिप्ट में पैरामीटर पास किए जाते हैं. अगर $SKIP_LIBVPX
को किसी भी वैल्यू पर सेट किया गया है, तो test
कमांड libvpx को बनाने की प्रोसेस को स्किप कर देगी.
अब अपने मॉड्यूल को कंपाइल किया जा सकता है. हालांकि, libvpx को फिर से बनाने की प्रोसेस को स्किप किया जा सकता है:
$ npm run build:emscripten -- SKIP_LIBVPX=1
बिल्ड एनवायरमेंट को पसंद के मुताबिक बनाना
कभी-कभी लाइब्रेरी बनाने के लिए, अतिरिक्त टूल की ज़रूरत होती है. अगर Docker इमेज से मिले बिल्ड एनवायरमेंट में ये डिपेंडेंसी मौजूद नहीं हैं, तो आपको इन्हें खुद जोड़ना होगा. उदाहरण के लिए, मान लें कि आपको doxygen का इस्तेमाल करके libvpx का दस्तावेज़ भी बनाना है. Doxygen, आपके Docker कंटेनर में उपलब्ध नहीं है. हालांकि, इसे apt
का इस्तेमाल करके इंस्टॉल किया जा सकता है.
अगर आपको build.sh
में ऐसा करना है, तो आपको अपनी लाइब्रेरी बनाने के लिए, हर बार doxygen को फिर से डाउनलोड और इंस्टॉल करना होगा. इससे न सिर्फ़ डेटा की खपत बढ़ेगी, बल्कि ऑफ़लाइन होने पर आपको अपने प्रोजेक्ट पर काम करने में भी परेशानी होगी.
ऐसे में, अपनी Docker इमेज बनाना सही रहता है. Docker इमेज, Dockerfile
लिखकर बनाई जाती हैं. इसमें इमेज बनाने के चरणों के बारे में बताया जाता है. Dockerfiles बहुत
काम की होती हैं और इनमें कई
कमांड होती हैं. हालांकि, ज़्यादातर मामलों में सिर्फ़ FROM
, RUN
, और ADD
का इस्तेमाल करके काम चलाया जा सकता है. इस मामले में:
FROM trzeci/emscripten
RUN apt-get update && \
apt-get install -qqy doxygen
FROM
की मदद से, यह तय किया जा सकता है कि आपको किस Docker इमेज का इस्तेमाल करना है. मैंने trzeci/emscripten
को आधार के तौर पर चुना है. यह वही इमेज है जिसका इस्तेमाल अब तक किया जा रहा था. RUN
की मदद से, Docker को कंटेनर में शेल कमांड चलाने का निर्देश दिया जाता है. इन कमांड से कंटेनर में जो भी बदलाव किए जाते हैं वे अब Docker इमेज का हिस्सा होते हैं. build.sh
चलाने से पहले, पक्का करें कि आपकी Docker इमेज बन गई हो और उपलब्ध हो. इसके लिए, आपको build.sh
में थोड़ा बदलाव करना होगा:package.json
{
// ...
"scripts": {
"build:dockerimage": "docker image inspect -f '.' mydockerimage || docker build -t mydockerimage .",
"build:emscripten": "docker run --rm -v $(pwd):/src mydockerimage ./build.sh",
"build": "npm run build:dockerimage && npm run build:emscripten && npm run build:app",
// ...
},
// ...
}
(यहां gist दिया गया है, जिसमें सभी फ़ाइलें शामिल हैं.)
इससे आपकी Docker इमेज बन जाएगी. हालांकि, ऐसा सिर्फ़ तब होगा, जब इमेज पहले से न बनी हो. इसके बाद, सब कुछ पहले की तरह चलता है. हालांकि, अब बिल्ड एनवायरमेंट में doxygen
कमांड उपलब्ध है. इससे libvpx का दस्तावेज़ भी बनाया जा सकेगा.
नतीजा
यह कोई हैरानी की बात नहीं है कि C/C++ कोड और npm एक साथ काम नहीं करते. हालांकि, कुछ अतिरिक्त टूल और Docker की मदद से, इन्हें आसानी से एक साथ काम करने के लिए सेट अप किया जा सकता है. यह सेटअप हर प्रोजेक्ट के लिए काम नहीं करेगा. हालांकि, यह एक अच्छा शुरुआती पॉइंट है, जिसे अपनी ज़रूरतों के हिसाब से अडजस्ट किया जा सकता है. अगर आपके पास कोई सुझाव है, तो कृपया शेयर करें.
अपेंडिक्स: Docker इमेज लेयर का इस्तेमाल करना
इन समस्याओं को हल करने का एक और तरीका है. इसके लिए, Docker और Docker की स्मार्ट कैशिंग सुविधा का इस्तेमाल करके, इन समस्याओं को ज़्यादा से ज़्यादा हल किया जा सकता है. Docker, Dockerfile को एक-एक करके एक्ज़ीक्यूट करता है. साथ ही, हर चरण के नतीजे को अपनी इमेज असाइन करता है. इन इंटरमीडिएट इमेज को अक्सर "लेयर" कहा जाता है. अगर Dockerfile में कोई कमांड नहीं बदली है, तो Dockerfile को फिर से बनाने के दौरान Docker उस चरण को फिर से नहीं चलाएगा. इसके बजाय, यह उस लेयर का फिर से इस्तेमाल करता है जिसका इस्तेमाल इमेज को पिछली बार बनाने के लिए किया गया था.
पहले, ऐप्लिकेशन बनाते समय आपको libvpx को हर बार फिर से बनाने से बचने के लिए कुछ मेहनत करनी पड़ती थी. इसके बजाय, Docker के कैश मेमोरी में सेव करने की सुविधा का इस्तेमाल करने के लिए, libvpx को बनाने के निर्देशों को अपने build.sh
से Dockerfile
में ले जाएं:
FROM trzeci/emscripten
RUN apt-get update && \
apt-get install -qqy doxygen git && \
mkdir -p /opt/libvpx/build && \
git clone https://github.com/webmproject/libvpx /opt/libvpx/src
RUN cd /opt/libvpx/build && \
emconfigure ../src/configure --target=generic-gnu && \
emmake make
(यहां gist दिया गया है, जिसमें सभी फ़ाइलें शामिल हैं.)
ध्यान दें कि आपको git को मैन्युअल तरीके से इंस्टॉल करना होगा और libvpx को क्लोन करना होगा, क्योंकि docker build
चलाते समय आपके पास बाइंड माउंट नहीं होते हैं. इसका एक और फ़ायदा यह है कि अब napa की ज़रूरत नहीं है.