[Reland] Switch pdfium target from a static library to a component
Reland reland fixes fuzzer issues and Windows startup failure in Debug
configuration. Verified by Chromium's CQ:
https://chromium-review.googlesource.com/c/chromium/src/+/1592280
Reland fixes linker failures, verified by Chromium's CQ:
https://chromium-review.googlesource.com/c/chromium/src/+/1590226
Reduces size of build directory by 206 MiB (-1.0%) when building "all"
with gn args "use_goma=true is_component_build=true is_debug=false
enable_nacl=false symbol_level=1". Build time also reduced from
426.111s to 405.252s, though I only took one sample.
Also added some missing dependencies that were causing linker failures
in component builds.
BUG=chromium:941663
R=thestig
Change-Id: I7f6786acad857ac62b4bbd8b5a5071147d91f505
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/53910
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index 83fc631..f0a6fee 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -129,7 +129,7 @@
public_configs = [ ":pdfium_public_config" ]
}
-jumbo_static_library("pdfium") {
+jumbo_component("pdfium") {
sources = [
"fpdfsdk/fpdf_annot.cpp",
"fpdfsdk/fpdf_attachment.cpp",
@@ -184,6 +184,8 @@
"core/fxcrt",
]
+ defines = [ "FPDF_IMPLEMENTATION" ]
+
if (pdf_enable_xfa) {
deps += [
"fpdfsdk/fpdfxfa",
@@ -212,6 +214,10 @@
complete_static_lib = true
configs -= [ "//build/config/compiler:thin_archive" ]
}
+
+ if (is_component_build) {
+ deps += [ "testing/fuzzers:fuzzer_impls" ]
+ }
}
# Targets below this are only visible within this file (and to the
@@ -359,6 +365,7 @@
]
deps = [
":pdfium",
+ "core/fxcrt",
"testing/image_diff",
"//build/win:default_exe_manifest",
]
diff --git a/core/fpdfapi/font/BUILD.gn b/core/fpdfapi/font/BUILD.gn
index 1e8c76e..c5ce882 100644
--- a/core/fpdfapi/font/BUILD.gn
+++ b/core/fpdfapi/font/BUILD.gn
@@ -48,6 +48,9 @@
"../cmaps",
"../parser",
]
+ if (is_mac) {
+ libs = [ "CoreFoundation.framework" ]
+ }
allow_circular_includes_from = [
"../../fxge",
"../cmaps",
diff --git a/core/fxge/BUILD.gn b/core/fxge/BUILD.gn
index 6c9ed9a..83374cc 100644
--- a/core/fxge/BUILD.gn
+++ b/core/fxge/BUILD.gn
@@ -168,6 +168,7 @@
"apple/fx_mac_imp.cpp",
"apple/fx_quartz_device.cpp",
]
+ libs = [ "CoreGraphics.framework" ]
}
if (is_win) {
diff --git a/public/fpdfview.h b/public/fpdfview.h
index 8892da5..f521259 100644
--- a/public/fpdfview.h
+++ b/public/fpdfview.h
@@ -154,12 +154,29 @@
// Dictionary value types.
typedef int FPDF_OBJECT_TYPE;
-#if defined(_WIN32) && defined(FPDFSDK_EXPORTS)
-// On Windows system, functions are exported in a DLL
+#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)
-#define FPDF_CALLCONV __stdcall
+#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
diff --git a/testing/fuzzers/BUILD.gn b/testing/fuzzers/BUILD.gn
index 0dbbccc..c2b501f 100644
--- a/testing/fuzzers/BUILD.gn
+++ b/testing/fuzzers/BUILD.gn
@@ -15,56 +15,74 @@
include_dirs = [ "../.." ]
}
+# "pdfium_fuzzer"s (which may depend on PDFium internals) should be added to
+# |fuzzer_list|. "pdfium_public_fuzzer"s (which can only depend on PDFium's
+# public API) should be added to |public_fuzzer_list|.
+fuzzer_list = [
+ "pdf_cmap_fuzzer",
+ "pdf_codec_a85_fuzzer",
+ "pdf_codec_fax_fuzzer",
+ "pdf_codec_icc_fuzzer",
+ "pdf_codec_jbig2_fuzzer",
+ "pdf_codec_rle_fuzzer",
+ "pdf_font_fuzzer",
+ "pdf_hint_table_fuzzer",
+ "pdf_jpx_fuzzer",
+ "pdf_psengine_fuzzer",
+ "pdf_streamparser_fuzzer",
+ "pdf_xml_fuzzer",
+]
+public_fuzzer_list = [ "pdfium_fuzzer" ]
+if (pdf_enable_v8) {
+ fuzzer_list += [
+ "pdf_cjs_util_fuzzer",
+ "pdf_fx_date_helpers_fuzzer",
+ ]
+ if (pdf_enable_xfa) {
+ fuzzer_list += [
+ "pdf_bidi_fuzzer",
+ "pdf_cfgas_stringformatter_fuzzer",
+ "pdf_cfx_barcode_fuzzer",
+ "pdf_codec_jpeg_fuzzer",
+ "pdf_css_fuzzer",
+ "pdf_fm2js_fuzzer",
+ "pdf_formcalc_fuzzer",
+ ]
+ public_fuzzer_list += [
+ "pdf_formcalc_context_fuzzer",
+ "pdfium_xfa_fuzzer",
+ ]
+ if (pdf_enable_xfa_bmp) {
+ fuzzer_list += [ "pdf_codec_bmp_fuzzer" ]
+ }
+ if (pdf_enable_xfa_gif) {
+ fuzzer_list += [
+ "pdf_codec_gif_fuzzer",
+ "pdf_lzw_fuzzer",
+ ]
+ }
+ if (pdf_enable_xfa_png) {
+ fuzzer_list += [ "pdf_codec_png_fuzzer" ]
+ }
+ if (pdf_enable_xfa_tiff) {
+ fuzzer_list += [ "pdf_codec_tiff_fuzzer" ]
+ }
+ }
+}
+
group("fuzzers") {
testonly = true
- deps = [
- ":pdf_cmap_fuzzer_src",
- ":pdf_codec_a85_fuzzer_src",
- ":pdf_codec_fax_fuzzer_src",
- ":pdf_codec_icc_fuzzer_src",
- ":pdf_codec_jbig2_fuzzer_src",
- ":pdf_codec_rle_fuzzer_src",
- ":pdf_font_fuzzer_src",
- ":pdf_hint_table_fuzzer_src",
- ":pdf_jpx_fuzzer_src",
- ":pdf_psengine_fuzzer_src",
- ":pdf_streamparser_fuzzer_src",
- ":pdf_xml_fuzzer_src",
- ":pdfium_fuzzer_src",
- ]
- if (pdf_enable_v8) {
- deps += [
- ":pdf_cjs_util_fuzzer_src",
- ":pdf_fx_date_helpers_fuzzer_src",
- ]
+ deps = []
+ foreach(fuzzer, fuzzer_list + public_fuzzer_list) {
+ deps += [ ":${fuzzer}_src" ]
+ }
+}
- if (pdf_enable_xfa) {
- deps += [
- ":pdf_bidi_fuzzer_src",
- ":pdf_cfgas_stringformatter_fuzzer_src",
- ":pdf_cfx_barcode_fuzzer_src",
- ":pdf_codec_jpeg_fuzzer_src",
- ":pdf_css_fuzzer_src",
- ":pdf_fm2js_fuzzer_src",
- ":pdf_formcalc_context_fuzzer_src",
- ":pdf_formcalc_fuzzer_src",
- ":pdfium_xfa_fuzzer_src",
- ]
- if (pdf_enable_xfa_bmp) {
- deps += [ ":pdf_codec_bmp_fuzzer_src" ]
- }
- if (pdf_enable_xfa_gif) {
- deps += [
- ":pdf_codec_gif_fuzzer_src",
- ":pdf_lzw_fuzzer_src",
- ]
- }
- if (pdf_enable_xfa_png) {
- deps += [ ":pdf_codec_png_fuzzer_src" ]
- }
- if (pdf_enable_xfa_tiff) {
- deps += [ ":pdf_codec_tiff_fuzzer_src" ]
- }
+if (is_component_build) {
+ group("fuzzer_impls") {
+ deps = []
+ foreach(fuzzer, fuzzer_list) {
+ deps += [ ":${fuzzer}_impl" ]
}
}
}
@@ -75,12 +93,18 @@
"pdfium_fuzzer_util.h",
]
- testonly = true
include_dirs = [ "../.." ]
+
+ # In component builds, the pdfium target (which is not testonly) depends on
+ # the fuzzer sources, which may depend on this target, so add testonly only in
+ # non-component builds.
+ if (!is_component_build) {
+ testonly = true
+ }
}
template("pdfium_public_fuzzer") {
- jumbo_source_set(target_name) {
+ jumbo_source_set(target_name + "_src") {
sources = invoker.sources + [
"pdfium_fuzzer_helper.cc",
"pdfium_fuzzer_helper.h",
@@ -109,15 +133,36 @@
}
template("pdfium_fuzzer") {
- jumbo_source_set(target_name) {
- sources = invoker.sources + [ "pdf_fuzzer_init.cc" ]
- deps = [
- "../../:pdfium",
- ]
+ if (is_component_build) {
+ # In component builds, fuzzers are split into "_impl" and "_src" targets.
+ # The "_impl" target exports the fuzzer implementation and gets statically
+ # linked into the PDFium shared library. The "_src" target is a thin
+ # wrapper that imports the fuzzer from PDFium; this gets linked into the
+ # real fuzzer executable. In static builds, there's only a single "_src"
+ # target that contains the implementation and statically links in PDFium.
+ impl_name = target_name + "_impl"
+ template_target_name = target_name
+ jumbo_source_set("${target_name}_src") {
+ testonly = true
+ sources = [
+ "component_fuzzer_template.cc",
+ "pdf_fuzzer_init.cc",
+ ]
+ deps = [
+ "../../:pdfium",
+ ]
+ configs += [ ":fuzzer_config" ]
+ defines = [ "FUZZER_IMPL=${template_target_name}" ]
+ }
+ } else {
+ impl_name = target_name + "_src"
+ }
+ jumbo_source_set(impl_name) {
+ sources = invoker.sources
+ deps = []
if (defined(invoker.deps)) {
deps += invoker.deps
}
- testonly = true
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [
"//build/config/compiler:no_chromium_code",
@@ -126,11 +171,27 @@
if (pdf_enable_v8) {
configs += [ "//v8:external_startup_data" ]
}
+ if (is_component_build) {
+ # |export| should be consistent with FPDF_EXPORT In public/fpdfview.h.
+ if (is_win) {
+ export = "__declspec(dllexport)"
+ } else {
+ export = "__attribute__((visibility(\"default\")))"
+ }
+ defines = [
+ "FPDF_IMPLEMENTATION",
+ "LLVMFuzzerTestOneInput=${export} ${template_target_name}",
+ ]
+ } else {
+ sources += [ "pdf_fuzzer_init.cc" ]
+ testonly = true
+ deps += [ "../../:pdfium" ]
+ }
}
}
if (pdf_enable_v8) {
- pdfium_fuzzer("pdf_cjs_util_fuzzer_src") {
+ pdfium_fuzzer("pdf_cjs_util_fuzzer") {
sources = [
"pdf_cjs_util_fuzzer.cc",
]
@@ -138,7 +199,7 @@
"../../fxjs",
]
}
- pdfium_fuzzer("pdf_fx_date_helpers_fuzzer_src") {
+ pdfium_fuzzer("pdf_fx_date_helpers_fuzzer") {
sources = [
"pdf_fx_date_helpers_fuzzer.cc",
]
@@ -148,18 +209,20 @@
}
if (pdf_enable_xfa) {
- pdfium_fuzzer("pdf_bidi_fuzzer_src") {
+ pdfium_fuzzer("pdf_bidi_fuzzer") {
sources = [
"pdf_bidi_fuzzer.cc",
]
deps = [
+ "../../:freetype_common",
"../../core/fxge",
"../../xfa/fgas",
"../../xfa/fgas/layout",
+ "//third_party/icu:icuuc",
]
}
- pdfium_fuzzer("pdf_cfgas_stringformatter_fuzzer_src") {
+ pdfium_fuzzer("pdf_cfgas_stringformatter_fuzzer") {
sources = [
"pdf_cfgas_stringformatter_fuzzer.cc",
]
@@ -169,23 +232,23 @@
]
}
- pdfium_fuzzer("pdf_cfx_barcode_fuzzer_src") {
+ pdfium_fuzzer("pdf_cfx_barcode_fuzzer") {
sources = [
"pdf_cfx_barcode_fuzzer.cc",
]
deps = [
"../../xfa/fwl",
+ "//third_party/icu:icuuc",
]
}
if (pdf_enable_xfa_bmp) {
- pdfium_fuzzer("pdf_codec_bmp_fuzzer_src") {
+ pdfium_fuzzer("pdf_codec_bmp_fuzzer") {
sources = [
"pdf_codec_bmp_fuzzer.cc",
"xfa_codec_fuzzer.h",
]
deps = [
- "../:test_support",
"../../core/fxcodec",
"../../core/fxge",
]
@@ -193,19 +256,18 @@
}
if (pdf_enable_xfa_gif) {
- pdfium_fuzzer("pdf_codec_gif_fuzzer_src") {
+ pdfium_fuzzer("pdf_codec_gif_fuzzer") {
sources = [
"pdf_codec_gif_fuzzer.cc",
"xfa_codec_fuzzer.h",
]
deps = [
- "../:test_support",
"../../core/fxcodec",
"../../core/fxge",
]
}
- pdfium_fuzzer("pdf_lzw_fuzzer_src") {
+ pdfium_fuzzer("pdf_lzw_fuzzer") {
sources = [
"pdf_lzw_fuzzer.cc",
]
@@ -215,26 +277,24 @@
}
}
- pdfium_fuzzer("pdf_codec_jpeg_fuzzer_src") {
+ pdfium_fuzzer("pdf_codec_jpeg_fuzzer") {
sources = [
"pdf_codec_jpeg_fuzzer.cc",
"xfa_codec_fuzzer.h",
]
deps = [
- "../:test_support",
"../../core/fxcodec",
"../../core/fxge",
]
}
if (pdf_enable_xfa_png) {
- pdfium_fuzzer("pdf_codec_png_fuzzer_src") {
+ pdfium_fuzzer("pdf_codec_png_fuzzer") {
sources = [
"pdf_codec_png_fuzzer.cc",
"xfa_codec_fuzzer.h",
]
deps = [
- "../:test_support",
"../../core/fxcodec",
"../../core/fxge",
]
@@ -242,20 +302,19 @@
}
if (pdf_enable_xfa_tiff) {
- pdfium_fuzzer("pdf_codec_tiff_fuzzer_src") {
+ pdfium_fuzzer("pdf_codec_tiff_fuzzer") {
sources = [
"pdf_codec_tiff_fuzzer.cc",
"xfa_codec_fuzzer.h",
]
deps = [
- "../:test_support",
"../../core/fxcodec",
"../../core/fxge",
]
}
}
- pdfium_fuzzer("pdf_css_fuzzer_src") {
+ pdfium_fuzzer("pdf_css_fuzzer") {
sources = [
"pdf_css_fuzzer.cc",
]
@@ -264,7 +323,7 @@
]
}
- pdfium_fuzzer("pdf_fm2js_fuzzer_src") {
+ pdfium_fuzzer("pdf_fm2js_fuzzer") {
sources = [
"pdf_fm2js_fuzzer.cc",
]
@@ -273,18 +332,19 @@
]
}
- pdfium_public_fuzzer("pdf_formcalc_context_fuzzer_src") {
+ pdfium_public_fuzzer("pdf_formcalc_context_fuzzer") {
sources = [
"pdf_formcalc_context_fuzzer.cc",
]
deps = [
+ "../../fpdfsdk",
"../../fpdfsdk/fpdfxfa",
"../../fxjs",
"../../xfa/fxfa",
]
}
- pdfium_fuzzer("pdf_formcalc_fuzzer_src") {
+ pdfium_fuzzer("pdf_formcalc_fuzzer") {
sources = [
"pdf_formcalc_fuzzer.cc",
]
@@ -293,7 +353,7 @@
]
}
- pdfium_public_fuzzer("pdfium_xfa_fuzzer_src") {
+ pdfium_public_fuzzer("pdfium_xfa_fuzzer") {
sources = [
"pdfium_xfa_fuzzer.cc",
]
@@ -301,16 +361,17 @@
}
}
-pdfium_fuzzer("pdf_cmap_fuzzer_src") {
+pdfium_fuzzer("pdf_cmap_fuzzer") {
sources = [
"pdf_cmap_fuzzer.cc",
]
deps = [
+ "../../:freetype_common",
"../../core/fpdfapi/font",
]
}
-pdfium_fuzzer("pdf_codec_a85_fuzzer_src") {
+pdfium_fuzzer("pdf_codec_a85_fuzzer") {
sources = [
"pdf_codec_a85_fuzzer.cc",
]
@@ -319,7 +380,7 @@
]
}
-pdfium_fuzzer("pdf_codec_fax_fuzzer_src") {
+pdfium_fuzzer("pdf_codec_fax_fuzzer") {
sources = [
"pdf_codec_fax_fuzzer.cc",
]
@@ -329,7 +390,7 @@
]
}
-pdfium_fuzzer("pdf_codec_icc_fuzzer_src") {
+pdfium_fuzzer("pdf_codec_icc_fuzzer") {
sources = [
"pdf_codec_icc_fuzzer.cc",
]
@@ -339,7 +400,7 @@
]
}
-pdfium_fuzzer("pdf_codec_jbig2_fuzzer_src") {
+pdfium_fuzzer("pdf_codec_jbig2_fuzzer") {
sources = [
"pdf_codec_jbig2_fuzzer.cc",
]
@@ -351,7 +412,7 @@
]
}
-pdfium_fuzzer("pdf_codec_rle_fuzzer_src") {
+pdfium_fuzzer("pdf_codec_rle_fuzzer") {
sources = [
"pdf_codec_rle_fuzzer.cc",
]
@@ -360,13 +421,13 @@
]
}
-pdfium_fuzzer("pdf_font_fuzzer_src") {
+pdfium_fuzzer("pdf_font_fuzzer") {
sources = [
"pdf_font_fuzzer.cc",
]
}
-pdfium_fuzzer("pdf_hint_table_fuzzer_src") {
+pdfium_fuzzer("pdf_hint_table_fuzzer") {
sources = [
"pdf_hint_table_fuzzer.cc",
]
@@ -375,7 +436,7 @@
]
}
-pdfium_fuzzer("pdf_jpx_fuzzer_src") {
+pdfium_fuzzer("pdf_jpx_fuzzer") {
sources = [
"pdf_jpx_fuzzer.cc",
]
@@ -385,7 +446,7 @@
]
}
-pdfium_fuzzer("pdf_psengine_fuzzer_src") {
+pdfium_fuzzer("pdf_psengine_fuzzer") {
sources = [
"pdf_psengine_fuzzer.cc",
]
@@ -394,7 +455,7 @@
]
}
-pdfium_fuzzer("pdf_streamparser_fuzzer_src") {
+pdfium_fuzzer("pdf_streamparser_fuzzer") {
sources = [
"pdf_streamparser_fuzzer.cc",
]
@@ -404,13 +465,13 @@
]
}
-pdfium_fuzzer("pdf_xml_fuzzer_src") {
+pdfium_fuzzer("pdf_xml_fuzzer") {
sources = [
"pdf_xml_fuzzer.cc",
]
}
-pdfium_public_fuzzer("pdfium_fuzzer_src") {
+pdfium_public_fuzzer("pdfium_fuzzer") {
sources = [
"pdfium_fuzzer.cc",
]
diff --git a/testing/fuzzers/component_fuzzer_template.cc b/testing/fuzzers/component_fuzzer_template.cc
new file mode 100644
index 0000000..7106417
--- /dev/null
+++ b/testing/fuzzers/component_fuzzer_template.cc
@@ -0,0 +1,22 @@
+// Copyright 2019 The PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <cstddef>
+#include <cstdint>
+
+// This template is used in component builds to forward to the real fuzzers
+// which are exported from the PDFium shared library. FUZZER_IMPL is a macro
+// defined at build time that contains the name of the real fuzzer.
+
+#if defined(WIN32)
+#define IMPORT __declspec(dllimport)
+#else
+#define IMPORT
+#endif
+
+extern "C" IMPORT int FUZZER_IMPL(const uint8_t* data, size_t size);
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ return FUZZER_IMPL(data, size);
+}