ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • PDFium 라이브러리 삽질기 - 2
    Linux 2019. 12. 10. 14:43

    PDFium 라이브러리 삽질기 - 2

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

    작성일자: 2019년 12월 10일

          최종수정: 2019년 12월 13일

    작성자: N3



    지난 삽질에서 여차저차해서 libpdfium.a 를 빌드했다.

    이제, 다른 라이브러리 및 시스템에서 사용해볼만한 동적 라이브러리를 빌드하기 위한 삽질을 해 보려한다.


    1. 공유 라이브러리로 빌드하기


     먼저, 지난 삽질과정에서 아규먼트 파일을 생성하고, ninja 컴파일 옵션을 생성할 때, 소스의 BUILD.gn 파일을 참조하는 것을 알았다.(build.ninja.d 파일)

     PDFium 소스의 주 디렉토리에서 BUILD.gn 을 살펴본다.


      if (pdf_is_complete_lib) {

        static_component_type = "static_library"

        complete_static_lib = true

        configs -= [ "//build/config/compiler:thin_archive" ]

      }


     args.gn 파일을 생성할 때 사용한 pdf__is_complete_lib = true 인 경우, 정적 라이브러리를 만들도록 되어 있으며, shared library 를 생성하는 룰은 찾을 수 없다.

     

     위 설정을 shared_library 로 변경하고 빌드해 본다.


    $ gn args out/shared


    # 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

    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 

    is_debug = true                              # Enable debugging features.

    is_clang = false                                    


    use_system_zlib = true

    use_system_libpng = true

    use_system_lcms2 = true

    use_system_libjpeg = true

    use_libjpeg_turbo = true

    use_system_libopenjpeg2 = true




    $ cd out/shared

    $ ninja pdfium

    FAILED: build.ninja

    ../../buildtools/linux64/gn --root=../.. -q gen .

    ERROR at //build/config/BUILDCONFIG.gn:640:5: Assertion failed.

        assert(invoker.static_component_type == "static_library" ||

        ^-----


    See //BUILD.gn:143:1: whence it was called.

    component("pdfium") {

    ^--------------------

    ninja: error: rebuilding 'build.ninja': subcommand failed


    pdfium/build/config/BUILDCONFIG.gn 파일의 오류를 찾아보면,  is_component_build 일 때 shared_library 를 활성화하는 것으로 보인다.

    조금 전 강제로 변경했던 부분을 고치고 아규먼트를 수정한다.


    pdf_is_complete_lib = false

    is_component_build = true

    로 변경하고 다시 빌드한다.


    위 두 옵션을 모두 true 로 사용할 수는 없다.

    FAILED: build.ninja

    ../../buildtools/linux64/gn --root=../.. -q gen .

    ERROR at //pdfium.gni:76:1: Assertion failed.

    assert(!pdf_is_complete_lib || !is_component_build,

    ^-----

    pdf_is_complete_lib=true requires is_component_build=false

    See //BUILD.gn:6:1: whence it was imported.

    import("pdfium.gni")

    ^------------------

    ninja: error: rebuilding 'build.ninja': subcommand failed



    [respiro@localhost shared]$ ninja pdfium

    [911/911] SOLINK ./libpdfium.so


    [respiro@localhost shared]$ ls

    args.gn        gen        genperf     icudtl.dat       libpdfium.so      re2c

    build.ninja    genmacro   genstring   libicuuc.so      libpdfium.so.TOC  toolchain.ninja

    build.ninja.d  genmodule  genversion  libicuuc.so.TOC  obj               yasm


    [respiro@localhost shared]$ ldd libpdfium.so

            linux-vdso.so.1 =>  (0x00007ffd56fb0000)

            libicuuc.so => /home/respiro/rpmbuild/SOURCES/PDFium/pdfium/out/shared/./libicuuc.so (0x00007f8164213000)

            libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f8163ff7000)

            liblcms2.so.2 => /lib64/liblcms2.so.2 (0x00007f8163d9d000)

            libopenjp2.so.7 => /lib64/libopenjp2.so.7 (0x00007f8163b4a000)

            libz.so.1 => /lib64/libz.so.1 (0x00007f8163933000)

            libjpeg.so.62 => /lib64/libjpeg.so.62 (0x00007fb2140a3000)

            libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f816362c000)

            libm.so.6 => /lib64/libm.so.6 (0x00007f816332a000)

            libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f8163114000)

            libc.so.6 => /lib64/libc.so.6 (0x00007f8162d46000)

            /lib64/ld-linux-x86-64.so.2 (0x00007f8164c4d000)



    [respiro@localhost test]$ nm libpdfium.so |grep InitLibrary
    00000000002f4aaa T FPDF_InitLibrary
    00000000002f4abb T FPDF_InitLibraryWithConfig


    libicuuc.so 와 libpdfium.so 두 개의 dynamic so 파일이 생성되었다.

    시스템의 동적 라이브러리를 사용하도록 설정했기 때문에, lib64 폴더의 동적 라이브러리를 링크하는 것을 볼 수 있다.

    (libicuuc.so 는 icu 라이브러리로 일단은 시스템에 설치된 라이브러리와 충돌할 수 있다.)


    삽질기-1 의 테스트 코드를 shared 라이브러리를 링크하도록 다시 빌드해본다.

    Makefile 경로 수정


    LIB_DIR= -L ${PDFIUM_REPO}/out/shared



    $ LD_LIBRARY_PATH=../pdfium/out/shared make


    $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/pdfium/out/shared/

    $ pdf_hello

    PDFium hello.


    정상 동작하는 것을 확인했다.


    다음 삽질기는 gdal 에서 pdfium 을 지원하기 위한 삽질 및 libpdfium 을 CentOS 7 RPM 패키지로 만드는 것이다.

    2. 내용 누락 추가

    삽질 중(gdal 과 함께 컴파일하는 도중)에 다음의 오류를 발견했다. 

     [respiro@localhost shared]$ readelf -a libpdfium.so |grep CPDF_OCContext

       246: 000000000006bbb0   494 FUNC    LOCAL  DEFAULT   12 _ZNK14CPDF_OCContext8GetO

      3998: 000000000006af90   172 FUNC   LOCAL  HIDDEN    12 _ZNK23CPDF_OCContextInter

      3999: 000000000006b0c0    61 FUNC    LOCAL  HIDDEN    12 _ZN14CPDF_OCContextC2EP13

      4000: 00000000003f35e8    48 OBJECT  LOCAL  HIDDEN    18 _ZTV14CPDF_OCContext

      4001: 000000000006b0c0    61 FUNC    LOCAL  HIDDEN    12 _ZN14CPDF_OCContextC1EP13

      4002: 000000000006b100  1146 FUNC    LOCAL  HIDDEN    12 _ZNK14CPDF_OCContext22Loa

      4003: 000000000006b580   704 FUNC    LOCAL  HIDDEN    12 _ZNK14CPDF_OCContext12Loa


    GDAL을 빌드하는 중 동적 라이브러리와 링크중에 위와 같은 링크 오류를 찾았다.

    함수를 찾을 수 없어서 확인하니까 모두 HIDDEN 으로 숨겨져 있다.


    함수 EXPORT 코드를 확인한 후 수정한다.


    ~/pdfium/public/fpdfview.h (수정 불필요)

    #if defined(COMPONENT_BUILD)

    // FPDF_EXPORT should be consistent with |export| in the pdfium_fuzzer

    // template in testing/fuzzers/BUILD.gn.

    #if defined(WIN32)

    #if defined(FPDF_IMPLEMENTATION)

    #define FPDF_EXPORT __declspec(dllexport)

    #else

    #define FPDF_EXPORT __declspec(dllimport)

    #endif  // defined(FPDF_IMPLEMENTATION)

    #else

    #if defined(FPDF_IMPLEMENTATION)

    #define FPDF_EXPORT __attribute__((visibility("default")))

    #else

    #define FPDF_EXPORT

    #endif  // defined(FPDF_IMPLEMENTATION)

    #endif  // defined(WIN32)

    #else

    #define FPDF_EXPORT

    #endif  // defined(COMPONENT_BUILD)


    #if defined(WIN32) && defined(FPDFSDK_EXPORTS)

    #define FPDF_CALLCONV __stdcall

    #else

    #define FPDF_CALLCONV

    #endif


    ./build/config/BUILDCONFIG.gn (아래와 같이 제거한다.)

    if (is_posix) {

      if (current_os != "aix") {

        default_compiler_configs +=

            [ "//build/config/gcc:symbol_visibility_hidden" ]

      }

    }

    symbol visibility hidden 을 제거한다.


    ~/pdfium/BUILD.gn 파일의 옵션을 보면, 수정할 필요없다.


    config("pdfium_implementation_config") {

      defines = [ "FPDF_IMPLEMENTATION" ]

      visibility = [ ":pdfium_public_headers" ]

    }



    group("pdfium_public_headers") {

      public_deps = [

        ":pdfium_public_headers_impl",

      ]

      public_configs = [

        ":pdfium_public_config",

        ":pdfium_implementation_config",

      ]

    }



    빌드된 라이브러리를 확인한다.


    [respiro@localhost shared]$ readelf -a libpdfium.so |grep CPDF_OCCon

    ...


    0000004b3b58  0a3000000007 R_X86_64_JUMP_SLO 0000000000132d10 _ZN14CPDF_OCContextD0E + 0

    0000004b3b60  173300000007 R_X86_64_JUMP_SLO 00000000001334e0 _ZNK14CPDF_OCContext15 + 0

    0000004b8f70  0ac100000007 R_X86_64_JUMP_SLO 0000000000132510 _ZN14CPDF_OCContextC1E + 0

       583: 00000000001329e0   704 FUNC    GLOBAL DEFAULT   12 _ZNK14CPDF_OCContext12Loa

       711: 00000000004a9b70    48 OBJECT  WEAK   DEFAULT   21 _ZTV14CPDF_OCContext

      1574: 00000000002f31b0    26 OBJECT  WEAK   DEFAULT   14 _ZTS23CPDF_OCContextInter

      1812: 0000000000133200   730 FUNC    GLOBAL DEFAULT   12 _ZNK14CPDF_OCContext13Loa

      2284: 0000000000132eb0   323 FUNC    GLOBAL DEFAULT   12 _ZNK14CPDF_OCContext13Get

      2608: 0000000000132d10    36 FUNC    GLOBAL DEFAULT   12 _ZN14CPDF_OCContextD0Ev

      2753: 0000000000132510    65 FUNC    GLOBAL DEFAULT   12 _ZN14CPDF_OCContextC1EP13

      3146: 00000000004a9b10    24 OBJECT  WEAK   DEFAULT   21 _ZTI23CPDF_OCContextInter

      3209: 00000000004a9b28    24 OBJECT  WEAK   DEFAULT   21 _ZTI14CPDF_OCContext

      4728: 0000000000132cf0    28 FUNC    GLOBAL DEFAULT   12 _ZN14CPDF_OCContextD1Ev

      5079: 00000000001323e0   172 FUNC    GLOBAL DEFAULT   12 _ZNK23CPDF_OCContextInter

      5939: 00000000001334e0   177 FUNC    GLOBAL DEFAULT   12 _ZNK14CPDF_OCContext15Che

      6302: 0000000000133000   512 FUNC    GLOBAL DEFAULT   12 _ZNK14CPDF_OCContext8GetO

      6803: 0000000000132cf0    28 FUNC    GLOBAL DEFAULT   12 _ZN14CPDF_OCContextD2Ev

      6887: 00000000004a9b40    48 OBJECT  WEAK   DEFAULT   21 _ZTV23CPDF_OCContextInter

      7527: 0000000000132510    65 FUNC    GLOBAL DEFAULT   12 _ZN14CPDF_OCContextC2EP13

    ...


    3. Test


    $ cd out/shared


    [respiro@localhost shared]$ ./pdfium_test  --help

    Unrecognized argument --help

    Usage: pdfium_test [OPTION] [FILE]...

      --show-config        - print build options and exit

      --show-metadata      - print the file metadata

      --show-pageinfo      - print information about pages

      --show-structure     - print the structure elements from the document

      --send-events        - send input described by .evt file

      --mem-document       - load document with FPDF_LoadMemDocument()

      --render-oneshot     - render image without using progressive renderer

      --lcd-text           - render text optimized for LCD displays

      --no-nativetext      - render without using the native text output

      --grayscale          - render grayscale output

      --limit-cache        - render limiting image cache size

      --force-halftone     - render forcing halftone

      --printing           - render as if for printing

      --no-smoothtext      - render disabling text anti-aliasing

      --no-smoothimage     - render disabling image anti-alisasing

      --no-smoothpath      - render disabling path anti-aliasing

      --reverse-byte-order - render to BGRA, if supported by the output format

      --save-attachments   - write embedded attachments <pdf-name>.attachment.<attachment-name>

      --save-images        - write embedded images <pdf-name>.<page-number>.<object-number>.png

      --save-thumbs        - write page thumbnails <pdf-name>.thumbnail.<page-number>.png

      --save-thumbs-dec    - write page thumbnails' decoded stream data<pdf-name>.thumbnail.decoded.<page-number>.png

      --save-thumbs-raw    - write page thumbnails' raw stream data<pdf-name>.thumbnail.raw.<page-number>.png

      --no-system-fonts    - do not use system fonts, overrides --font-dir

      --bin-dir=<path>     - override path to v8 external data

      --font-dir=<path>    - override path to external fonts

      --scale=<number>     - scale output size by number (e.g. 0.5)

      --pages=<number>(-<number>) - only render the given 0-based page(s)

      --txt   - write page text in UTF32-LE <pdf-name>.<page-number>.txt

      --png   - write page images <pdf-name>.<page-number>.png

      --ppm   - write page images <pdf-name>.<page-number>.ppm

      --annot - write annotation info <pdf-name>.<page-number>.annot.txt

      --md5   - write output image paths and their md5 hashes to stdout.

      --time=<number> - Seconds since the epoch to set system time.


    $ pdfium_test --png gdalautotest-2.3.2/gdrivers/data/adobe_style_geospatial_with_xmp.pdf


    adobe_style_geospatial_with_xmp.pdf


    ninja 빌드시에  ninja pdfium_all 옵션으로 빌드하면, 두 가지 테스트 도구를 더 생성한다.

    pdfium_unittests

    pdfium_embeddertests


    이 외에 test 폴더에도 테스트 도구들이 더 생성된다.

    testing/tools/run_corpus_tests.py

    testing/tools/run_javascript_tests.py

    testing/tools/run_pixel_tests.py


    $ ./run_corpus_tests.py  --build-dir ~/PDFium/pdfium/out/shared/

    ..
    test_control.pdf result is suppressed
    text_field.pdf result is suppressed
    text_field.pdf result is suppressed
    text_field.pdf result is suppressed
    text_field.pdf result is suppressed


    Summary of Failures:
    /home/respiro/PDFium/pdfium/testing/corpus/fx/FRC_4.5_part1/FRC_4.5.4_ICCBased.pdf
    /home/respiro/PDFium/pdfium/testing/corpus/fx/color/color_icc_based.pdf
    /home/respiro/PDFium/pdfium/testing/corpus/fx/other/3bigpreview.pdf
    /home/respiro/PDFium/pdfium/testing/corpus/fx/text/050_extra_m.pdf
    /home/respiro/PDFium/pdfium/testing/corpus/fx/text/5.5_simple_font.pdf
    /home/respiro/PDFium/pdfium/testing/corpus/fx/text/test_m.pdf
    /home/respiro/PDFium/pdfium/testing/corpus/third_party/tcpdf/example_033.pdf
    /home/respiro/PDFium/pdfium/testing/corpus/third_party/tcpdf/example_038.pdf
    /home/respiro/PDFium/pdfium/testing/corpus/third_party/tcpdf/example_055.pdf

    Test cases executed: 693
      Successes: 599
      Suppressed: 85
        Surprises: 0
      Failures: 9

     ./run_pixel_tests.py  --build-dir ~/PDFium/pdfium/out/shared/
    ...
    Summary of Failures:
    /home/respiro/rpmbuild/SOURCES/PDFium/pdfium/testing/resources/pixel/bug_1308.pdf

    Test cases executed: 84
      Successes: 77
      Suppressed: 6
        Surprises: 0
      Failures: 1


    fail 이 있지만 일단 무시하자.

    'Linux' 카테고리의 다른 글

    PDFium 라이브러리 삽질기 - 4  (0) 2019.12.13
    PDFium 라이브러리 삽질기 - 3  (0) 2019.12.11
    PDFium 라이브러리 삽질기 - 1  (0) 2019.12.10
    TmaxOS 3.9.1 x64 설치기  (0) 2019.08.20
    북한 폰트  (0) 2019.08.08

    댓글

Designed by Tistory.