For my education, I’m trying to compile a simple program from the command line to see how things work underneath all the IDEs and build tools.
Here are some minimal shell commands on my macOS system to build a C++ hello world, using a clang 15 binary that I just downloaded. (% is the shell prompt).
% SYSR=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk
% clang++ -isysroot $SYSR hello.cc
% ./a.out
hi
I keep adding to that line in response to error messages, but it still fails. So I’m curious, is there way to make clang++ echo the commands that it sent to the linker so I can see what the flags are to do it manually?
Minus typos. Apple Clang will find all the paths that it needs. If clang++ is an Open Source clang, then it is going to be complicated. But note that clang can invoke the linker for you.
(For easier reading I’ve stripped an irrelevant path prefix from my clang 15 directory below)
Thanks, that’s interesting. The -v or -### to clang++ shows the linker command. It’s calling /usr/bin/ld, even though I started by calling my newer clang++ at another path (/clang+llvm-15.0.1-x86_64-apple-darwin/bin/clang++).
I can substitute /usr/bin/ld with the newer linker next to clang 15, and it works. (I had to add a -platform_version flag.) However, I think it is still linking to the older C++ library with Xcode, not the newer one in the custom clang directory.
Related question: is there a similar way to see the libraries that the linker finds? I tried -v to the linker and it does print its search path, but it doesn’t show what it finally linked to. The library search paths suggest it will find the older C++ lib.
% which ld64.lld
/clang+llvm-15.0.1-x86_64-apple-darwin/bin/ld64.lld
% ld64.lld -dynamic -arch x86_64 -macosx_version_min 13.0.0 -platform_version macos 13 13 -syslibroot $SYSR -o hi2 hello.o -lc++ -lSystem /clang+llvm-15.0.1-x86_64-apple-darwin/lib/clang/15.0.1/lib/darwin/libclang_rt.osx.a -v
LLD 15.0.1
Library search paths:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk/usr/lib
Framework search paths:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk/System/Library/Frameworks
% ./hi2
hi
% otool -L hi2
hi2:
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1300.23.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.100.3)
Maybe if download a newer clang and want to link to new libc++, the best way is to include the static library in the build commands.
-fuse-lld appears to be a GCC flag. That rust link says: “Clang chooses the linker name based on passed --target”. But I don’t know what the target value should be there. I tried a few things, but clang++ is still using /usr/bin/ld.
LLVM has linkers (lld) for Linux, Apple, Windows, and WASM? Your OS Clang will know that the target is Apple and will pick ld64.lld. -fuse-lld is supported by clang and gcc.
You can see it in the rust issue or at ⚙ D74704 Support -fuse-ld=lld for riscv. It is two els. -fuse-ld=lld. I couldn’t find in man clang nor clang --help?!?