Windows 下編譯 ejdb2(msys2+mingw64)


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、下載源代碼

  • 首先下載 ejdb2 源碼,直接使用git克隆倉庫。
  • 下載 iowow 源碼。這里也可以不下載,在執行 cmake 的時候可以自動下載。
# 下載源碼文件
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.hmman.c文件拷貝到build-win/src/src/extern_iowow/src/fs/
  • 根據上面報錯,修改對應的代碼文件 iwlog.ciwexfile.ciwal.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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM