ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • PDFium 라이브러리 삽질기 - 5
    Linux 2019. 12. 16. 17:14

    PDFium 라이브러리 삽질기 - 5

    v8 과 xfa 지원 및 skia 테스트


    작성 일자: 2019년 12월 16일

    최종 수정: 2020년 02월 05일

    작성자: N3


     

    이번 삽질은 지난 삽질과정에서 제외한 v8 과 xfa 지원 및 skia에 대해 삽질을 해 보도록 한다.


    # Build arguments go here.

    # See "gn args <out_dir> --list" for available build arguments.

    pdf_is_standalone   = true                 # Set for a non-embedded build.

    pdf_is_complete_lib = true                 # Static Library - libpdfium.a

    pdf_enable_xfa      = false                # XFA support enabled.

    pdf_enable_v8       = false                # Javascript support enabled.

    pdf_use_skia        = false                 # Avoid skia backend experiment.

    pdf_use_skia_paths  = false               # Avoid other skia backend experiment.


    pdf_bundle_freetype = true

    use_system_freetype = false


    clang_use_chrome_plugins = false


    use_goma            = false

    use_custom_libcxx   = false

    use_sysroot         = false


    is_component_build  = false                # Dynamic Library - libpdfium.so

    is_debug            = false                # Enable debugging features.

    is_clang            = false                # Avoid dependency hell.


    use_system_zlib     = true

    use_system_libpng   = true

    use_system_lcms2    = true

    use_system_libjpeg  = true

    use_libjpeg_turbo   = true

    use_system_libopenjpeg2 = true

    1. v8 지원

     v8 이란? 구글에서 개발하고 있는 C++ 로 작성된 오픈소스로, 고성능의 자바스크립트 와 웹 어셈블리 엔진이다. 크롬, Node.js 등에서 사용되며,  ECMAScript(ECMA-262) 와 웹어셈블리를 구현한다. Windows 7 이상, macOS 10.12 이상, Linux 시스템에서 동작한다.


     CentOS 7 에서 다음과 같이 설치할 수 있다.

    $ sudo yum install v8 v8-devel


    pdfium 소스에  v8 소스가 포함되어 함께 빌드되기 때문에, 따로 설치할 필요는 없다.


    앞의 삽질들에서 C++14 지원 등의 컴파일러 문제로  v8 지원 기능을 끄고 테스트했으나, 컴파일러 제한을 없앤 지금 이제 이 옵션을 다시 켜고 컴파일해 본다.


    args.gn

    pdf_enable_v8       = true


    PDF 파일을 만들 때, 자바스크립트를 쓰겠다는 것으로 추정되는데, 일단 빌드가 잘 되므로 해당 기능을 켠다.



    v8 동적 라이브러리 유의!!!

    v8 지원을 위한 shared library 로 빌드하게 되면, 

    libv8.so libv8_libbase.so libv8_libplatform.so 등 3개의 v8 동적 라이브러리가 함께 생성된다.

    이 라이브러리는 CentOS의 패키지중 v8-devel 에 포함된 libv8.so 와 이름이 같다.

    주의가 필요하다.

    2. xfa 지원

     xfa(XFA Form) 란? XML 포맷 아키텍처로 웹 폼 처리를 위해 JetForm 에 의해 개발된 독점적 XML 포맷이었다. 향후, PDF 1.5 표준에 사용될 수 있게 되었다. PDF 1.7 (ISO 32000-1) 의 완전한 응용에 필요한 외부 명세서로 참조된다.  XML 폼 아키텍처는 ISO 표준으로 표준화되지 않았으며, PDF 2.0 에서 사양권고 되었다.


    주로 PDF 1.7 포맷의 Adobe 확장 포맷에서 사용된 것으로 보인다. 별로 중요하지 않은 기능으로 보인다.


    pdf_enable_xfa 가 활성화되면 아래의 옵션이 영향을 받게 된다.

    pdf_enable_xfa         = true

    pdf_enable_xfa_bmp  = true

    pdf_enable_xfa_gif    = true

    pdf_enable_xfa_png   = true

    pdf_enable_xfa_tiff     = true


    해당 옵션을 모두 켜고 빌드해도 오류없이 잘 된다.


    앞에서 만든 libpdfium 패키지에 위 옵션을 추가하고, 릴리스 버전을 2로 올리고, 빌드하고, 설치한다.

    3. skia 

     Skia 는 2D 그래픽 라이브러리로, 구글의 크롬 또는 크롬 OS, 안드로이드등에서 그래픽 엔진을 위해 이용된다.  

     pdfium 은 디폴트로 Skia 를 사용하지 한고, Mapnik 등에서 검증(AGG 예전 버전을 고쳐서 사용하고 있다.) 된 AGG 라이브러리를 사용한다.


     아직 pdfium 에서의 skia 지원은 실험적이라 하니, 여기서는 실험적으로 테스트만 해 본다.


    Cairo 와 같은 벡터 그래픽 엔진으로 보인다. Skia 는 Shadow 를 뜻하는 그리스어라 한다.


     Cairo 가 C 로 작성된것과 다르게 Skia 는 C++ 로 작성되었다.

     

    Skia 를 빌드하기 위해서는 C++17 을 지원하는 툴체인이 있어야 한다.\


    pdfium 과 마찬가지로 ninja 로 빌드한다.

    $ git clone 'https://chromium.googlesource.com/chromium/tools/depot_tools.git'

    $ export PATH="${PWD}/depot_tools:${PATH}"


    $ git clone https://skia.googlesource.com/skia.git

    $ cd skia

    $ python2 tools/git-sync-deps

    Skipping "../src".

    buildtools                           > 505de88083136eefd056e5ee4ca0f01fe9b33de8

    common                               > 9737551d7a52c3db3262db5856e6bcd62c462b92

    third_party/externals/piex           > bb217acdca1cc0c16b704669dd6f91a1b509c406

    third_party/externals/microhttpd     > 748945ec6f1c67b7efc934ab0808e1d32f2fb98d

    third_party/externals/egl-registry   > a0bca08de07c7d7651047bedc0b653cfaaa4f2ae

    third_party/externals/dng_sdk        > c8d0c9b1d16bfda56f15165d39e0ffa360a11123

    third_party/externals/opencl-lib     > 4e6d30e406d2e5a65e1d65e404fe6df5f772a32b

    third_party/externals/spirv-tools    > 0c4feb643b89d1792b02f7cbef315e9d95633bd7

    third_party/externals/libjpeg-turbo  > 574f3a772c96dc9db2c98ef24706feb3f6dbda9a

    third_party/externals/wuffs          > 4080840928c0b05a80cda0d14ac2e2615f679f1a

    third_party/externals/zlib           > 47af7c547f8551bd25424e56354a2ae1e9062859

    third_party/externals/dawn           > 3c086a0c2e1dc3e2e14aaa3d78c052c7e07274b4

    ...


    $ mkdir -p out/static

    $ mkdir -p out/shared


    skia 는 pdfium 과 달리 args.gn  파일이 아니라, --args 로 설정값을 전달한다.

    args 옵션이 추가되면, args.gn  파일이 생성된다.


    일단, 해당 아규먼트 목록을 출력한다.

    $ gn gen out/static

    $ gn args out/static --list

    ar

        Current value (from the default) = "ar"

          From //gn/BUILDCONFIG.gn:20


    cc

        Current value (from the default) = "cc"

          From //gn/BUILDCONFIG.gn:21


    cc_wrapper

        Current value (from the default) = ""

          From //gn/toolchain/BUILD.gn:35


    clang_win

        Current value (from the default) = ""

          From //gn/BUILDCONFIG.gn:30


    current_cpu

        Current value (from the default) = ""

          (Internally set; try `gn help current_cpu`.)


    current_os

        Current value (from the default) = ""

          (Internally set; try `gn help current_os`.)


    cxx

        Current value (from the default) = "c++"

          From //gn/BUILDCONFIG.gn:22


    dlsymutil_pool_depth

        Current value (from the default) = 24

          From //gn/toolchain/BUILD.gn:42


        dsymutil seems to kill the machine when too many processes are run in

        parallel, so we need to use a pool to limit the concurrency when passing

        large -j to Ninja (e.g. Goma build). Unfortunately this is also one of the

        slowest steps in a build, so we don't want to limit too much. Use the number

        of CPUs as a default.


    extra_asmflags
        Current value (from the default) = []
          From //gn/BUILD.gn:11

    extra_cflags
        Current value (from the default) = []
          From //gn/BUILD.gn:12

    extra_cflags_c
        Current value (from the default) = []
          From //gn/BUILD.gn:13

    extra_cflags_cc
        Current value (from the default) = []
          From //gn/BUILD.gn:14

    extra_ldflags
        Current value (from the default) = []
          From //gn/BUILD.gn:15

    host_ar
        Current value (from the default) = "ar"
          From //gn/toolchain/BUILD.gn:6

    host_cc
        Current value (from the default) = "cc"
          From //gn/toolchain/BUILD.gn:7

    host_cpu
        Current value (from the default) = "x64"
          (Internally set; try `gn help host_cpu`.)

    host_cxx
        Current value (from the default) = "c++"
          From //gn/toolchain/BUILD.gn:8

    host_os
        Current value (from the default) = "linux"
          (Internally set; try `gn help host_os`.)

    is_component_build
        Current value (from the default) = false
          From //gn/BUILDCONFIG.gn:12

    is_debug
        Current value (from the default) = true
          From //gn/BUILDCONFIG.gn:36

    is_official_build
        Current value (from the default) = false
          From //gn/BUILDCONFIG.gn:11

    malloc
        Current value (from the default) = ""
          From //gn/BUILD.gn:17

    ndk
        Current value (from the default) = ""
          From //gn/BUILDCONFIG.gn:13

    ndk_api
        Current value (from the default) = 21
          From //gn/BUILDCONFIG.gn:16

        Android 5.0, Lollipop

    paragraph_bench_enabled
        Current value (from the default) = false
          From //modules/skparagraph/BUILD.gn:8

    paragraph_tests_enabled
        Current value (from the default) = true
          From //modules/skparagraph/BUILD.gn:7

    sanitize
        Current value (from the default) = ""
          From //gn/BUILDCONFIG.gn:18

    skia_android_serial
        Current value (from the default) = ""
          From //gn/skia.gni:12

    skia_compile_processors
        Current value (from the default) = false
          From //gn/skia.gni:13

    skia_enable_atlas_text
        Current value (from the default) = true
          From //gn/skia.gni:89

    skia_enable_ccpr
        Current value (from the default) = true
          From //gn/skia.gni:14

    skia_enable_discrete_gpu
        Current value (from the default) = true
          From //gn/skia.gni:15

    skia_enable_flutter_defines
        Current value (from the default) = false
          From //gn/skia.gni:16

    skia_enable_fontmgr_android
        Current value (from the default) = true
          From //gn/skia.gni:90

    skia_enable_fontmgr_custom
        Current value (from the default) = false
          From //gn/skia.gni:92

    skia_enable_fontmgr_custom_empty
        Current value (from the default) = false
          From //gn/skia.gni:93

    skia_enable_fontmgr_empty
        Current value (from the default) = false
          From //gn/skia.gni:17

    skia_enable_fontmgr_fuchsia
        Current value (from the default) = false
          From //gn/skia.gni:18

    skia_enable_fontmgr_win
        Current value (from the default) = false
          From //gn/skia.gni:19

    skia_enable_fontmgr_win_gdi
        Current value (from the default) = false
          From //gn/skia.gni:20

    skia_enable_gpu
        Current value (from the default) = true
          From //gn/skia.gni:21

    skia_enable_nvpr
        Current value (from the default) = true
          From //gn/skia.gni:94

    skia_enable_particles
        Current value (from the default) = true
          From //modules/particles/BUILD.gn:7

    skia_enable_pdf
        Current value (from the default) = true
          From //gn/skia.gni:22

    skia_enable_skottie
        Current value (from the default) = true
          From //modules/skottie/BUILD.gn:9

    skia_enable_skparagraph
        Current value (from the default) = true
          From //modules/skparagraph/BUILD.gn:6

    skia_enable_skshaper
        Current value (from the default) = true
          From //modules/skshaper/BUILD.gn:9

    skia_enable_sksl_interpreter
        Current value (from the default) = true
          From //gn/skia.gni:23

    skia_enable_skvm_jit
        Current value (from the default) = true
          From //gn/skia.gni:25

    skia_enable_spirv_validation
        Current value (from the default) = true
          From //gn/skia.gni:95

    skia_enable_tools
        Current value (from the default) = true
          From //gn/skia.gni:27

    skia_enable_vulkan_debug_layers
        Current value (from the default) = true
          From //gn/skia.gni:28

    skia_generate_workarounds
        Current value (from the default) = false
          From //gn/skia.gni:29

    skia_gl_standard
        Current value (from the default) = ""
          From //gn/skia.gni:76

    skia_include_multiframe_procs
        Current value (from the default) = false
          From //gn/skia.gni:30

    skia_lex
        Current value (from the default) = false
          From //gn/skia.gni:31

    skia_libgifcodec_path
        Current value (from the default) = "third_party/externals/libgifcodec"
          From //gn/skia.gni:32

    skia_moltenvk_path
        Current value (from the default) = ""
          From //gn/BUILDCONFIG.gn:32

    skia_pdf_subset_harfbuzz
        Current value (from the default) = false
          From //gn/skia.gni:33

    skia_qt_path
        Current value (from the default) = ""
          From //gn/skia.gni:34

    skia_skqp_global_error_tolerance
        Current value (from the default) = 0
          From //gn/skia.gni:35

    skia_tools_require_resources
        Current value (from the default) = false
          From //gn/skia.gni:36

    skia_update_fuchsia_sdk
        Current value (from the default) = false
          From //gn/skia.gni:37

    skia_use_angle
        Current value (from the default) = false
          From //gn/skia.gni:38

    skia_use_dawn
        Current value (from the default) = false
          From //gn/skia.gni:39

    skia_use_dng_sdk
        Current value (from the default) = true
          From //gn/skia.gni:96

    skia_use_egl
        Current value (from the default) = false
          From //gn/skia.gni:40

    skia_use_expat
        Current value (from the default) = true
          From //gn/skia.gni:41

    skia_use_experimental_xform
        Current value (from the default) = false
          From //gn/skia.gni:42

    skia_use_ffmpeg
        Current value (from the default) = false
          From //gn/skia.gni:43

    skia_use_fixed_gamma_text
        Current value (from the default) = false
          From //gn/skia.gni:44

    skia_use_fontconfig
        Current value (from the default) = true
          From //gn/skia.gni:45

    skia_use_fonthost_mac
        Current value (from the default) = false
          From //gn/skia.gni:46

    skia_use_freetype
        Current value (from the default) = true
          From //gn/skia.gni:47

    skia_use_gl
        Current value (from the default) = true
          From //gn/skia.gni:49

    skia_use_harfbuzz
        Current value (from the default) = true
          From //gn/skia.gni:48

    skia_use_icu
        Current value (from the default) = true
          From //gn/skia.gni:50

    skia_use_libgifcodec
        Current value (from the default) = true
          From //gn/skia.gni:97

    skia_use_libheif
        Current value (from the default) = true
          From //gn/skia.gni:51

    skia_use_libjpeg_turbo
        Current value (from the default) = true
          From //gn/skia.gni:52

    skia_use_libpng
        Current value (from the default) = true
          From //gn/skia.gni:53

    skia_use_libwebp
        Current value (from the default) = true
          From //gn/skia.gni:54

    skia_use_lua
        Current value (from the default) = true
          From //gn/skia.gni:55

    skia_use_metal
        Current value (from the default) = false
          From //gn/skia.gni:56

    skia_use_opencl
        Current value (from the default) = false
          From //gn/skia.gni:57

    skia_use_piex
        Current value (from the default) = true
          From //gn/skia.gni:58

    skia_use_sfntly
        Current value (from the default) = true
          From //gn/skia.gni:98

    skia_use_system_expat
        Current value (from the default) = false
          From //third_party/expat/BUILD.gn:7

    skia_use_system_freetype2
        Current value (from the default) = true
          From //third_party/freetype2/BUILD.gn:9

    skia_use_system_harfbuzz
        Current value (from the default) = false
          From //third_party/harfbuzz/BUILD.gn:10

    skia_use_system_icu
        Current value (from the default) = false
          From //third_party/icu/BUILD.gn:11

    skia_use_system_libjpeg_turbo
        Current value (from the default) = false
          From //third_party/libjpeg-turbo/BUILD.gn:7

    skia_use_system_libpng
        Current value (from the default) = false
          From //third_party/libpng/BUILD.gn:7

    skia_use_system_libwebp
        Current value (from the default) = false
          From //third_party/libwebp/BUILD.gn:7

    skia_use_system_lua
        Current value (from the default) = false
          From //third_party/lua/BUILD.gn:7

    skia_use_system_zlib
        Current value (from the default) = false
          From //third_party/zlib/BUILD.gn:7

    skia_use_vulkan
        Current value (from the default) = false
          From //gn/skia.gni:84

    skia_use_wuffs
        Current value (from the default) = false
          From //gn/skia.gni:59

    skia_use_x11
        Current value (from the default) = true
          From //gn/skia.gni:60

    skia_use_xps
        Current value (from the default) = true
          From //gn/skia.gni:61

    skia_use_zlib
        Current value (from the default) = true
          From //gn/skia.gni:62

    skia_vtune_path
        Current value (from the default) = ""
          From //gn/skia.gni:64

    target_ar
        Current value (from the default) = "ar"
          From //gn/toolchain/BUILD.gn:30

    target_cc
        Current value (from the default) = "cc"
          From //gn/toolchain/BUILD.gn:31

    target_cpu
        Current value (from the default) = ""
          (Internally set; try `gn help target_cpu`.)

    target_cxx
        Current value (from the default) = "c++"
          From //gn/toolchain/BUILD.gn:32

    target_os
        Current value (from the default) = ""
          (Internally set; try `gn help target_os`.)

    werror
        Current value (from the default) = false
          From //gn/BUILDCONFIG.gn:33

    win_sdk
        Current value (from the default) = "C:/Program Files (x86)/Windows Kits/10"
          From //gn/BUILDCONFIG.gn:24

    win_sdk_version
        Current value (from the default) = ""
          From //gn/BUILDCONFIG.gn:25

    win_toolchain_version
        Current value (from the default) = ""
          From //gn/BUILDCONFIG.gn:28

    win_vc
        Current value (from the default) = ""
          From //gn/BUILDCONFIG.gn:27

    xcode_sysroot
        Current value (from the default) = ""
          From //gn/BUILD.gn:18


    기본 아규먼트로만 테스트해본다.

    is_official_build 는 라이브러리 최적화를 수행한다. pdfium  빌드 옵션에도 추가해주는것이 좋다.


    $ gn gen out/static --args='is_official_build=true'

    $ ninja -C out/static

     float8 Sqrt(float8 x) { return sqrt(x); }

            ^~~~

    [3272/3272] link jitter_gms


    [respiro@localhost static]$ ls *.a

    libdng_sdk.a   libjpeg.a        libpiex.a    libskottie.a      libspvtools.a      libzlib_x86.a

    libexpat.a     liblua.a         libpng.a     libskparagraph.a  libspvtools_val.a

    libharfbuzz.a  libmicrohttpd.a  libsdl.a     libskresources.a  libwebp.a

    libicu.a       libparticles.a   libsfntly.a  libsksg.a         libwebp_sse41.a

    libimgui.a     libpathkit.a     libskia.a    libskshaper.a     libzlib.a


    동적 라이브러리로 빌드하기

    $ gn gen out/shared --args='is_official_build=true is_component_build=true '


    $ ninja -C out/shared

    ..

    c++ -MD -MF obj/src/codec/jpeg.SkJpegCodec.o.d -DNDEBUG -DSKIA_DLL -DSK_R32_SHIFT=16 -DSK_GAMMA_APPLY_TO_A8 -DSKIA_IMPLEMENTATION=1 -DSK_HAS_JPEG_LIBRARY -I../.. -fstrict-aliasing -fPIC -fvisibility=hidden -O3 -fdata-sections -ffunction-sections -Wno-unused-parameter -std=c++17 -fvisibility-inlines-hidden -fno-exceptions -fno-rtti -c ../../src/codec/SkJpegCodec.cpp -o obj/src/codec/jpeg.SkJpegCodec.o

    ../../src/codec/SkJpegCodec.cpp: In member function ‘virtual SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo&, const SkCodec::Options&)’:

    ../../src/codec/SkJpegCodec.cpp:679:9: error: ‘jpeg_crop_scanline’ was not declared in this scope

             jpeg_crop_scanline(fDecoderMgr->dinfo(), &startX, &width);

             ^~~~~~~~~~~~~~~~~~

    ..

    ../../src/codec/SkJpegCodec.cpp: In member function ‘virtual bool SkJpegCodec::conversionSupported(const SkImageInfo&, bool, bool)’:

    ../../src/codec/SkJpegCodec.cpp:372:57: error: ‘JCS_RGB565’ was not declared in this scope

                     fDecoderMgr->dinfo()->out_color_space = JCS_RGB565;



    오류가 발생했다. 시스템의 libjpeg-turbo 헤더를 물고가서 컴파일하고 있다.

    임베드된 버전은 2.0 인데, 시스템은 그 전 버전으로 몇 가지 함수와 디파인이 빠져 있다.


    ....


    삽질이 귀챦아졌다.  skia 는 skip 하자.


    4. pdfium skia 

    pdfium 에 포함된  third_party 의 skia 랑 같이 빌드하는 방법이 더 쉽겠다는 생각을 하게 된다.


    args.gn 에 다음을 수정하자.

    pdf_use_skia          = true                # Avoid skia backend experiment../

    pdf_use_skia_paths  = false             # Avoid other skia backend experiment.


    빌드가 오류없이 잘 된다.

    $ cd out/static 

    $ ninja pdfium_all

    $ ./pdfium_embeddertest

    ...

    ../../testing/embedder_test.cpp:640: Failure

    Expected equality of these values:

      expected_md5sum

        Which is: "b0170c575b65ecb93ebafada0ff0f038"

      HashBitmap(bitmap)

        Which is: "4e7e280c1597222afcb0ee3bb90ec119"

    ...

    Expected equality of these values:

      expected_md5sum

        Which is: "ff6e5c509d1f6984bcdfd18b26a4203a"

      HashBitmap(bitmap)

        Which is: "4e7e280c1597222afcb0ee3bb90ec119"

    [  FAILED  ] FPDFViewEmbedderTest.RenderManyRectanglesWithFlags (35 ms)

    [ RUN      ] FPDFViewEmbedderTest.RenderHelloWorldWithFlags

    ../../testing/embedder_test.cpp:640: Failure

    Expected equality of these values:

    ...
    [  FAILED  ] 2 tests, listed below:
    [  FAILED  ] FPDFViewEmbedderTest.RenderManyRectanglesWithFlags
    [  FAILED  ] FPDFViewEmbedderTest.RenderHelloWorldWithFlags


    이전 테스트에서 오류가 하나 더 생겼다.


    'Linux' 카테고리의 다른 글

    AMD Ryzen CPU 와 CentOS 리눅스  (0) 2020.03.11
    PDFium 라이브러리 삽질기 - 4  (0) 2019.12.13
    PDFium 라이브러리 삽질기 - 3  (0) 2019.12.11
    PDFium 라이브러리 삽질기 - 2  (0) 2019.12.10
    PDFium 라이브러리 삽질기 - 1  (0) 2019.12.10

    댓글

Designed by Tistory.