cannot find -lcuda when linking with g++ - c

I'm trying to link these object files with the command:
g++ NT_FFT_Decomp.o T_FFT_Decomp.o SNT_FFT_Comp.o ST_FFT_Comp.o VNT_FFT_Comp.o VT_FFT_Comp.o CUDA_FFT_Comp.o Globals.o main.o \
-L/media/wiso/Programs/Setups/CUDA/include -lcuda -lcudart -lpthread -o DevicesTest
/media/wiso/Programs/Setups/CUDA
is my cuda installation directory.
and my LD_LIBRARY_PATH is like this :
Irrelevant:/media/wiso/Programs/Setups/CUDA/lib64:/media/wiso/Programs/Setups/CUDA/lib:Irrelevant
the command gives this error message:
/usr/bin/ld: cannot find -lcuda
/usr/bin/ld: cannot find -lcudart
removing -lcuda and -lcudart generates undefined reference to cuda functions errors.
how can I link this properly ??

You need to add the compiler switch:
-L/usr/local/cuda/lib64
or something similar, to tell g++ where to find the -lcuda and -lcudart libraries.
In your case, the line is probably:
-L/media/wiso/Programs/Setups/CUDA/lib64
instead of the existing statement that you have. (change include to lib64 or possibly lib)
Again, LD_LIBRARY_PATH has nothing to do with compiling and linking.

-L/media/wiso/Programs/Setups/CUDA/include // WRONG: "-L" is for libraries ... but "/include" is usually for headers
SUGGESTED CHANGE: -L/media/wiso/Programs/Setups/CUDA/lib64
COMPLETE LINK LINE:
g++ NT_FFT_Decomp.o \
T_FFT_Decomp.o \
SNT_FFT_Comp.o \
ST_FFT_Comp.o \
VNT_FFT_Comp.o \
VT_FFT_Comp.o \
CUDA_FFT_Comp.o \
Globals.o main.o \
-L/media/wiso/Programs/Setups/CUDA/lib64 -lcuda -lcudart -lpthread \
-o DevicesTest

Related

Compiling CUDA code while linking a static library

I have C code main_code.c and helper_code.c. The former depends on some CUDA code cuda_code.cu and the latter on an external library mylib. For my external library mylib to work, I need to link it to my code with the -static flag:
g++ main_code.c helper_code.c -o main_code -static -L/usr/local/mylib/lib -lmylib -lmylib2
But main_code.c also depends on CUDA code- cuda_code.cu. I can link it with:
nvcc cuda_code.cu -c
g++ main_code.c -o main_code cuda_code.o -L/usr/local/cuda-10.0/lib64 -lcudart -lpthread
I want to compile my code together with the CUDA code and the external library mylib. However, linking mylib works only with the -static flag. A naive attempt would be the following but it does not work:
nvcc cuda_code.cu -c
g++ main_code.c helper_code.c -o main_code cuda_code.o -static -L/usr/local/mylib/lib -lmylib -lmylib2 -L/usr/local/cuda-10.0/lib64 -lcudart -lpthread
This gives the error:
/usr/bin/ld: cannot find -lcudart
which I'm assuming is because you cannot use the static flag while linking with CUDA (because it goes away when I remove the -static flag (in addition to also removing the mylib library linking)).
I then tried compiling helper_code.c separately and then linking it to main_code.c since it's just helper_code.c that needs mylib:
helper.o:
g++ helper_code.c -c -static -L/usr/local/mylib/lib -lmylib -lmylib2
cuda-code.o:
nvcc cuda_code.cu -c
main-code: helper.o cuda-code.o
g++ main_code.c -o main_code helper_code.o cuda_code.o -L/usr/local/cuda-10.0/lib64 -lcudart -lpthread
But this also does not work. I get an undefined reference error that's referring to a function defined in mylib, meaning the linking to mylib isn't working. I can resolve that error by including the mylib library and using the -static flag but that then breaks the CUDA linking.
I can separately get the CUDA linking (to cuda_code.cu) to work or mylib linking to work but not both at the same time.
So is there a workaround to link mylib (which needs -static) while at the same time also linking my CUDA code (which does not allow -static)?
Following the answer linked in talonmies's comment, the following did the trick:
g++ main_code.c -o main_code helper_code.o cuda_code.o -L/usr/local/mylib/lib -L/usr/local/cuda-10.0/lib64 -Wl,-Bstatic -lmylib -lmylib2 -Wl,-Bdynamic -lcudart

compiling /usr/bin/ld undefined reference to XMapSubwindows and DSO missing from command line

I'm trying to compile my patched dwm on Debian.
This is my config.mk file, it's mostly the one from apt source dwm but the patches added some extra libraries, and I had to add the two -Ifreetype2 links myself:
# dwm version
VERSION = 6.1
# Customize below to fit your system
# paths
PREFIX = /usr/local
MANPREFIX = ${PREFIX}/share/man
# Xinerama, comment if you don't want it
XINERAMALIBS = -lXinerama
XINERAMAFLAGS = -DXINERAMA
# freetype
FREETYPELIBS = -lfontconfig -lXft
FREETYPEINC = /usr/include/freetype2
# OpenBSD (uncomment)
#FREETYPEINC = ${X11INC}/freetype2
# includes and libs
INCS = -I${X11INC} -I${FREETYPEINC} -I/usr/include/freetype2 -I/usr/include/libpng16
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} -lXrender -lX11-xcb -lxcb -lxcb-res
# flags
CPPFLAGS += -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
CFLAGS += -std=c99 -pedantic -Wall -Wno-deprecated-declarations ${INCS} ${CPPFLAGS}
LDFLAGS += -s ${LIBS}
# Solaris
#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
#LDFLAGS = ${LIBS}
# compiler and linker
CC = cc
This is the error I get when running make clean install
cc -o dwm drw.o dwm.o util.o -s -L -lX11 -lXinerama -lfontconfig -lXft -lXrender -lX11-xcb -lxcb -lxcb-res
/usr/bin/ld: dwm.o: undefined reference to symbol 'XMapSubwindows'
/usr/bin/ld: //lib/x86_64-linux-gnu/libX11.so.6: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
make: *** [Makefile:29: dwm] Error 1
But I have no idea how to fix this. Do I need a library installed? do I need to add somthing to the libs variable? please help!
I have tried looking at this, but I have no idea what a "DSO" is, nor how to fix the linkage.
Not sure if it's the only problem but your link line...
cc -o dwm drw.o dwm.o util.o -s -L -lX11 -lXinerama -lfontconfig -lXft -lXrender -lX11-xcb -lxcb -lxcb-res
appears to have a -L option with no parameter. Or, perhaps more correctly, it will assume that its parameter is -lX11. I'm assuming this is because the variable X11LIB is unspecified in your makefile. Not sure exactly how X11LIB is supposed to be specified with the makefile you're using but you could try setting it explicitly...
X11LIB := /usr/lib64 # Assumes the path to libX11.so is /usr/lib64/libX11.so
-L -lX11
This means "add a directory named -lX11 to the library search path". This is unlikely to have any effect as such directory probably does nit exist.
Remove -L or add a non-empty directory argument after it.

Fail to create an executable file linking a static library

In folder test, I create hello.h,hello.c,main.c.
My goal is to create a static lib from hello.h, hello.c and an executable file from the library and main.c.
The following is what I have done.
hello.h:
#ifndef HELLO_H
#define HELLO_H
void hello(const char* name);
#endif
hello.c:
#include <stdio.h>
void hello(const char* name){
printf("hello %s! \n",name);
}
main.c:
#include "hello.h"
int main(){
hello("everyone");
return 0;
}
In the terminal (in the test folder): I run
gcc -c hello.c
ar crv libmyhello.a hello.o // to create a staticlib
gcc -c main.c
ld -o Cuteee hello.o -lmyhello
>>> ld: cannot find -lmyhello
I wonder if anything is wrong?
You need to provide -L to let gcc know where to look for your -l libraries:
gcc -c hello.c
ar crv libmyhello.a hello.o
gcc -c main.c
gcc main.o -L. -lmyhello -o Cuteee
To create the final executable it's enough to use gcc, ld is not needed.
See this question in order to understand why you probably don't need to use ld specifically.
This takes account of your comments:
Then I tried ld -o Cuteee main.o -L. -lmyhello but still fails with ld: warning: cannot find entry symbol _start; defaulting to 00000000004000b0 ./libmyhello.a(hello.o): In function 'hello': hello.c:(.text+0x1e): undefined reference to 'printf' I am puzzled again.
gcc is the GCC tooldriver for compiling and linking C programs.
When you invoke it with options and inputs that signify you want to a compile a C
source file, say hello.c, it first invokes the GNU C compiler, cc1, to compile hello.c
file to a temporary assembly file, say /tmp/cc8bfSqS.s. It quietly adds to the compiler commandline
various boilerplate options that are invariant for compiling C
on your system, to spare you the trouble.
Then it invokes the GNU assembler, as, to assemble /tmp/cc8bfSqS.s to the object file
hello.o.
You can pick out all of this from the compilation output if you ask gcc to be verbose,
e.g.
gcc -v -c hello.c
When you invoke gcc with options and inputs that signify you want to link
object files and possibly libraries into a program or shared library,
it invokes the GCC internal tool collect2 to do it - which
in turn invokes the system linker ld - and gcc quietly adds to the commandline
many boilerplate options, libraries and object files that are always
required for linking a C language program or shared library, once again to
spare you trouble.
You have used gcc to compile hello.c and main.c and allowed it to Do The Right
Thing behind the scenes. You haven't attempted to invoke cc1 and as yourself.
But in contrast, when you come to link your program, you haven't used gcc; you've
invoked ld yourself, without any of the boilerplate additions to the
the commandline that gcc would make. That's why the linkage fails.
If you link your program with gcc in verbose mode:
gcc -v -o Cuteee main.o -L. -lhello
you can pick the collect2 commandline out of the output, something like:
/usr/lib/gcc/x86_64-linux-gnu/7/collect2 \
-plugin /usr/lib/gcc/x86_64-linux-gnu/7/liblto_plugin.so \
-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper \
-plugin-opt=-fresolution=/tmp/ccgWPdno.res \
-plugin-opt=-pass-through=-lgcc \
-plugin-opt=-pass-through=-lgcc_s \
-plugin-opt=-pass-through=-lc \
-plugin-opt=-pass-through=-lgcc \
-plugin-opt=-pass-through=-lgcc_s \
--sysroot=/ --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu \
--as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 \
-pie -z now -z relro -o Cuteee \
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o \
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o \
/usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o -L. \
-L/usr/lib/gcc/x86_64-linux-gnu/7 \
-L/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu \
-L/usr/lib/gcc/x86_64-linux-gnu/7/../../../../lib \
-L/lib/x86_64-linux-gnu -L/lib/../lib \
-L/usr/lib/x86_64-linux-gnu \
-L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/7/../../.. \
main.o -lhello -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc \
--as-needed -lgcc_s --no-as-needed \
/usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o \
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o
All of those options that are passed to collect2 are passed through to
ld. So if you replace /usr/lib/gcc/x86_64-linux-gnu/7/collect2 with
ld in that monster commandline (or rather the commandline you get on
your own system), you will find that it links your program ./Cuteee.
That is what linking the program with gcc does, over an above:
ld -o Cuteee hello.o -lmyhello
One of the errors that your linkage attempt fails on:
cannot find entry symbol _start
is due to the fact that you haven't linked Scrt1.o (/usr/lib/x86_64-linux-gnu/Scrt1.o,
in the commandline above) which contains the C runtime initialization code for
a dynamically linked C program: it defines the symbol _start, whose address is the entry point of the program,
to which the loader passes initial control at runtime, and after program initialization
is complete it calls main.
The other linkage error:
undefined reference to 'printf
is due to the fact that you haven't linked the standard C library, -lc
(/lib/x86_64-linux-gnu/libc.so.6).
Programmers don't link with ld directly if they don't have to - e.g.
unless they're targeting an application to a bare-metal environment, and you
can see why.
the following proposed code:
corrects several problems in the posted code and in the command line statements.
performs the desired operation
cleanly compiles/links
And now the proposed changes to the posted code and command line statements:
hello.h
#ifndef HELLO_H
#define HELLO_H
void hello( const char* );
#endif
=======================
hello.c:
#include <stdio.h>
#include "hello.h"
void hello(const char* name)
{
printf("hello %s! \n",name);
}
========================
main.c:
#include "hello.h"
int main( void )
{
hello("everyone");
return 0;
}
=========================
In terminal (in test folder):
gcc -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c hello.c -o hello.o -I.
ar crv libmyhello.a hello.o
=========================
gcc -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c main.c -o main.o -I.
ld -static main.o -o Cuteee -L. -lmyhello
=========================
./Cuteee
=========================
this should eliminate the error message:
>>> ld: cannot find -lmyhello

How to set gcc RPATH without including any build paths?

I need to build a wget incomplete executable using gcc for RHEL4 that will use a specific OpenSSL shared lib. LD_LIBRARY_PATH is unset at build time.
This is quite simple by specifying:
LDFLAGS="-W1,-rpath=/usr/local/ssl/lib -L/my_build_dir/usr/local/ssl/lib"
and all is good.
But this makes the RPATH in the dynamic section of my incomplete executable:
Library rpath: [/usr/local/ssl/lib:/my_build_dir/usr/local/ssl/lib]
Is it possible using the gcc toolchain to set the RPATH to only use what is specified using the -rpath option and to ignore all library paths declared at build time?
I have looked at many SO posts today incl.:
I don't understand -Wl,-rpath -Wl, , and
What's the difference between -rpath and -L?
but nothing seems to address the issue of removing build info from the final incomplete executable.
EDIT: Here is the full command line for the final link phase.
gcc -Wall -std=c99 -m32 -march=athlon -mfpmath=sse -msse2 -O2 -pipe -s \
-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -m32 -march=athlon \
-mfpmath=sse -msse2 -O2 -pipe -s -Wl,-rpath,/usr/local/ssl/lib \
-L/my_build_dir/usr/local/ssl/lib -o wget cmpt.o connect.o convert.o \
cookies.o ftp.o css_.o css-url.o ftp-basic.o ftp-ls.o hash.o host.o \
html-parse.o html-url.o http.o init.o log.o main.o netrc.o progress.o \
ptimer.o recur.o res.o retr.o spider.o url.o warc.o utils.o exits.o
build_info.o iri.o version.o ftp-opie.o openssl.o http-ntlm.o \
../lib/libgnu.a /my_build_dir/usr/local/ssl/lib/libssl.so \
/my_build_dir/usr/local/ssl/lib/libcrypto.so -Wl,-rpath \
-Wl,/my_build_dir/usr/local/ssl/lib -ldl -lz -lidn -luuid -lrt
Thanks to the comments of nos and keltar below I can see where the issue is.
Now to work out why configure finishes up specifying the two openssl libs with their fullpath.
EDIT 2: Just to confirm that that the -rpath and -L option are working correctly.
If I rewrite the above command to remove the hard references to the build location of the openssl libs then RPATH in the incomplete executable is set to just /usr/local/ssl/lib.
Full edited command is:
gcc -Wall -std=c99 -m32 -march=athlon -mfpmath=sse -msse2 -O2 -pipe -s \
-D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -m32 -march=athlon \
-mfpmath=sse -msse2 -O2 -pipe -s -Wl,-rpath,/usr/local/ssl/lib \
-L/my_build_dir/usr/local/ssl/lib -o wget cmpt.o connect.o convert.o \
cookies.o ftp.o css_.o css-url.o ftp-basic.o ftp-ls.o hash.o host.o \
html-parse.o html-url.o http.o init.o log.o main.o netrc.o progress.o \
ptimer.o recur.o res.o retr.o spider.o url.o warc.o utils.o exits.o \
build_info.o iri.o version.o ftp-opie.o openssl.o http-ntlm.o \
../lib/libgnu.a -lssl -lcrypto -ldl -lz -lidn -luuid -lrt

usage: cc [ options] files. Use 'cc -flags' for details

I have a makefile. When I run it on Unix I get this error:
cc -I/opt/oracle/product/9.2.0/rdbms/demo -I/opt/oracle/product/9.2.0/rdbms/public \
-I/opt/oracle/product/9.2.0/plsql/public \
-I/opt/oracle/product/9.2.0/network/public -I../common -I../include -I. \
-L/opt/oracle/product/9.2.0/lib -L/opt/oracle/product/9.2.0/rdbms/lib -L../../lib \
-g -errwarn=%all -Xt -lclntsh -ldl -Bstatic -lclient9 -lvsn9 -lcommon9 -lgeneric9 \
-lmm -lcore9 -lnls9 -lwssmbx -ldes -lnsl -lsocket -lgen -lm -o bessToWss
usage: cc [ options] files. Use 'cc -flags' for details
*** Error code 1
What does "usage: cc [ options] files. Use 'cc -flags' for details" mean?
I'm not sure why I get the error because I do use cc -flags:
$(TARGET_DIR)/bessToWss: $(INTFOBJS)
cc $(CFLAGS) $(INTFOBJS) $(OCISHAREDLIBS) -o $#
EDIT: Adding my entire makefile
ORACLE_HOME=/opt/oracle/product/9.2.0
COMMON_SRC=../common
BNS_INCLUDE=../include
LIBHOME=$(ORACLE_HOME)/lib/
RDBMSLIB=$(ORACLE_HOME)/rdbms/lib/
WSSLIBS =-lwssmbx -ldes
LLIBRDBMS_CLT =-lclient9 -lvsn9 -lcommon9 -lgeneric9 -lmm
LLIBCLNTSH =-lclntsh -ldl
CORELIBS =-lcore9 -lnls9
LDLIBS =-lnsl -lsocket -lgen -lm
EXSYSLIBS =-R $(ORACLE_HOME)/lib
STATICTTLIBS =$(LLIBRDBMS_CLT) $(CORELIBS) $(WSSLIBS) $(LDLIBS)
OCISHAREDLIBS =$(LLIBCLNTSH) -Bstatic $(STATICTTLIBS)
LDFLAGS =-L$(ORACLE_HOME)/lib -L$(ORACLE_HOME)/rdbms/lib -L../../lib
INCLUDE =-I$(ORACLE_HOME)/rdbms/demo -I$(ORACLE_HOME)/rdbms/public -I$(ORACLE_HOME)/plsql/public -I$(ORACLE_HOME)/network/public -I$(COMMON_SRC) -I$(BNS_INCLUDE) -I.
CFLAGS =$(INCLUDE) $(LDFLAGS) -g -errwarn=%all -Xt
BESSOBJS=bessToWss.o
COMMONLIST=$(COMMON_SRC)/oracle.c \
$(COMMON_SRC)/logger.c
INTFOBJS=$(BESSOBJS) $(COMMONLIST)
$(TARGET_DIR)/bessToWss: $(INTFOBJS)
cc $(CFLAGS) $(INTFOBJS) $(OCISHAREDLIBS) -o $#
clean:
$(RM) *.o
It means you have an invalid compiler option on the command line. It might be that you are using the 'wrong' compiler (maybe GCC instead of Sun's compiler, for example). The probable problem options I see are:
-Xt
-errwarn=%all
and maybe (but probably not)
-Bstatic
The others would not lead to usage errors like that.
(NB: It would help to identify the machine and the compiler you are using, and the compiler Oracle expects you to use.)
It looks like you don't have any object files to actually link together. The $(INTFOBJS) variable is likely empty. Along with potentially having the wrong flags, this would also cause it to fail.

Resources