argument unused during compilation: '-fuse-ld=lld' - linker

I have successfully built clang and lld from source, and both are now available under my .../llvm-project/build/bin directory.
Following lld documentation, I am now trying to pass -fuse-ld=lld command line directive to clang to force it to use lld instead of system's default linker (which is GNU ld if I am not mistaken) as follows:
../llvm-project/build/bin/clang -fuse-ld=lld -c test.c
But I get this warning:
clang-16: warning: argument unused during compilation: '-fuse-ld=lld' [-Wunused-command-line-argument]
Which I suppose means lld was not used as the linker despite me asking for it.
What am I doing wrong?
I am on Ubuntu 22.04.1 LTS x86_64 and I am using clang version 16.0.0 and lld 16.0.0.

What am I doing wrong?
This: clang -fuse-ld=lld -c test.c is a compilation command. It does not perform any linking.
This argument: -fuse-ld=lld is telling the compiler driver which linker to use at link time.
You told the driver:
to not do linking (the -c argument) and
to use lld for linking in the same command
The driver has no choice but to ignore your second instruction, since it's not going to do any linking, and that's what the warning is all about.
You can safely ignore this warning, but a better solution is to pass the -fuse-ld=lld argument only to the link stage, and not to any compile stages.

Related

LLD and the Linker Scripts

I am trying to send the linker scripts for one of the simple c program .
I tried on both on Ubuntu and Windows.
On Ubuntu
After some research I found out that it was taking GNU-ld ,so With clang command line option -fuse-ld=lld ,So now I linked with clang default linker lld
I tried with this command
clang main.c -ffreestanding -nostartfiles -nodefaultlibs -fuse-ld=lld -Wl,-Map,output.map,-T Example_Linker.ld -o main
Everything works correctly.
I got the memory map file and also able to pass linker scripts.
On Windows
Clang initially look for Microsoft Visual Studio Linker link.exe for to generate executables.
It wont support Linker scripts.
So with -fuse-ld=lld
I tried the below command
clang main.c -ffreestanding -nostartfiles -nodefaultlibs -fuse-ld=lld -Wl,-Map,output.map,-T Example_Linker.ld -o main
So now error thrown was
clang: error: unknown argument: '-Map'
lld-link: warning: ignoring unknown argument: -T
How should I write a command so I may be able to get a memory map file and in same time I can pass Linker Scripts?
kindly help me with solution.
The linker flags you write here:
-Wl,-Map,output.map
should be
-Wl,-Map=output.map
You have to use the same target triple as on Ubuntu.
On my Ubuntu clang outputs this information:
$ clang-8 --version
clang version 8.0.0-3~ubuntu18.04.2 (tags/RELEASE_800/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
So you would use the following on windows:
clang --target=x86_64-pc-linux-gnu main.c -ffreestanding -nostartfiles -nodefaultlibs -fuse-ld=lld -Wl,-Map=output.map,-T Example_Linker.ld -o main
I cannot try this, because I don't have a linker script.
You can try to change the target triple.

Libtool/clang: let me pass arguments to compiler but not linker

I'm obfuscating many GitHub projects with o-llvm. It's a compile time linker implemented in clang. With o-llvm, I'm trying to compile/obfuscate a GitHub project that uses libtool, but the flags needed to specify the obfuscation transform mess up the linker.
The extra flags that I'm passing in are like:
/path/to/obfuscator/clang -O0 -mllvm -bcf -mllvm -boguscf-loop=1 -mllvm -ann
-bcf means apply bogus control flow transformation, -boguscf-loop limits how many times it runs per basic block and -ann indicates to annotate the basic blocks with printf statements.
At first, I tried doing this at the make step after configure:
make CC=/path/to/obfuscator/clang CFLAGS="-O0 -mllvm -bcf -mllvm -boguscf-loop=1 -mllvm -ann
But then gcc was the linker and it failed because it did not know the "-mllvm" option. Libtool also automatically removed the "-bcf" "-boguscf-loop=1" and "-ann" options
In another project, dropping back to configure and specifying CFLAGS in CC worked:
./configure CC="/path/to/obfuscator/clang -O0 -mllvm -bcf -mllvm -boguscf-loop=1 -mllvm -ann"
This makes the "linker" be clang, which recognizes the "-mllvm" option, but libtool removing the corresponding flags still messes up the invocation:
[...] -O0 -mllvm -mllvm -mllvm -Wl,-z -Wl,defs -Wl,-soname [...]
clang: warning: argument unused during compilation: '-mllvm -bcf'
clang: warning: argument unused during compilation: '-mllvm -boguscf-loop=1'
clang: warning: argument unused during compilation: '-mllvm -ann'
clang: warning: argument unused during compilation: '-mllvm -mllvm'
clang: warning: argument unused during compilation: '-mllvm -Wl,-z'
/usr/bin/ld: error: cannot open defs: No such file or directory
I tried prepending my compiler-only arguments with -Wc,flag or -Xcompile but clang recognizes neither of those.
Is there some other way to tell Libtool or Clang to only use the obfuscation arguments for compilation and not linking?
Thank you.
I was trying to avoid this but I ended up modifying the libtool script to drop -mllvm like the other obfuscation options during linking.
sed -i "s/-m\*|/-mtune=*|-march=*|-mcpu=*|-mfpmath=*|-masm=*|-mieee-fp|-mno-ieee-fp|-msoft-float|-mno-fp-ret-in-387|-mno-fancy-math-387|-malign-double|-mno-align-double|-m96bit-long-double|-m128bit-long-double|-mlarge-data-threshold=*|-mrtd|-mregparm=*|-msseregparm|-mpc32|-mpc64|-mpc80|-mstackrealign|-mpreferred-stack-boundary=*|-mincoming-stack-boundary=*|-mmmx|-mno-mmx|-msse|-mno-sse|-msse2|-mno-sse2|-msse3|-mno-sse3|-mssse3|-mno-ssse3|-msse4.1|-mno-sse4.1|-msse4.2|-mno-sse4.2|-msse4|-mno-sse4|-mavx|-mno-avx|-maes|-mno-aes|-mpclmul|-mno-pclmul|-msse4a|-mno-sse4a|-mfma4|-mno-fma4|-mxop|-mno-xop|-mlwp|-mno-lwp|-m3dnow|-mno-3dnow|-mpopcnt|-mno-popcnt|-mabm|-mno-abm|-mfused-madd|-mno-fused-madd|-mcld|-mcx16|-msahf|-mmovbe|-mcrc32|-mrecip|-mveclibabi=*|-mabi=*|-mpush-args|-mno-push-args|-maccumulate-outgoing-args|-mthreads|-mno-align-stringops|-minline-all-stringops|-minline-stringops-dynamically|-mstringop-strategy=*|-momit-leaf-frame-pointer|-mtls-direct-seg-refs|-mno-tls-direct-seg-refs|-msse2avx|-mno-sse2avx|-m32|-m64|-mno-red-zone|-mcmodel=*|-mcmodel=*|-mcmodel=*|-mcmodel=*|/g" libtool
Basically, expand -m* with every possible value from the gcc manual, minus -mllvm which is solely a clang thing. Now I can automatically compile vlc with arbitrary invocations using different compilers as part of the Chimera corpus.

Linking with shared libraries

I'm trying to compile and link some .c file. I have been using Eclipse IDE for C/C++ developers, and in my local machine i can compile without problems. However, when i try to compile and link the same file in a RedHat OS (gcc version is 4.9.2-6 in this OS) i'm having problems. I get some warnings at compile time, but those are fine, i think, i just ignored and the application still runs fine. Here are the commands i executed and the associated output:
gcc -O0 -g3 -Wall -c -fmessage-length=0 -std=c99 -MMD -MP -MF"example.d" -MT"example.d" -o "example.o" "example.c"
warning: suggest parentheses around assignment used as truth value [-Wparentheses]
warning: implicit declaration of function ‘wait’ [-Wimplicit-function-declaration]
This generates two files, example.d and example.o. Then, i try to link them, without luck, with the following command:
gcc -Xlinker -L/usr/lib -lrt -static -pthread example.o -o example
/usr/bin/ld: cannot find -lrt
/usr/bin/ld: cannot find -lpthread
/usr/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
The commands are taken directly from the ones that Eclipse generates, and work just fine in my local computer (Ubuntu OS) but not in the RedHat environment. The last command didn't work, with and without the -L option. I suppose the directory in -L is fine, as i run, for example,
locate libpthread.so
And one of the locations i get is /usr/lib (also /usr/lib64, but neither work).
Any help will be greatly appreciated!! :)
If you try to link a static executable, it will look for the *.a versions of the libraries, not what you usually want. Remove the -static flag. Or you can install the static libraries if you really want to. It also should not be necessary to add -L/usr/lib explicitly.

Questions about "gcc: unrecognized option `-rdynamic'"

I use gcc on Solaris 10 to build make program, and get the following information:
gcc: unrecognized option `-rdynamic'
After checking the rdynamic in gcc document, I get the following explantions:
-rdynamic
Pass the flag -export-dynamic to the ELF linker, on targets that support it. This instructs the linker to add all symbols, not only used ones, to the dynamic symbol table. This option is needed for some uses of dlopen or to allow obtaining backtraces from within a program.
My questions are:
(1) Although gcc prints "gcc: unrecognized option -rdynamic", the build is still success. Is this the default behavior of gcc?
(2) I replace "-rdynamic" with "-export-dynamic" in Makefile, and the build is success. Is there any side-effect of this substitution?
P.S. My gcc information:
bash-3.00# gcc -v
Reading specs from /usr/local/lib/gcc/i386-pc-solaris2.10/3.4.6/specs
Configured with: ../configure --with-as=/usr/ccs/bin/as --with-ld=/usr/ccs/bin/ld --enable-shared --enable-languages=c,c++,f77
Thread model: posix
gcc version 3.4.6
You are using an obsolete version of gcc, but you refer to an up-to-date documentation. There is no such linker option for gcc-3.4.6, see https://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Link-Options.html.
Try using -Wl,--export-dynamic option when linking instead.
I replace -rdynamic with -export-dynamic in Makefile, and the build is success. Is there any side-effect of this substitution.
This option is not documented, it may well do nothing, you need to check strace output what command line options it passes to the linker.

intel_sse2 problems when linking to gsl with icc

My program links to both PETSc and gsl, and both libraries were compiled with icc. Here's the link command:
/usr/local/mpich2/bin/mpicc -Wall -Wwrite-strings -Wno-strict-aliasing -Wno-unknown-pragmas -g3 -I/usr/local/gsl-icc-1.15/include/ -I/usr/local/gsl-icc-1.15/include/ -L/usr/local/gsl-icc-1.15/lib/ -lgsl -lgslcblas prog_name.o -L/usr/local/petsc-3.2-p6/lib -lpetsc -lX11 -lpthread -llapack -lblas -L/central/intel/Compiler-11.1.072/mkl/lib/em64t -L/central/intel/Compiler-11.1.072/lib/intel64 -L/central/intel/Compiler-11.1.072/tbb/intel64/cc3.4.3_libc2.3.4_kernel2.6.9/lib -L/usr/lib/gcc/x86_64-redhat-linux/4.1.2 -ldl -lgcc_s -lifport -lifcore -limf -lsvml -lm -lipgo -lirc -lpthread -lirc_s -lm -lstdc++ -lstdc++ -ldl -lgcc_s -ldl -o prog_name
MPICH_CC is set to icc, so mpicc calls the intel compiler.
When I try to link to the gsl .so file, I get the following errors:
gsl-icc-1.15/lib/libgsl.so: undefined reference to `__intel_sse2_strcpy'
gsl-icc-1.15/lib/libgsl.so: undefined reference to `__intel_sse2_strchr'
gsl-icc-1.15/lib/libgsl.so: undefined reference to `__intel_sse2_strncpy'
What could be the cause of this error? Is gsl incompatible with the intel compiler?
What could be the cause of this error?
You didn't show us your link command, but my crystall ball tells me that you are trying to link libgsl.so with ld (or perhaps with gcc), instead of icc.
In general, one should never link anything directly with ld on UNIX. Always use appropriate compiler driver (icc in this case).
I also get the same error message when linking some code with gcc against a PETSc version that was compiled with icc. Even more, when using the newest Intel 12.x compiler for the final code, and compiling PETSc with Intel 11.x results in the same error message as Intel 12.x uses 11.x.
So check, that mpicc really use the Intel 11.1.072 compiler. Check for mpic++ -show and which icc.
Maybe the intel environment not set.
Try the following environment setting:
source /etc/Intel_Compiler/10.0/XXXX/iccvars_intel64.sh
source /etc/Intel_Compiler/10.0/XXXX/ifortvars_intel64.sh
make the folder to your Intel Compiler folder. Some version's environment setting is different, you can also try:
source /etc/Intel_Compiler/10.0/XXXX/iccvars.sh intel64
source /etc/Intel_Compiler/10.0/XXXX/ifortvars.sh intel64
Hope helpfully.

Resources