Joseph Quinn
Joseph Quinn

Reputation: 142

Unable to compile C++ program with Clang-14

I am currently trying to compile a small program I have been working on with Clang and am getting the following error on compilation using scons as the build system:

/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)

main.o is being generated as a IR bitcode

file src/PluGen/main.o
src/PluGen/main.o: LLVM IR bitcode

Running the linker outside of the scons builder yields the following message:

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

The program does compile correctly using GCC. Just not with Clang.

What is going on?

Upvotes: 0

Views: 1736

Answers (1)

n. m. could be an AI
n. m. could be an AI

Reputation: 119877

You are using -flto when compiling, but not when linking. clang can't do that. -c -flto compiles to LLVM IR bitcodes which the linker cannot use directly. You should either drop -flto everywhere, or use it everywhere.

$ 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

gcc works differently. It compiles to "fat objects" with both machine code and internal compiler representation baked in. Linker can use these, and apply the LTO plugin automatically.

$ 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

Upvotes: 5

Related Questions