-
PDFium 라이브러리 삽질기 - 5Linux 2019. 12. 16. 17:14
PDFium 라이브러리 삽질기 - 5
v8 과 xfa 지원 및 skia 테스트
작성 일자: 2019년 12월 16일
최종 수정: 2020년 02월 05일
작성자: N3
* PDFium 라이브러리 삽질기(정적 라이브러리 빌드하기) - 1
* PDFium 라이브러리 삽질기(동적 라이브러리 빌드하기) - 2
* PDFium 라이브러리 삽질기(libpdfium RPM 패키징하기) - 3
* PDFium 라이브러리 삽질기(GDAL 과 함께 사용하기) - 4
* 크롬 V8
* 크롬 V8 엔진 프로젝트 소스
* XFA
이번 삽질은 지난 삽질과정에서 제외한 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_asmflagsCurrent value (from the default) = []From //gn/BUILD.gn:11extra_cflagsCurrent value (from the default) = []From //gn/BUILD.gn:12extra_cflags_cCurrent value (from the default) = []From //gn/BUILD.gn:13extra_cflags_ccCurrent value (from the default) = []From //gn/BUILD.gn:14extra_ldflagsCurrent value (from the default) = []From //gn/BUILD.gn:15host_arCurrent value (from the default) = "ar"From //gn/toolchain/BUILD.gn:6host_ccCurrent value (from the default) = "cc"From //gn/toolchain/BUILD.gn:7host_cpuCurrent value (from the default) = "x64"(Internally set; try `gn help host_cpu`.)host_cxxCurrent value (from the default) = "c++"From //gn/toolchain/BUILD.gn:8host_osCurrent value (from the default) = "linux"(Internally set; try `gn help host_os`.)is_component_buildCurrent value (from the default) = falseFrom //gn/BUILDCONFIG.gn:12is_debugCurrent value (from the default) = trueFrom //gn/BUILDCONFIG.gn:36is_official_buildCurrent value (from the default) = falseFrom //gn/BUILDCONFIG.gn:11mallocCurrent value (from the default) = ""From //gn/BUILD.gn:17ndkCurrent value (from the default) = ""From //gn/BUILDCONFIG.gn:13ndk_apiCurrent value (from the default) = 21From //gn/BUILDCONFIG.gn:16Android 5.0, Lollipopparagraph_bench_enabledCurrent value (from the default) = falseFrom //modules/skparagraph/BUILD.gn:8paragraph_tests_enabledCurrent value (from the default) = trueFrom //modules/skparagraph/BUILD.gn:7sanitizeCurrent value (from the default) = ""From //gn/BUILDCONFIG.gn:18skia_android_serialCurrent value (from the default) = ""From //gn/skia.gni:12skia_compile_processorsCurrent value (from the default) = falseFrom //gn/skia.gni:13skia_enable_atlas_textCurrent value (from the default) = trueFrom //gn/skia.gni:89skia_enable_ccprCurrent value (from the default) = trueFrom //gn/skia.gni:14skia_enable_discrete_gpuCurrent value (from the default) = trueFrom //gn/skia.gni:15skia_enable_flutter_definesCurrent value (from the default) = falseFrom //gn/skia.gni:16skia_enable_fontmgr_androidCurrent value (from the default) = trueFrom //gn/skia.gni:90skia_enable_fontmgr_customCurrent value (from the default) = falseFrom //gn/skia.gni:92skia_enable_fontmgr_custom_emptyCurrent value (from the default) = falseFrom //gn/skia.gni:93skia_enable_fontmgr_emptyCurrent value (from the default) = falseFrom //gn/skia.gni:17skia_enable_fontmgr_fuchsiaCurrent value (from the default) = falseFrom //gn/skia.gni:18skia_enable_fontmgr_winCurrent value (from the default) = falseFrom //gn/skia.gni:19skia_enable_fontmgr_win_gdiCurrent value (from the default) = falseFrom //gn/skia.gni:20skia_enable_gpuCurrent value (from the default) = trueFrom //gn/skia.gni:21skia_enable_nvprCurrent value (from the default) = trueFrom //gn/skia.gni:94skia_enable_particlesCurrent value (from the default) = trueFrom //modules/particles/BUILD.gn:7skia_enable_pdfCurrent value (from the default) = trueFrom //gn/skia.gni:22skia_enable_skottieCurrent value (from the default) = trueFrom //modules/skottie/BUILD.gn:9skia_enable_skparagraphCurrent value (from the default) = trueFrom //modules/skparagraph/BUILD.gn:6skia_enable_skshaperCurrent value (from the default) = trueFrom //modules/skshaper/BUILD.gn:9skia_enable_sksl_interpreterCurrent value (from the default) = trueFrom //gn/skia.gni:23skia_enable_skvm_jitCurrent value (from the default) = trueFrom //gn/skia.gni:25skia_enable_spirv_validationCurrent value (from the default) = trueFrom //gn/skia.gni:95skia_enable_toolsCurrent value (from the default) = trueFrom //gn/skia.gni:27skia_enable_vulkan_debug_layersCurrent value (from the default) = trueFrom //gn/skia.gni:28skia_generate_workaroundsCurrent value (from the default) = falseFrom //gn/skia.gni:29skia_gl_standardCurrent value (from the default) = ""From //gn/skia.gni:76skia_include_multiframe_procsCurrent value (from the default) = falseFrom //gn/skia.gni:30skia_lexCurrent value (from the default) = falseFrom //gn/skia.gni:31skia_libgifcodec_pathCurrent value (from the default) = "third_party/externals/libgifcodec"From //gn/skia.gni:32skia_moltenvk_pathCurrent value (from the default) = ""From //gn/BUILDCONFIG.gn:32skia_pdf_subset_harfbuzzCurrent value (from the default) = falseFrom //gn/skia.gni:33skia_qt_pathCurrent value (from the default) = ""From //gn/skia.gni:34skia_skqp_global_error_toleranceCurrent value (from the default) = 0From //gn/skia.gni:35skia_tools_require_resourcesCurrent value (from the default) = falseFrom //gn/skia.gni:36skia_update_fuchsia_sdkCurrent value (from the default) = falseFrom //gn/skia.gni:37skia_use_angleCurrent value (from the default) = falseFrom //gn/skia.gni:38skia_use_dawnCurrent value (from the default) = falseFrom //gn/skia.gni:39skia_use_dng_sdkCurrent value (from the default) = trueFrom //gn/skia.gni:96skia_use_eglCurrent value (from the default) = falseFrom //gn/skia.gni:40skia_use_expatCurrent value (from the default) = trueFrom //gn/skia.gni:41skia_use_experimental_xformCurrent value (from the default) = falseFrom //gn/skia.gni:42skia_use_ffmpegCurrent value (from the default) = falseFrom //gn/skia.gni:43skia_use_fixed_gamma_textCurrent value (from the default) = falseFrom //gn/skia.gni:44skia_use_fontconfigCurrent value (from the default) = trueFrom //gn/skia.gni:45skia_use_fonthost_macCurrent value (from the default) = falseFrom //gn/skia.gni:46skia_use_freetypeCurrent value (from the default) = trueFrom //gn/skia.gni:47skia_use_glCurrent value (from the default) = trueFrom //gn/skia.gni:49skia_use_harfbuzzCurrent value (from the default) = trueFrom //gn/skia.gni:48skia_use_icuCurrent value (from the default) = trueFrom //gn/skia.gni:50skia_use_libgifcodecCurrent value (from the default) = trueFrom //gn/skia.gni:97skia_use_libheifCurrent value (from the default) = trueFrom //gn/skia.gni:51skia_use_libjpeg_turboCurrent value (from the default) = trueFrom //gn/skia.gni:52skia_use_libpngCurrent value (from the default) = trueFrom //gn/skia.gni:53skia_use_libwebpCurrent value (from the default) = trueFrom //gn/skia.gni:54skia_use_luaCurrent value (from the default) = trueFrom //gn/skia.gni:55skia_use_metalCurrent value (from the default) = falseFrom //gn/skia.gni:56skia_use_openclCurrent value (from the default) = falseFrom //gn/skia.gni:57skia_use_piexCurrent value (from the default) = trueFrom //gn/skia.gni:58skia_use_sfntlyCurrent value (from the default) = trueFrom //gn/skia.gni:98skia_use_system_expatCurrent value (from the default) = falseFrom //third_party/expat/BUILD.gn:7skia_use_system_freetype2Current value (from the default) = trueFrom //third_party/freetype2/BUILD.gn:9skia_use_system_harfbuzzCurrent value (from the default) = falseFrom //third_party/harfbuzz/BUILD.gn:10skia_use_system_icuCurrent value (from the default) = falseFrom //third_party/icu/BUILD.gn:11skia_use_system_libjpeg_turboCurrent value (from the default) = falseFrom //third_party/libjpeg-turbo/BUILD.gn:7skia_use_system_libpngCurrent value (from the default) = falseFrom //third_party/libpng/BUILD.gn:7skia_use_system_libwebpCurrent value (from the default) = falseFrom //third_party/libwebp/BUILD.gn:7skia_use_system_luaCurrent value (from the default) = falseFrom //third_party/lua/BUILD.gn:7skia_use_system_zlibCurrent value (from the default) = falseFrom //third_party/zlib/BUILD.gn:7skia_use_vulkanCurrent value (from the default) = falseFrom //gn/skia.gni:84skia_use_wuffsCurrent value (from the default) = falseFrom //gn/skia.gni:59skia_use_x11Current value (from the default) = trueFrom //gn/skia.gni:60skia_use_xpsCurrent value (from the default) = trueFrom //gn/skia.gni:61skia_use_zlibCurrent value (from the default) = trueFrom //gn/skia.gni:62skia_vtune_pathCurrent value (from the default) = ""From //gn/skia.gni:64target_arCurrent value (from the default) = "ar"From //gn/toolchain/BUILD.gn:30target_ccCurrent value (from the default) = "cc"From //gn/toolchain/BUILD.gn:31target_cpuCurrent value (from the default) = ""(Internally set; try `gn help target_cpu`.)target_cxxCurrent value (from the default) = "c++"From //gn/toolchain/BUILD.gn:32target_osCurrent value (from the default) = ""(Internally set; try `gn help target_os`.)werrorCurrent value (from the default) = falseFrom //gn/BUILDCONFIG.gn:33win_sdkCurrent value (from the default) = "C:/Program Files (x86)/Windows Kits/10"From //gn/BUILDCONFIG.gn:24win_sdk_versionCurrent value (from the default) = ""From //gn/BUILDCONFIG.gn:25win_toolchain_versionCurrent value (from the default) = ""From //gn/BUILDCONFIG.gn:28win_vcCurrent value (from the default) = ""From //gn/BUILDCONFIG.gn:27xcode_sysrootCurrent 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