Calm Hill My Random Thoughts

Building ICU Enabled SQLite Static Library for Node.js with Microsoft Visual C++

ICU နဲ့ SQLite ကို Windows ပေါ်မှာ Build လုပ်ဖို့အရေးကို နေ့ရွှေ့ညရွှေ့နဲ့ လုပ်လာလိုက်တာ တရုတ်မတွေကလည်း ပူညံပူညံလုပ်ပြီဆိုတော့ ပြေးမလွတ်တဲ့အချိန်ကျမှ ကိုယ်တိုင်ပဲ Build လုပ်ရတော့တယ်။ တတ်နိုင်သလောက်တော့ Build လုပ်ထားပြီးသား လိုက်ရှာကြည့်ပေမယ့် အဆင်မပြေပါဘူး အဓိကပြဿနာ ၂ ခုရှိတယ် ICU Library တွေကို Official Build လုပ်ပြီးသားရှိပေမယ့် VC 2010 နဲ့ Build လုပ်ထားတာဖြစ်လို့ VC 2010 နဲ့ Build လုပ်လို့မရတဲ့ Node SQLite အတွက်ကြောင့် သုံးလို့မရဘူး။ နောက်တချက်က ICU ရဲ့ Build Setting တွေမှာ Static library ဆိုပေမယ့် \MD (Multi-threaded DLL) Flag နဲ့ Build လုပ်ထားတဲ့အတွက် Node SQLite ဟာ VC 2010 ကို Support လုပ်ရင်တောင် သုံးလို့ရမှာ မဟုတ်ပါဘူး။ အဲဒီအတွက်ကြောင့် Visual Studio 2015 ကိုသုံးပြီးတော့ အစအဆုံး Build လုပ်ယူလိုက်ရတယ်။

ICU ကို Build လုပ်ဖို့မှာက Visual Studio 2015 အပြင် Configuration လုပ်တဲ့အခါမှာ GNU Autotools တွေ လိုအပ်တဲ့အတွက် make နဲ့ binutils ကို Install လုပ်ထားတဲ့ Cygwin လိုပါလိမ့်မယ်။ Mac မှာ Build လုပ်ခဲ့သလိုပဲ Build လုပ်ပြီးရင် Library တွေ Headers တွေကို Install လုပ်ဖို့အတွက်က Home Directory အောက်မှာ local ဆိုပြီးတော့ပဲ Install လုပ်မယ်။ Build မလုပ်ခင်မှာ Cygwin နဲ့ PREFIX တွေကို Visual Studio မှာပါလာတဲ့ Developer Command Prompt မှာ အောက်မှာပြထားသလို Configure လုပ်ဖို့လိုလိမ့်မယ်။ Build မလုပ်ခင်မှာ 32-bits or 64-bits စသည်ဖြင့်တော့ လိုချင်တာကို Developer Command Prompt မှာ Define လုပ်ဖို့တော့ မမေ့ဖို့လိုတယ်။

Cygwin & Prefix

set PATH=%PATH%;C:\cygwin64\bin
set PREFIXWIN=%HOME%\local
cygpath %PREFIXWIN% > cygprefix.txt
set /p PREFIX=<cygprefix.txt
del cygprefix.txt
"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86

ICU: Download

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

ICU ရဲ့ Configuration Script ဖြစ်တဲ့ runConfigureICU ဟာ Cygwin/MSVC ကို Static နဲ့ Configure လုပ်ရင် \MD (Multi-threaded DLL) နဲ့ Configure လုပ်ပေးလိမ့်မယ် အဲဒါကြောင့် runConfigureICU ကိုမသုံးပဲနဲ့ CFLAGS နဲ့ CXXFLAGS မှာ \MT (Multi-threaded) Flag ကို Manual ပဲထည့်ပေးပြီးတော့ configure script ကိုပဲ တိုက်ရိုက်သုံးပြီးတော့ configure လုပ်ပြီးတော့ Build လုပ်ရင် ICU ကို Build လုပ်လို့ရပါလိမ့်မယ်။ ICU Data ကို Update လုပ်ဖို့ လိုတယ်ဆိုရင်တော့ Configure မလုပ်ခင်မှာ Update လုပ်ပြီးမှ Configure လုပ်ပါ။

ICU: Build

set CC=cl
set CXX=cl
set CFLAGS=-Gy -MT
set CXXFLAGS=-Gy -MT
bash configure --enable-static --disable-shared --prefix="%PREFIX%"
make
make install

SQLite: Download

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

SQLite အတွက်ကတော့ amalgamate လုပ်ထားတဲ့ Source Code ကိုသုံးမယ်ဆိုရင် Windows ပေါ်မှာ Build လုပ်ရတာ Makefile တွေနဲ့ Configure လုပ်စရာမလိုပါဘူး အောက်မှာပြထားတဲ့ Command တွေနဲ့ Build လုပ်မယ်ဆိုရင် ရပါလိမ့်မယ်။

SQLite: Build

cl /I%PREFIXWIN%\include sqlite3.c -c -Gy -MT -DSQLITE_ENABLE_ICU -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_COLUMN_METADATA
lib /out:sqlite3.lib sqlite3.obj
copy sqlite3.h %PREFIXWIN%\include
copy sqlite3.lib %PREFIXWIN%\lib

Node SQLite3: Download

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

node-sqlite3 အတွက်က Build မလုပ်ခင်မှာ binding.gyp မှာ အောက်မှာပြထားသလို Link လုပ်ရမယ့် ICU Library စာရင်းတွေကို ထပ်ထည့်ပေးမှပဲ Build လုပ်လို့ရပါလိမ့်မယ်။ Build လုပ်တာကတော့ npm install ကို --build-from-source နဲ့ Build လုပ်ရင်ရမယ်။ အောက်မှာလည်း Node.js အတွက်ရယ် NW.js အတွက်ရယ်အတွက် Build လုပ်တဲ့ Command တွေကို နမူနာကြည့်ပြီးတော့ သင့်တော်သလိုသုံးရင် Build လုပ်လို့ အလွယ်တကူ ရပါလိမ့်မယ်။

Modify binding.gyp

"libraries": [
   "-l<(sqlite_libname)",
   "-lsicudt",
   "-lsicuin",
   "-lsicuio",
   "-lsicule",
   "-lsiculx",
   "-lsicutu",
   "-lsicuuc"
]

Node SQLite3: Build for Node.js

npm install --build-from-source --sqlite=%PREFIXWIN%

Node SQLite3: Build for NW.js

npm install --build-from-source --sqlite=%PREFIXWIN% --target_arch=ia32 --target="0.16.1" --runtime=node-webkit

အခုအချိန်မှာ ပြန်ကြည့်ပြန်တော့ ဘာမှမဟုတ်ဘူး ထင်ရပေမယ့် လိုအပ်တဲ့ Flags တွေမှန်ဖို့ စမ်းကြည့်လိုက် Error တွေတက်လာလိုက် config script တွေ ဖတ်ကြည့်ပြီး နည်းနည်းပြောင်း ပြန်စမ်းလိုက်နဲ့ အချိန်အတော်ကုန်တယ် ၁ ရက် ၂ ရက်လောက် အလုပ်ပျက်သွားတယ် အဲဒီတော့ နောက်တချိန် အသုံးလိုရင် ကိုယ်တိုင် ပြန်သုံးလို့ရအောင် မေ့မသွားအောင် Blog Post အဖြစ်နဲ့ ရေးထားရတယ်။ လူအများ အသုံးကျဖို့အတွက် တကယ်တမ်း ရေးသင့်တာက အင်္ဂလိပ်လိုဖြစ်မယ် ကိုယ့်ရဲ့ တောင်ရာက်မြောက်ရောက် စာရေးပုံကို Google Translate နဲ့ဖတ်ကြရင် ရူးသွားနိုင်တယ် လက်ရှိလုပ်နေတဲ့ ARM processor တွေအတွက် ပြီးတဲ့အခါမှပဲ အားလုံးပေါင်းပြီး Post ၁ ခုထဲအနေနဲ့ အင်္ဂလိပ်လို စုပေါင်းပြီး ရေးတော့မယ်။

References

  • https://www.sqlite.org/howtocompile.html
  • https://wiki.qt.io/Compiling-ICU-with-MSVC
  • http://www.npcglib.org/~stathis/blog/precompiled-icu/
  • http://bugs.icu-project.org/trac/attachment/ticket/10406/ICU_51.2_static_runtime_Cygwin_MSVC.patch
  • http://kevgriffin.com/specifying-visual-studio-version-in-npm-installs/
  • http://www.calmhill.com/2016/08/07/sqlite3-icu-nodejs.html
  • http://www.calmhill.com/2011/10/07/cross-compile-with-mingw-w64.html