Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added fallback ffi dload #119

Closed
wants to merge 1 commit into from

Conversation

cinatic
Copy link

@cinatic cinatic commented Feb 6, 2019

this will help in case ctypes.util find_libary is not working (e.g. in alpine 3.x)

see also
docker-library/python#111 (comment)
#699 (comment)
Kozea/WeasyPrint#784

@liZe
Copy link
Member

liZe commented Feb 6, 2019

Wow, I've just tried another (more violent) solution in 509af10. Does it work for you?

@cinatic
Copy link
Author

cinatic commented Feb 6, 2019

yes i did a quick test it works as good as my change, thanks for the update

@cinatic
Copy link
Author

cinatic commented Feb 6, 2019

actually it does not work, i think this

lib = ffi.dlopen(path or name)

was meant to be

lib = ffi.dlopen(path or lib_name)

@liZe
Copy link
Member

liZe commented Feb 6, 2019

yes i did a quick test it works as good as my change, thanks for the update

Thanks a lot for the quick answer.

actually it does not work, i think this

lib = ffi.dlopen(path or name)

was meant to be

lib = ffi.dlopen(path or lib_name)

Of course!

@liZe liZe closed this Feb 6, 2019
liZe added a commit that referenced this pull request Feb 6, 2019
@cinatic cinatic deleted the alpine_cffi_load_fallback branch February 6, 2019 21:02
@Tontyna
Copy link

Tontyna commented Aug 8, 2019

@liZe I suggest to not call find_library at all -- afaik ffi.dlopen() calls it anyway (unless the given name contains dots or slashes, then it tries to load_library first) -- cf. dlopen() in weasyprint.text
That is to say, I don't believe this workaround is a workaround for libraries without soname and a dot-less searchname. IMHO it's the added 'cairo.so.2 that saved the day for @cinatic.

BTW: I'm wondering why cairo-gobject-2 is in the search name list for the cairo library. Isn't cairo-gobject a helper library providing GObject bindings for cairo?

@liZe
Copy link
Member

liZe commented Aug 10, 2019

That is to say, I don't believe this workaround is a workaround for libraries without soname and a dot-less searchname. IMHO it's the added 'cairo.so.2 that saved the day for @cinatic.

You're right, we should probably use WeasyPrint's dlopen function (and see if anyone complains).

BTW: I'm wondering why cairo-gobject-2 is in the search name list for the cairo library. Isn't cairo-gobject a helper library providing GObject bindings for cairo?

It was added by #112, and as it was harmless I had merged it. But again you're right, it's probably useless. @redbug312 uses "might" in #112, so we can assume that it actually never helped anyone.

@liZe
Copy link
Member

liZe commented Aug 10, 2019

See #63 and #69 too about load_library.

liZe added a commit that referenced this pull request Aug 10, 2019
cairo-gobject is not cairo, and it probably never worked for anyone. It had
been added by #112.

Related to #119.
liZe added a commit that referenced this pull request Aug 10, 2019
As the simpler code used in WeasyPrint is widely used, we can assume that it
works. If someone complains, adding more library names in various dlopen calls
is probably the way to go.

This commit somehow reverts #69. Related to #119.
liZe added a commit that referenced this pull request Aug 10, 2019
liZe added a commit that referenced this pull request Aug 10, 2019
@liZe
Copy link
Member

liZe commented Aug 10, 2019

I've open #135, but we should add CI for Windows and Mac before merging.

@Tontyna
Copy link

Tontyna commented Aug 10, 2019

It was added by #112, and as it was harmless.

It is harmless as long as loading cairo-gobject-2 only succeeds when it opens a library with an interface that fulfills our cairo.cdef
Which, of course, is true for all given library search names. Reminds me of css font stacks. Though an ugly font stack doesnt crash the browser...

Main and unsolvable problem when loading a library is that ctypes.util.find_library() and ctypes.CDLL() use different algorithms to detect the requested library.
Not talking about the fact how complicated and sometimes impossible it is on Linux to retrieve the soname, OMG! calling a compiler, catching and grepping its output to get a filename, that's beyond me...
Not talking about the fact that find_library on Linux (intentionally) doesn't return a full path.

CDLL() uses LoadLibrary on Windows, on Posix dlopen is called. If you compare the docs of those OS funtions with the pythonic implementation of find_library you can't but count yourself lucky each time ffi.dlopen() indeed opened exactly the library you wanted...

@redbug312
Copy link
Contributor

redbug312 commented Aug 11, 2019

@redbug312 uses "might" in #112, so we can assume that it actually never helped anyone.

Sorry that I've misused the word. In my side project, cairo-gobject-2 has to be appended to support PyGObject for Windows. It names its dll library libcairo-gobject-2.dll, thus ctypes.util.find_library and cffi.FFI().dlopen has to search from the name libcairo-gobject-2.

cairo

calling a compiler, catching and grepping its output to get a filename

find_library fetches library filename by searching library caches (ldconfig). I think calling linker (gcc) or scanning compiled files (objdump) are just fallback approaches.

Btw, ffi.dlopen doc said default in-line mode already handles magics like prepending lib or appending .so. Then 'libcairo.so' is not required if 'cairo' has been checked.

@Tontyna
Copy link

Tontyna commented Aug 11, 2019

find_library fetches library filename by searching library caches (ldconfig). I think calling linker (gcc) or scanned compiled files (objdump) are just fallback approaches.

Afaik, on Windows find_library only checks Python's os.environ['PATH'}.
Afaik, on Windows, find_library only appends .dll to the given search name. lib, .so and .dylib magics only happens on posix OS.

Are you sure that PyGObject doesnt follow this pattern?

Of course, if PyGObject's cairo library is named libcairo-gobject-2, this search name is required.

@Tontyna
Copy link

Tontyna commented Aug 11, 2019

The PyGObject docs state:

Note that PyGObject currently does not support cairocffi, only pycairo.

I'm almost sure that the libcairo-gobject-2.dll in your site-packages\gnome folder is not the cairo DLL that cairocffi requires. Indeed I believe it's not a Cairo library at all but, as the name says: a libraray that provides gobject bindings for cairo.

@Tontyna
Copy link

Tontyna commented Aug 11, 2019

@redbug312 Can you import and use cairocffi after it dlopened libcairo-gobject-2.dll as its cairo variable?
I mean, cairo = ffi.dlopen() succeeds with any given search name that successfully loads a dll, could be libgraphite2 as well as libpcre-1 -- you won't notice that on import cairocff but when you try to use it, e.g.

from cairocffi import cairo_version_string
print(cairo_version_string())

@redbug312
Copy link
Contributor

redbug312 commented Aug 11, 2019

Oh I got it, it may just bypasses dlopen, but actually pointed to a wrong dll.

As you've mentioned, apt package also says libcairo-gobject2 is just a wrapper for cairo. Though the code you gave successes and shows '1.15.2' (because it's a wrapper?).

I experiented if all the other entries of dir(cairocffi.cairo) exists (it remains same even if it's pointed to curl-4). It turns out 17 of 589 are absented if it's pointed to libcairo-gobject-2. Even if libcairo-gobject2 is cairo dll, it brings compatibility problem.

Moreover, cairocffi has dropped support for Python < 3.5 in commit c93eb81; PyGObject for Windows only supports Python < 3.5. So it's better to remove libcairo-gobject2 from the searching.

@Tontyna
Copy link

Tontyna commented Aug 11, 2019

the code you gave successes and shows '1.15.2' (because it's a wrapper?).

Yes. The files in the site-packages/gnome folder seem to be a special build (special names, minimized, optimized, patched, ...) for PyGI/PyGObjects.

BTW: The docs I quoted aren't relatet to the PyGObject for Windows on SourceForge but belong to the PyGObject package available on PyPI.

@liZe liZe mentioned this pull request Aug 11, 2019
liZe added a commit that referenced this pull request Aug 12, 2019
netbsd-srcmastr referenced this pull request in NetBSD/pkgsrc Apr 30, 2024
Version 1.7.0
.............

Released on 2024-04-27

* Drop Python 3.7 support, add Python 3.12 support
* `#221 <https://github.com/Kozea/cairocffi/pull/225>`_:
  Add environment variable to set folder where DLLs are installed on Windows
* `#225 <https://github.com/Kozea/cairocffi/pull/225>`_:
  Use Ruff instead of Flake8 and isort


Version 1.6.1
.............

Released on 2023-07-24

* `#217 <https://github.com/Kozea/cairocffi/issues/217>`_:
  Repair installation with PyInstaller


Version 1.6.0
.............

Released on 2023-06-12

**This version uses a new CFFI mode that may break your program.**

CairoCFFI now uses Flit for packaging and is also distributed as a Python
wheel.

Please test carefully and don’t hesitate to report issues before using it in
production.

* `#216 <https://github.com/Kozea/cairocffi/pull/216>`_:
  Use ABI-level in-line CFFI mode


Version 1.5.1
.............

Released on 2023-04-15

* `#212 <https://github.com/Kozea/cairocffi/issues/212>`_:
  Bring back XCB support during wheel generation


Version 1.5.0
.............

Released on 2023-03-17

* `#106 <https://github.com/Kozea/cairocffi/issues/106>`_,
  `#200 <https://github.com/Kozea/cairocffi/issues/200>`_:
  Fallback to manual PNG file creation on hardened systems
* `#210 <https://github.com/Kozea/cairocffi/pull/210>`_:
  Use pyproject.toml for packaging and remove other useless files


Version 1.4.0
.............

Released on 2022-09-23

* `#205 <https://github.com/Kozea/cairocffi/pull/205>`_:
  Use pikepdf to parse generated PDF
* `#171 <https://github.com/Kozea/cairocffi/pull/171>`_:
  Don’t use deprecated pytest-runner anymore


Version 1.3.0
.............

Released on 2021-10-04

* `2cd512d <https://github.com/Kozea/cairocffi/commit/2cd512d>`_:
  Drop Python 3.6 support
* `#196 <https://github.com/Kozea/cairocffi/pull/196>`_:
  Fix import `constants.py` import
* `#169 <https://github.com/Kozea/cairocffi/pull/169>`_:
  Add extra library name "cairo-2.dll"
* `#178 <https://github.com/Kozea/cairocffi/pull/178>`_:
  Workaround for testing date string with cairo 1.17.4
* `#186 <https://github.com/Kozea/cairocffi/pull/186>`_:
  Fix link in documentation
* `#195 <https://github.com/Kozea/cairocffi/pull/195>`_:
  Fix typo in documentation
* `#184 <https://github.com/Kozea/cairocffi/pull/184>`_,
  `a4fc2a7 <https://github.com/Kozea/cairocffi/commit/a4fc2a7>`_:
  Clean .gitignore


Version 1.2.0
.............

Released on 2020-10-29

* `#152 <https://github.com/Kozea/cairocffi/pull/152>`_:
  Add NumPy support
* `#143 <https://github.com/Kozea/cairocffi/issues/143>`_:
  Make write_to_png function work on hardened systems
* `#156 <https://github.com/Kozea/cairocffi/pull/156>`_:
  Use major version name to open shared libraries
* `#165 <https://github.com/Kozea/cairocffi/pull/165>`_:
  Don’t list setuptools as required for installation


Version 1.1.0
.............

Released on 2019-09-05

* `#135 <https://github.com/Kozea/cairocffi/pull/135>`_,
  `#127 <https://github.com/Kozea/cairocffi/pull/127>`_,
  `#119 <https://github.com/Kozea/cairocffi/pull/119>`_:
  Clean the way external libraries are found
* `#126 <https://github.com/Kozea/cairocffi/pull/126>`_:
  Remove const char* elements from cdef
* Support Cairo features up to 1.17.2
* Fix documentation generation


Version 1.0.2
.............

Released on 2019-02-15

* `#123 <https://github.com/Kozea/cairocffi/issues/123>`_:
  Rely on a recent version of setuptools to handle VERSION


Version 1.0.1
.............

Released on 2019-02-12

* `#120 <https://github.com/Kozea/cairocffi/issues/120>`_:
  Don't delete _generated modules on ffi_build import


Version 1.0.0
.............

Released on 2019-02-08

6 years after its first release, cairocffi can now be considered as stable.

* Drop Python 2.6, 2.7 and 3.4 support
* Test with Python 3.7
* Clean code, tests and packaging
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants