llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.96k stars 11.94k forks source link

llvm-ranlib produces invalid universal archives #98997

Open michael-jabbour-sonarsource opened 3 months ago

michael-jabbour-sonarsource commented 3 months ago

llvm-ranlib seems to produce invalid universal .a files, that are not usable by the linker.

Steps to reproduce

I could reproduce the problem on llvm-ranlib (version 18.1.8) installed using brew on my Mac arm64 machine:

Start with a file main.cpp with the following content:

% cat main.cpp
#include <stdio.h>
int main() { printf("This is working as expected!\n"); }

Processing the fat archive when using ranlib from XCode command line developer tools works as expected:

% /opt/homebrew/opt/llvm/bin/clang++ -arch x86_64 -arch arm64 -o main.cpp.o -c main.cpp
% /Library/Developer/CommandLineTools/usr/bin/ar qc main_xcode.a main.cpp.o && /Library/Developer/CommandLineTools/usr/bin/ranlib main_xcode.a
% /opt/homebrew/opt/llvm/bin/clang++ -arch x86_64 -arch arm64 -o main_xcode main_xcode.a
% ./main_xcode
This is working as expected!

On the other hand, replacing ranlib with llvm-ranlib causes the linker to fail:

% /opt/homebrew/opt/llvm/bin/llvm-ar qc main_llvm.a main.cpp.o && /opt/homebrew/opt/llvm/bin/llvm-ranlib main_llvm.a
% /opt/homebrew/opt/llvm/bin/clang++ -arch x86_64 -arch arm64 -o main_llvm main_llvm.a
ld: archive member 'main.cpp.o' not a mach-o file in '/Users/user/Documents/llvm_ranlib_issue/main_llvm.a'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)

Note that running lipo -info on main_llvm.a suggests that there is a problem with the file:

% lipo -info main_xcode.a
Architectures in the fat file: main_xcode.a are: x86_64 arm64
% lipo -info main_llvm.a
fatal error: /Library/Developer/CommandLineTools/usr/bin/lipo: archive member main_llvm.a(main.cpp.o) is a fat file (not allowed in an archive)

Furthermore, running llvm-lipo crashes on main_llvm.a:

% /opt/homebrew/opt/llvm/bin/llvm-lipo -info main_xcode.a
Architectures in the fat file: main_xcode.a are: x86_64 arm64
% /opt/homebrew/opt/llvm/bin/llvm-lipo -info main_llvm.a
Non-fat file: main_llvm.a is architecture: PLEASE submit a bug report to https://github.com/Homebrew/homebrew-core/issues and include the crash backtrace.
Stack dump:
0.  Program arguments: /opt/homebrew/opt/llvm/bin/llvm-lipo -info main_llvm.a
 #0 0x00000001101b5d60 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x4695d60)
 #1 0x00000001101b6134 SignalHandler(int) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x4696134)
 #2 0x0000000191e97584 (/usr/lib/system/libsystem_platform.dylib+0x180477584)
 #3 0x0000000102ab1420 (anonymous namespace)::createSliceFromIR(llvm::object::IRObjectFile const&, unsigned int) (/opt/homebrew/Cellar/llvm/18.1.8/bin/llvm-lipo+0x100009420)
 #4 0x0000000102ab1420 (anonymous namespace)::createSliceFromIR(llvm::object::IRObjectFile const&, unsigned int) (/opt/homebrew/Cellar/llvm/18.1.8/bin/llvm-lipo+0x100009420)
 #5 0x0000000102ab17b4 printBinaryArchs(llvm::LLVMContext&, llvm::object::Binary const*, llvm::raw_ostream&) (/opt/homebrew/Cellar/llvm/18.1.8/bin/llvm-lipo+0x1000097b4)
 #6 0x0000000102ab5434 printInfo(llvm::LLVMContext&, llvm::ArrayRef<llvm::object::OwningBinary<llvm::object::Binary>>) (/opt/homebrew/Cellar/llvm/18.1.8/bin/llvm-lipo+0x10000d434)
 #7 0x0000000102aad558 llvm_lipo_main(int, char**, llvm::ToolContext const&) (/opt/homebrew/Cellar/llvm/18.1.8/bin/llvm-lipo+0x100005558)
 #8 0x0000000102ab524c main (/opt/homebrew/Cellar/llvm/18.1.8/bin/llvm-lipo+0x10000d24c)
 #9 0x0000000191ade0e0
zsh: segmentation fault  /opt/homebrew/opt/llvm/bin/llvm-lipo -info main_llvm.a
%

I hit this problem while trying to build my CMake project using clang from brew (It used to work fine with Apple Clang). Currently, I have to work around this by passing -DCMAKE_RANLIB=/Library/Developer/CommandLineTools/usr/bin/ranlib to my CMake configuration.

llvmbot commented 3 months ago

@llvm/issue-subscribers-tools-llvm-ar-llvm-ranlib

Author: Michael Jabbour (michael-jabbour-sonarsource)

I am having problems linking against fat `.a` archives processed by `llvm-ranlib`. I could reproduce the problem on `llvm-ranlib` (version 18.1.8) installed [using brew](https://formulae.brew.sh/formula/llvm) on my Mac arm64 machine: Start with a file `main.cpp` with the following content: ``` % cat main.cpp #include <stdio.h> int main() { printf("This is working as expected!\n"); } ``` Processing the fat archive when using `ranlib` from XCode command line developer tools works as expected: ``` % /opt/homebrew/opt/llvm/bin/clang++ -arch x86_64 -arch arm64 -o main.cpp.o -c main.cpp % /Library/Developer/CommandLineTools/usr/bin/ar qc main_xcode.a main.cpp.o && /Library/Developer/CommandLineTools/usr/bin/ranlib main_xcode.a % /opt/homebrew/opt/llvm/bin/clang++ -arch x86_64 -arch arm64 -o main_xcode main_xcode.a % ./main_xcode This is working as expected! ``` On the other hand, using `llvm-ranlib` causes the linker to fail: ``` % /opt/homebrew/opt/llvm/bin/llvm-ar qc main_llvm.a main.cpp.o && /opt/homebrew/opt/llvm/bin/llvm-ranlib main_llvm.a % /opt/homebrew/opt/llvm/bin/clang++ -arch x86_64 -arch arm64 -o main_llvm main_llvm.a ld: archive member 'main.cpp.o' not a mach-o file in '/Users/user/Documents/llvm_ranlib_issue/main_llvm.a' clang++: error: linker command failed with exit code 1 (use -v to see invocation) ``` Note that running `lipo -info` on `main_llvm.a` suggests that there is a problem with the file: ``` % lipo -info main_xcode.a Architectures in the fat file: main_xcode.a are: x86_64 arm64 % lipo -info main_llvm.a fatal error: /Library/Developer/CommandLineTools/usr/bin/lipo: archive member main_llvm.a(main.cpp.o) is a fat file (not allowed in an archive) ``` Furthermore, running `llvm-lipo` crashes on `main_llvm.a`: ``` % /opt/homebrew/opt/llvm/bin/llvm-lipo -info main_xcode.a Architectures in the fat file: main_xcode.a are: x86_64 arm64 % /opt/homebrew/opt/llvm/bin/llvm-lipo -info main_llvm.a Non-fat file: main_llvm.a is architecture: PLEASE submit a bug report to https://github.com/Homebrew/homebrew-core/issues and include the crash backtrace. Stack dump: 0. Program arguments: /opt/homebrew/opt/llvm/bin/llvm-lipo -info main_llvm.a #0 0x00000001101b5d60 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x4695d60) #1 0x00000001101b6134 SignalHandler(int) (/opt/homebrew/Cellar/llvm/18.1.8/lib/libLLVM.dylib+0x4696134) #2 0x0000000191e97584 (/usr/lib/system/libsystem_platform.dylib+0x180477584) #3 0x0000000102ab1420 (anonymous namespace)::createSliceFromIR(llvm::object::IRObjectFile const&, unsigned int) (/opt/homebrew/Cellar/llvm/18.1.8/bin/llvm-lipo+0x100009420) #4 0x0000000102ab1420 (anonymous namespace)::createSliceFromIR(llvm::object::IRObjectFile const&, unsigned int) (/opt/homebrew/Cellar/llvm/18.1.8/bin/llvm-lipo+0x100009420) #5 0x0000000102ab17b4 printBinaryArchs(llvm::LLVMContext&, llvm::object::Binary const*, llvm::raw_ostream&) (/opt/homebrew/Cellar/llvm/18.1.8/bin/llvm-lipo+0x1000097b4) #6 0x0000000102ab5434 printInfo(llvm::LLVMContext&, llvm::ArrayRef<llvm::object::OwningBinary<llvm::object::Binary>>) (/opt/homebrew/Cellar/llvm/18.1.8/bin/llvm-lipo+0x10000d434) #7 0x0000000102aad558 llvm_lipo_main(int, char**, llvm::ToolContext const&) (/opt/homebrew/Cellar/llvm/18.1.8/bin/llvm-lipo+0x100005558) #8 0x0000000102ab524c main (/opt/homebrew/Cellar/llvm/18.1.8/bin/llvm-lipo+0x10000d24c) #9 0x0000000191ade0e0 zsh: segmentation fault /opt/homebrew/opt/llvm/bin/llvm-lipo -info main_llvm.a % ``` I hit this problem while trying to build my CMake project using clang from brew (It used to work fine with Apple Clang). Currently, I have to work around this by passing `-DCMAKE_RANLIB=/Library/Developer/CommandLineTools/usr/bin/ranlib` to my CMake configuration.