Calm Hill My Random Thoughts

Building ICU Enabled SQLite Static Library for Node.js

အခုနှစ်ပိုင်းတွေမှာ ကိုယ်တိုင်ကိုယ်ကျ Implement လုပ်တဲ့အလုပ်တွေ သိသိသာသာနည်းသွားတယ် အမြဲတမ်းတော့လည်း Development နဲ့ ဝေးသွားတယ်တော့ မဟုတ်ဘူးပေါ့လေ ကိုယ့်ထက်ငယ်တဲ့လူတွေ မြင်ဖူးတဲ့ Error ဆိုတာက ကိုယ်တက်ခဲ့ဖူးတဲ့ Error အကြိမ်ထက်တော့ ဘယ်များနိုင်ပါ့မလဲ လိုအပ်တဲ့အခါတော့ နှမ်းဝင်ဖြူးရတဲ့ အခါလည်းရှိတာပေါ့။ အလုပ်ထဲက Software တခုက Text Content တွေကို ရှာဖို့ဆိုပြီးတော့ SQLite ထဲက Full-Text Search နဲ့ Index လုပ်ထားတာ အဆင်ပြေနေရာကနေ တရုတ်ပြည်ကို ရောင်းလိုက်မိရာက တရုတ်လိုလည်း နောက်လာမယ့် Update ကျရင် ရှာလို့ရမယ်လို့ အာမခံလိုက်မိတယ် ဖြစ်ချင်တော့ SQLite က Build လုပ်ပြီးသားတွေမှာ ICU ကို Default Enable မပါလာတာကို သတိမထားလိုက်မိဘူး။

ကိုယ့်ရဲ့ Programmer တွေကို Full-Text Index မှာ Tokenizer ကို ICU ပေးလိုက်ပြီးတော့ SQLite Library တွေကို ICU Enable လုပ်ထားတဲ့ Library ရှာပြီးသုံးလိုက် မရှိရင်တော့ Build လုပ်လို့ပဲ မှာပြီးတော့ လုပ်ခိုင်းထားမိလိုက်တာ သူတို့တတွေက Source ကနေ Build လုပ်နေကျလူတွေ မဟုတ်ကြတော့ လုပ်မရဘူးဆိုပြီး ဗြဟ္မာကြီးဦးခေါင်းက ကိုယ့်ဆီပြန်ရောက်လာတယ်။ စမ်းကြည့်တော့မှ ပြဿနာကထင်သလောက် မလွယ်ဘူးဖြစ်နေတယ် ကိုယ့်စက်တခုအတွက်က အဲလောက်မခက်ဘူး ဒါပေမယ့် Dynamic Linked Library တွေက Dependence Library တွေအကုန် မပါလာရင် သုံးလို့မရဘူး Customer ဆိုတာက မတထောင်သားသမီးတွေရယ် File တခုပေးလိုက် Double Click နှိပ်လိုက်လို့ အလုပ်လုပ်တယ်ဆိုရင် အကောင်းဆုံးပဲ မဟုတ်ရင် အင်မတန်နားပူတယ်လေ ရော့အင့်ဆိုပြီး Copy ကူးပေးလို့ရအောင် ရှိသမျှကို Static Linked Library အဖြစ် Build လုပ်ဖို့လိုလာတယ်။

Build လုပ်ရမယ့် Platform ကို စဉ်းစားလိုက်တော့ iOS အတွက်က ARM အမျိုးမျိုးရှိသမျှလိုတယ် Server ပေါ်မှာသုံးတဲ့ Node.js အတွက်လည်း သူသုံးထားတဲ့ node_modules ကို customize လုပ်ပေးဖို့ လိုလာပြန်တယ် PC အတွက်က Mac ရယ် Windows ရယ်အတွက် NW.js အတွက်လည်း Build လုပ်ရဦးမယ် C နဲ့ပတ်သက်တာတွေကုန်ရင် Android အတွက်က Java Library တွေကို စမ်းကြည့်ရဦးမယ်ဆိုပြီး Platform စာရင်းကို စဉ်းစားမိတာနဲ့ နည်းနည်းရူးချင်မိတယ်။ Mobile တွေကို ခဏချန်ထားပြီးတော့ အရှုပ်ထုပ်ဖြစ်နေတဲ့ Node.js နဲ့ ပတ်သက်တာ အရင်ဆုံးရှင်းလိုက်တော့ ကံဆိုးတယ်ထင်တယ် ဘယ်သူမှကိုယ့်လို ပေါက်ပေါက်ရှာရှာ Build လုပ်ကြပုံမပေါ်ဘူး အင်တာနက်ပေါ်က ကိုယ်လိုပြဿနာတက်တဲ့လူ သိပ်များများရှာလို့မရတော့ ကိုယ်တိုင်ပဲ Document တွေရှာဖတ် Source Code တွေထဲက Configuration Script တွေဖွင့်ဖတ်ပြီး Build Option တွေကို တခုစီပြောင်းလိုက် Build လုပ်ကြည့်လိုက်နဲ့ မုန့်လုံးစက္ကူကပ်ပြီးတော့ ရတော့ရလာပါတယ်။

သပွတ်အူလိုဖြစ်နေတဲ့ ကိုယ့်ရဲ့ Build လုပ်တဲ့ Process ကို နောင်လိုအပ်တဲ့အခါ ပြန်သုံးလို့ရအောင် အတတ်နိုင်ဆုံးတော့ ပြန်ရှင်းပြီးရေးထားတယ် ကိုယ့်ဟာကိုယ် စမ်းကြည့်နေတုံးကတော့ လိုအပ်တဲ့ Option တွေကို အလွယ်တကူပဲ Configuration File တွေထဲဝင်ပြင်တာတို့ Source Code တွေကိုပြင်တာတို့ လုပ်ထားပေမယ့် အတတ်နိုင်ဆုံးတော့ Configuration Parameters တွေအဖြစ် ရှင်းထားလိုက်တယ် မတတ်သာတဲ့ အဆင့်လောက်ပဲ File တွေထဲကို ဝင်ပြင်ဖို့လိုမှာဆိုတော့ အခုစမ်းထားတဲ့ အချိန်မှာသုံးထားတဲ့ Source Code Version တွေမဟုတ်ပဲနဲ့ နောက်ထပ် Version တွေပြောင်းသွားလည်း ဆက်သုံးလို့ရမယ်ထင်တယ် အသေးစိတ်ကို အောက်မှာကြည့်ပါ။

ပထမဆုံးအနေနဲ့ Build လုပ်ပြီးရင် Install လုပ်ဖို့အတွက် နေရာတခုရှိဖို့လိုတယ် သာမန်အားဖြင့် Build လုပ်ထားတဲ့ Software တွေကို System Directory တွေအထဲကို မထည့်တာပဲ ကောင်းတယ် ကိုယ်ကတော့ အများအားဖြင့် Home Directory အထဲမှာပဲ အလုပ်လုပ်တာများတယ် အလွယ်တခုရှင်းလို့ရအောင် Home အောက်မှာ local ဆိုပြီး Directory တခုထဲမှာ ကိုယ်တိုင် Custom Build လုပ်ထားတဲ့ Software တွေကိုထားလေ့ရှိတယ် တခြားမှာထားချင်ရင်တော့ တခြားနေရာကိုပြောင်းပြီးတော့ Configure လုပ်လို့ရတယ် ကိုယ့်ကိစ္စနဲ့ကိုယ် ထားချင်တဲ့နေရာထားပါ သိပ်အရေးမကြီးပါဘူး နောင်တချိန်ပြန်မသုံးလည်း ပြီးတာနဲ့လည်း ပြန်ဖျက်ချင်လည်း ဖျက်လို့ရပါတယ်။

Prefix

PREFIX=$HOME/local

ICU ကို Build လုပ်ဖို့အတွက် ICU4C Source Code တွေကို အောက်မှာပြထားတဲ့ Site ကနေ Download လုပ်ဖို့လိုလိမ့်မယ် ICU မှာ Source ရယ် Data ရယ်ဆိုပြီး ၂ ခုရှိတယ် Source ထဲမှာလည်း Built-in အနေနဲ့ Data ပါပေမယ့် Update လုပ်ဖို့ လိုအပ်တယ်ထင်ရင်တော့ Data ကိုလည်း Download လုပ်ပြီးတော့ အစားထိုးဖို့လိုလိမ့်မယ်။ သာမန်အားဖြင့် ICU Build လုပ်တာက ပြဿနာလုပ်လေ့မရှိပါဘူး နောက်ဆုံးအနေနဲ့ make install ဆိုရင် ကိုယ်သတ်မှတ်ထားတဲ့ PREFIX အောက်က lib နဲ့ include အောက်မှာ Build လုပ်ထားတဲ့ Library တွေရယ် Header Files တွေရယ်ကို ကူးထည့်ပေးလိမ့်မယ်။

ICU: Download

http://site.icu-project.org/download

ICU: Build

./runConfigureICU MacOSX --enable-static --disable-shared --prefix=$PREFIX
make
make install

ICU ပြီးသွားရင် နောက်တဆင့်အနေနဲ့ SQLite ကို Build လုပ်ဖို့အတွက် SQLite Source တွေကို Download လုပ်ဖို့လိုမယ် SQLite Source ထဲမှာ Autoconf နဲ့ Source Code ကိုပဲသုံးထားတယ်။ SQLite မှာ ICU က Default မပါတဲ့အတွက် -DSQLITE_ENABLE_ICU ကိုထည့်ပေးရမယ် CFLAGS မှာ ICU Headers တွေရှိတဲ့ Path နဲ့ LDFLAGS မှာ ICU Static Library တွေရှိတဲ့ Path ကို ထည့်ပေးရမယ် LIBS မှာတော့ Static Link လုပ်ပေးရမယ့် ICU Library တွေကို -l နဲ့တခုစီထည့်ပေးပြီးတော့ —enable-static နဲ့ Configure လုပ်ပြီး Build လုပ်မယ်ဆိုရင် SQLite အတွက် Static Library ရလိမ့်မယ် make install လုပ်လိုက်မယ်ဆိုရင် PREFIX အောက်မှာပဲ Install လုပ်သွားလိမ့်မယ် အဲဒါဆိုရင် Node.js အတွက်သုံးရယ် ICU နဲ့ SQLite Static Library တွေက PREFIX အောက်က lib ထဲမှာ အားလုံးအဆင်သင့်ဖြစ်ပြီ။

SQLite: Download

https://www.sqlite.org/download.html

SQLite: Build

./configure CFLAGS="-I$PREFIX/include -DSQLITE_ENABLE_ICU" LDFLAGS=-L$PREFIX/lib LIBS="-lc++ -licudata -licui18n -licuio -licule -liculx -licutu -licuuc" --enable-static --disable-shared --prefix=$PREFIX
make
make install

Node SQLite3 ကို Build လုပ်ရတာက နည်းနည်းဒုက္ခရောက်တယ် သူ့ရဲ့ Issues တခုထဲမှာ ကိုယ်တိုင် Build လုပ်ထားတဲ့ SQLite ကိုသုံးမယ်ဆိုရင် --sqlite နဲ့ ထည့်ပေးရင်ရတယ်ဆိုလို့ ထည့်ပေးလိုက်တယ် Build တော့လုပ်သွားတယ် SQLite Library တွေပါသွားတယ် ဒါပေမယ့် ICU မပါလာတော့ တကယ်သုံးတဲ့အချိန်မှ Error တက်ပြီးတော့ အလုပ်မလုပ်ပဲ ဖြစ်နေပါရော။ ဒီတခုကတော့ Configuration မှာ Option တွေထည့်ပေးပြီး Build လုပ်လို့မရတဲ့အတွက် နည်းနည်းတော့ပြင်ဖို့လိုမယ် အရင်ဆုံးအနေနဲ့ သူ့ရဲ့ Git Repo ကနေ Clone လုပ်ရင်လုပ် မလုပ်ချင်ရင်တော့ Download လုပ်ရမယ်။ ပြီးရင် binding.gyp ထဲမှာ -l<(sqlite_libname) ဆိုတာကိုလိုက်ရှာပြီးတော့ လိုအပ်တဲ့ ICU Library တွေအတွက်ပါ -l<(sqlite_libname) -licudata -licui18n -licuio -licule -liculx -licutu -licuuc ဆိုပြီးတော့ ထပ်ထည့်ပေးပြီး npm install နဲ့ Build လုပ်ရမယ် ပြီးရင်တော့ ကိုယ်သုံးချင်တဲ့ Node Project ထဲက node_modules ထဲကို Build လုပ်ထားတဲ့ Directory လိုက် ကူးထည့်ပြီးတော့ သုံးလို့ရပြီ။

Node SQLite3: Download

https://github.com/mapbox/node-sqlite3

Node SQLite3: Build for Node.js

npm install --build-from-source --sqlite=$PREFIX

Node SQLite3: Build for NW.js

npm install --build-from-source --sqlite=$PREFIX --runtime=node-webkit --target_arch=x64 --target="0.16.1"

လောလောဆယ်က Mac အတွက်ပဲ အရေးပေါ်လိုနေတာဆိုတော့ ကိုယ် Build လုပ်ထားတာကို Implement လုပ်မယ့်လူတွေကို ပေးလိုက်ပြီးရင် သူတို့အလုပ်ဆက်လုပ်လို့ ရသွားပြီဆိုတော့ နည်းနည်းတော့ အသက်ရှူချောင်သွားတယ် iOS ARM တွေအတွက် ကျန်သေးတာတွေအတွက် သိပ်မပူပန်ပေမယ့် Windows အတွက် Microsoft ရဲ့ Tools တွေကိုသုံးပြီးတော့ Build လုပ်ရဦးမယ် ဆိုတာကတော့ ကျားအမြီးကိုပဲ ပြေးပြီးတော့သာ ဆွဲလိုက်ချင်မိတယ် စာရေးချင်စိတ် မကုန်သေးဘူးဆိုရင်တော့ နောက်ထပ်လည်း Post တခုထွက်ကောင်း ထွက်လာနိုင်ပါသေးတယ်။