paulocoutinhox / pdfium-lib

PDFium - Project to compile PDFium library to multiple platforms.

Home Page:https://pdfviewer.github.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Would be interesting to build dylib for iOS

jmgeffroy opened this issue · comments

It would be convenient to add an option to build iOS dynamic libraries. It would allow integrating Pdfium in Dart through dart:ffi, which basically relies on dlopen+dlsym.

Closing this issue as irrelevant. Simply load the static lib with ffi.

We have problems using static libraries with Dart/Flutter.

Do you have a sample about how to do it?

Hello Paulo,

Thank you for your follow-up. In fact, I had closed this topic since I thought it would be easy to dlopen the static lib, but I'm struggling with it too! I am for now focusing on trying to dlopen+dlsym in AppDelegate.swift, and it doesn't work. So it's not really a Dart/Flutter issue. Here is the code:

    let handle = dlopen("libpdfium.a", RTLD_NOW|RTLD_LOCAL)
    print(handle != nil ? "libpdfium LOADED" : "libpdfium NOT LOADED")
    print(dlsym(handle, "FPDF_InitLibrary") != nil ? "FPDF_InitLibrary FOUND" : "FPDF_InitLibrary NOT FOUND")
    print(dlsym(handle, "FPDF_DestroyLibrary") != nil ? "FPDF_DestroyLibrary FOUND" : "FPDF_DestroyLibrary NOT FOUND")

A few days ago, the static lib was correctly loaded but I couldn't lookup the symbols. I broke some config and now the dlopen doesn't work anymore... Shame on me...

That's weird since the symbols such as FPDF_InitLibrary are global in libpdfium.a.
I am right now investigating again, with really no clue... But I'll share any discovery I would make.
BTW congratulations on your Pdfium Library!

I forgot to mention that I tried to convert the static lib into a dynamic one, following this article. But at the end of the process I got a dylib where the FPDF_XXX symbols such as FPDF_InitLibrary are local :-(

To create dylib's, you only need this change:

diff --git a/modules/ios.py b/modules/ios.py
index 8101883..4d72a78 100644
--- a/modules/ios.py
+++ b/modules/ios.py
@@ -278,13 +278,13 @@ def run_task_build():
             args.append("pdf_use_skia_paths=false")
             args.append("pdf_enable_xfa=false")
             args.append("pdf_enable_v8=false")
-            args.append("is_component_build=false")
+            args.append("is_component_build=true")
             args.append("clang_use_chrome_plugins=false")
             args.append("pdf_is_standalone=false")
             args.append('ios_deployment_target="9.0"')
             args.append("ios_enable_code_signing=false")
             args.append("use_xcode_clang=true")
-            args.append("pdf_is_complete_lib=true")
+            args.append("pdf_is_complete_lib=false")
 
             if target["target_cpu"] == "arm":
                 args.append("enable_ios_bitcode=true")

And call python3 make.py run build-ios.
You will find the dylib's in the build\ios\pdfium\out folder.

But there is then another problem: If you want to submit the app to the Apple Store, you have to put the dylib's into a framework. This is an easy task, but when you run the app with this framework, you get this error:

dyld: Library not loaded: @rpath/libicuuc.dylib
  Referenced from: /private/var/containers/Bundle/Application/8C47761E-F2F0-43BC-8807-BC8F41673572/TestPdfiumDylib.app/Frameworks/PdfiumFramework.framework/PdfiumFramework
  Reason: no suitable image found.  Did find:
	/private/var/containers/Bundle/Application/8C47761E-F2F0-43BC-8807-BC8F41673572/TestPdfiumDylib.app/Frameworks/PdfiumFramework.framework/Frameworks/libicuuc.dylib: code signature in (/private/var/containers/Bundle/Application/8C47761E-F2F0-43BC-8807-BC8F41673572/TestPdfiumDylib.app/Frameworks/PdfiumFramework.framework/Frameworks/libicuuc.dylib) not valid for use in process using Library Validation: mapped file has no cdhash, completely unsigned? Code has to be at least ad-hoc signed.
dyld: launch, loading dependent libraries
DYLD_LIBRARY_PATH=/usr/lib/system/introspection
DYLD_INSERT_LIBRARIES=/Developer/usr/lib/libBacktraceRecording.dylib:/Developer/usr/lib/libMainThreadChecker.dylib:/Developer/Library/PrivateFrameworks/DTDDISupport.framework/libViewDebuggerSupport.dylib

You have to sign the dylib's with the following command, but the Library not loaded error stays. So currently, I don't see a way to use dylib's for apps you want to publish on Apple App Store.

codesign -f -s "Apple Development: <you email address>" lib*.dylib

Hi,

I have problems with codesign tool, so i made a script for other projects. Maybe it can help you.

How to use?
https://github.com/paulo-coutinho/cef-sample/blob/master/.github/workflows/macos.yml#L71

Where is script?
https://github.com/paulo-coutinho/cef-sample

Hi,

Im updating the project and see something that can help you.

On android i set visibility to default with the patch:

# build gn flags
source_file = os.path.join(
    source_dir,
    "BUILD.gn",
)
if f.file_line_has_content(source_file, 19, "  cflags = []\n"):
    f.replace_line_in_file(
        source_file, 19, '  cflags = [ "-fvisibility=default" ]\n'
    )

    f.debug("Applied: Build GN Flags")
else:
    f.debug("Skipped: Build GN Flags")

Can you apply it to static lib on iOS and see if you can see the symbols?

There is other files/lines with:

"-fvisibility=hidden",

And:

"-fvisibility-inlines-hidden",

Maybe you will need remove these too.

If works, i can make a patch to solve this.

Hi,

I launched a new version (4692).

To test, you can access:
https://pdfviewer.github.io/

Can you check the docs/code to see if your problem still happen?

You can donate, if you want, to help the project.

Thanks.

Hello @paulo-coutinho,
Thanks a lot for your messages and active support. I'll check your latest version quickly (next week). From our side, we are currently using the dylib with success.
We'll share our dart:ffi code soon (pretty straightforward but it may help people unfamiliar with ffi).
Very best regards

@paulo-coutinho I did this change to get the libpdfium.a lib running in my Flutter project:

diff --git a/public/fpdfview.h b/public/fpdfview.h
index 1cc7bd9bb..1eb6ac7e4 100644
--- a/public/fpdfview.h
+++ b/public/fpdfview.h
@@ -178,25 +178,7 @@ typedef int FPDF_ANNOT_APPEARANCEMODE;
 // Dictionary value types.
 typedef int FPDF_OBJECT_TYPE;
 
-#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)
+#define FPDF_EXPORT __attribute__((visibility("default"))) __attribute__((used))
 
 #if defined(WIN32) && defined(FPDFSDK_EXPORTS)
 #define FPDF_CALLCONV __stdcall

After this change, I built a new libpdfium.a like described in your Github project.

I'm not sure if there is a better way to apply this change. And the line numbers in the diff may be wrong because it is some months ago since I did this change.

@RalphBergmannKMB and @CetinSert, guys, do you think that it can be a permanent patch for iOS?

I'm not sure if there is a better way to apply this change. And the line numbers in the diff may be wrong because it is some months ago since I did this change. – @RalphBergmannKMB

  1. Who is going to keep this in-sync now?
  2. Although increasing default visibility in all platforms for the sake of just one seems like a non-issue, this might mean a larger attack surface = easier security vulnerabilities in the future. (not sure how likely)

@RalphBergmannKMB now is easy make a new patch in this project after recently modernization, because i've created functions that search for the lines to apply the patch in the correct (found) lines. You can use this to add your patch. Add first line of patch and the last line, call the function to comment all from start to end, and add a new line after end line found in previous step. Feel free to reopen this issue if you need a help to create it.