NetBSD / pkgsrc

Automatic conversion of the NetBSD pkgsrc CVS module, use with care
https://www.pkgsrc.org
308 stars 164 forks source link

Always make shared library IDs absolute on Darwin #70

Closed Mitsos101 closed 3 years ago

Mitsos101 commented 4 years ago

Purpose of this patch

This patch aims to eliminate "relative library path" errors. [1] Relative library paths, as defined above, are designed to allow application folders to be relocated. [2] This is an unnecessary feature for pkgsrc, as binary packages are not designed to be relocatable. Homebrew [3], MacPorts [4], and Fink [5] allow relative library paths, but the rationale for this decision is not sufficiently explained. Since a relative library path is only resolvable at runtime, it is better to err on the side of caution and assume that it will not be found, as doing otherwise would defeat the purpose of check-shlibs. Nix has generally addressed the @rpath (@loader_path, @executable_path) issue, and I was also able to find a (stale) issue that is similar to this pull request. [6,7] It is trivial to fix "relative library path" errors on Nix, as it implements a generalized solution that works for any package. [8,9] pkgsrc has not satisfactorily addressed this issue: I was able to find 35 nearly identical functions that emulate Nix's solution. [10] Therefore, I have chosen to implement an approach similar to Nix's, but with only install_name_tool -id. This does not fix all of the affected packages, but it does fix the vast majority of them.

Implementation

I originally considered adding a post-install target to mk/platform/Darwin.mk, but I was unable to find any precedent for adding targets to mk/platform/*.mk. Therefore, I have chosen to implement the solution as a privileged-install-hook, given how similar check-shlibs is to the intended solution: one runs otool(1) on every shared library, whereas the other runs install_name_tool(1). An important difference is that install_name_tool modifies the libraries, whereas most other privileged-install-hooks in the mk directory do not modify any files. However, checks are also allowed to fix the files they examine: mk/check/check-perms.mk does so with CHECK_PERMS_AUTOFIX. [11] For this reason, I have decided to add a CHECK_SHLIBS_AUTOFIX variable to mk/check/check-shlibs.mk. Note that CHECK_PERMS_AUTOFIX has not seen much use: Its only use was in lang/python/extension.mk for 48 hours, before being removed for "breaking unprivileged bulk builds". [12] However, this seems to be an issue with sysutils/checkperms, and not the privileged-install-hook itself. [13] Note also @jsonn's concern with this option in PR #50649: "It is not run for PKG_DEVELOPER=no by default and errors only visible in that case are horrible...": I have attempted to address this by making it possible to useCHECK_SHLIBS_AUTOFIX without enabling PKG_DEVELOPER. [14] As this is my first contribution to pkgsrc, please excuse me for any mistakes.

References

  1. https://github.com/NetBSD/pkgsrc/blob/8042be2acf72e9a0b8cc5e86d4a59a300fcb63cf/mk/check/check-shlibs-macho.awk#L88-L92
  2. https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/RunpathDependentLibraries.html
  3. https://github.com/Homebrew/brew/pull/107
  4. https://trac.macports.org/changeset/81754
  5. https://github.com/fink/fink/pull/112
  6. https://github.com/NixOS/nixpkgs/pull/30150
  7. https://github.com/NixOS/nixpkgs/issues/21624
  8. https://github.com/NixOS/nixpkgs/commit/4bba954e13e0d60269a4d4947884308cd175d5a9
  9. https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/setup-hooks/fix-darwin-dylib-names.sh
  10. https://github.com/NetBSD/pkgsrc/search?q=install_name_tool&unscoped_q=install_name_tool
  11. https://github.com/NetBSD/pkgsrc/blob/3c58419e1d4d291d341fe8c428ac425a7ba3f8ca/mk/check/check-perms.mk#L24-L27
  12. https://github.com/NetBSD/pkgsrc/commit/d398473df3b77f6fc482b9eb1eec3e54f6b3e8e6
  13. https://github.com/NetBSD/pkgsrc/commit/a6a11c656ba1617f9f3bcf0a8e2d635cf52dc0f5
  14. https://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=50649
krytarowski commented 4 years ago

@jperkin

jperkin commented 4 years ago

I like having a centralised way to fix these, but I don't agree for doing them on every package build, as the vast majority of packages do not need it. It also shouldn't be part of the mk/check infrastructure.

Could you put it behind a per-package variable, I'd suggest FIX_INSTALL_NAME, which takes a list of paths relative to ${DESTDIR}${PREFIX}, and move the logic to mk/install/install.mk? Yes, this loses some of the automation of having things fixed magically, but we generally prefer to identify issues clearly so that they can be verified at later dates to see if they are still necessary. This way would still reduce the various copy/paste post-install targets down to single line additions in each Makefile.

I'd be happy to test this in a macOS bulk build when ready. Thanks.

Mitsos101 commented 4 years ago

I like having a centralised way to fix these, but I don't agree for doing them on every package build, as the vast majority of packages do not need it.

It is impossible to know if a package needs this before check-shlibs when PKG_DEVELOPER is enabled, and before it runs if it is not. It is impossible for this change to break a package, since a package that passes check-shlibs already has absolute install names. Since it is better to prevent problems before they arise, especially if they can be solved in a generalized manner, this should be enabled for all packages.

It also shouldn't be part of the mk/check infrastructure.

Please justify this and the 2nd paragraph, having regard to CHECK_PERMS_AUTOFIX and Nix's successful implementation of fixDarwinDylibNames.