LibreOffice 是由文档基金会开发的自由及开放源代码的办公室套件。LibreOffice 套件包含文字处理器、电子表格、演示文稿程序、矢量图形编辑器和图表工具、数据库管理程序及创建和编辑数学公式的应用程序。借助 LibreOffice 的命令行接口可以方便地将 office 文件转换成 pdf。如下所示:
$ soffice --convert-to pdf --outdir /tmp /tmp/test.doc一个完整版本的 LibreOffice 大小为 2 GB,而函数计算运行时缓存目录 /tmp 空间限制为 512M,zip 程序包大小限制为 50M。好在社区已经有项目 aws-lambda-libreoffice 成功的将 libreoffice 移植到 AWS Lambda 平台,基于前人的方法和经验,本人创建了 fc-libreoffice 项目,使 libreoffice 成功的运行在阿里云函数计算平台。fc-libreoffice 在 aws-lambda-libreoffice 的基础上解决了如下问题:
- 重新编译和裁剪 libreoffice ,使其适配 FC nodejs8 runtime 内置的 gcc 和内核版本;
 - 安装运行时缺失的 libssl3 依赖;
 - 借助 OSS 运行时下载解压,以绕过 zip 程序包 50M 的限制;
 - 制作了一个 example 项目,支持一键部署,快速体验。
 
本文侧重于记述整个移植过程,记录关键步骤以备忘,也为类似的转换工具移植到函数计算平台提供参考。如果您对于如何快速搭建一个廉价且可扩展的 word 转换 pdf 云服务更感兴趣,可以阅读另一篇文章《五分钟上线——函数计算 Word 转 PDF 云服务》。
准备工作
在开始之前建议找一个台配置较好的 Debain/Ubuntu 机器,libreoffice 编译比较消耗计算资源。并在机器上安装和配置如下工具:
- docker-ce 安装方法参考官方安装文档
 -     
fun 一款函数计算的编排工具,用于快速部署函数计算应用。
MacOS 平台可以使用如下方法安装
brew tap vangie/formula brew install fun其他平台可以通过 npm 安装
npm install @alicloud/fun -g - ossutil oss 的命令行工具。将其下载并放置到 $PATH 所在目录。
 
编译 libreoffice
我们会采用 fc-docker 提供的 aliyunfc/runtime-nodejs8:build docker 镜像进行编译。fc-docker 提供了一系列的 docker 镜像,这些 docker 镜像环境非常接近函数计算的真实环境。因为我们打算把 libreoffice 跑在 nodejs8 环境中,所以我们选用了 aliyunfc/runtime-nodejs8:build,build 标签镜像相比于其他镜像会多一些构建需要的基础包。
启动一个编译环境
通过如下命令可启动一个用于构建 libreoffice 的容器。
docker run --name libre-builder --rm  -v $(pwd):/code -d -t --cap-add=SYS_PTRACE --security-opt seccomp=unconfined aliyunfc/runtime-nodejs8:build bash上面的命令,我们启动了一个名为 libre-builder 的容器并把当前目录挂载到容器内文件系统的 /code 目录。附加参数 --cap-add=SYS_PTRACE --security-opt seccomp=unconfined 是 cpp 程序编译需要的,否则会报出一些警告。-d 表示以后台 daemon 的方式启动。-t 表示启动 tty,配合后面的 bash 命令是为了卡主容器不退出。而 --rm 表示一旦容器停止了就自动删除容器。
安装编译工具
接下来进入容器安装编译工具
apt-get install -y ccache apt-get build-dep -y libreofficeccache 是一个编译工具,可以加速 gcc 对同一个程序的多次编译。尽管第一次编译会花费长一点的时间,有了ccache,后续的编译将变得非常非常快。
apt-get 的 build-dep 子命令会建立某个要编译软件的环境。具体行为就是把所有依赖的工具和软件包都安装上。
克隆源码
git clone --depth=1 git://anongit.freedesktop.org/libreoffice/core libreoffice cd libreoffice记得加上 --depth=1 参数,因为 libreoffice 项目比较大,进行全量克隆会比较费时间,对于编译来说 git 提交历史没有意义。
配置并编译
# 如果多次编译,该设置可以加速后续编译 ccache --max-size 16 G && ccache -s通过 --disable 参数去掉不需要的模块,以减少最终编译产物的体积。
# the most important part. Run ./autogen.sh --help to see wha each option means ./autogen.sh --disable-report-builder --disable-lpsolve --disable-coinmp \     --enable-mergelibs --disable-odk --disable-gtk --disable-cairo-canvas \     --disable-dbus --disable-sdremote --disable-sdremote-bluetooth --disable-gio --disable-randr \     --disable-gstreamer-1-0 --disable-cve-tests --disable-cups --disable-extension-update \     --disable-postgresql-sdbc --disable-lotuswordpro --disable-firebird-sdbc --disable-scripting-beanshell \     --disable-scripting-javascript --disable-largefile --without-helppack-integration \     --without-system-dicts --without-java --disable-gtk3 --disable-dconf --disable-gstreamer-0-10 \     --disable-firebird-sdbc --without-fonts --without-junit --with-theme="no" --disable-evolution2 \     --disable-avahi --without-myspell-dicts --with-galleries="no" \     --disable-kde4 --with-system-expat --with-system-libxml --with-system-nss \     --disable-introspection --without-krb5 --disable-python --disable-pch \     --with-system-openssl --with-system-curl --disable-ooenv --disable-dependency-tracking开始编译
make最终的编译结果位于 ./instdir/ 目录下。
精简尺寸
使用 strip 命令去除二进制文件中的符号信息和编译信息
# this will remove ~100 MB of symbols from shared objects strip ./instdir/**/*
