无法使用 Clang-14 编译 C++ 程序

Jos*_*inn 0 c++ linux clang clang++ llvm-ir

scons我目前正在尝试编译一个我一直在使用 Clang 编写的小程序,并且在使用构建系统进行编译时出现以下错误:

/usr/bin/clang++ -o src/PluGen/main.o -c -std=c++17 -fPIC -I. -O2 -fno-strict-aliasing -fpermissive -fopenmp --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security -fpermissive -fPIC -I. -O2 -flto -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -DHAVE_PYTHON -D_REENTRANT -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DLARGE_SOURCE -D_FILE_OFFSET_BITS=64 -DHAVE_PERL -DREENTRANT -DHAVE_R -I/usr/include -I/usr/local/include -Isrc -I/usr/include/python3.10 -I/usr/lib/perl5/5.36/core_perl/CORE -I/usr/include/R -I/usr/lib/R/library/Rcpp/include -I/usr/lib/R/library/RInside/include -I/usr/lib/R/site-library/RInside/include -I/usr/lib/R/site-library/Rcpp/include -I/usr/local/lib/R/library/Rcpp/include -I/usr/local/lib/R/library/RInside/include -I/usr/local/lib/R/site-library/RInside/include -I/usr/local/lib/R/site-library/Rcpp/include -I/usr/local/lib/R/site-library/RInside/lib src/PluGen/main.cxx
...
/usr/bin/clang++ -o PluGen/plugen -rdynamic -Wl,-E -Wl,-rpath,/usr/lib/perl5/5.36/core_perl/CORE -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now src/PluGen/main.o src/PluGen/PluginGenerator.o -L/lib -L/usr/lib -L/usr/local/lib -L/usr/lib/perl5/5.36/core_perl/CORE -L/usr/lib/R/lib -L/usr/lib/R/library/RInside/lib -L/usr/lib/R/site-library/RInside/lib -L/usr/local/lib/R/library/RInside/lib -L/usr/local/lib/R/site-library/RInside/lib -Llib -lc -lc++ -lstdc++fs
src/PluGen/main.o: file not recognized: file format not recognized
clang-14: error: linker command failed with exit code 1 (use -v to see invocation)
Run Code Online (Sandbox Code Playgroud)

main.o正在生成为 IR 位码

file src/PluGen/main.o
src/PluGen/main.o: LLVM IR bitcode
Run Code Online (Sandbox Code Playgroud)

在构建器外部运行链接器scons会产生以下消息:

clang version 14.0.6
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-pc-linux-gnu/12.1.0
Found candidate GCC installation: /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.1.0
Selected GCC installation: /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.1.0
Candidate multilib: .;@m64
Candidate multilib: 32;@m32
Selected multilib: .;@m64
 "/usr/bin/ld" -pie -export-dynamic --eh-frame-hdr -m elf_x86_64 -export-dynamic -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o PluGen/plugen /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../lib64/Scrt1.o /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../lib64/crti.o /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.1.0/crtbeginS.o -L/lib -L/usr/lib -L/usr/local/lib -L/usr/lib/perl5/5.36/core_perl/CORE -L/usr/lib/R/lib -L/usr/lib/R/library/RInside/lib -L/usr/lib/R/site-library/RInside/lib -L/usr/local/lib/R/library/RInside/lib -L/usr/local/lib/R/site-library/RInside/lib -Llib -L/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.1.0 -L/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/bin/../lib -L/lib -L/usr/lib -E -rpath /usr/lib/perl5/5.36/core_perl/CORE -O1 --sort-common --as-needed -z relro -z now src/PluGen/main.o src/PluGen/PluginGenerator.o -lc -lc++ -lstdc++fs -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.1.0/crtendS.o /usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/12.1.0/../../../../lib64/crtn.o
src/PluGen/main.o: file not recognized: file format not recognized
Run Code Online (Sandbox Code Playgroud)

程序使用 GCC 正确编译。只是不和 Clang 在一起。

到底是怎么回事?

n. *_* m. 5

您在编译时使用-flto,但在链接时不使用。clang不能那样做。-c -flto编译为链接器无法直接使用的 LLVM IR 位码。您应该要么到处使用-flto它,要么到处使用它。

$ clang++ -flto -c hello.cpp
$ file hello.o
hello.o: LLVM IR bitcode
$ clang++ -o hello hello.o && echo Ok
hello.o: file not recognized: file format not recognized
clang: error: linker command failed with exit code 1 (use -v to see invocation)
$ clang++ -o hello hello.o -flto && echo Ok
Ok
Run Code Online (Sandbox Code Playgroud)

gcc工作方式不同。它编译为“胖对象”,其中包含机器代码和内部编译器表示。链接器可以使用它们,并自动应用 LTO 插件。

$ g++ -c hello.cpp -flto
$ file hello.o
hello.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
$ g++ -o hello hello.o && echo Ok
Ok
Run Code Online (Sandbox Code Playgroud)