-
PDFium 라이브러리 삽질기 - 2Linux 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 InitLibrary00000000002f4aaa T FPDF_InitLibrary00000000002f4abb T FPDF_InitLibraryWithConfiglibicuuc.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 suppressedtext_field.pdf result is suppressedtext_field.pdf result is suppressedtext_field.pdf result is suppressedtext_field.pdf result is suppressedSummary 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.pdfTest cases executed: 693Successes: 599Suppressed: 85Surprises: 0Failures: 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.pdfTest cases executed: 84Successes: 77Suppressed: 6Surprises: 0Failures: 1fail 이 있지만 일단 무시하자.
'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