I'm building a Makefile for a libpcap-based program. This Makefile will be used to compile the program in the OpenWrt SDK and then transfer the executable to my router. This is the Makefile:
path = /home/foo/Desktop/sdk/openwrt-sdk-18.06.4-x86-64_gcc- 7.3.0_musl.Linux-x86_64/staging_dir/target-x86_64_musl/usr/lib
pcap_retrans: pcap_retrans.o
$(CC) $(LDFLAGS) -o pcap_retrans pcap_retrans.o -L$(path) -lpcap -L -libc
pcap_retrans.o: pcap_retrans.c
$(CC) $(CFLAGS) -c pcap_retrans.c cbuffer.c
However, the following errors appear when I "make":
cc -c pcap_retrans.c cbuffer.c
cc -o pcap_retrans pcap_retrans.o -L/home/inesmll/Desktop/sdk/openwrt-sdk-18.06.4-x86-64_gcc-7.3.0_musl.Linux-x86_64/staging_dir/target-x86_64_musl/usr/lib -lpcap -L -libc
/usr/bin/ld: warning: libc.so, needed by
/home/inesmll/Desktop/sdk/openwrt-sdk-18.06.4-x86-64_gcc-7.3.0_musl.Linux-x86_64/staging_dir/target-x86_64_musl/usr/lib/libpcap.so, not found (try using -rpath or -rpath-link)
pcap_retrans.o: In function `got_packet':
pcap_retrans.c:(.text+0x30a): undefined reference to `cbuffer_put'
pcap_retrans.c:(.text+0x334): undefined reference to `cbuffer_getretrans'
pcap_retrans.c:(.text+0x364): undefined reference to `cbuffer_getnumretrans'
pcap_retrans.o: In function `main':
pcap_retrans.c:(.text+0x818): undefined reference to `cbuffer_init'
pcap_retrans.c:(.text+0x87c): undefined reference to `cbuffer_free'
/usr/bin/ld: pcap_retrans: hidden symbol `atexit' in /usr/lib/x86_64-linux-gnu/libc_nonshared.a(atexit.oS) is referenced by DSO
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
Makefile:4: recipe for target 'pcap_retrans' failed
make: *** [pcap_retrans] Error 1
I believe it has to do with the way I'm linking the cbuffer.c in the Makefile (this file is in the same folder as pcap_retrans.c), however I don't know how to fix it. Any ideas?
$(CC) $(CFLAGS) -c pcap_retrans.c cbuffer.c looks suspect.
You may like to compile pcap_retrans.c and cbuffer.c into separate object files. And make pcap_retrans depend on pcap_retrans.o and cbuffer.o. E.g.
pcap_retrans: pcap_retrans.o cbuffer.o
$(CC) $(LDFLAGS) -o $# $^ -L$(path) -lpcap
%.o: %.c
$(CC) -c $(CFLAGS) -o $# $<
Just realized that -libc actually links a library called libibc.so or libibc.a, not the standard C library. If that library is in directory <dir>, you can link it in a couple of ways:
Pass the full path to the library in the linker command, e.g. $(CC) $(LDFLAGS) -o $# $^ -L$(path) -lpcap <dir>/libibc.so.
Specify the linker paths in the linker command, e.g. $(CC) $(LDFLAGS) -o $# $^ -L$(path) -lpcap -L<dir> -Wl,-rpath=<dir> -libc. You can specify multiple -Wl,-rpath= and this is where ld.so (the runtime dynamic linker) will search for libibc.so at run-time.
Related
I'm trying to make a program using the ncurses library, but for some reason when I try to compile using my Makefile it says there's an error in the Makefile and all of the functions from ncurses are undefined. I included the library in the main.c file correctly since when I compile using gcc main.c -lncurses the program works correctly and doesn't give any errors or say that anything is undefined. I've tried messing around with the Makefile and I can't get it to work properly, does anyone have a solution?
Makefile:
CC = gcc
CFLAGS = -Wall --std=c99 -g
LDFLAGS = -lncurses
OBJECTS = main.o
ALL: space_invaders
space_invaders: $(OBJECTS)
$(CC) $(CFLAGS) -o space_invaders $(OBJECTS)
main.o: main.c
$(CC) $(CFLAGS) -c main.c -o main.o
clean:
rm space_invaders $(OBJECTS)
Output:
gcc -Wall --std=c99 -g -o space_invaders main.o
/usr/bin/ld: main.o: in function main': /home/kyle/space_invaders/main.c:9: undefined reference to initscr'
/usr/bin/ld: /home/kyle/space_invaders/main.c:10: undefined reference to noecho' /usr/bin/ld: /home/kyle/space_invaders/main.c:11: undefined reference to curs_set'
/usr/bin/ld: /home/kyle/space_invaders/main.c:22: undefined reference to stdscr' /usr/bin/ld: /home/kyle/space_invaders/main.c:22: undefined reference to stdscr'
/usr/bin/ld: /home/kyle/space_invaders/main.c:22: undefined reference to stdscr' /usr/bin/ld: /home/kyle/space_invaders/main.c:22: undefined reference to stdscr'
/usr/bin/ld: /home/kyle/space_invaders/main.c:23: undefined reference to stdscr' /usr/bin/ld: /home/kyle/space_invaders/main.c:23: undefined reference to wclear'
/usr/bin/ld: /home/kyle/space_invaders/main.c:24: undefined reference to mvprintw' /usr/bin/ld: /home/kyle/space_invaders/main.c:25: undefined reference to stdscr'
/usr/bin/ld: /home/kyle/space_invaders/main.c:25: undefined reference to `wrefresh'
collect2: error: ld returned 1 exit status
make: *** [Makefile:7: space_invaders] Error 1
LDFLAGS is defined but not used. Add it to the rule that links the final executable.
space_invaders: $(OBJECTS)
$(CC) $(CFLAGS) -o space_invaders $(OBJECTS) $(LDFLAGS)
Alternatively the Make implicit rules can be used to simplify the makefile:
CC = gcc
CFLAGS = -Wall --std=c99 -g
LDFLAGS = -lncurses
OBJECTS = main.o
ALL: space_invaders
space_invaders: $(OBJECTS)
clean:
rm space_invaders $(OBJECTS)
you have to specify the $(LDFLAGS) variable in the linking command:
space_invaders: $(OBJECTS)
$(CC) $(CFLAGS) $(LDFLAGS) -o space_invaders $(OBJECTS)
As you probably have seen, the linking command in the output of your run doesn't show the -lncurses option, so the library has not been including, making all the calls to library functions to be unresolved.
I don't recommend you to use the alternative given in another answer about using the implicit linking rule, as it is applicable only to GNU make, and so, it is not portable to other make's around.
I am working on a c project. https://github.com/eantoranz/gitmod It's broken up into separate c/h files. In my current Makefile, I take each one of the c files and compile them into their own .o file, then when I want to create the final program, I ask to compile a c file that has a main and provide all the other .o files. So far, so good (let me know if this approach is not correct).
As a next step, I want to separate the main part of the program from all the other pieces of the code and would like to pack all of the previous o files into a single so file (that had been compiled as just another .o file so far).
So, old approach was like this:
gitmod.o: src/gitmod.c include/gitmod.h lock.o root_tree.o thread.o object.o cache.o
$(CC) -c -o $# $< $(CFLAGS)
gitmod: src/main.c gitmod.o
$(CC) $< *.o -o $# $(CFLAGS)
These would be the last 2 steps of this process using the so replacing gitmod.o for libgitmod.so, after creating all the previous .o files:
libgitmod.so: src/gitmod.c include/gitmod.h lock.o root_tree.o thread.o object.o cache.o
$(CC) $< *.o -shared -o $# $(CFLAGS)
gitmod: src/main.c libgitmod.so
$(CC) $< -llibgitmod.so -o $# $(CFLAGS)
libgitmod.so would be the shared library that I would like to actually contain all the other sections of code (I really hope that is possible).
When make is going through libgitmod.so, I am getting this:
gcc src/gitmod.c *.o -shared -o libgitmod.so -Iinclude `pkg-config fuse3 libgit2 glib-2.0 --cflags --libs` -DGITMOD_DEBUG -Wall -g
/usr/bin/ld: object.o: warning: relocation against `stderr##GLIBC_2.2.5' in read-only section `.text'
/usr/bin/ld: /tmp/ccir4Ou9.o: relocation R_X86_64_PC32 against symbol `stderr##GLIBC_2.2.5' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status
make: *** [Makefile:32: libgitmod.so] Error 1
What am I doing wrong?
-fPIC, which means Position Indepent Code, flags is required to create shared object.
You can add the flag in the compile flag, then you can create a shared object.
I am able to run and compile my c example program with openssl using
gcc azureconn.c -o azureconn -lssl -lcrypto
but when I try to compile using makefile with LDLIBS flag in make file, it result into error as undefined reference OPENSSL_Init
Below is my make file
DEFINES = $(GDEFINES)
INCLUDES = $(DIR_PATH)
CFLAGS = $(GCFLAGS) $(DEFINES) $(INCLUDES) -D_GNU_SOURCE
LDLIBS = -lssl -lcrypto
MAIN_OBJECTS = xxxx.o yyy.o zzz.o \
aaaa.o
all: $(MAIN_OBJECTS)
mv $(MAIN_OBJECTS) $(BIN_PATH)
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $# $(LDLIBS)
clean:
rm -rf *.o
Error
undefined reference to `OPENSSL_init_ssl' collect2: error: ld returned
1 exit status
Since you've changed your question. Which module has the main(...) function in it? I assumed it was azureconn.c since you said you can compile with this.
gcc azureconn.c -o azureconn -lssl -lcrypto
Try using a rule like this to build your executable;
azureconn:
$(CC) $(CFLAGS) azureconn.c -o $# $(LDLIBS)
The %.o:%.c rule is not typically used to link, just create object files as the name implies
I have 3 functions separated in .c files and the main.c I would like to make the make file, I wrote in the file:
# Indicate that the compiler is the gcc compiler
CC=gc
# Indicate to the compiler to include header files in the local folder
CPPFLAGS = -I
main: method1.o
main: method2.o
main: method3.o
main: method4.o
main.o: main.h
Whereas method 1,2,3,4 is the functions of the main .c and I have the following problem when I type make in the shell:
make
gcc -I -c -o method1.o method1.c
/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld returned 1 exit status
make: *** [method1.o] Error 1
if your project contains the following files: method1.c method2.c method3.c method4.c and main.c
you can use the following make file
CPPFLAGS=-I/path/to/header/files
CC=gcc
all: main
%.o: %.c
$(CC) $(CPPFLAGS) -c -o $# $^
main: method1.o method2.o method3.o method4.o main.o
$(CC) -o $# $^
The issue is in your CPPFLAGS definition:
# Indicate to the compiler to include header files in the local folder
CPPFLAGS = -I
According to the comment above it, it misses a .:
CPPFLAGS = -I.
Otherwise, gcc will treat the -c that comes after -I in your command line as the name of a directory where it can search for headers. Thus, as far as gcc is concerned there's no -c option, and it will attempt to link method1.c as a complete application, hence the error message complaining that there's no main function.
CC=gcc
CPPFLAGS=-I include
VPATH=src include
main: main.o method1.o method2.o method3.o method4.o -lm
$(CC) $^ -o $#
main.o: main.c main.h
$(CC) $(CPPFLAGS) -c $<
method1.o: method1.c
$(CC) $(CPPFLAGS) -c $<
method2.o: method2.c
$(CC) $(CPPFLAGS) -c $<
method3.o: method3.c
$(CC) $(CPPFLAGS) -c $<
method4.o: method4.c
$(CC) $(CPPFLAGS) -c $<
it worked like this
I'm having some trouble trying to compile a program that uses exp function on Ubuntu. I get this error from gcc:
selied#Apolo:~/Dropbox/practicas UAM/Neuro/practica3$ make
gcc -lm -o retropropagacion retropropagacion.o
retropropagacion.o: In function `main':
/home/selied/Dropbox/practicas UAM/Neuro/practica3/retropropagacion.c:177: undefined reference to `exp'
/home/selied/Dropbox/practicas UAM/Neuro/practica3/retropropagacion.c:186: undefined reference to `exp'
/home/selied/Dropbox/practicas UAM/Neuro/practica3/retropropagacion.c:297: undefined reference to `exp'
/home/selied/Dropbox/practicas UAM/Neuro/practica3/retropropagacion.c:306: undefined reference to `exp'
collect2: ld devolvió el estado de salida 1
make: *** [retropropagacion] Error 1
Here I show you my makefile.
CC = gcc
LDLAGS = -lm
CFLAGS = -Wall -g
EXE = retropropagacion normalizar
OBJ =
INC =
compile : $(EXE)
clean :
#echo Borrando archivos temporales...
rm -f *~ *.o core $(EXE)
help :
#echo
backpropagation :
./retropropagacion entrada.txt 0 0 salida.txt
and :
./retropropagacion and.dat 0 0 salida_and.txt
$(EXE) : % : %.o $(OBJ)
$(CC) $(LDLAGS) -o $# $#.o $(OBJ)
%.o : %.c $(INC)
$(CC) $(CFLAGS) -c $<
Also I have include at the top of my header file and it works on another computer.
Do you know what's happening?
$(CC) $(LDLAGS) -o $# $#.o $(OBJ)
should be
$(CC) -o $# $#.o $(OBJ) $(LDLAGS)
Whether -l flags can be given before object files depends on the GCC version.
Never mind. For further interested about this issue or struggling also too long, also line
LDLAGS = -lm
should be written as
LDLIBS = -lm
because LDLIBS are put after the object files, unlike the LDFLAGS, which ends in front of them in default make template, as documentation hints.