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

Configure datachannel target_properties for APPLE #1091

Merged
merged 1 commit into from
Jan 17, 2024

Conversation

Sean-Der
Copy link
Contributor

@Sean-Der Sean-Der commented Jan 11, 2024

After 7591b96 libdatachannel stopped working with OBS on macOS[0].
XCode only resolves one level of symlinks [1]. libdatachannel
is generating two levels.

This commit updates the shared object to only use only the major version
in the name.

[0] https://stackoverflow.com/questions/29946961/xcode-copy-files-build-phase-and-symlinks
[1] obsproject/obs-deps#204 (comment)

@Sean-Der
Copy link
Contributor Author

@PatTheMav does this look ok?

CMakeLists.txt Outdated Show resolved Hide resolved
CMakeLists.txt Outdated Show resolved Hide resolved
@Sean-Der
Copy link
Contributor Author

@PatTheMav I am reading the CMake docs and it seems to recommend NOT setting NO_SONAME

use this property only for leaf private libraries or plugins. If you use it on normal shared libraries which other targets link against, on some platforms a linker will insert a full path to the library (as specified at link time) into the dynamic section of the dependent binary.

When I set NO_SONAME in libdatachannel's CMakeLists.txt it also breaks the test. I have no idea what other impact it will have on dependent projects. I don't understand the benefit of these changes, but I do see some negatives.

@paullouisageneau what do you think is best here?

@PatTheMav
Copy link

@PatTheMav I am reading the CMake docs and it seems to recommend NOT setting NO_SONAME

use this property only for leaf private libraries or plugins. If you use it on normal shared libraries which other targets link against, on some platforms a linker will insert a full path to the library (as specified at link time) into the dynamic section of the dependent binary.

When I set NO_SONAME in libdatachannel's CMakeLists.txt it also breaks the test. I have no idea what other impact it will have on dependent projects. I don't understand the benefit of these changes, but I do see some negatives.

@paullouisageneau what do you think is best here?

The SONAME is only used to set the install_name on the generated library by CMake, which it prepends with the @rpath/ prefix. It is expected that an app binary has a set of rpath entries it uses to replace the prefix with when resolving library paths.

Xcode does that by itself, but if you do not use Xcode to build the library for macOS, you need to add that manually: target_link_options(datachannel PRIVATE -install_name "@rpath/libdatachannel.dylib"). We dropped all support for non-Xcode generators on macOS for OBS Studio, which is why we can omit that step.

FWIW, omitting the NO_SONAME property and ensuring a single version token is used (e.g. libdatachannel.5.dylib) is fine and should work as long as there is no additional symlink redirection. Setting the MACHO properties is still recommended though (as those are the actual properties checked by the library loader).

@PatTheMav
Copy link

PatTheMav commented Jan 12, 2024

I took a look at the dyld source code (https://opensource.apple.com/source/dyld/dyld-852.2/src/ImageLoader.cpp.auto.html) and it seems that contrary to my understanding (and what the manpage states), checks of the compatibility version are skipped since macOS 10.14 (macOS Mojave - check bool MachOFile::enforceCompatVersion() const in https://opensource.apple.com/source/dyld/dyld-852.2/dyld3/MachOFile.cpp.auto.html).

As such I stand corrected that using a single version-token SONAME (e.g. libdatachannel.1.dylib) and incrementing that single number on an ABI break is the correct approach (alternatively A/B/C can be used similar to how Frameworks are versioned, but that's entirely semantics). The MACHO ELF headers will still work on macOS 10.13 and older.

Annoying, but the more you know...

@paullouisageneau
Copy link
Owner

@PatTheMav MacOS 10.13 is legacy now, right? Is there still a point in setting the MACHO_ properties?

@PatTheMav
Copy link

@PatTheMav MacOS 10.13 is legacy now, right? Is there still a point in setting the MACHO_ properties?

See #1091 (comment) - the MACHO_ properties can be kept if the exact version numbers are desired to be visible via otool on the library and consumers of the library, but as far as breaking the link on ABI change is required, it doesn't seem necessary anymore.

@paullouisageneau
Copy link
Owner

@PatTheMav Thank you for testing and clarifying!

@Sean-Der If you want to keep the MACHO_ properties even if they are not strictly necessary, they were introduced in CMake 3.17, so you must bump cmake_minimum_required to 3.17.

@Sean-Der
Copy link
Contributor Author

Sean-Der commented Jan 13, 2024

@PatTheMav can/should we drop the MACHO values?

I don’t care what we do, my hope/goal is

  • Works with OBS
  • Doesn’t impact other libdatachannel users

@paullouisageneau would you be ok with a new var? MACOS_SO_VERSION and we start it at 0. I would put it next to VERSION in CmakeLists.txt. From this thread that seems idiomatic?

When a v0.20.0 is ready will then bump OBS and resolve issues.

@PatTheMav
Copy link

@PatTheMav can/should we drop the MACHO values?

I don’t care what we do, my hope/goal is

  • Works with OBS
  • Doesn’t impact other libdatachannel users

@paullouisageneau would you be ok with a new var? MACOS_SO_VERSION and we start it at 0. I would put it next to VERSION in CmakeLists.txt. From this thread that seems idiomatic?

When a v0.20.0 is ready will then bump OBS and resolve issues.

You can drop them, the values will be inferred from VERSION/SOVERSION then, so they'll always be limited to ..0 but that shouldn't introduce major issues.

After 7591b96 libdatachannel stopped working with OBS on macOS[0].
XCode only resolves one level of symlinks [1]. libdatachannel
is generating two levels.

This commit updates the shared object to only use only the major version
in the name.

[0] https://stackoverflow.com/questions/29946961/xcode-copy-files-build-phase-and-symlinks
[1] obsproject/obs-deps#204 (comment)
@Sean-Der
Copy link
Contributor Author

Sean-Der commented Jan 13, 2024

@PatTheMav @paullouisageneau @RytoEX How does this look? I think it hits everyones concerns.

  • It doesn't require setting/maintaining a new variable
  • We only have one symlink
  • Just puts the major version number in the name
  • For other platforms (Linux) we don't effect the naming scheme (major/minor) etc..

Copy link
Owner

@paullouisageneau paullouisageneau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Sean-Der It looks good to me. Would you like the change on 0.19? If so, could you please rebase on the v0.19 branch?

@Sean-Der
Copy link
Contributor Author

@paullouisageneau no thanks! v0.20 only (if that is ok)

That way I can fix both bugs

@paullouisageneau paullouisageneau merged commit 9c81967 into paullouisageneau:master Jan 17, 2024
11 checks passed
@Sean-Der Sean-Der deleted the macos-lib branch January 17, 2024 14:37
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