mesonbuild / meson

The Meson Build System
http://mesonbuild.com
Apache License 2.0
5.38k stars 1.54k forks source link

Investigate extension for OS X bundles #1160

Open nirbheek opened 7 years ago

nirbheek commented 7 years ago

Currently we default to dylib. This can be changed with the name_suffix kwarg, but perhaps our default should be so or bundle. This needs investigation.

Continued from https://github.com/mesonbuild/meson/pull/1126 and https://github.com/mesonbuild/meson/issues/1112

nirbheek commented 6 years ago

See also: https://github.com/mesonbuild/meson/issues/3053

raimue commented 6 years ago

It would be helpful to have a way to get the filename extension a shared_module() gets. Then we could pass this to the program via some -DPLUGIN_SUFFIX or a config.h and use this macro instead of relying on G_MODULE_SUFFIX from glib, which is currently wrong on macOS (see https://github.com/mesonbuild/meson/issues/3053#issuecomment-365005193).

With such a function to get the default filename extension, it would continue to work even if meson later decides to change it.

raimue commented 6 years ago

On a closer look, the .dylib suffix might actually be wrong as the files have a different filetype in the Mach-O header. otool -hv on a shared module shows "BUNDLE" and on a shared library "DYLIB".

GNU libtool has always used ".so" on Darwin/macOS for shared modules, so it might make sense to just keep it that way.

albfan commented 5 years ago

@nirbheek, maybe related https://gitlab.gnome.org/GNOME/gitg/issues/145#note_352754. Although homebrew tries to mimic linux on mac, so using so as suffix could be a false positive here.

albfan commented 5 years ago

Opps. That was on purpose: https://gitlab.gnome.org/GNOME/glib/merge_requests/280/diffs

neverpanic commented 1 year ago

macOS itself uses three possible formats for loadable modules, .so, .bundle, or no extension in subfolder of a folder named ${name}.bundle.

For example, there are loadable modules for the SASL authentication framework in /usr/lib/sasl2 on macOS Ventura, which use .so. Note that this location (and all the others I will look at) is protected by system integrity protection, which means it cannot be edited by users, even with root privileges. All these files, consequently, are directly from Apple.

$ ls -lash /usr/lib/sasl2/
total 1256
  0 drwxr-xr-x  22 root  wheel   704B Apr  1 18:46 .
  0 drwxr-xr-x  32 root  wheel   1.0K Apr  1 18:46 ..
 48 -rwxr-xr-x   1 root  wheel   164K Apr  1 18:46 apop.so
 40 -rwxr-xr-x   1 root  wheel   164K Apr  1 18:46 atoken.so
216 -rwxr-xr-x   1 root  wheel   344K Apr  1 18:46 dhx.so
104 -rwxr-xr-x   1 root  wheel   231K Apr  1 18:46 digestmd5WebDAV.so
 48 -rwxr-xr-x   1 root  wheel   165K Apr  1 18:46 libanonymous.2.so
 48 -rwxr-xr-x   1 root  wheel   165K Apr  1 18:46 libcrammd5.2.so
112 -rwxr-xr-x   1 root  wheel   231K Apr  1 18:46 libdigestmd5.2.so
 80 -rwxr-xr-x   1 root  wheel   217K Apr  1 18:46 libgssapiv2.2.0.18.so
  0 lrwxr-xr-x   1 root  wheel    21B Apr  1 18:46 libgssapiv2.2.so -> libgssapiv2.2.0.18.so
 80 -rwxr-xr-x   1 root  wheel   198K Apr  1 18:46 libntlm.so
 48 -rwxr-xr-x   1 root  wheel   165K Apr  1 18:46 libplain.2.so
 48 -rwxr-xr-x   1 root  wheel   165K Apr  1 18:46 login.so
 56 -rwxr-xr-x   1 root  wheel   166K Apr  1 18:46 mschapv2.so
 40 -rwxr-xr-x   1 root  wheel   164K Apr  1 18:46 oauthbearer.so
  0 drwxr-xr-x   5 root  wheel   160B Apr  1 18:46 openldap
 40 -rwxr-xr-x   1 root  wheel   164K Apr  1 18:46 plain-clienttoken.so
 40 -rwxr-xr-x   1 root  wheel   165K Apr  1 18:46 pwauxprop.so
 56 -rwxr-xr-x   1 root  wheel   167K Apr  1 18:46 shadow_auxprop.so
 56 -rwxr-xr-x   1 root  wheel   165K Apr  1 18:46 smb_ntlmv2.so
 96 -rwxr-xr-x   1 root  wheel   202K Apr  1 18:46 srp.so

As previously outlined above by @raimue, these files all have a filetype of MH_BUNDLE (0x8), not MH_DYLIB (0x6), see also /Library/Developer/CommandLineTools/SDKs/MacOS.sdk/usr/include/mach-o/loader.h:

$ otool -hv /usr/lib/sasl2/atoken.so /usr/lib/libgmalloc.dylib
/usr/lib/sasl2/atoken.so:
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64   X86_64        ALL  0x00      BUNDLE    16       1136   NOUNDEFS DYLDLINK TWOLEVEL
/usr/lib/libgmalloc.dylib:
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64   X86_64        ALL  0x00       DYLIB    16       1616   NOUNDEFS DYLDLINK TWOLEVEL NO_REEXPORTED_DYLIBS APP_EXTENSION_SAFE

For other loadable modules, e.g. those associated with perl, Apple uses .bundle:

$ otool -hv /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Hash/Util/Util.bundle
/System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Hash/Util/Util.bundle:
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64   X86_64        ALL  0x00      BUNDLE    14       1336   NOUNDEFS DYLDLINK TWOLEVEL

Additionally, Apple also uses .bundle for directories that contain (similar to how .app bundles are structured) the loadable module at Contents/MacOS/$name, e.g. in /System/Library/Security/ldapl.bundle:

$ otool -hv ./Security/ldapdl.bundle/Contents/MacOS/ldapdl
./Security/ldapdl.bundle/Contents/MacOS/ldapdl:
Mach header
      magic  cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64   X86_64        ALL  0x00      BUNDLE    19       1752   NOUNDEFS DYLDLINK TWOLEVEL WEAK_DEFINES BINDS_TO_WEAK

Some old documents from Apple (that I could no longer find on the Apple website) suggest that .bundle is the convention for file types that use MH_BUNDLE as header:

The MH_BUNDLE file type is the type typically used by code that you load at runtime (typically called bundles or plug-ins). By convention, the file name extension for this format is .bundle.

(from https://github.com/aidansteele/osx-abi-macho-file-format-reference/blob/master/Mach-O_File_Format.pdf)

I ran a quick check for all files that claim to be of type MH_BUNDLE in /usr/lib, /usr/libexec and /System/Library, and could not find a single .dylib file, which suggests that the behavior currently used by meson is wrong. Meson should thus either use .so, or .bundle, and given that using .bundle would break existing code that worked when autoconf build systems were used, I would recommend using .so.

For your own analysis, the command I used to locate all bundle files was

find /usr/lib /usr/libexec /System/Library -type f -exec bash -c 'for file; do if otool -hv "$file" |& grep -q BUNDLE; then echo "$file"; fi; done' {} +
Results ``` /usr/lib/dsc_extractor.bundle /usr/lib/rpcsvc/netlogon.bundle /usr/lib/rpcsvc/wkssvc.bundle /usr/lib/rpcsvc/srvsvc.bundle /usr/lib/rpcsvc/mdssvc.bundle /usr/lib/rpcsvc/dssetup.bundle /usr/lib/rpcsvc/echosvc.bundle /usr/lib/rpcsvc/lsarpc.bundle /usr/lib/zsh/5.9/zsh/termcap.so /usr/lib/zsh/5.9/zsh/zleparameter.so /usr/lib/zsh/5.9/zsh/example.so /usr/lib/zsh/5.9/zsh/newuser.so /usr/lib/zsh/5.9/zsh/nearcolor.so /usr/lib/zsh/5.9/zsh/deltochar.so /usr/lib/zsh/5.9/zsh/net/tcp.so /usr/lib/zsh/5.9/zsh/net/socket.so /usr/lib/zsh/5.9/zsh/complete.so /usr/lib/zsh/5.9/zsh/mapfile.so /usr/lib/zsh/5.9/zsh/stat.so /usr/lib/zsh/5.9/zsh/compctl.so /usr/lib/zsh/5.9/zsh/zselect.so /usr/lib/zsh/5.9/zsh/sched.so /usr/lib/zsh/5.9/zsh/parameter.so /usr/lib/zsh/5.9/zsh/datetime.so /usr/lib/zsh/5.9/zsh/watch.so /usr/lib/zsh/5.9/zsh/terminfo.so /usr/lib/zsh/5.9/zsh/clone.so /usr/lib/zsh/5.9/zsh/rlimits.so /usr/lib/zsh/5.9/zsh/regex.so /usr/lib/zsh/5.9/zsh/attr.so /usr/lib/zsh/5.9/zsh/param/private.so /usr/lib/zsh/5.9/zsh/curses.so /usr/lib/zsh/5.9/zsh/files.so /usr/lib/zsh/5.9/zsh/system.so /usr/lib/zsh/5.9/zsh/zpty.so /usr/lib/zsh/5.9/zsh/zle.so /usr/lib/zsh/5.9/zsh/mathfunc.so /usr/lib/zsh/5.9/zsh/zutil.so /usr/lib/zsh/5.9/zsh/complist.so /usr/lib/zsh/5.9/zsh/zftp.so /usr/lib/zsh/5.9/zsh/cap.so /usr/lib/zsh/5.9/zsh/computil.so /usr/lib/zsh/5.9/zsh/zprof.so /usr/lib/zsh/5.9/zsh/langinfo.so /usr/lib/sasl2/shadow_auxprop.so /usr/lib/sasl2/mschapv2.so /usr/lib/sasl2/atoken.so /usr/lib/sasl2/login.so /usr/lib/sasl2/srp.so /usr/lib/sasl2/smb_ntlmv2.so /usr/lib/sasl2/libdigestmd5.2.so /usr/lib/sasl2/libntlm.so /usr/lib/sasl2/plain-clienttoken.so /usr/lib/sasl2/libcrammd5.2.so /usr/lib/sasl2/digestmd5WebDAV.so /usr/lib/sasl2/apop.so /usr/lib/sasl2/oauthbearer.so /usr/lib/sasl2/pwauxprop.so /usr/lib/sasl2/libplain.2.so /usr/lib/sasl2/libanonymous.2.so /usr/lib/sasl2/dhx.so /usr/lib/xpc/support.bundle/Contents/MacOS/support /usr/libexec/apache2/mod_dav_lock.so /usr/libexec/apache2/mod_auth_form.so /usr/libexec/apache2/mod_dav.so /usr/libexec/apache2/mod_socache_memcache.so /usr/libexec/apache2/mod_rewrite.so /usr/libexec/apache2/mod_setenvif.so /usr/libexec/apache2/mod_lbmethod_byrequests.so /usr/libexec/apache2/mod_proxy.so /usr/libexec/apache2/mod_proxy_fdpass.so /usr/libexec/apache2/mod_proxy_ajp.so /usr/libexec/apache2/mod_slotmem_plain.so /usr/libexec/apache2/mod_speling.so /usr/libexec/apache2/mod_headers.so /usr/libexec/apache2/mod_proxy_scgi.so /usr/libexec/apache2/mod_proxy_uwsgi.so /usr/libexec/apache2/mod_ssl.so /usr/libexec/apache2/mod_proxy_html.so /usr/libexec/apache2/mod_lbmethod_bytraffic.so /usr/libexec/apache2/mod_dialup.so /usr/libexec/apache2/mod_dumpio.so /usr/libexec/apache2/mod_lbmethod_heartbeat.so /usr/libexec/apache2/mod_buffer.so /usr/libexec/apache2/mod_proxy_express.so /usr/libexec/apache2/mod_proxy_balancer.so /usr/libexec/apache2/mod_mime_magic.so /usr/libexec/apache2/mod_http2.so /usr/libexec/apache2/mod_session_cookie.so /usr/libexec/apache2/mod_authn_file.so /usr/libexec/apache2/mod_usertrack.so /usr/libexec/apache2/mod_log_forensic.so /usr/libexec/apache2/mod_cache.so /usr/libexec/apache2/mod_heartbeat.so /usr/libexec/apache2/mod_filter.so /usr/libexec/apache2/mod_lbmethod_bybusyness.so /usr/libexec/apache2/mod_slotmem_shm.so /usr/libexec/apache2/mod_authn_anon.so /usr/libexec/apache2/mod_proxy_wstunnel.so /usr/libexec/apache2/mod_info.so /usr/libexec/apache2/mod_cache_socache.so /usr/libexec/apache2/mod_negotiation.so /usr/libexec/apache2/mod_authz_owner.so /usr/libexec/apache2/mod_dbd.so /usr/libexec/apache2/mod_reqtimeout.so /usr/libexec/apache2/mod_include.so /usr/libexec/apache2/mod_vhost_alias.so /usr/libexec/apache2/mod_echo.so /usr/libexec/apache2/mod_watchdog.so /usr/libexec/apache2/mod_authn_dbd.so /usr/libexec/apache2/mod_status.so /usr/libexec/apache2/mod_socache_redis.so /usr/libexec/apache2/mod_authz_dbd.so /usr/libexec/apache2/mod_data.so /usr/libexec/apache2/mod_alias.so /usr/libexec/apache2/mod_socache_shmcb.so /usr/libexec/apache2/mod_mpm_worker.so /usr/libexec/apache2/mod_log_debug.so /usr/libexec/apache2/mod_ratelimit.so /usr/libexec/apache2/mod_authz_user.so /usr/libexec/apache2/mod_xml2enc.so /usr/libexec/apache2/mod_deflate.so /usr/libexec/apache2/mod_authn_socache.so /usr/libexec/apache2/mod_authz_groupfile.so /usr/libexec/apache2/mod_mime.so /usr/libexec/apache2/mod_mpm_prefork.so /usr/libexec/apache2/mod_reflector.so /usr/libexec/apache2/mod_logio.so /usr/libexec/apache2/mod_proxy_hcheck.so /usr/libexec/apache2/mod_ldap.so /usr/libexec/apache2/mod_unique_id.so /usr/libexec/apache2/mod_cgid.so /usr/libexec/apache2/mod_charset_lite.so /usr/libexec/apache2/mod_session.so /usr/libexec/apache2/mod_macro.so /usr/libexec/apache2/mod_sed.so /usr/libexec/apache2/mod_request.so /usr/libexec/apache2/mod_remoteip.so /usr/libexec/apache2/mod_allowmethods.so /usr/libexec/apache2/mod_substitute.so /usr/libexec/apache2/mod_actions.so /usr/libexec/apache2/mod_proxy_ftp.so /usr/libexec/apache2/mod_cgi.so /usr/libexec/apache2/mod_perl.so /usr/libexec/apache2/mod_authnz_ldap.so /usr/libexec/apache2/mod_hfs_apple.so /usr/libexec/apache2/mod_authn_core.so /usr/libexec/apache2/mod_file_cache.so /usr/libexec/apache2/mod_proxy_connect.so /usr/libexec/apache2/mod_log_config.so /usr/libexec/apache2/mod_dav_fs.so /usr/libexec/apache2/mod_auth_digest.so /usr/libexec/apache2/mod_authn_dbm.so /usr/libexec/apache2/mod_env.so /usr/libexec/apache2/mod_expires.so /usr/libexec/apache2/mod_authz_host.so /usr/libexec/apache2/mod_access_compat.so /usr/libexec/apache2/mod_authnz_od_apple.so /usr/libexec/apache2/mod_autoindex.so /usr/libexec/apache2/mod_dir.so /usr/libexec/apache2/mod_proxy_http.so /usr/libexec/apache2/mod_imagemap.so /usr/libexec/apache2/mod_authz_dbm.so /usr/libexec/apache2/mod_ext_filter.so /usr/libexec/apache2/mod_socache_dbm.so /usr/libexec/apache2/mod_auth_basic.so /usr/libexec/apache2/mod_asis.so /usr/libexec/apache2/mod_heartmonitor.so /usr/libexec/apache2/mod_cache_disk.so /usr/libexec/apache2/mod_unixd.so /usr/libexec/apache2/mod_authz_core.so /usr/libexec/apache2/mod_session_dbd.so /usr/libexec/apache2/mod_version.so /usr/libexec/apache2/mod_mpm_event.so /usr/libexec/apache2/mod_userdir.so /usr/libexec/apache2/mod_proxy_fcgi.so /System/Library/Assistant/UIPlugins/AssistantSystemUI.siriUIBundle/Contents/MacOS/AssistantSystemUI /System/Library/Assistant/UIPlugins/SettingsUI.siriUIBundle/Contents/MacOS/SettingsUI /System/Library/Assistant/UIPlugins/Notes.siriUIBundle/Contents/MacOS/Notes /System/Library/Assistant/UIPlugins/GeneralKnowledgeUI.siriUIBundle/Contents/MacOS/GeneralKnowledgeUI /System/Library/Assistant/UIPlugins/SiriFindMyUIPlugin.siriUIBundle/Contents/MacOS/SiriFindMyUIPlugin /System/Library/Assistant/UIPlugins/AirQualityUI.siriUIBundle/Contents/MacOS/AirQualityUI /System/Library/Assistant/UIPlugins/SystemInformationUI.siriUIBundle/Contents/MacOS/SystemInformationUI /System/Library/Assistant/UIPlugins/WAAnswerUI.siriUIBundle/Contents/MacOS/WAAnswerUI /System/Library/Assistant/UIPlugins/UniversalSearchUI.siriUIBundle/Contents/MacOS/UniversalSearchUI /System/Library/Assistant/UIPlugins/AcousticId.siriUIBundle/Contents/MacOS/AcousticId /System/Library/Assistant/UIPlugins/RemindersUI.siriUIBundle/Contents/MacOS/RemindersUI /System/Library/Assistant/UIPlugins/ClockUI.siriUIBundle/Contents/MacOS/ClockUI /System/Library/Assistant/UIPlugins/MailUI.siriUIBundle/Contents/MacOS/MailUI /System/Library/Assistant/UIPlugins/CalendarUI.siriUIBundle/Contents/MacOS/CalendarUI /System/Library/Assistant/UIPlugins/MicroblogUI.siriUIBundle/Contents/MacOS/MicroblogUI /System/Library/Assistant/UIPlugins/Maps.siriUIBundle/Contents/MacOS/Maps /System/Library/Assistant/UIPlugins/FileSearchUI.siriUIBundle/Contents/MacOS/FileSearchUI /System/Library/Assistant/UIPlugins/MessagesUI.siriUIBundle/Contents/MacOS/MessagesUI /System/Library/Assistant/Plugins/WebSearch.assistantBundle/Contents/MacOS/WebSearch /System/Library/Assistant/Plugins/activity.assistantBundle/Contents/MacOS/activity /System/Library/Assistant/Plugins/mediasupport.assistantBundle/Contents/MacOS/mediasupport /System/Library/Assistant/Plugins/Social.assistantBundle/Contents/MacOS/Social /System/Library/Assistant/Plugins/Maps.assistantBundle/Contents/MacOS/Maps /System/Library/Assistant/Plugins/Mail.assistantBundle/Contents/MacOS/Mail /System/Library/Assistant/Plugins/Podcasts.assistantBundle/Contents/MacOS/Podcasts /System/Library/Assistant/Plugins/Stocks.assistantBundle/Contents/MacOS/Stocks /System/Library/Assistant/Plugins/Notes.assistantBundle/Contents/MacOS/Notes /System/Library/Assistant/Plugins/SystemAutomation.assistantBundle/Contents/MacOS/SystemAutomation /System/Library/Assistant/Plugins/SiriFindMyBundle.assistantBundle/Contents/MacOS/SiriFindMyBundle /System/Library/Assistant/Plugins/Settings.assistantBundle/Contents/MacOS/Settings /System/Library/Assistant/Plugins/Reminders.assistantBundle/Contents/MacOS/Reminders /System/Library/Assistant/PrivateLearningPlugins/SiriPrivateLearningTTSMispronunciationPlugin.bundle/Contents/MacOS/SiriPrivateLearningTTSMispronunciationPlugin /System/Library/Assistant/PrivateLearningPlugins/SiriPrivateLearningPatternExtractionPlugin.bundle/Contents/MacOS/SiriPrivateLearningPatternExtractionPlugin /System/Library/Assistant/PrivateLearningPlugins/SiriReferenceResolutionMetricsPlugin.bundle/Contents/MacOS/SiriReferenceResolutionMetricsPlugin /System/Library/Assistant/PrivateLearningPlugins/SiriPrivateLearningInferencePlugin.bundle/Contents/MacOS/SiriPrivateLearningInferencePlugin /System/Library/Assistant/Suggestions/InferenceBridge/SiriSuggestionsInferenceBridge.bundle/Contents/MacOS/SiriSuggestionsInferenceBridge /System/Library/Assistant/FlowDelegatePlugins/ContactsFlowDelegatePlugin.bundle/Contents/MacOS/ContactsFlowDelegatePlugin /System/Library/Assistant/FlowDelegatePlugins/ClockFlowPlugin.bundle/Contents/MacOS/ClockFlowPlugin /System/Library/Assistant/FlowDelegatePlugins/WellnessFlowPlugin.bundle/Contents/MacOS/WellnessFlowPlugin /System/Library/Assistant/FlowDelegatePlugins/InformationFlowPlugin.bundle/Contents/MacOS/InformationFlowPlugin /System/Library/Assistant/FlowDelegatePlugins/AudioFlowDelegatePlugin.bundle/Contents/MacOS/AudioFlowDelegatePlugin […] /System/Library/CoreServices/TouchBarEvent.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Devel/Peek/Peek.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/POSIX/POSIX.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Compress/Raw/Zlib/Zlib.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Compress/Raw/Bzip2/Bzip2.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Unicode/Collate/Collate.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Unicode/Normalize/Normalize.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/File/DosGlob/DosGlob.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/File/Glob/Glob.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Hash/Util/FieldHash/FieldHash.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Hash/Util/Util.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Digest/MD5/MD5.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Digest/SHA/SHA.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/NDBM_File/NDBM_File.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/IO/IO.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Storable/Storable.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/EBCDIC/EBCDIC.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Encode.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Unicode/Unicode.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/CN/CN.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/TW/TW.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Symbol/Symbol.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/KR/KR.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/Byte/Byte.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Encode/JP/JP.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/SDBM_File/SDBM_File.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Math/BigInt/FastCalc/FastCalc.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Time/Piece/Piece.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Time/HiRes/HiRes.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/attributes/attributes.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Sys/Syslog/Syslog.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Sys/Hostname/Hostname.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Tie/Hash/NamedCapture/NamedCapture.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/threads/shared/shared.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/threads/threads.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/List/Util/Util.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/PerlIO/mmap/mmap.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/PerlIO/encoding/encoding.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/PerlIO/via/via.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/PerlIO/scalar/scalar.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/MIME/Base64/Base64.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/IPC/SysV/SysV.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Filter/Util/Call/Call.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/mro/mro.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/I18N/Langinfo/Langinfo.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Fcntl/Fcntl.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Cwd/Cwd.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Data/Dumper/Dumper.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Opcode/Opcode.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/B/B.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/DB_File/DB_File.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/re/re.bundle /System/Library/Perl/5.30/darwin-thread-multi-2level/auto/Socket/Socket.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Devel/Peek/Peek.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/POSIX/POSIX.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Compress/Raw/Zlib/Zlib.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Compress/Raw/Bzip2/Bzip2.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Unicode/Collate/Collate.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Unicode/Normalize/Normalize.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/File/DosGlob/DosGlob.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/File/Glob/Glob.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Hash/Util/FieldHash/FieldHash.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Hash/Util/Util.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Digest/MD5/MD5.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Digest/SHA/SHA.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/NDBM_File/NDBM_File.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/IO/IO.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Storable/Storable.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Encode/EBCDIC/EBCDIC.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Encode/Encode.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Encode/Unicode/Unicode.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Encode/CN/CN.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Encode/TW/TW.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Encode/Symbol/Symbol.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Encode/KR/KR.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Encode/Byte/Byte.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Encode/JP/JP.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/SDBM_File/SDBM_File.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Math/BigInt/FastCalc/FastCalc.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Time/Piece/Piece.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Time/HiRes/HiRes.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/attributes/attributes.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Sys/Syslog/Syslog.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Sys/Hostname/Hostname.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/threads/shared/shared.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/threads/threads.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/List/Util/Util.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/PerlIO/mmap/mmap.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/PerlIO/encoding/encoding.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/PerlIO/via/via.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/PerlIO/scalar/scalar.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/MIME/Base64/Base64.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/IPC/SysV/SysV.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Filter/Util/Call/Call.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/mro/mro.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/I18N/Langinfo/Langinfo.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Fcntl/Fcntl.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Cwd/Cwd.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Data/Dumper/Dumper.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Opcode/Opcode.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/B/B.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/DB_File/DB_File.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/re/re.bundle /System/Library/Perl/5.34/darwin-thread-multi-2level/auto/Socket/Socket.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Proc/ProcessTable/ProcessTable.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Devel/Declare/Declare.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Devel/Caller/Caller.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Devel/CallChecker/CallChecker.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/PerlObjCBridge/PerlObjCBridge.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Compress/Bzip2/Bzip2.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Net/SSLeay/SSLeay.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Net/DNS/DNS.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Lexical/SealRequireHints/SealRequireHints.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Moose/Moose.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Bit/Vector/Vector.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Socket6/Socket6.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Variable/Magic/Magic.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/DateTime/DateTime.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Crypt/OpenSSL/RSA/RSA.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Crypt/OpenSSL/Random/Random.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Digest/CRC/CRC.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Digest/SHA1/SHA1.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Term/ReadKey/ReadKey.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/DBI/DBI.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/IO/Tty/Tty.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/XString/XString.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Foundation/Foundation.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Encode/Detect/Detector/Detector.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/HTML/Parser/Parser.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/bareword/filehandles/filehandles.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/XML/LibXML/LibXML.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/XML/LibXSLT/LibXSLT.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/XML/Parser/Expat/Expat.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/ModPerl/Interpreter/Interpreter.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/ModPerl/Util/Util.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/ModPerl/InterpPool/InterpPool.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/ModPerl/TiPool/TiPool.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/ModPerl/TiPoolConfig/TiPoolConfig.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/ModPerl/Const/Const.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/ModPerl/Global/Global.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Internals/Internals.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Sub/Identify/Identify.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Sub/Name/Name.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Unix/Syslog/Syslog.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/Response/Response.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/Access/Access.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/Connection/Connection.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/Util/Util.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/ServerUtil/ServerUtil.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/Module/Module.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/FilterRec/FilterRec.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/Provider/Provider.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/ConnectionUtil/ConnectionUtil.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/Const/Const.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/RequestRec/RequestRec.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/SubProcess/SubProcess.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/Directive/Directive.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/CmdParms/CmdParms.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/MPM/MPM.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/Log/Log.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/SubRequest/SubRequest.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/Command/Command.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/Filter/Filter.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/RequestIO/RequestIO.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/HookRun/HookRun.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/URI/URI.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/RequestUtil/RequestUtil.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/ServerRec/ServerRec.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Apache2/Process/Process.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/JSON/XS/XS.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Clone/Clone.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/indirect/indirect.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/multidimensional/multidimensional.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/List/MoreUtils/XS/XS.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Params/Validate/XS/XS.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Params/Classify/Classify.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Params/Util/Util.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/APR/BucketType/BucketType.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/APR/ThreadMutex/ThreadMutex.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/APR/IpSubnet/IpSubnet.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/APR/Finfo/Finfo.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/APR/Util/Util.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/APR/SockAddr/SockAddr.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/APR/ThreadRWLock/ThreadRWLock.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/APR/Date/Date.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/APR/Base64/Base64.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/APR/Status/Status.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/APR/Brigade/Brigade.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/APR/Const/Const.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/APR/Bucket/Bucket.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/APR/Table/Table.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/APR/PerlIO/PerlIO.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/APR/OS/OS.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/APR/String/String.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/APR/BucketAlloc/BucketAlloc.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/APR/URI/URI.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/APR/UUID/UUID.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/APR/Error/Error.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/APR/Pool/Pool.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/APR/Socket/Socket.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/APR/APR.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/autobox/autobox.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Class/Load/XS/XS.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Class/XSAccessor/XSAccessor.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/PerlIO/eol/eol.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/PerlIO/gzip/gzip.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/YAML/XS/LibYAML/LibYAML.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/YAML/Syck/Syck.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/PadWalker/PadWalker.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/GSSAPI/GSSAPI.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Text/Soundex/Soundex.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/DBD/SQLite/SQLite.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/CoreFoundation/CoreFoundation.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/BerkeleyDB/BerkeleyDB.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/B/Hooks/OP/Check/Check.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/B/COW/COW.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Package/Stash/XS/XS.bundle /System/Library/Perl/Extras/5.30/darwin-thread-multi-2level/auto/Convert/UUlib/UUlib.bundle /System/Library/BridgeSupport/ruby-2.6/bridgesupportparser.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/continuation.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/pty.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/coverage.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/stringio.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/etc.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/zlib.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/fiber.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/digest/bubblebabble.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/digest/md5.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/digest/sha2.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/digest/rmd160.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/digest/sha1.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/pathname.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/io/wait.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/io/console.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/io/nonblock.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/ripper.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/fiddle.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/dbm.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/socket.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/euc_tw.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/windows_1253.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/utf_32be.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/iso_8859_13.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/iso_8859_3.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/iso_8859_1.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/windows_1251.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/iso_8859_11.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/iso_8859_5.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/cp949.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/iso_8859_9.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/utf_16be.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/iso_8859_15.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/shift_jis.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/windows_31j.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/windows_1257.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/koi8_r.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/iso_8859_7.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/iso_8859_2.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/big5.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/utf_32le.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/encdb.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/gb18030.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/gbk.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/windows_1252.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/iso_8859_10.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/windows_1250.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/euc_kr.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/koi8_u.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/euc_jp.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/windows_1254.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/iso_8859_14.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/trans/ebcdic.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/trans/utf8_mac.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/trans/emoji_sjis_docomo.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/trans/transdb.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/trans/emoji_sjis_softbank.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/trans/escape.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/trans/japanese_sjis.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/trans/single_byte.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/trans/emoji.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/trans/japanese.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/trans/utf_16_32.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/trans/big5.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/trans/gb18030.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/trans/gbk.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/trans/iso2022.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/trans/emoji_sjis_kddi.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/trans/chinese.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/trans/emoji_iso2022_kddi.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/trans/japanese_euc.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/trans/korean.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/utf_16le.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/iso_8859_4.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/iso_8859_8.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/iso_8859_6.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/emacs_mule.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/iso_8859_16.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/enc/gb2312.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/cgi/escape.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/date_core.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/psych.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/json/ext/generator.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/json/ext/parser.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/bigdecimal.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/racc/cparse.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/syslog.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/strscan.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/nkf.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/fcntl.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/objspace.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/openssl.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/digest.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/rbconfig/sizeof.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/sdbm.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/universal-darwin22/readline.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/gems/2.6.0/extensions/universal-darwin-22/2.6.0/libxml-ruby-3.2.1/libxml_ruby.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/gems/2.6.0/extensions/universal-darwin-22/2.6.0/sqlite3-1.3.13/sqlite3/sqlite3_native.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/gems/2.6.0/extensions/universal-darwin-22/2.6.0/nokogiri-1.13.8/nokogiri/nokogiri.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/gems/2.6.0/gems/libxml-ruby-3.2.1/ext/libxml/libxml_ruby.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/gems/2.6.0/gems/libxml-ruby-3.2.1/lib/libxml_ruby.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/gems/2.6.0/gems/sqlite3-1.3.13/ext/sqlite3/sqlite3_native.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/gems/2.6.0/gems/sqlite3-1.3.13/lib/sqlite3/sqlite3_native.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/gems/2.6.0/gems/nokogiri-1.13.8/ext/nokogiri/nokogiri.bundle /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/gems/2.6.0/gems/nokogiri-1.13.8/lib/nokogiri/nokogiri.bundle /System/Library/Frameworks/OpenCL.framework/Versions/A/Libraries/AMDil.dylib /System/Library/Frameworks/CoreImage.framework/Versions/A/Frameworks/libWrapGL.dylib /System/Library/Frameworks/CoreImage.framework/Versions/A/Frameworks/libWrapGLES.dylib ```

Edit: My search did find three .dylib files that are bundles:

/System/Library/Frameworks/OpenCL.framework/Versions/A/Libraries/AMDil.dylib
/System/Library/Frameworks/CoreImage.framework/Versions/A/Frameworks/libWrapGL.dylib
/System/Library/Frameworks/CoreImage.framework/Versions/A/Frameworks/libWrapGLES.dylib

I think those are the exception, not the rule.

neverpanic commented 1 year ago

CMake also uses .so, btw: https://gitlab.kitware.com/cmake/cmake/-/blob/master/Modules/Platform/Darwin.cmake#L47

Midar commented 2 months ago

I would recommend going with the bundle directory structure as that is the only thing that can be code signed. However, these have a different structure for iOS and macOS. There is also some discussion in https://github.com/audacious-media-player/audacious/issues/1364 which references this issue.

mohd-akram commented 2 months ago

Not using .so breaks any project using libtool for modules. Just ran into this with PulseAudio.

Midar commented 2 months ago

.so is the extension for ELF shared objects. macOS/iOS does not support those, so it is the wrong extension.

neverpanic commented 2 months ago

.so is the extension for ELF shared objects. macOS/iOS does not support those, so it is the wrong extension.

This isn't correct. There's plenty of prior art of using .so on macOS for Mach-O loadable modules as outlined above in https://github.com/mesonbuild/meson/issues/1160#issuecomment-1511157623, for example for the SASL loadable modules shipped by Apple.

That being said, there are also plenty of loadable modules in .dylib files on macOS, so this seems like a bug in libtool that libtool should fix.

Midar commented 2 months ago

.so is the extension for ELF shared objects. macOS/iOS does not support those, so it is the wrong extension.

This isn't correct. There's plenty of prior art of using .so on macOS for Mach-O loadable modules as outlined above in #1160 (comment), for example for the SASL loadable modules shipped by Apple.

Sorry, but this is just plain wrong. Yes, Python ships as part of macOS. And yes, Python got it wrong. Does Apple shipping 3rd party software that gets it wrong suddenly make it right? I doubt so. Please provide a link to the Apple documentation that states that .so is an acceptable extension for Mach-O (spoiler alert: it's not).

That being said, there are also plenty of loadable modules in .dylib files on macOS, so this seems like a bug in libtool that libtool should fix.

I agree on that.

The correct format for extensions on macOS and iOS is bundles, though. See https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFBundles/AboutBundles/AboutBundles.html and https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html#//apple_ref/doc/uid/10000123i-CH101-SW32

raimue commented 2 months ago

At least the problem has been mititgated in the glib world with the changes to the g_module_open() API only taking the basename without file extension. Depending on the platform, it will now try possible combinations with and without the "lib" prefix and different file extensions (thank you @nirbheek): https://gitlab.gnome.org/GNOME/glib/-/merge_requests/2950

For over 20 years, software ported to macOS has just used the .so file extension for compatibility. Even if Apple had intended that software should be using .bundle, the .so filename extension was adopted by the community as the de facto standard. In fact, Apple states at the very top of the previously linked bundle documentation:

Note: Although bundles are one way of packaging executable code, they are not the only way that is supported. UNIX shell scripts and command-line tools do not use the bundle structure, neither do static and dynamic shared libraries.

https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html#//apple_ref/doc/uid/10000123i-CH101-SW1

For sure in other places Apple's documentation will also always tell you that applications are being shipped as .app bundles. But I assume you also do not expect meson to always create .app bundles instead of plain executable files? No, the exception for command-line tools applies to this case.

A .bundle is a directory structure that requires more files than what is now being done with plain files. The ported software will never use anything from the Info.plist, why should developers be forced to create it?

To follow up on your earlier argument, codesign works just fine with a MH_BUNDLE file. There is no strict requirement to wrap inside a .bundle directory structure just for code signing. You are aware that code signing also works for plain executable files without an .app bundle? So why do you think that a .bundle is required to codesign a loadable module? The signature will be attached directly to the Mach-O file.

I think the only case in which a bundle directory structure is strictly required would be for provisioning profiles. But as far as I am aware, these only exist for the whole program anyway and there is no way to have provisioning profiles or entitlements on a loadable module, as these are applied to the whole program. https://developer.apple.com/documentation/xcode/signing-a-daemon-with-a-restricted-entitlement

Midar commented 2 months ago

The macOS and iOS developer community has most certainly not adopted .so as an extension. Some lazy programmers coming from other UNIX systems and not properly porting their software to macOS have. But from my understanding, Meson wants to be a build system that supports platforms properly instead of trying to use a hammer to make all OSes behave as closely as possible as Linux.

The argument with .app is a little bit weak, as that's for graphical apps. Command line apps, as shipped by Apple, are not .apps. So there is precedent in first party software not being an .app. But there is absolutely zero precedent for first party software using .so or using .bundle on anything that is not a directory.

The situation is bad enough as it is with software not supporting macOS / iOS natively. Let's not contribute to this by Meson requiring software to not support macOS / iOS properly. There is a native way to handle plugins, let's use it. Generating an Info.plist from Meson would be a possibility, too, if that is your concern.

raimue commented 2 months ago

You already have to write custom scripts to create an .app bundle anyway (see #48). Nobody stops you from creating a .bundle directory structure after meson has built the loadable module. You can rename a foobar.so to a foobar.bundle/Contents/foobar, if you prefer. Then you also need to adapt the dlopen() code to make it find the loadable module. But I still do not see the benefit? Why would you make it more complicated than it has to be?

After all there is no technical reason to prefer a specific file extension for loadable modules. It all just comes down to finding a convention that both build system and the code loading the module will agree upon.

To find a common ground, I think we all agree that .dylib was not the best choice. Changing the default of .dylib to .so would allow some projects to drop conditional code setting the name_suffix property to .so. Using .so would be in line with other build tools (in particular libtool and cmake) that settled on using .so for loadable modules on macOS. But of course such a change would most probably also break other software that relied on the wrong .dylib default that was kept in meson for so long.

Midar commented 2 months ago

You already have to write custom scripts to create an .app bundle anyway (see #48). Nobody stops you from creating a .bundle directory structure after meson has built the loadable module. You can rename a foobar.so to a foobar.bundle/Contents/foobar, if you prefer. Then you also need to adapt the dlopen() code to make it find the loadable module. But I still do not see the benefit? Why would you make it more complicated than it has to be?

By that logic, you would also be okay to just rename a .dylib to .framework and call it a day. Why lie about what something is via the file extensions? Of course you can name a file however you want. You can call it .txt if you want. But that doesn't make it correct.

After all there is no technical reason to prefer a specific file extension for loadable modules. It all just comes down to finding a convention that both build system and the code loading the module will agree upon.

Then let's use no extension -- because that is the only extension you can find for plugins themselves that are not in a bundle.

To find a common ground, I think we all agree that .dylib was not the best choice.

Certainly a 100x better choice than .so. At least it's not lying. It is a dynamic library of type MH_BUNDLE, after all.

Changing the default of .dylib to .so would allow some projects to drop conditional code setting the name_suffix property to .so.

Those projects should be fixed instead.

Using .so would be in line with other build tools (in particular libtool and cmake) that settled on using .so for loadable modules on macOS.

Why are you so keen on breaking the ecosystem that already is quite broken even further? That bug should be fixed in libtool and cmake, not propagated to meson!

But of course such a change would most probably also break other software that relied on the wrong .dylib default that was kept in meson for so long.

If you insist on doing something that is not how it is done on the platform, at least .dylib is the least terrible of the options.

But let me make another proposal: If we're going to lie and intentionally break the ecosystem anyway, why not .dll? That is at least consistent with what Windows does and everybody knows what a DLL is. And it certainly isn't more wrong than .so.

eli-schwartz commented 2 months ago

The correct file extension is, of course, "whichever one the software that loads it is looking for". Everything is just a convention, if you care enough to change it.

And the Apple convention is that different projects baked their own conventions for convenience. The Apple convention is also "for meson projects, use dylib", no? Changing the output filename runs the risk of breaking existing projects in the wild.

Perhaps the answer is to add a kwarg, similar to the way we already special-case darwin with darwin_versions:. For shared_modules it would be darwin_suffix. Unsure whether that's better than just conditional definitions.

I don't think it's possible to have a one-size-fits-all extension, given that there are always going to be projects that hardcode a filename to load rather than iterating over many possible formats, and given that even if projects use -DPLUGIN_EXT=' + shmod.full_path().split('.')[-1] there will still be projects where a plugin is built with meson for another project that isn't built with meson and may have any extension style, so users do have to unfortunately control that.

So the answer will always have to be "users are empowered to deal with the preexisting world they have to live in".