diff --git a/docker/android/Dockerfile b/docker/android/Dockerfile index c5f8ad0..3870610 100644 --- a/docker/android/Dockerfile +++ b/docker/android/Dockerfile @@ -5,20 +5,15 @@ ARG DEBIAN_FRONTEND=noninteractive ENV PROJ_TARGET="android" -ENV ANDROID_NDK_VERSION="r21d" -ENV ANDROID_COMPILE_SDK="30" -ENV ANDROID_BUILD_TOOLS="30.0.2" -ENV ANDROID_SDK_TOOLS_REV="4333796" -ENV ANDROID_CMAKE_REV="3.6.4111459" -ENV ANDROID_CMAKE_REV_3_10="3.10.2.4988404" +ENV ANDROID_NDK_VERSION="r25c" ENV ANDROID_HOME="/opt/android-sdk-linux" ENV ANDROID_NDK_HOME="/opt/android-ndk-linux" -ENV GRADLE_VERSION="6.1.1" -ENV GRADLE_HOME="/opt/gradle-6.1.1" +ENV GRADLE_VERSION="8.10" +ENV GRADLE_HOME="/opt/gradle-8.10" -ENV JAVA_VERSION="8" -ENV JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64/" +ENV JAVA_VERSION="17" +ENV JAVA_HOME="/usr/lib/jvm/java-17-openjdk-amd64/" ENV PYTHONIOENCODING="utf8" ENV LC_ALL=C.UTF-8 diff --git a/docs/BUILD_ANDROID.md b/docs/BUILD_ANDROID.md index 0ab845f..b0a4936 100644 --- a/docs/BUILD_ANDROID.md +++ b/docs/BUILD_ANDROID.md @@ -47,3 +47,7 @@ Now you can execute any command with pattern: If you are in a macOS with arm64 processors (M*), build with command: ```docker build --platform linux/amd64 -t pdfium-android -f docker/android/Dockerfile docker/android``` + +and + +```docker run --platform linux/amd64 -v ${PWD}:/app -it pdfium-android echo "test"``` diff --git a/docs/BUILD_WASM.md b/docs/BUILD_WASM.md index bfa8794..0db5108 100644 --- a/docs/BUILD_WASM.md +++ b/docs/BUILD_WASM.md @@ -56,6 +56,10 @@ If you are in a macOS with arm64 processors (M*), build with command: ```docker build --platform linux/amd64 -t pdfium-wasm -f docker/wasm/Dockerfile docker/wasm``` +and + +```docker run --platform linux/amd64 -v ${PWD}:/app -it pdfium-wasm echo "test"``` + ## Run on browser You can test the sample using commands: diff --git a/modules/android.py b/modules/android.py index d02e9db..96bcf19 100644 --- a/modules/android.py +++ b/modules/android.py @@ -5,7 +5,9 @@ from pygemstones.system import runner as r from pygemstones.util import log as l +import modules.common as cm import modules.config as c +import modules.patch as patch import modules.pdfium as p @@ -21,17 +23,12 @@ def run_task_patch(): source_dir = os.path.join("build", "android", "pdfium") # shared lib - source_file = os.path.join(source_dir, "BUILD.gn") + if c.shared_lib_android: + patch.apply_shared_library("android") - original_content = 'component("pdfium") {' - has_content = f.file_has_content(source_file, original_content) - - if has_content: - new_content = 'shared_library("pdfium") {' - f.replace_in_file(source_file, original_content, new_content) - l.bullet("Applied: shared lib", l.GREEN) - else: - l.bullet("Skipped: shared lib", l.PURPLE) + # public headers + if c.shared_lib_android: + patch.apply_public_headers("android") # build config source_file = os.path.join( @@ -90,23 +87,12 @@ def run_task_build(): l.YELLOW, ) - arg_is_debug = "true" if config == "debug" else "false" - - args = [] - args.append('target_os="{0}"'.format(target["pdfium_os"])) - args.append('target_cpu="{0}"'.format(target["target_cpu"])) - args.append("use_goma=false") - args.append("is_debug={0}".format(arg_is_debug)) - args.append("treat_warnings_as_errors=false") - args.append("pdf_use_skia=false") - args.append("pdf_enable_xfa=false") - args.append("pdf_enable_v8=false") - args.append("is_component_build=false") - args.append("pdf_is_standalone=true") - args.append("pdf_bundle_freetype=true") - - if config == "release": - args.append("symbol_level=0") + args = cm.get_build_args( + config, + c.shared_lib_android, + target["pdfium_os"], + target["target_cpu"], + ) args_str = " ".join(args) diff --git a/modules/common.py b/modules/common.py index c8b73cb..1faa9ca 100644 --- a/modules/common.py +++ b/modules/common.py @@ -102,3 +102,91 @@ def run_task_format(): r.run(command) l.ok() + + +# ----------------------------------------------------------------------------- +def get_build_args( + config, + shared, + target_os, + target_cpu, + target_environment=None, + libc=None, + enable_v8=False, +): + args = [] + + arg_is_debug = "true" if config == "debug" else "false" + + args.append(f"is_debug={arg_is_debug}") + args.append("pdf_use_partition_alloc=false") + args.append(f'target_cpu="{target_cpu}"') + args.append(f'target_os="{target_os}"') + args.append(f"pdf_enable_v8={str(enable_v8).lower()}") + args.append(f"pdf_enable_xfa={str(enable_v8).lower()}") + args.append("treat_warnings_as_errors=false") + args.append("is_component_build=false") + + if enable_v8: + args.append("v8_use_external_startup_data=false") + args.append("v8_enable_i18n_support=false") + + if target_os == "android": + args.append("clang_use_chrome_plugins=false") + args.append("default_min_sdk_version=21") + args.append("pdf_is_standalone=true") + args.append("pdf_bundle_freetype=true") + elif target_os == "ios": + args.append("ios_enable_code_signing=false") + args.append("use_blink=true") + args.append("pdf_is_standalone=false") + args.append("use_custom_libcxx=false") + args.append('target_environment="{0}"'.format(target_environment)) + + if enable_v8 and target_cpu == "arm64": + args.append('arm_control_flow_integrity="none"') + args.append("clang_use_chrome_plugins=false") + + # static lib + if not shared: + args.append("pdf_is_complete_lib=true") + elif target_os == "linux": + args.append("clang_use_chrome_plugins=false") + args.append("pdf_is_standalone=true") + elif target_os.startswith("mac"): + args.append('mac_deployment_target="10.13.0"') + args.append("clang_use_chrome_plugins=false") + args.append("pdf_is_standalone=true") + args.append("use_custom_libcxx=false") + args.append("use_sysroot=false") + args.append("use_allocator_shim=false") + + # static lib + if not shared: + args.append("pdf_is_complete_lib=true") + elif target_os.startswith("wasm"): + args.append("pdf_is_complete_lib=true") + args.append("is_clang=false") + args.append("use_custom_libcxx=false") + args.append("use_sysroot=false") + + if libc == "musl": + args.append("is_musl=true") + args.append("is_clang=false") + args.append("use_custom_libcxx=false") + + if enable_v8: + if target_cpu == "arm": + args.append( + 'v8_snapshot_toolchain="//build/toolchain/linux:clang_x86_v8_arm"' + ) + elif target_cpu == "arm64": + args.append( + 'v8_snapshot_toolchain="//build/toolchain/linux:clang_x64_v8_arm64"' + ) + else: + args.append( + f'v8_snapshot_toolchain="//build/toolchain/linux:{target_cpu}"' + ) + + return args diff --git a/modules/config.py b/modules/config.py index 97be6bc..9774105 100644 --- a/modules/config.py +++ b/modules/config.py @@ -14,6 +14,7 @@ # macos configurations_macos = ["release"] +shared_lib_macos = False targets_macos = [ {"target_os": "macos", "target_cpu": "x64", "pdfium_os": "mac"}, {"target_os": "macos", "target_cpu": "arm64", "pdfium_os": "mac"}, @@ -21,6 +22,7 @@ # ios configurations_ios = ["release"] +shared_lib_ios = False targets_ios = [ { "target_os": "ios", @@ -44,6 +46,7 @@ # android configurations_android = ["release"] +shared_lib_android = True targets_android = [ { "target_os": "android", @@ -73,6 +76,7 @@ # wasm configurations_wasm = ["release"] +shared_lib_wasm = False targets_wasm = [ {"target_os": "wasm32", "target_cpu": "wasm", "pdfium_os": "wasm"}, ] diff --git a/modules/ios.py b/modules/ios.py index 1c7dafd..e0637e6 100644 --- a/modules/ios.py +++ b/modules/ios.py @@ -6,7 +6,9 @@ from pygemstones.system import runner as r from pygemstones.util import log as l +import modules.common as cm import modules.config as c +import modules.patch as patch import modules.pdfium as p @@ -21,6 +23,14 @@ def run_task_patch(): source_dir = os.path.join("build", "ios", "pdfium") + # shared lib + if c.shared_lib_ios: + patch.apply_shared_library("ios") + + # public headers + if c.shared_lib_ios: + patch.apply_public_headers("ios") + # rules - test source_file = os.path.join(source_dir, "build", "config", "ios", "rules.gni") @@ -115,34 +125,13 @@ def run_task_build(): l.YELLOW, ) - arg_is_debug = "true" if config == "debug" else "false" - - args = [] - args.append('target_os="{0}"'.format(target["pdfium_os"])) - args.append('target_cpu="{0}"'.format(target["target_cpu"])) - args.append('target_environment="{0}"'.format(target["target_environment"])) - args.append("use_goma=false") - args.append("is_debug={0}".format(arg_is_debug)) - args.append("treat_warnings_as_errors=false") - args.append("pdf_use_skia=false") - args.append("pdf_enable_xfa=false") - args.append("pdf_enable_v8=false") - args.append("is_component_build=false") - args.append("clang_use_chrome_plugins=false") - args.append("pdf_is_standalone=false") - args.append('ios_deployment_target="11.0"') - args.append("ios_enable_code_signing=false") - args.append("use_xcode_clang=true") - args.append("pdf_is_complete_lib=true") - args.append("use_custom_libcxx=false") - args.append("pdf_use_partition_alloc=false") - args.append("use_blink=true") - - if target["target_cpu"] == "arm64": - args.append("enable_ios_bitcode=true") - - if config == "release": - args.append("symbol_level=0") + args = cm.get_build_args( + config, + c.shared_lib_ios, + target["pdfium_os"], + target["target_cpu"], + target["target_environment"], + ) args_str = " ".join(args) diff --git a/modules/macos.py b/modules/macos.py index 46d9fd6..24b23ef 100644 --- a/modules/macos.py +++ b/modules/macos.py @@ -6,7 +6,9 @@ from pygemstones.system import runner as r from pygemstones.util import log as l +import modules.common as cm import modules.config as c +import modules.patch as patch import modules.pdfium as p @@ -19,7 +21,13 @@ def run_task_build_pdfium(): def run_task_patch(): l.colored("Patching files...", l.YELLOW) - # none + # shared lib + if c.shared_lib_macos: + patch.apply_shared_library("macos") + + # public headers + if c.shared_lib_macos: + patch.apply_public_headers("macos") l.ok() @@ -60,30 +68,12 @@ def run_task_build(): l.YELLOW, ) - arg_is_debug = "true" if config == "debug" else "false" - - args = [] - args.append('target_os="{0}"'.format(target["pdfium_os"])) - args.append('target_cpu="{0}"'.format(target["target_cpu"])) - args.append("use_goma=false") - args.append("is_debug={0}".format(arg_is_debug)) - args.append("treat_warnings_as_errors=false") - args.append("pdf_use_skia=false") - args.append("pdf_enable_xfa=false") - args.append("pdf_enable_v8=false") - args.append("is_component_build=false") - args.append("clang_use_chrome_plugins=false") - args.append("pdf_is_standalone=true") - args.append("use_xcode_clang=false") - args.append("pdf_is_complete_lib=true") - args.append("use_custom_libcxx=false") - args.append("use_sysroot=false") - args.append('mac_deployment_target="11.0.0"') - args.append("pdf_use_partition_alloc=false") - args.append("use_allocator_shim=false") - - if config == "release": - args.append("symbol_level=0") + args = cm.get_build_args( + config, + c.shared_lib_macos, + target["pdfium_os"], + target["target_cpu"], + ) args_str = " ".join(args) diff --git a/modules/patch.py b/modules/patch.py new file mode 100644 index 0000000..9f1b230 --- /dev/null +++ b/modules/patch.py @@ -0,0 +1,50 @@ +import os + +from pygemstones.io import file as f +from pygemstones.util import log as l + + +# ----------------------------------------------------------------------------- +def apply_shared_library(target): + source_dir = os.path.join("build", target, "pdfium") + source_file = os.path.join(source_dir, "BUILD.gn") + + original_content = 'component("pdfium") {' + has_content = f.file_has_content(source_file, original_content) + + if has_content: + new_content = 'shared_library("pdfium") {' + f.replace_in_file(source_file, original_content, new_content) + l.bullet("Applied: shared library", l.GREEN) + else: + l.bullet("Skipped: shared library", l.PURPLE) + + +# ----------------------------------------------------------------------------- +def apply_public_headers(target): + source_dir = os.path.join("build", target, "pdfium") + public_dir = os.path.join(source_dir, "public") + + # file: public/fpdfview.h (p1) + source_file = os.path.join(public_dir, "fpdfview.h") + + original_content = "#if defined(COMPONENT_BUILD)\n// FPDF_EXPORT should be consistent with |export| in the pdfium_fuzzer\n// template in testing/fuzzers/BUILD.gn." + has_content = f.file_has_content(source_file, original_content) + + if has_content: + f.replace_in_file(source_file, original_content, "") + l.bullet("Applied: public headers (p1)", l.GREEN) + else: + l.bullet("Skipped: public headers (p1)", l.PURPLE) + + # file: public/fpdfview.h (p2) + source_file = os.path.join(public_dir, "fpdfview.h") + + original_content = "#else\n#define FPDF_EXPORT\n#endif // defined(COMPONENT_BUILD)" + has_content = f.file_has_content(source_file, original_content) + + if has_content: + f.replace_in_file(source_file, original_content, "") + l.bullet("Applied: public headers (p2)", l.GREEN) + else: + l.bullet("Skipped: public headers (p2)", l.PURPLE) diff --git a/modules/wasm.py b/modules/wasm.py index 1547b32..3f0d664 100644 --- a/modules/wasm.py +++ b/modules/wasm.py @@ -6,7 +6,9 @@ from pygemstones.system import runner as r from pygemstones.util import log as l +import modules.common as cm import modules.config as c +import modules.patch as patch import modules.pdfium as p @@ -21,6 +23,14 @@ def run_task_patch(): source_dir = os.path.join("build", "wasm32", "pdfium") + # shared lib + if c.shared_lib_wasm: + patch.apply_shared_library("wasm32") + + # public headers + if c.shared_lib_wasm: + patch.apply_public_headers("wasm32") + # build target source_file = os.path.join( source_dir, @@ -318,29 +328,12 @@ def run_task_build(): l.YELLOW, ) - arg_is_debug = "true" if config == "debug" else "false" - - args = [] - args.append('target_os="{0}"'.format(target["pdfium_os"])) - args.append('target_cpu="{0}"'.format(target["target_cpu"])) - args.append("use_goma=false") - args.append("is_debug={0}".format(arg_is_debug)) - args.append("treat_warnings_as_errors=false") - args.append("pdf_use_skia=false") - args.append("pdf_enable_xfa=false") - args.append("pdf_enable_v8=false") - args.append("is_component_build=false") - args.append("clang_use_chrome_plugins=false") - args.append("pdf_is_standalone=true") - args.append("use_debug_fission=false") - args.append("use_custom_libcxx=false") - args.append("use_sysroot=false") - args.append("pdf_is_complete_lib=true") - args.append("pdf_use_partition_alloc=false") - args.append("is_clang=false") - - if config == "release": - args.append("symbol_level=0") + args = cm.get_build_args( + config, + c.shared_lib_wasm, + target["pdfium_os"], + target["target_cpu"], + ) args_str = " ".join(args)