What is missing in my makefile? - c

I am trying to create my first makefile. I tested my program by using the following commands:
Command 1: gcc -Wall -ggdb3 -std=c99 -o file1 file1.c -lm -lpthread -l
Command 2: gcc -Wall -ggdb3 -std=c99 -o file2 file2.c -lm -lpthread
Everything works great. Then I created a makefile (please see below). I keep getting an error message. Can someone take a look at my code and give me a hint on what the problem is?
file2.o: In function `seed_primes':
file2.c:(.text+0x461): undefined reference to `sqrt'
file2.c:(.text+0x466): undefined reference to `sqrt'
file2:(.text+0x533): undefined reference to `sqrt'
file2.o: In function `create_threads':
file2.c:(.text+0x668): undefined reference to `pthread_create'
file2.c:(.text+0x6b5): undefined reference to `pthread_join'
file2.o: In function `next_seed':
file2.c:(.text+0x860): undefined reference to `sqrt'
collect2: ld returned 1 exit status
make: *** [file2] Error 1
Here is my makefile:
CC=gcc
DEBUG=-ggdb3
CFLAGS=#(DEBUG) -Wall -lm -lpthread -lrt -l
PROGS=file1 file2
all: $(PROGS)
file1: file1.o
$(CC) $(CFLAGS) -o file1 file1.o
file1.o: file1.c
$(CC) $(CFLAGS) -c file1.c
file2: file2.o
$(CC) $(CFLAGS) -o file2 file2.o
file2.o: file2.c
$(CC) $(CFLAGS) -c file2.c
clean:
rm -f $(PROGS) *.o *~

You've set CFLAGS to an empty string because of the # comment character (you probably intended to use a $ instead).
You should not set libraries into CFLAGS; they belong in LDLIBS.
You don't need the file1: rule, the file2: rule, or the object file rules.
CC = gcc
DEBUG = -ggdb3
CFLAGS = $(DEBUG) -Wall
LDLIBS = -lm -lpthread -lrt -l
PROGS = file1 file2
all: $(PROGS)
clean:
rm -f $(PROGS) *.o *~
NB: LDLIBS and the related LDFLAGS are not 100% uniform across variants of make. LDFLAGS should be used for library paths; LDLIBS is for the library names (-lxyz etc).
If you need different libraries for the two programs, you will need to create separate build rules (as you had originally), or use conditional macro assignments (GNU make).

You put all of your flags in CFLAGS which makes them appear before the object files in the command line. Notice that your test commands didn't do that.
Change your flags:
CFLAGS=$(DEBUG) -Wall
LDFLAGS=-lm -lpthread -lrt
And then in the recipes:
$(CC) $(CFLAGS) -o file1 file1.o $(LDFLAGS)

Related

Makefile with OpenSSL LDLIBS flag enabled giving error

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

Error when trying link jsoncpp and include it in a CUDA project: undefined reference to `Json::Value::Value(Json::ValueType)'

When I try and #include "json/json.h" in a .cu file, then run make, I get the following error:
nvcc -o sound main.o process.o -L /usr/lib -lopencv_core -lopencv_imgproc -lopencv_highgui -O3 -arch=sm_20 -Xcompiler -Wall -Xcompiler -Wextra -m64
/usr/local/cuda/bin/crt/link.stub:90:13: warning: ‘void __cudaRegisterLinkedBinary(const __fatBinC_Wrapper_t*, void (*)(void**), void*)’ defined but not used [-Wunused-function]
process.o: In function `count_tracks()':
tmpxft_00006061_00000000-3_process.cudafe1.cpp:(.text+0x75): undefined reference to `Json::Value::Value(Json::ValueType)'
tmpxft_00006061_00000000-3_process.cudafe1.cpp:(.text+0x7d): undefined reference to `Json::Value::~Value()'
collect2: ld returned 1 exit status
make: *** [student] Error 1
in reference to when I try and create a Json::Value. I've tried moving around where I link JsonCpp library, and I wasn't having this problem #including jsoncpp and creating a Json::Value in the main.cpp of the project. It just doesn't seem to be working correctly when in a .cu file.
Here is the pertinent stuff from my Makefile, which I got from Udacity's CUDA course and modified to fit my needs:
NVCC=nvcc
CXX = g++
LDFLAGS = -L ~/parallelcomputing/soundcloud/jsoncpp/build/debug/lib -ljsoncpp
INC = -I ~/parallelcomputing/soundcloud/jsoncpp/include
OPENCV_LIBPATH=/usr/lib
OPENCV_INCLUDEPATH=/usr/include
OPENCV_LIBS=-lopencv_core -lopencv_imgproc -lopencv_highgui
CUDA_INCLUDEPATH=/usr/local/cuda/include
NVCC_OPTS=-O3 -arch=sm_20 -Xcompiler -Wall -Xcompiler -Wextra -m64
GCC_OPTS=-O3 -Wall -Wextra -m64
student: main.o process.o Makefile
$(NVCC) -o sound main.o process.o -L $(OPENCV_LIBPATH) $(OPENCV_LIBS) $(NVCC_OPTS)
main.o: main.cpp
g++ -c main.cpp $(GCC_OPTS) $(LDFLAGS) $(INC) -I $(CUDA_INCLUDEPATH) -I $(OPENCV_INCLUDEPATH)
process.o: process.cu
nvcc -c process.cu $(NVCC_OPTS) $(LDFLAGS) $(INC)
clean:
rm -f *.o *.png hw
You've got LDFLAGS defined in your makefile, but you're not using it in the link phase that I can see.
As a result, -ljsoncpp doesn't show up in the link command you posted, that is showing the error.
Add LDFLAGS to your link phase:
student: main.o process.o Makefile
$(NVCC) -o sound main.o process.o $(LDFLAGS) -L $(OPENCV_LIBPATH) $(OPENCV_LIBS) $(NVCC_OPTS)
(And while we're cleaning up your makefile, LDFLAGS contains link specification, and is not relevant in, and can be safely deleted from, the subsequent compile targets.)
EDIT:
Since that is not working, but you say the link is successful with a .cpp file, try linking the executable with g++ instead of nvcc:
LDFLAGS2=-L/usr/local/cuda/lib64 -lcudart
student: main.o process.o Makefile
$(CXX) -o sound main.o process.o $(LDFLAGS) $(LDFLAGS2) -L $(OPENCV_LIBPATH) $(OPENCV_LIBS)

Undefined reference and linking libraries

I'm experiencing some compilation issues with my dynamic library. It should be linked to main.c but for all references to it I receive "undefined reference to function_name".
The contents of main.c isn't really that important; I include my library:
#include "matrix.h"
Then I have a simple Makefile to link the two.
#Variables
LIB = matrix
# Usual compilation flags
CFLAGS = -std=c99 -Wall -Wextra -g
CPPFLAGS = -I../include -DDEBUG
LDFLAGS = -lm
# Special rules and targets
.PHONY: all clean help
all: $(LIB).o libmatrix.so main
$(LIB).o: $(LIB).c $(LIB).h
$(CC) $(CFLAGS) $(CPPFLAGS) -fPIC -c -o $# $<
libmatrix.so: $(LIB).o
$(CC) $(CFLAGS) -fPIC -shared -o $# $< $(LDFLAGS)
main: main.o libmatrix.so
$(CC) $(CFLAGS) -o $# $< -L -lmatrix
Can anyone direct me to where I might be going wrong? Many thanks in advance.
You probably want -L. not -L in your last line, so:
main: main.o libmatrix.so
$(CC) $(CFLAGS) -o $# $< -L. -lmatrix
You should read Program Library HOWTO and Drepper's paper: How to Write Shared Libraries; you might want to set some -rpath at link time (maybe using -Wl,-rpath,. ...), and you might want to link with -rdynamic ....
Alternatively, set your LD_LIBRARY_PATH environment variable to contain . (I don't recommend that), or install your shared library in /usr/local/lib/ (and add it to /etc/ld.so.conf then run ldconfig). See also dlopen(3), environ(7), ld.so(8), ldconfig(8)

How to create two C executable with different -D variable=value using makefile

My code uses one macro which I am defining during the build as follows.
gcc -D VAR=1000 main.c -0 main
But I want to create two executable, one with VAR=1000 and other with VAR=2000. Lets say executable names would be main_1000 and main_2000.
How can I do that using Makefile.
My attempt to do that is as follows. But it does not work and gives me an error.
gcc -g -c -o main.o main.c
main.c: In function ‘main’:
main.c:5:16: error: ‘VAR’ undeclared (first use in this function)
main.c:5:16: note: each undeclared identifier is reported only once for each function it appears in
make: *** [main.o] Error 1
Makefile:
CC=gcc
CFLAGS=-g
all: main_1000 main_2000
main_1000: main.o
$(CC) -D VAR=1000 -o main_1000 main.o $(CFLAGS)
main_2000: main.o
$(CC) -D VAR=2000 -o main_2000 main.o $(CFLAGS)
main_1000: main.o
This implies that you already expect main.o to be there. Since there's no rule for compiling a c file to an o file, make uses its implicit rule, which doesn't include the definition. What you want instead is this:
CC=gcc
CFLAGS=-g
all: main_1000 main_2000
main_1000: main.c
$(CC) -D VAR=1000 -o $# $^ $(CFLAGS)
main_2000: main.c
$(CC) -D VAR=2000 -o $# $^ $(CFLAGS)

Unable to link math lib using a makefile [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Linker errors when compiling against glib…?
Okay, I know this may be a duplicate, but I can't find any other answer to my problem.
I am trying to install Pintos and when I run 'make' in the src/utils directory, I get the error that there is an undefined reference to 'floor'. I checked the makefile and here's what I got:
all: setitimer-helper squish-pty squish-unix
# 2207718881418
CC = gcc
CFLAGS = -Wall -W
LDFLAGS = -lm
setitimer-helper: setitimer-helper.o
squish-pty: squish-pty.o
squish-unix: squish-unix.o
clean:
rm -f *.o setitimer-helper squish-pty squish-unix
I tried adding LIBS = -lm but that didn't help.
Output of make:
gcc -lm setitimer-helper.o -o setitimer-helper
setitimer-helper.o: In function `main':
setitimer-helper.c:(.text+0xbb): undefined reference to `floor'
collect2: ld returned 1 exit status
make: *** [setitimer-helper] Error 1
Any solutions to this dilemma?
Your original makefile defines a bunch of variables
CC = gcc
# etc
and lists some dependencies
setitimer-helper: setitimer-helper.o
# etc
but doesn't have any recipes giving the exact commands to be used to remake the targets, except for the clean rule. This means that built-in implicit rules will be used; e.g., to link setitimer-helper the following built-in rule will be used:
$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $#
For setitemer-helper, the automatic variables are filled in using the relevant dependency:
$(CC) $(LDFLAGS) setitimer-helper.o $(LDLIBS) -o setitimer-helper
and from this you can see how the remaining variables -- $(CC), $(LDFLAGS), and $(LDLIBS) -- were filled in to give the output of make that you saw.
As various people have noted, you need to make sure that -lm goes at the end of the link command so that it can be used to satisfy references to library functions like floor(). At the moment, your makefile sets $(LDFLAGS) to -lm, but that variable is used at the start of the link command.
The conventional variables are set up in this built-in rule so that LDFLAGS can be used for options (a.k.a. "flags") that (historically) need to be at the start of the link command, and LDLIBS can be used for libraries that need to be specified after the *.o object files.
So to fix this in terms of the makefile you are using, you need to remove -lm from the LDFLAGS variable that is defined, and instead add another variable definition for LDLIBS:
LDLIBS = -lm
(I'm oversummarising slightly: the built-in rule also contains $(TARGET_ARCH) and $(LOADLIBES), but those aren't of interest here.)
It's compiled in wrong order, the way to proceed is:
CC = gcc
CFLAGS = -Wall -W
LDFLAGS = -lm
myprog: myprog.o more_code.o
${CC} ${CFLAGS} myprog.o more_code.o ${LDFLAGS} -o myprog
myprog.o: myprog.c
${CC} ${CFLAGS} -c myprog.c
more_code.o: more_code.c
${CC} ${CFLAGS} -c more_code.c
clean:
\rm myprog.o more_code.o myprog
More info: http://www.physics.utah.edu/~p5720/rsrc/make.html
Can you show me in terms of the original makefile?
I can try :)
CC = gcc
CFLAGS = -Wall -W
LDFLAGS = -lm
OBJECTS = setitimer-helper.o squish-pty.o squish-unix.o
all: setitimer-helper
setitimer-helper: $(OBJECTS)
${CC} ${CFLAGS} $(OBJECTS) ${LDFLAGS} -o setitimer-helper
setitimer-helper.o: setitimer-helper.c
${CC} ${CFLAGS} -c setitimer-helper.c
squish-pty.o: squish-pty.c
${CC} ${CFLAGS} -c squish-pty.c
squish-unix.o: squish-unix.c
${CC} ${CFLAGS} -c squish-unix.c
And since you are new to Makefile, it's a good idea to add -Wextra -pedantic to CFLAGS

Resources