Google 从福昕阅读器那拿了7%的代码,搞了这么一个玩意儿:
https://pdfium.googlesource.com/pdfium/
实际上还有一个 Android 版本:
https://android.googlesource.com/platform/external/pdfium
通过对比源码,Android 这个链接源码差异主要是以下几点:
- Android版本的头文件包含的接口偏少。
- 由于开发者不同,命名上存在区别 Android 版多为驼峰命名。
- 增加了 Android.bp 文件,大概是 Android 源码中的那套。
- Android 版更新频率较慢,空方法也较多。
所以基于资料以及稳定性,这里都是使用这个版本:https://pdfium.googlesource.com/pdfium/
准备阶段
准备一个Ubuntu系统,如果使用衍生版Ubuntu则可能需要注释掉源码 build/install-build-deps.sh
脚本中的依赖判断语句(但依旧需要确认版本是debian系以及在下述的版本中):
下载源码
开终端,配置代理(不配置则无法下载):
export http_proxy=http://host:port
export https_proxy=http://host:port
可使用 curl https://google.com
进行查看是否成功。
下载编译链工具:
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
并将相关编译工具添加到环境变量以供使用:
export PATH=/path/to/depot_tools:$PATH
此时可以用gclient
命令进行pdfium
配置了,创建一个文件夹,终端切入该文件夹,同步源码:
gclient.py config https://pdfium.googlesource.com/pdfium.git
因为是编译 Android 库,所以需要配置下(必须):
echo "target_os = ['android']" >> .gclient
开始同步pdfium源码(没有代理则会无响应):
gclient.py sync
大概文件10gb,同步完成会有提示:
但这还不够,还需要继续下载一些工具(很重要):
gclient runhooks
接下来将终端切入到下载好的pdfium源码中,执行该脚本安装依赖:
cd pdfium
sudo ./build/install-build-deps-android.sh
等待安装完成。
PS:如果后面缺点什么,可能还需要装点,因为系统安装完成时附带的package并不是固定的。
apt-get update
apt-get install -y build-essential git subversion pkg-config python libtool cmake glib2.0-dev libatspi2.0-dev wget
配置修改
- 打开
pdfium/BUILD.gn
文件,找到config("pdfium_common_config")
(大概在17行),将以下配置:
config("pdfium_common_config") { cflags = [ "" ] ldflags = [] include_dirs = [ "." ] defines = [ "PNG_PREFIX", "PNG_USE_READ_MACROS", ]
修改为(增加-fvisibility=default
,增加"FPDFSDK_EXPORTS"
):
config("pdfium_common_config") { cflags = [ "-fvisibility=default" ] ldflags = [] include_dirs = [ "." ] defines = [ "PNG_PREFIX", "PNG_USE_READ_MACROS", "FPDFSDK_EXPORTS" ]
- 增加
"-fvisibility=default"
到cflags
,将符号的可见性设置为默认值。这意味着其他组件可以引用该符号,并且符号定义可以被另一个组件中的同名定义覆盖。 - 增加
“FPDFSDK_EXPORTS”
到defines
— 把符号表嵌入到共享库中。
2. 继续修改pdfium/BUILD.gn
文件,滚动到大约 152 行,在component("pdfium")
前追加以下配置:
shared_library("pdfsdk") { deps = [":pdfium"] ldflags = [ "-latomic" ] if (target_os == "android") { configs -= [ "//build/config/android:hide_all_but_jni_onload" ] } } component("pdfium") { //…
3. 修改pdfium/build_overrides/build.gni
,大概在25行,注释掉以下代码:
#if (current_cpu == "arm") { #arm_use_neon = true #}
编译 so
编辑配置:
执行 gn
命令生成编译所必须的一些配置文件:
gn gen out/$arch
同时这里需要配置一些参数,参数配置的方式有两种:
- 进入
out/$arch
,编辑文件args.gn
,参数填上:
target_os="android" target_cpu="$arch" pdf_bundle_freetype=true pdf_is_standalone=false is_component_build=false pdf_enable_xfa=false pdf_enable_v8=false is_debug=false is_official_build=true
- 直接跟在命令后面
gn gen out/$arch --args="target_os=\"android\" pdf_bundle_freetype=true pdf_is_standalone=false is_component_build=false pdf_enable_xfa=false pdf_enable_v8=false is_debug=false is_official_build=true target_cpu=\"$arch\"" 例: gn gen out/x86 --args="target_os=\"android\" pdf_bundle_freetype=true pdf_is_standalone=false is_component_build=false pdf_enable_xfa=false pdf_enable_v8=false is_debug=false is_official_build=true target_cpu=\"x86\""
这样可减少体积与编译时间,因为一些组件是用于web/chrome/js使用的。
执行编译:
ninja -C out/$arch pdfsdk
注:此处的$arch
指x86
、x86_64
、armeabi-v7a
、arm64-v8a
,也就是 ndk
中包含的 abis
最后文件pdfsdk.so
会生成在out
目录下,如:
该方式一次只能编译一个abi
。编译多个abi文件可使用下文列出的脚本:
https://github.com/benjinus/android-support-pdfium/blob/master/BUILD.md
中间某些错误,大多数的失败原因都是源码未同步完整,包含编译工具链等,一共大概是10gb(其中包含Android SDK/NDK 以及一些引擎,时间巨长)。
其他问题(完全下载完则不存在问题)
如果pdfium/buildtools/linux64
下没有gn
则需要自编译gn
(实际上在sync成功的情况下会自动去做这步),gn
工具相关说明:https://gn.googlesource.com/gn/
git clone https://gn.googlesource.com/gn cd gn python build/gen.py ninja -C out To run tests: out/gn_unittests
其他编译时报错则需要看缺少什么,如可能缺少clang
,则装一下:
sudo apt install clang
相关资料:
ninja: error: loading ‘build.ninja’: No such file or directory #1463
https://pdfium.googlesource.com/pdfium/#get-the-code
How to build PDFium library for Android
https://medium.com/@johngray1965/i-wrote-a-script-to-handle-all-this-60ef838b49ee
主要参考:
https://github.com/benjinus/android-support-pdfium/blob/master/BUILD.md
So库
- 基于版本:
837fe726e639f823a62ed4aa4abda45d40f3c803
(时间:文章书写时)
- 基于版本:4f67a285e22100c9dc9d175e8269c8fed1734f34(2020.12.24最新)
更新到指定版本可使用命令:
gclient sync --revision 837fe726e639f823a62ed4aa4abda45d40f3c803
本站由以下主机服务商提供服务支持:
knziha
我也在编译这个.so,拉取的是aosp上的pdfium,但是自己搭工具链。性能较旧版变低了,能否交流一下?
Mosaic-C
性能 那真不了解~(T▽T)
knziha
很简单,分享一下你用gn编译的。我用makefile编译了好几个版本,发现启用了skia后性能更低。
Mosaic-C
已上传文章末尾。
knziha
编译的好全,而且体积是最小的。https://github.com/KnIfER/LibPDFium/issues/1。不知支不支持安卓4?
Mosaic-C
试试?我没关注到4.4 官方似乎没有直接说明 但其他文章或者lib给到的是API 14,具体看实际测试情况吧~ (¬_¬)瞄
knziha
试了下不行。。这个跟工具链的平台版本有关的。比如makefile里可以指定$(CC)为 $(TOOLCHAIN)/bin/armv7a-linux-androideabi19-clang,就可以兼容安卓19了。
Mosaic-C
嗯,我猜也是需要调整编译参数,如果产品需要这样做,那就还是得重新打了,只是现在4.4 还有支持必要么?目测,也没几个软件能运行得动了
knziha
可以的哦,实机测试,pdfium可在安卓4流畅运行。关键安卓4省电……
运行大厂的软件倒是很慢,什么抖音快手,微信支付宝,这类后台任务很多的跑不起。
Mosaic-C
哈哈,刚刚我看了你的项目,很棒,直接 cmake 编译会方便很多,厉害~
knziha
搭建的时候,cmake 一不小心就要整个重新编译。不过最后用来看代码很爽
笑而不语c
朋友 能联系下不 ?有偿学习 Q :气死气一四贰气四久