EJDB2是根據MIT許可發布的可嵌入JSON數據庫引擎。 http://ejdb.org
因為EJDB2使用C11
標准,msvc 不能很好的編譯,且它的存儲層libiowow
庫大量使用了 posix 接口實現,所以編譯的過程需要做一定的處理。
編譯前准備
1、下載並安裝編譯環境
這里采用 msys2 + mingw64 作為編譯環境。
- 首先下載安裝 msys2,具體安裝過程可以參考官方頁面 https://www.msys2.org/
- 安裝完成之后,修改 pacman 鏡像源地址,參考 MSYS2 鏡像使用幫助 進行操作。可執行命令
pacman -Syu
進行基礎軟件更新,也可以不更新。 - 執行命令
pacman -S mingw-w64-x86_64-gcc
安裝編譯器等。或者安裝完整的工具鏈軟件mingw-w64-x86_64-toolchain
。 - 執行名稱
pacman -S make cmake
安裝必要的工具軟件命令工具。 - 安裝完成之后,需要打開msys2安裝目錄下的 mingw64.exe 開啟新的命令行窗口。
注意這里安裝的是 mingw-w64-x86_64-gcc
而不是安裝 msys2 的gcc
。這兩個的區別是 使用 mingw-gcc 編譯的目標文件是windows原生的,而使用 msys2-gcc 編譯的目標文件,依賴於 msys-2.0.dll 提供的虛擬 POSIX 環境,用於給 VC 進行調用的時候會出現錯誤。
2、下載源代碼
# 下載源碼文件
git clone https://github.com/Softmotions/ejdb.git
git clone https://github.com/Softmotions/iowow.git
# 打包 iowow 源碼為 zip 包
cd iowow && git archive --output ../iowow.zip master && cd ..
生成編譯腳本
# 創建構建目錄並進入
mkdir build-win && cd build-win
# 拷貝下載好的 iowow.zip 到構建目錄下的 src 目錄
mkdir src && cp ../../iowow.zip src/
# 執行 cmake ,生成 Makefile
# -DCMAKE_C_COMPILER=gcc 指定編譯器
# -DCMAKE_BUILD_TYPE=Release 指定構建類型
# -DCMAKE_OSX_ARCHITECTURES=x86_64 指定系統平台架構
# -DENABLE_HTTP=OFF 不開啟 http 支持
# -DCMAKE_INSTALL_PREFIX=./output 指定輸出目錄
# 這里不添加 -DWIN32=1 定義,因為 cmake 會報 未知命令 add_w32_importlib 的錯誤
# add_w32_importlib 是定義在 源碼cmake/Modules/Win32LIBTools.cmake文件中的
# 這在編譯 iowow 庫也是一樣的情況,我嘗試直接在 CMakeLists.txt 中直接 include 這個
# 文件,也是沒有用的,所以直接先去掉WIN32定義進行編譯,再手動生成VC需要的庫導出定義文件
cmake .. -DCMAKE_C_COMPILER=gcc -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES=x86_64 -DENABLE_HTTP=OFF -DCMAKE_INSTALL_PREFIX=./output
這時候已經可以編譯了,但是鏈接會無法通過,大量 " 找不到 xxxx 定義" 的報錯。執行一次編譯,這里需要解壓 iowow.zip
文件。
make
Scanning dependencies of target extern_iowow
[ 2%] Creating directories for 'extern_iowow'
[ 4%] Performing download step (download, verify and extract) for 'extern_iowow'
-- File already exists but no hash specified (use URL_HASH):
file='/d/Downloads/temp/ejdb2/build-win/src/iowow.zip'
Old file will be removed and new file downloaded from URL.
-- Downloading...
dst='/d/Downloads/temp/ejdb2/build-win/src/iowow.zip'
timeout='360 seconds'
-- Using src='https://github.com/Softmotions/iowow/archive/master.zip'
-- [download 100% complete]
-- Downloading... done
-- extracting...
src='/d/Downloads/temp/ejdb2/build-win/src/iowow.zip'
dst='/d/Downloads/temp/ejdb2/build-win/src/extern_iowow'
-- extracting... [tar xfz]
-- extracting... [analysis]
-- extracting... [rename]
-- extracting... [clean up]
-- extracting... done
[ 7%] No patch step for 'extern_iowow'
[ 9%] No skip-update step for 'extern_iowow'
[ 11%] Performing configure step for 'extern_iowow'
.................... 這里省略很多行..................
[ 57%] Linking C shared library libejdb2.so
extern_iowow-build/src/libiowow-1.a(iwlog.c.obj):iwlog.c:(.text+0x237): undefined reference to `localtime_r'
extern_iowow-build/src/libiowow-1.a(iwexfile.c.obj):iwexfile.c:(.text+0x4f8): undefined reference to `msync'
extern_iowow-build/src/libiowow-1.a(iwexfile.c.obj):iwexfile.c:(.text+0x59d): undefined reference to `msync'
extern_iowow-build/src/libiowow-1.a(iwexfile.c.obj):iwexfile.c:(.text+0x782): undefined reference to `munmap'
extern_iowow-build/src/libiowow-1.a(iwexfile.c.obj):iwexfile.c:(.text+0xc94): undefined reference to `msync'
......................
extern_iowow-build/src/libiowow-1.a(iwfile.c.obj):iwfile.c:(.text+0x42c): undefined reference to `xstrndup'
extern_iowow-build/src/libiowow-1.a(iwal.c.obj):iwal.c:(.text+0xaab): undefined reference to `mmap'
extern_iowow-build/src/libiowow-1.a(iwal.c.obj):iwal.c:(.text+0xbcf): undefined reference to `munmap'
extern_iowow-build/src/libiowow-1.a(iwal.c.obj):iwal.c:(.text+0xdfd): undefined reference to `munmap'
extern_iowow-build/src/libiowow-1.a(iwal.c.obj):iwal.c:(.text+0x1077): undefined reference to `munmap'
修改 iowow 項目,使之能夠編譯通過
- 首先下載一個在 windows 上支持
mmap
等 posix 系統調用的庫。 - 將 mmap 庫里面的
mman.h
、mman.c
文件拷貝到build-win/src/src/extern_iowow/src/fs/
。 - 根據上面報錯,修改對應的代碼文件
iwlog.c
、iwexfile.c
、iwal.c
。- 修改
fs/iwlog.c
文件 366 行,將localtime_r(&ts_sec, &timeinfo);
修改為localtime_s(&timeinfo,&ts_sec);
,也可以使用宏來區分版本。 - 修改
fs/iwfile.c
文件 39 行,將#define strndup xstrndup
修改為#define strndup(*s*,*len*) strncpy(malloc(strlen(s) + 1), s, len)
,這里的修改不是很優,最好還是寫成內聯函數而不是宏定義的方式。
- 修改
- 進入
build-win
下的src/extern_iowow-build/
目錄,運行cmake
刷新Makefile
腳本,然后重新編譯libiowow
庫。 - 回到 build-win 目錄,重新執行 make 進行編譯。
# 下載 mmap 庫(windows下的mmap實現)
git clone https://github.com/plettplett/mmap.git
# 將對應的源碼文件拷貝到對應目錄下
cp ../../mmap/mman.* src/extern_iowow/src/fs/
# 進入 iowow 的構建目錄
cd src/extern_iowow-build/
# 修改源碼文件,這里省略 ....................
# 重新執行cmake 命令,更新 Makefile 文件
cmake ../extern_iowow -DCMAKE_C_COMPILER=gcc -DCMAKE_BUILD_TYPE=Release -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_INSTALL_PREFIX=../../output
# 重新生成 libiowow 庫,並安裝到輸出目錄
make && make install
# 回到 build-win 目錄
cd ../../
# 執行 make 命令,繼續生成 libejdb2 庫
make && make install
生成VC可調用文件
1、修改生成的文件名后綴,將.so
修改為.dll
。不修改也不影響使用,修改會比較好看一點。
cd output
mv libejdb2.so lib2jdb2.dll
mv libiowow.dll libiowow.dll
2、使用 pexports.exe(點此去下載) 生成動態庫對應的.def
(函數導出定義)文件。
pexports.exe libejdb2.dll -o > libejdb2.def
pexports.exe libiowow.dll -o > libiowow.def
生成這兩個文件之后,打開這兩個文件,將第一行中的文件名的.so
修改為.dll
。如果前面沒有修改后綴名,這里也不修改。
3、使用Visual Studio
自帶lib.exe
生成對應的.lib
文件。
lib /machine:X64 /def:libejdb2.def
/machine:X64 /def:libiowow.def
4、修改iwp.h
文件。將第 40 行的 #include <sys/time.h>
修改為:
#ifndef _WIN32
#include <sys/time.h>
#else
#include <sys/types.h>
#endif
5、拷貝 msys2
安裝目錄下的 mingw64/bin/libwinpthread-1.dll
文件到輸出目錄,這是一個依賴項。
編譯好的文件可以在這里下載:https://files.cnblogs.com/files/oloroso/ejdb.7z