appsignal-elixir icon indicating copy to clipboard operation
appsignal-elixir copied to clipboard

AppSignal doesn't build with the new linker in Xcode 15

Open kkostov opened this issue 1 year ago • 8 comments

Describe the bug

Hi,

Xcode 15 comes with a new linker which is enabled by default since Xcode 15 beta 3. The linker seems to enable additional warnings which are causing the build to fail.

The AppSignal library fails to build with the new linker:

==> appsignal
AppSignal installation failed: Build error was encountered while running `make` (exit code: 2):

In file included from c_src/appsignal_extension.c:11:
/Users/konstantin/Developer/zofx/zofx/_build/dev/lib/appsignal/priv/appsignal.h:79:25: warning: a function declaration without a prototype is deprecated in all versions of C [-Wstrict-prototypes]
void appsignal_env_clear();
                        ^
                         void
c_src/appsignal_extension.c:118:43: warning: unused parameter 'env' [-Wunused-parameter]
static ERL_NIF_TERM _env_clear(ErlNifEnv* env, int UNUSED(argc), const ERL_NIF_TERM UNUSED(argv[]))
                                          ^
c_src/appsignal_extension.c:125:39: warning: unused parameter 'env' [-Wunused-parameter]
static ERL_NIF_TERM _start(ErlNifEnv* env, int UNUSED(arc), const ERL_NIF_TERM UNUSED(argv[]))
                                      ^
c_src/appsignal_extension.c:131:38: warning: unused parameter 'env' [-Wunused-parameter]
static ERL_NIF_TERM _stop(ErlNifEnv* env, int UNUSED(arc), const ERL_NIF_TERM UNUSED(argv[]))
                                     ^
c_src/appsignal_extension.c:824:54: warning: unused parameter 'env' [-Wunused-parameter]
static ERL_NIF_TERM _running_in_container(ErlNifEnv* env, int UNUSED(argc), const ERL_NIF_TERM UNUSED(argv[])) {
                                                     ^
c_src/appsignal_extension.c:864:40: warning: unused parameter 'env' [-Wunused-parameter]
static ERL_NIF_TERM _loaded(ErlNifEnv *env, int UNUSED(argc), const ERL_NIF_TERM UNUSED(argv[])) {
                                       ^
6 warnings generated.
ld: warning: search path '/usr/local/lib' not found
ld: fatal warning(s) induced error (-fatal_warnings)
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[1]: *** [all] Error 1


Compiling 51 files (.ex)
warning: Error loading NIF (Is your operating system (aarch64-apple-darwin22.4.0) supported? Please check http://docs.appsignal.com/support/operating-systems.html):
Failed to load NIF library: 'dlopen(/Users/konstantin/Developer/zofx/zofx/_build/dev/lib/appsignal/priv/appsignal_extension.so, 0x0002): tried: '/Users/konstantin/Developer/zofx/zofx/_build/dev/lib/appsignal/priv/appsignal_extension.so' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/Users/konstantin/Developer/zofx/zofx/_build/dev/lib/appsignal/priv/appsignal_extension.so' (no such file), '/Users/konstantin/Developer/zofx/zofx/_build/dev/lib/appsignal/priv/appsignal_extension.so' (no such file), '/Users/konstantin/Developer/zofx/zofx/deps/appsignal/priv/appsignal_extension.so' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/Users/konstantin/Developer/zofx/zofx/deps/appsignal/priv/appsignal_extension.so' (no such file), '/Users/konstantin/Developer/zofx/zofx/deps/appsignal/priv/appsignal_extension.so' (no such file)'
  lib/appsignal/nif.ex:23: Appsignal.Nif.init/0
  (kernel 9.0.2) code_server.erl:1332: anonymous fn/1 in :code_server.handle_on_load/5

To Reproduce

Steps to reproduce the behavior:

  • Using AppSignal for Elixir package version 2.7.7, Elixir 1.15.4 (compiled with Erlang/OTP 26) on Arm/Apple Silicon (M2)
  • Running on macOS 13 or 14 (Sonoma) with Xcode 15 beta 6

Notes

  • While researching I found this issue to include some additional details and possible workarounds, but not sure if/how they can be applied for an elixir project.
  • The classic linker can be re-enabled using the -ld64 flag

kkostov avatar Aug 18 '23 15:08 kkostov

Hi @kkostov, thanks for the report!

We're not really in a position to try the beta now. Can you give us some more information by running these commands and sharing the output when using the beta?

cc --version
ld -v
ld -version_details

So far adding -ld64 as a flag to the build doesn't work on macOS using the latest stable build, so it might need to be added only for Xcode 15 which I hope we can do using the output from the above commands.

ld: library not found for -ld64

tombruijn avatar Aug 21 '23 09:08 tombruijn

Adding -ld64 can be a good work-around, just bear in mind that the old toolchain is deprecated and will be removed from Xcode at some point.

I can test building with -ld64 but I'm not sure how to configure it in my project (I'm still a bit new to Elixir 😅).

❯ cc --version
Apple clang version 15.0.0 (clang-1500.0.40.1)
Target: arm64-apple-darwin23.0.0
Thread model: posix
InstalledDir: /Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
❯ ld -v
@(#)PROGRAM:ld  PROJECT:dyld-1015.1
BUILD 17:44:19 Jul 30 2023
configured to support archs: armv6 armv7 armv7s arm64 arm64e arm64_32 i386 x86_64 x86_64h armv6m armv7k armv7m armv7em
will use ld-classic for: armv6 armv7 armv7s arm64_32 i386 armv6m armv7k armv7m armv7em
LTO support using: LLVM version 15.0.0 (static support for 29, runtime is 29)
TAPI support using: Apple TAPI version 15.0.0 (tapi-1500.0.12.3)
Library search paths:
Framework search paths:
❯ ld -version_details
{
	"version": "1015.1",
	"architectures": [
		"armv6",
		"armv7",
		"armv7s",
		"arm64",
		"arm64e",
		"arm64_32",
		"i386",
		"x86_64",
		"x86_64h",
		"armv6m",
		"armv7k",
		"armv7m",
		"armv7em"
	],
	"lto": {
		"runtime_api_version": 29,
		"static_api_version": 29,
		"version_string": "LLVM version 15.0.0"
	},
	"tapi": {
		"version": "15.0.0",
		"version_string": "Apple TAPI version 15.0.0 (tapi-1500.0.12.3)"
	}
}

kkostov avatar Aug 21 '23 15:08 kkostov

Adding -ld64 can be a good work-around, just bear in mind that the old toolchain is deprecated and will be removed from Xcode at some point.

My thought was to make it work now by using the legacy linker and once Xcode 15 is out of beta we can test against the final release version to use the new linker.

I can test building with -ld64 but I'm not sure how to configure it in my project (I'm still a bit new to Elixir 😅).

It requires some Makefile changes, but I'm unsure which.

I ended up installing the Xcode 15 command line tools beta 6 on another machine, and it just works?

I'm on Ventura 13.5, but it works. According to your cc --version output you're on the next macOS, which I can't upgrade to for testing.

I looked at the docs for both cc and ld from the beta, but neither mentions -ld64 as a config option, so I don't know where we should configure that.

tombruijn avatar Aug 22 '23 09:08 tombruijn

Thanks a lot! I just updated to beta 7 (15A5229h) as it was released yesterday, and it seems the issue doesn't persist any more (no additional warnings are emitted and so the library is compiled successfully).

kkostov avatar Aug 23 '23 07:08 kkostov

Thanks for the update @kkostov ! Let's wait until it gets out of beta then before we do anymore testing 👍 Leaving the issue open but putting it on the backlog.

Updated release notes link: https://developer.apple.com/documentation/xcode-release-notes/xcode-15-release-notes

tombruijn avatar Aug 23 '23 07:08 tombruijn

I am experiencing exactly the same issue on a brand new M3 Max MBP (aarch64-apple-darwin23.1.0) with macOS 14.1.2 (23B2091). I tried your workarounds with installing different versions of Command Line Tools but it didn't help. I tried "Command Line Tools for Xcode 15.1 beta 3" (newest ATM), "Command Line Tools for Xcode 15 beta 7", "Command Line Tools for Xcode 15 beta 6", and , "Command Line Tools for Xcode 15". All produce the same error.

I'm not sure what else to try (my C/low-level programming knowledge is non-existent 😢).

angelikatyborska avatar Dec 01 '23 14:12 angelikatyborska

@angelikatyborska I know you've probably tries this but is it possible something wasn't getting cleaned up when switching the command line tools versions and it keeps trying to build with the older version of the build tools?

Two issues I faced while troubleshooting this is that

a) the Elixir project had to be cleaned when switching Xcode version (mix clean --deps and deleting the build folder and language server folders if they remain)

b) switching command line tools versions requires a terminal restart (you can verify the correct version by checking for example the current version of clang with cc --version which should be something like "Apple clang version 15.0.0 (clang-1500.1.0.2.5)" for Xcode 15.1 Beta 3 and "Apple clang version 15.0.0 (clang-1500.0.x.x.x" for current stable 15.0. Also the InstallerDir should point to the version you expect e.g. /Applications/<Xcode version>.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

kkostov avatar Dec 04 '23 11:12 kkostov

Yes, I was already doing all of those steps.

However I took another another look at the problem and managed to solve it for myself 🎉

I noticed a difference on one line in the error that this issue's author got:

ld: warning: search path '/usr/local/lib' not found

and the error that I got:

ld: warning: search path '/opt/homebrew/opt/libssh/lib/' not found

After running ls /opt/homebrew/opt/libssh/, I realized I only have libssh@2 installed, so I ran brew install libssh and that fixed it 🤷‍♀️

Don't know if it's relevant, but I also don't have Xcode installed, only the Command Line Tools. Maybe that made the difference?

angelikatyborska avatar Dec 05 '23 13:12 angelikatyborska