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

dlopen shared library symlink using major version name. #156

Merged
merged 1 commit into from
May 21, 2020

Conversation

kalekseev
Copy link
Contributor

cffi.dlopen should use .so.N symlinks instead of .so to
make sure we load ABI compatible version of the library and
the same library used by the rest of the system.

cffi uses ctypes.util.find_library to search for libraries
and the docs for find_library states that
"The exact functionality is system dependent."
so different system may expect different names for the same library.

To overcome that problem we try to load several names until success
among these names exact file name with .so suffix
eg. libcairo.so but .so symlink is not always safe to use.

Shared library usually consist of two of three files:

  • libcairo.so.N.M - N.M exact version number
  • libcairo.so.N - symlink to library.so.N.M with major ABI version
  • libcairo.so - symlink to library.so.N

When -lcairo flag is used linker search for libcairo.so,
but when the programm loaded it loads libcairo.so.N where N
is the version that it was linked with.

Some downsides of .so usage:

  • .so may point to the wrong ABI version, e.g. we expect libcairo
    version 2 but libcairo.so points at libcairo.so.1
  • usually .so files are shipped with development packages -dev
    in debian and -devel in centos and they are just symlinks
    to the .so.N files. So it safer to search for .so.N files they
    will exist even if dev package is not installed.
  • hard symlink .so -> .so.N not always preserved, eg. if we zip
    them we get two copies of the library and while the rest of the
    system will use .so.N file we will load .so files that may lead
    to crash

cffi.dlopen should use .so.N symlinks instead of .so to
make sure we load ABI compatible version of the library and
the same library used by the rest of the system.

cffi uses `ctypes.util.find_library` to search for libraries
and the docs for `find_library` states that
"The exact functionality is system dependent."
so different system may expect different names for the same library.

To overcome that problem we try to load several names until success
among these names exact file name with `.so` suffix
eg. `libcairo.so` but .so symlink is not always safe to use.

Shared library usually consist of two of three files:
- libcairo.so.N.M - N.M exact version number
- libcairo.so.N - symlink to library.so.N.M with major ABI version
- libcairo.so - symlink to library.so.N

When -lcairo flag is used linker search for libcairo.so,
but when the programm loaded it loads libcairo.so.N where N
is the version that it was linked with.

Some downsides of .so usage:
- .so may point to the wrong ABI version, e.g. we expect libcairo
  version 2 but libcairo.so points at libcairo.so.1
- usually .so files are shipped with development packages `-dev`
  in debian and `-devel` in centos and they are just symlinks
  to the .so.N files. So it safer to search for .so.N files they
  will exist even if dev package is not installed.
- hard symlink .so -> .so.N not always preserved, eg. if we zip
  them we get two copies of the library and while the rest of the
  system will use .so.N file we will load .so files that may lead
  to crash
@liZe
Copy link
Member

liZe commented May 21, 2020

Hello!

You’re right, thank you for the long explanation.

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.

2 participants