網上流傳的舊版本編譯方法(GYP),編譯出來的pdfium沒有高亮標注等功能。所以需要探索新版本的編譯方法。
一、window 編譯。
之前提過 vs_pdfium ,完全可以在windows平臺使用VS編譯 Pdfium 并運行測試。不過產物(靜態庫)竟然達到了上百兆,著實嚇退了一波。
通過調整編譯參數,比如打開代碼優化O2,開啟多線程編譯/MP,取消生成debug信息等,上面的項目可以在數分鐘內編譯成45MB左右的靜態庫。
參考 pdfium-binaries ,如果編譯成dll的話產物很小的,所以嘗試編譯成dll動態庫,結果只有5.4
兆字節,再次充滿信心!
主要是周圍模塊編譯成靜態庫,最后fpdfsdk
模塊鏈接這些模塊,生成動態庫。代碼生成方式仍然是MD。
下面將過程從頭“錄制”一遍:
1. 獲取代碼。
gclient config --unmanaged https://android.googlesource.com/platform/external/pdfium
gclient sync
第一句生成一個.gclient文件,第二句正式開始拉取。關于代理設置,不同代理協議做法不同,有的直接就可以聯網拉取代碼,有的則須額外配置git proxy,參見系列第一篇。
使用 gclient sync 主要是將配套的依賴庫也下載下來。可以修改DEPS
跳過v8、skia等暫時不需要的模塊。若反復出現Still working on:
不用慌,后臺仍在下載,可以通過查看臨時文件夾的大小估算下載速度。(任務管理器中沒有顯示相應的流量訪問)
若依循官方指引,運氣好的話可以繼續下去,不過運氣不好,卡在了 gn args out/release
上面,先是讓安裝Windows 10 SDK version 10.0.19041.0,裝完了又報錯說找不到 user32.lib。
所以參考 vs_pdfium 手動搭建vs項目。
2. 編譯穩定分支
PDFium倉庫有兩個:https://android.googlesource.com/platform/external/pdfium 和 https://pdfium.googlesource.com/pdfium.git
我下載下來的是安卓的倉庫。切到最新的穩定分支,android11-mainline-release
。
然后目標是用VS編譯出 fpdfsdk.dll。檢查各模塊的 BUILD.gn 得知編譯范圍,項目工程我直接復用 vs_pdfium 的,需要將新的源代碼文件添加到工程中去。VS 并不擅長做這個,僅僅一兩百個文件拖進去,就會卡住一會兒。
所以一部分文件我選擇手工拖拽添加,另外一些則通過直接修改工程文件 (*.vcxproj
和*.vcxproj.filters
) 加入。
其中 fpdfsdk 模塊會編譯成最后的動態庫,其 c++預定義中的 static 須改為 COMPONENT_BUILD;FPDF_IMPLEMENTATION;FPDFSDK_EXPORTS;
。
最好先從小的第三方模塊開始編譯,比如zlib。
第三方模塊中,一些模塊需要應用patch修改,比如 freetype。在根目錄進入bash,應用指令為patch -p0 < third_party/freetype/0000-include.patch
。
另一個模塊 libjpeg_turbo 則有部分的匯編代碼,需用 nasm.exe 編譯。參考項目Libjpeg-turbo-VS,在VS中可以很方便地書寫自定義編譯指令。
nasm.exe -fwin$(PlatformArchitecture) -DWIN$(PlatformArchitecture) -D__x86_64__ %(FullPath) -i$(SolutionDir)pdfium_lib\pdfium\third_party\libjpeg_turbo\simd\x86_64 -i$(SolutionDir)pdfium_lib\pdfium\third_party\libjpeg_turbo\simd\nasm -o$(Platform)\$(Configuration)\%(Filename).obj
編譯成功后,得到 5.39MB 的 fpdfsdk.dll,測試項目鏈接上它的導入庫 fpdfsdk.lib,最后成功編譯運行。
二、為安卓交叉編譯 PDFium.so
1. 使用 bash 與 ndk 路線。
編譯 libjpeg_turbo 時,windows 平臺的數個 *.asm 換成了一個 .S 文件,clang工具鏈可以直接編譯這樣的匯編代碼,無需額外下載 yasm。
當然也可以和舊版一樣使用 libjpeg,不過libjpeg的部分代碼需要修改。
JNI層的FPDFDest_GetPageIndex
換成了FPDFDest_GetDestPageIndex
。
與舊版相比,性能不升反降。簡單測試下,接連渲染 Gpu Pro 1.pdf 的前十頁,發現性能有輕微下降。經查,是內存管理模塊 thirdparty/base 引起的。
2. 使用 cmake 編譯。
大同小異,已更新開源倉庫(包含最新的Pdfium源碼)。與上文一樣進行了性能測試,額外測試了代碼優化選項對性能以及體積的影響:
- 無優化 : 夸張地用了4秒多才渲染完前十頁。大小 10MB。
- -Os : 700ms 左右。大小 6.15MB。
- -O3 : 與上文一致。大小 6.49MB.