HaxeFoundation/hashlink

macOS libhl.dylib path causes crash

mmulet opened this issue · 1 comments

Info

Machine: M1 Max macOS 14.2.1
commit: 03110f7 (should be the commit tagged 1.14)

Problem

When building hashlink from source, the built executable hl uses a relative reference to libh.dllib

otool -L hl output:

hl:
	libhl.dylib (compatibility version 0.0.0, current version 0.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1336.61.1)

which means that running hl fails when installed (with make install), I just get a missing libhl.dylib error:

~ hl --version
dyld[94153]: Library not loaded: libhl.dylib
  Referenced from: <F9D3E1A1-6488-3C1D-B525-C7A169A4478A> /usr/local/bin/hl
  Reason: tried: 'libhl.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OSlibhl.dylib' (no such file), 'libhl.dylib' (no such file), '/Users/m/libhl.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/Users/m/libhl.dylib' (no such file), '/Users/m/libhl.dylib' (no such file)
[1]    94153 abort      hl --version

Workaround

Patch the executable with install_name_tool (do this before code signing and installing)

install_name_tool -change libhl.dylib /usr/local/lib/libhl.dylib hl

otool -L hl output:

hl:
	/usr/local/lib/libhl.dylib (compatibility version 0.0.0, current version 0.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1336.61.1)

Suggested fix

In the Makefile add -install_name $ ( INSTALL_LIB_DIR)/libhl.$(LIBEXT) to the libhl target (also add ifdef macOS guards, etc)

191: libhl: ${LIB}
	${CC} ${CFLAGS} -o libhl.$(LIBEXT) -m${MARCH} ${LIBFLAGS} -shared ${LIB} -lpthread -lm -install_name $(INSTALL_LIB_DIR)/libhl.$(LIBEXT)

This will set the libhl.dylib to the correct directory:
otool -L hl output:

hl:
	/usr/local/lib/libhl.dylib (compatibility version 0.0.0, current version 0.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1336.61.1)

and hl doesn't crash now:

~ hl --version
1.14.0%

With the suggested fix, is the hl executable still able to load libhl.dylib from the same directory as itself (for example when distributing a HL app)?

If not, the solution will probably have to involve rpath like on Linux.