美文网首页
Ubuntu下编译pdfium

Ubuntu下编译pdfium

作者: cgnail | 来源:发表于2018-04-21 16:03 被阅读0次

    源代码下载

    1. 前提条件是打开ss,不然毛都下载不下来
    2. google重新发明了一套下载、编译、测试自家项目的工具(轮子)depot_tool(包括gcllient、GYP、GN和Ninja等),所有的代码都需要利用这些工具从命令行下载编译。于是我们需要让终端也具备ss的能力。
      • 下载polipo,终端执行sudo polipo socksParentProxy=localhost:1080
      • 终端执行export https_proxy=127.0.0.1:8123,搞定。嫌每次打开终端都要输入这句很麻烦的话,可以把它加到bashrc里面。
    3. 下载depot_tools。或者打开ss的全局模式,去googlesource.com网站上下载,或者终端执行
          git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
      
    4. 将depot_tools目录添加到系统$PATH,执行
          gclient config --unmanaged https://pdfium.googlesource.com/pdfium.git
      

    加入要同步的项目目录

    1. 执行gclient sync进行同步,获得pdfium的源代码。同步时间会很长,因为同步下来的目录大小大概是3.5G
    2. 期间会提示“To use a proxy in this situation, please supply those settings in a .boto file pointed to by the NO_AUTH_BOTO_CONFIG environment var.” 可能需要配置一下polipo,不过我依然下载了全部代码,编译通过了。

    编译

    没有找到项目首页里说的编译文件build/gyp_pdfium,因为据说google已经放弃GYP,只支持GN构建了。GN的用法参考这里。按照代码目录下的README.md的步骤编译就好啦。我关掉了v8和xfa支持,编译起来还挺快。几个注意事项如下:

    1. pdfium默认静态编译,不放心的话在args.gn文件里加上一句pdf_is_complete_lib = true。这个条件定义在根目录下的BUILD.gn里,它的关键在于设置了GN工具的参数complete_static_lib为真。
    2. 如果想修改args.gn或者某个BUILD.gn里定义的参数重新编译,执行下列命令即可:
          ninja -C <out_dir> -t clean  # 清除已生成文件
          gn gen <out_dir>             # 重新生成编译文件
          ninja -C <out_dir>           # 编译
      
    3. 编译过程中如果出现cc1plus: all warnings being treated as errors的错误,去/build/config/compiler/BUILD.gn文件里把treat_warnings_as_errors改成false

    用AFL对pdfium做模糊测试

    AFL需要对测试对象插桩,所以得用afl-gccafl-clang来编译测试对象。虽然对google新发明的这套编译流程一窍不通,不过我还是找到两种办法。

    方法1:利用chromium中的现成代码

    不知道为什么,chromium代码是直接支持afl测试的,但是作为它的pdf解析器的pdfium却去掉了相应的代码,然后又在BUILD.gn中保留了这个选项。幸好我见过不少精分,还比较淡定。

    1. 首先下载chromium的afl支持文件,放到third_party/afl目录下。其实管用的就那一个BUILD.gn,src目录下就是afl的源代码,我直接用的我本机上的。
    2. 在args.gn文件里里加上use_afl = trueoptimize_for_fuzzing = true的开关,重新编译。
    3. 编译完成后在你的<out_dir>目录下会有afl-fuzz文件,以及业已插桩完毕pdfium_test。下面用afl的默认方式测试pdfium_test即可。不过测试速度很慢,exec_speed只有200/sec左右。

    PS:从pdfium的BUILD.gn代码里可以知道,它还支持libfuzzer和drfuzz的测试,开关为use_drfuzzuse_libfuzzer。不过默认也是没有对应支持文件的,需要自己加,我就没研究了。

    方法2. 在toolchain中指定自己编译的afl-gcc

    GN工具用toolchains来制定构建项目用到的编译器、链接器以及相应参数等。通常GN的主配置文件会根据主机和目标的架构设置default_toolchain,比如pdfium就在build/config/BUILDCONFIG.gn里对这样设置Linux x86_64下的缺省toolchain。

        if (is_clang) {
             _default_toolchain = "//build/toolchain/linux:clang_$target_cpu"
        } else {
             _default_toolchain = "//build/toolchain/linux:$target_cpu"
        }
    

    其中is_clang可以在args.gn里声明,缺省似乎是is_clang = true。想用哪个编译器插桩,就去代码中引号指明的对应文件里把cc = "xxx"改成 cc = "afl-xxx",并对应地将is_clang设为truefalse

    不知道得到的pdfium用的什么编译器编译出来的?执行

       objdump -s --section .comment out/Debug/pdfium_test
    

    看看注释里有无clang或gcc字样就可以了。

    其他pdf引擎的编译

    常见的C/C++编写的pdf引擎有poppler(Evince、Xpdf、Libreoffice)、podofo(ImageMagick)和mupdf(SumatraPDF,Zathura)

    编译Podofo

    采用了CMake编译系统,使用模糊测试同样需要指定CCCXX--disable-shared。所以编译命令形如:

         CC=afl-gcc CXX=afl-g++ cmake -G "Unix Makefiles" ../podofo-0.9.5/ -DPODOF O_BUILD_SHARED:BOOL=FALSE -DPODOFO_BUILD_STATIC:BOOL=TRUE
    

    如果提示找不到FREETYPE_LIBRARYFONTCONFIG_LIBRARY,安装libfreetype6-dev,libfontconfig1-dev包就行了。剩下的找不到libjpeg、libtiff之类不影响程序编译。

    编译poppler

    同样采用了CMake,编译命令形如:

         CC=afl-gcc CXX=afl-g++ cmake ../poppler-0.64.0/ -DBUILD_SHARED_LIBS=OFF
    

    相关文章

      网友评论

          本文标题:Ubuntu下编译pdfium

          本文链接:https://www.haomeiwen.com/subject/aevakftx.html