CUDA linker error: undefined reference to main - linux

I'm trying to compile a CUDA program in Linux and I get the following linker error:
/usr/lib/gcc/x86_64-redhat-linux/4.4.4/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld returned 1 exit status
This is my Makefile:
mtrand.o : mtrand/mtrand.cpp
nvcc -I"./mtrand" -O2 -c mtrand/mtrand.cpp
CUDAMCMLrng.o : CUDAMCMLrng.cu
nvcc --use_fast_math -O2 -c CUDAMCMLrng.cu
kernel.o : CUDAMCMLrng.o kernel.cu
nvcc --use_fast_math -O2 -c kernel.cu
main.o : mtrand.o CUDAMCMLrng.o kernel.o main.cu
nvcc --use_fast_math -O2 -Xcompiler "-fopenmp -Wall" -c main.cu
lab : main.o mtrand.o CUDAMCMLrng.o kernel.o
nvcc -lgomp -o lab main.o mtrand.o CUDAMCMLrng.o kernel.o
The main function is in the main.cu file but for some reason the linker is not seeing it.
Could anyone please tell me what am I doing wrong?
Thanks!

I recommend doing the final linking with g++ rather than nvcc. If you only have .o files and libraries as input to the link line, I see no reason to use nvcc.

Related

How does make use variables when expanding and compiling before linking?

Info:
Linux watvde0453 3.10.0-1062.1.1.el7.x86_64 #1 SMP Fri Sep 13 22:55:44 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
GNU Make 4.2.1
Built for x86_64-pc-linux-gnu
Hi
I have been playing around with a make file to allow builds of shared, static libraries and an exe (and also to get some sort of understanding about how it works) and came across some behavior I do not understand.
I was trying to separate out the flags used for lib / exe into separate variables, but when using a line to compile and link all in one it looks like only the CFLAGS variable is being included for the compile step.
When using the following makefile:
LIBCFLAGS := -fPIC
CFLAGS := -O3 -g -Wall -Werror
CC := gcc
SRCS=hashfunction.c hashtable.c hashtablelinkedlist.c
OBJS=hashfunction.o hashtable.o hashtablelinkedlist.o
LIBSO = lib$(NAME).so
libso: $(OBJS)
$(CC) $(LIBCFLAGS) $(CFLAGS) -shared -o $(LIBSO) $(OBJS)
I get the following output when running the make command for libso:
$ make libso
gcc -O3 -g -Wall -Werror -c -o hashfunction.o hashfunction.c
gcc -O3 -g -Wall -Werror -c -o hashtable.o hashtable.c
gcc -O3 -g -Wall -Werror -c -o hashtablelinkedlist.o hashtablelinkedlist.c
gcc -fPIC -O3 -g -Wall -Werror -shared -o lib.so hashfunction.o hashtable.o hashtablelinkedlist.o
/tools/oss/packages/x86_64-centos7/binutils/default/bin/ld: hashtable.o: relocation R_X86_64_32 against `.rodata.str1.8' can not be used when making a shared object; recompile with -fPIC
hashtable.o: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
make: *** [Makefile:12: libso] Error 1
I can get it all working by sticking all the flags in CFLAGS, but I was wondering if anyone could explain what make is doing underneath ?
It looks like the $(LIBCFLAGS) is being ignored for the implicit compile lines, but $(CFLAGS) is not. Is CFALGS used implicitly by make for all compilations ?
You can see all the built-in rules make knows about by running make -p -f/dev/null. There you'll see:
%.o: %.c
# recipe to execute (built-in):
$(COMPILE.c) $(OUTPUT_OPTION) $<
which is the built-in rule make uses to create a .o file from a .c file. Looking elsewhere in the output you'll see:
COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
so these are the variables make uses to compile .c files into .o files.

ld -shared success but got a segmentation fault when run

I'm a beginner to learn the basic compiling. I create a very simple c file as below
#include <stdio.h>
int main (void) {
printf("Hello World!\n");
return 0;
}
then I run the commands,
cpp -E helloworld.c -o helloworld.i
gcc -S helloworld.i -o helloworld.s
as helloworld.s -o helloworld.o
ld -shared -o helloworld /usr/lib64/libc.so helloworld.o
in here, I got an error message like this,
ld -shared -o helloworld /usr/lib64/libc.so helloworld.o
ld: helloworld.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC
ld: final link failed: Nonrepresentable section on output
so I rerun the upper but with a -fPIC
cpp -E helloworld.c -o helloworld.i
gcc -S helloworld.i -o helloworld.s -fPIC
as helloworld.s -o helloworld.o
ld -shared -o helloworld /usr/lib64/libc.so helloworld.o
at last, I got my helloworld, but when I try ./helloworld, I got a Segmentation fault.
anyone can help? Thanks in advance!
I try the gcc helloworld.c -Wl,--verbose | grep succeeded and get some output as below,
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o succeeded
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crti.o succeeded
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o succeeded
attempt to open /tmp/ccSuIvy2.o succeeded
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc.a succeeded
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc_s.so succeeded
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libc.so succeeded
attempt to open /lib64/libc.so.6 succeeded
attempt to open /usr/lib64/libc_nonshared.a succeeded
attempt to open /lib64/ld-linux-x86-64.so.2 succeeded
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc.a succeeded
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc_s.so succeeded
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o succeeded
attempt to open /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crtn.o succeeded
but I still don't know how to do the link, I try this one
ld -shared -o helloworld /usr/lib64/libc.so /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc_s.so /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o /usr/lib64/crtn.o helloworld.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc.a /usr/lib64/libc_nonshared.a /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o
but get an error message,
ld: /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o: relocation R_X86_64_32S against undefined symbol `__libc_csu_fini' can not be used when making a shared object; recompile with -fPIC
ld: final link failed: Nonrepresentable section on output

make "cannot find libraries"

I am trying to compile til parameter estimation tool PEST (http://www.pesthomepage.org/) for linux.
According to the PEST-manual I did:
make -f pest.mak all
but I get following error message:
gfortran -c -O3 -static pestdata.for
gfortran -c -O3 -static pest.for
gfortran -c -O3 -static pestsub2.for
gfortran -c -O3 -static writall.for
gfortran -c -O3 -static pardef.for
gfortran -c -O3 -static readpest.for
gfortran -c -O3 -static runpest.for
gfortran -static -o pest \
pest.o pestsub1.o pestsub2.o dercalc.o modrun.o writall.o \
linpos.o lapack1.o writsig.o common.o \
pgetcl.o pestwait.o writint.o pardef.o\
drealrd.o space.o optwt.o cgsolve.o compress.o \
readpest.o runpest.o lsqr.o orthog.o ms_stubs.o pestdata.o
/bin/ld: cannot find -lgfortran
/bin/ld: cannot find -lm
/bin/ld: cannot find -lquadmath
/bin/ld: cannot find -lm
/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
make: *** [pest] Error 1
After goggling I have tried different things, but without results. Can somebody please help
me?
Regards Tanja
Solutions to a problem shouldn't be hidden in comments, which is why I write this answer.
The make output shows that the Makefile tries to link statically.
That requires the libraries that can be linked statically, notably libm.a, libgfortran.a, libquadmath.a and libc.a
A possible solution is to remove the -static flag in the final step.
The resulting executable will of course need the shared objects (libm.so and friends) in order to be able to run. In most situations that's not a problem though.

Undefined references to any libc symbol despite direct link with archive

I am working with the ARM-gcc cross compiler and am having issues linking to any implementation within libc.
Compiling prog.c, writing to prog.o...
~/.programs/arm-gcc/bin/arm-none-eabi-gcc -Wall -fno-common -mcpu=cortex-m4 -mthumb -O0 -g -DF_CPU=72000000 -I~/.programs/arm-gcc/arm-none-eabi/include -I../include -I. -I../src/include -c prog.c -o prog.o > prog.lst
Compiling ../common/sysinit.c, writing to sysinit.o...
~/.programs/arm-gcc/bin/arm-none-eabi-gcc -Wall -fno-common -mcpu=cortex-m4 -mthumb -O0 -g -DF_CPU=72000000 -I~/.programs/arm-gcc/arm-none-eabi/include -I../include -I. -I../src/include -c ../common/sysinit.c -o sysinit.o > sysinit.lst
Assembling ../common/crt0.s, writing to crt0.o...
~/.programs/arm-gcc/bin/arm-none-eabi-as -mcpu=cortex-m4 -o crt0.o ../common/crt0.s > crt0.lst
Compiling uart.c, writing to uart.o...
~/.programs/arm-gcc/bin/arm-none-eabi-gcc -Wall -fno-common -mcpu=cortex-m4 -mthumb -O0 -g -DF_CPU=72000000 -I~/.programs/arm-gcc/arm-none-eabi/include -I../include -I. -I../src/include -c uart.c -o uart.o > uart.lst
~/.programs/arm-gcc/bin/arm-none-eabi-ld prog.o sysinit.o crt0.o uart.o -Map=prog.map -T../common/Teensy31_flash.ld -L~/.programs/arm-gcc/arm-none-eabi/lib -o prog.elf
prog.o: In function `print_char':
/home/user/workspace/prog/src/prog.c:47: undefined reference to `sprintf'
/home/user/workspace/prog/src/prog.c:48: undefined reference to `printf'
/home/user/workspace/prog/src/prog.c:49: undefined reference to `strlen'
prog.o: In function `main':
/home/user/workspace/prog/src/prog.c:72: undefined reference to `memset'
make: *** [makefile:133: prog.elf] Error 1
I threw in a few calls to stdlib to make the point. I have tried to explicitly link against libc using -lc but am met with:
/home/prog/.programs/arm-gcc/bin/arm-none-eabi-ld: cannot find -lc
The archive directory is passed to the linker via:
L~/.programs/arm-gcc/arm-none-eabi/lib
I have checked the contents of this directory and verified the archive to be present:
$ ls ~/.programs/arm-gcc/arm-none-eabi/lib
aprofile-validation.specs libc_s.a linux.specs
aprofile-ve.specs libg.a nano.specs
armv6-m libgloss-linux.a nosys.specs
armv7-ar libg_s.a pid.specs
armv7e-m libm.a rdimon-crt0.o
armv7-m libnosys.a rdimon.specs
cpu-init librdimon.a rdpmon-crt0.o
crt0.o librdimon_s.a rdpmon.specs
fpu librdpmon.a redboot-crt0.o
iq80310.specs libstdc++.a redboot.ld
ldscripts libstdc++.a-gdb.py redboot.specs
libarm_cortexM0l_math.a libstdc++_s.a redboot-syscalls.o
libarm_cortexM4lf_math.a libsupc++.a thumb
libarm_cortexM4l_math.a libsupc++_s.a
libc.a linux-crt0.o
And, finally, the libc does export sprintf (and others)
$ nm libc.a | grep "sprintf"
...
lib_a-sprintf.o:
00000000 T sprintf
00000000 T _sprintf_r
U sprintf
U _sprintf_r
...
Info on the ARM-GCC build I am using:
$ ./arm-none-eabi-gcc -v
Using built-in specs.
COLLECT_GCC=./arm-none-eabi-gcc
COLLECT_LTO_WRAPPER=/home/user/.programs/arm-gcc/bin/../lib/gcc/arm-none-eabi/5.4.1/lto-wrapper
Target: arm-none-eabi
Configured with: /home/build/work/GCC-5-0-build/src/gcc/configure --target=arm-none-eabi --prefix=/home/build/work/GCC-5-0-build/install-native --libexecdir=/home/build/work/GCC-5-0-build/install-native/lib --infodir=/home/build/work/GCC-5-0-build/install-native/share/doc/gcc-arm-none-eabi/info --mandir=/home/build/work/GCC-5-0-build/install-native/share/doc/gcc-arm-none-eabi/man --htmldir=/home/build/work/GCC-5-0-build/install-native/share/doc/gcc-arm-none-eabi/html --pdfdir=/home/build/work/GCC-5-0-build/install-native/share/doc/gcc-arm-none-eabi/pdf --enable-languages=c,c++ --enable-plugins --disable-decimal-float --disable-libffi --disable-libgomp --disable-libmudflap --disable-libquadmath --disable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-tls --with-gnu-as --with-gnu-ld --with-newlib --with-headers=yes --with-python-dir=share/gcc-arm-none-eabi --with-sysroot=/home/build/work/GCC-5-0-build/install-native/arm-none-eabi --build=i686-linux-gnu --host=i686-linux-gnu --with-gmp=/home/build/work/GCC-5-0-build/build-native/host-libs/usr --with-mpfr=/home/build/work/GCC-5-0-build/build-native/host-libs/usr --with-mpc=/home/build/work/GCC-5-0-build/build-native/host-libs/usr --with-isl=/home/build/work/GCC-5-0-build/build-native/host-libs/usr --with-cloog=/home/build/work/GCC-5-0-build/build-native/host-libs/usr --with-libelf=/home/build/work/GCC-5-0-build/build-native/host-libs/usr --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm' --with-pkgversion='GNU Tools for ARM Embedded Processors' --with-multilib-list=armv6-m,armv7-m,armv7e-m,armv7-r,armv8-m.base,armv8-m.main
Thread model: single
gcc version 5.4.1 20160609 (release) [ARM/embedded-5-branch revision 237715] (GNU Tools for ARM Embedded Processors)
The ~ in -L~/.programs/arm-gcc/arm-none-eabi/lib doesn't get expanded. It is the shell that expands ~ into /home/user, but only when it is at the beginning of a word.
Actually, it isn't necessary to add this -L option, because this is already in gcc's default search path. However, you link directly with ld instead of with gcc. That is not a good idea. It is better to link with gcc and allow it to add the default search paths and other required libraries, like libc and libgcc. Since you supply your own crt0, add -nostartfiles to the arguments. So link with:
~/.programs/arm-gcc/bin/arm-none-eabi-gcc prog.o sysinit.o crt0.o uart.o \
-Wl,-Map=prog.map -Wl,-T../common/Teensy31_flash.ld -nostartfiles -o prog.elf

How to build a user level program in parallel with building Linux kernel

I have a set of kernel source files in ~linux/fs/wrapfs/. Besides, there is also a source file present for a user level program. I want to build that user level program while the kernel gets compiled by running "make" in ~/linux folder i.e in the top level kernel directory.
So, I tried adding following in ~/linux/fs/wrapfs/Makefile:
EXTRA_CFLAGS += prog
prog:
gcc -Wall -Werror prog.c -o prog -lssl -lcrypto
But, then everytime I do "make" in ~/linux, I get following error:
gcc: prog: No such file or directory
I then tried changing it to following but nothing helped:
EXTRA_CFLAGS += prog
all:
gcc -Wall -Werror prog.c -o prog -lssl -lcrypto
EXTRA_CFLAGS += prog
prog:
gcc -Wall -Werror ./fs/wrapfs/prog.c -o ./fs/wrapfs/prog -lssl -lcrypto
Please suggest how can this be solved.
You should not be trying to pass prog in CFLAGS, extra or otherwise.

Resources