我是一个SUSE Leap 15虚拟机,并且由zypper安装了clang5,我想编译一个必须编译为32位的软件,但似乎clang不会用-m32编译一个简单的例子。 (安装了必要的32位库)。
我正在尝试编译此文件:
#include <iostream>
int main()
{
auto x = 2;
std::cout << x << std::endl;
}
使用以下命令(没有-m32可以正常工作):
clang ++ main.cpp -o alma -std = c ++ 17 -m32 -v
clang version 5.0.1 (tags/RELEASE_501/final 312548)
Target: i386-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib64/gcc/x86_64-suse-linux/7
Found candidate GCC installation: /usr/lib64/gcc/x86_64-suse-linux/7
Selected GCC installation: /usr/bin/../lib64/gcc/x86_64-suse-linux/7
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Selected multilib: 32;@m32
"/usr/bin/clang-5.0.1" -cc1 -triple i386-unknown-linux-gnu -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -discard-value-names -main-file-name main.cpp -mrelocation-model static -mthread-model posix -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -fuse-init-array -target-cpu i586 -v -dwarf-column-info -debugger-tuning=gdb -resource-dir /usr/lib64/clang/5.0.1 -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/7/../../../../include/c++/7 -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/7/../../../../include/c++/7/x86_64-suse-linux/32 -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/7/../../../../include/c++/7/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/5.0.1/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/martonka/test -ferror-limit 19 -fmessage-length 227 -fobjc-runtime=gcc -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -o /tmp/main-d5b20e.o -x c++ main.cpp
clang -cc1 version 5.0.1 based upon LLVM 5.0.1 default target x86_64-unknown-linux-gnu
ignoring nonexistent directory "/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/bin/../lib64/gcc/x86_64-suse-linux/7/../../../../include/c++/7
/usr/bin/../lib64/gcc/x86_64-suse-linux/7/../../../../include/c++/7/x86_64-suse-linux/32
/usr/bin/../lib64/gcc/x86_64-suse-linux/7/../../../../include/c++/7/backward
/usr/local/include
/usr/lib64/clang/5.0.1/include
/usr/include
End of search list.
"/usr/bin/ld" -z relro --hash-style=gnu --hash-style=both --build-id --enable-new-dtags --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o alma /usr/bin/../lib64/gcc/x86_64-suse-linux/7/../../../crt1.o /usr/bin/../lib64/gcc/x86_64-suse-linux/7/../../../crti.o /usr/bin/../lib64/gcc/x86_64-suse-linux/7/32/crtbegin.o -L/usr/bin/../lib64/gcc/x86_64-suse-linux/7/32 -L/usr/bin/../lib64/gcc/x86_64-suse-linux/7 -L/usr/bin/../lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/lib -L/usr/bin/../lib64/gcc/x86_64-suse-linux/7/../../.. -L/usr/bin/../lib -L/lib -L/usr/lib /tmp/main-d5b20e.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/bin/../lib64/gcc/x86_64-suse-linux/7/32/crtend.o /usr/bin/../lib64/gcc/x86_64-suse-linux/7/../../../crtn.o
/usr/bin/ld: skipping incompatible /usr/bin/../lib64/gcc/x86_64-suse-linux/7/../../../libm.so when searching for -lm
/usr/bin/ld: skipping incompatible /usr/bin/../lib64/gcc/x86_64-suse-linux/7/../../../libc.so when searching for -lc
/usr/bin/ld: i386:x86-64 architecture of input file `/usr/bin/../lib64/gcc/x86_64-suse-linux/7/../../../crt1.o' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file `/usr/bin/../lib64/gcc/x86_64-suse-linux/7/../../../crti.o' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file `/usr/bin/../lib64/gcc/x86_64-suse-linux/7/../../../crtn.o' is incompatible with i386 output
clang-5.0.1: error: unable to execute command: Segmentation fault (core dumped)
clang-5.0.1: error: linker command failed due to signal (use -v to see invocation)
&#34; g ++ main.cpp -o alma -std = c ++ 17 -m32&#34;工作正常。
似乎问题是clang将64位版本的crtn.o,crti.o和crt1.o传递给了ld。 如果我只是编译一个目标文件: clang ++ main.cpp -std = c ++ 17 -c -o alma.o 然后执行上面的链接器命令,修复crtn.o,crti.o和crt1.o路径,然后就可以了。
看起来clang认为g ++在/ usr / lib /下(在ubuntu,centos上都是如此,但在suse上却没有),它只是添加../../../来到达32位库,这显然是错误的。
如何解决这个问题?
更新:再多搜索一下
这是一个开放的suse bug:bugzilla.suse.com/show_bug.cgi?id=1051881#c4
一个开放的llvm bug:bugs.llvm.org/show_bug.cgi?id=12108
在第二个中,有一个解决方法:
cd /usr/lib64/gcc/x86_64-suse-linux/7/32
ln -s /usr/lib/crt1.o
ln -s /usr/lib/crti.o
ln -s /usr/lib/crtn.o
但是clang仍然发出警告:
/usr/bin/ld: skipping incompatible /usr/bin/../lib64/gcc/x86_64-suse-linux/7/../../../libm.so when searching for -lm
/usr/bin/ld: skipping incompatible /usr/bin/../lib64/gcc/x86_64-suse-linux/7/../../../libc.so when searching for -lc
有没有更好的解决方案?