etesync / libetebase

The C client-side library
BSD 3-Clause "New" or "Revised" License
29 stars 9 forks source link

Use SO version and create appropriate symlinks #4

Open pcworld opened 3 years ago

pcworld commented 3 years ago

I am currently packaging libetebase for Alpine, and it seems that libetebase is currently not using versioning for its shared object; so currently we have to create symlinks manually: https://gitlab.alpinelinux.org/alpine/aports/-/merge_requests/23675#3d7890f078f0c91507ca805d810f5e1141c6c189_0_22. Without them, software like evolution-etesync doesn't work properly as (at least on Alpine's build system) it automatically links against libetebase.so.0.
Do you want to consider using proper SO names with API versions, or should distributions patch it on their own?

tasn commented 3 years ago

Yeah, we really need to add this. I'm just unsure about how to get the correct version from cargo (I think it's maybe still not possible?) in order to create the symlink.

pcworld commented 3 years ago

Without them, software like evolution-etesync doesn't work properly as (at least on Alpine's build system) it automatically links against libetebase.so.0.

This probably is so because the ELF soname of libetebase.so is set to libetebase.so.0 for whatever reason:

$ scanelf --soname libetebase.so 
 TYPE   SONAME FILE 
ET_DYN libetebase.so.0 libetebase.so 

It seems that cargo does not support setting sonames: https://github.com/rust-lang/cargo/issues/5045
So if the soname in ELF headers is statically libetebase.so.0 anyway, I suppose you can just create these symlinks manually in the Makefile (as I do currently in the APKBUILD for Alpine, moving libetebase.so to libetebase.so.0.0.0 and creating symlinks libetebase.so.0 and libetebase.so [not sure if the latter is needed/wanted]). Of course this doesn't allow proper versioning, but that does appear to be an issue in Cargo. If you're fine with this approach, I can submit a PR if you wish.

tasn commented 3 years ago

That's the correct soname to set for a library. E.g. see libssh2:

% readelf -d  /usr/lib/libssh2.so | grep SONAME
 0x000000000000000e (SONAME)             Library soname: [libssh2.so.1]
%  ls -l /usr/lib/libssh2.*
lrwxrwxrwx 1 root root   16 Mar 19 16:24 /usr/lib/libssh2.so -> libssh2.so.1.0.1
lrwxrwxrwx 1 root root   16 Mar 19 16:24 /usr/lib/libssh2.so.1 -> libssh2.so.1.0.1
-rwxr-xr-x 1 root root 255K Mar 19 16:24 /usr/lib/libssh2.so.1.0.1

Cargo doesn't support it, but we set it manually in: https://github.com/etesync/libetebase/blob/master/build.rs#L13 This is based on the correct version of the library. Anyhow, yeah, I think creating the symlinks manually is the right way to do, but they should not be 0.0.0 but rather they should have the correct version, and we can do that by either reading the Cargo.toml or using cargo to get the right version. That's why I haven't done it yet. I don't want to manually set the version in the makefile, I want to get the correct version.

Summary: the soname is correct, and we can do proper versioning. The only thing we don't do is symlinks, and we should do them, but do them automatically, not manually.

PR welcome!

tasn commented 3 years ago

One more comment: also rename the main .so to .so.MAJOR.MINOR.MICRO and have the symlinks point to that. Again, list libssh2. This is needed so versions can be installed in parallel.

mcrha commented 1 week ago

I've been toying with evolution-etesync and found out that the linker requires the versioned number of the library now, anything what builds against it cannot run due to the versioned one is missing. Currently:

module_load: libetebase.so.0: cannot open shared object file: No such file or directory

Maybe it was always that way, I do not recall.