-lm Not linking math library in makefile - c

I know this error has been beaten to death, but I cannot seem to get it to work. I have linked my makefile below:
all: gensine info cs229towav
encode.o: encode.h encode.c
gcc -c encode.c
write.o: write.c write.h
gcc -c write.c
gensine.o: encode.c gensine.h gensine.c helper.c write.c
gcc -c gensine.c -lm
helper.o: helper.c helper.h
gcc -c helper.c
read.o: read.h read.c
gcc -c read.c
info.o:read.c info.h info.c decode.c
gcc -c info.c
decode.o: decode.c decode.h helper.c
gcc -c decode.c
cs229towav.o: write.c read.c cs229towav.c cs229towav.h helper.c decode.c encode.c
gcc -c cs229towav.c -lm
gensine: encode.o gensine.o write.o helper.o
gcc -o gensine encode.o gensine.o write.o helper.o -lm
info: read.o info.o decode.o helper.o
gcc read.o info.o decode.o helper.o
cs229towav: write.o read.o cs229towav.o decode.o encode.o helper.o
gcc -o write.o read.o cs229towav.o decode.o encode.o helper.o -lm
Clean:
rm -rf *o gensine info cs229towav
When I run a command such as "make gensine" I am returned with the following result:
>cc gensine.c -o gensine
/tmp/ccojm09X.o: In function `encodeCsFormat':
gensine.c:(.text+0x4b1): undefined reference to `sin'
/tmp/ccojm09X.o: In function `encodeWavFormat':
gensine.c:(.text+0xa39): undefined reference to `sin'
collect2: error: ld returned 1 exit status
After reading this is says undefined reference to sin, which is with the math library. Those functions listed are in the "encode.c" file which are included in the "gensine.c" file.

The command in the makefile:
gcc -o gensine encode.o gensine.o write.o helper.o -lm
does not match the command you printed at the end:
cc gensine.c -o gensine
Notice also that there is no -lm
Note that make knows how to make object files so you don't need most of the makefile. Try this (remember to indent with TABs):
.PHONY : all clean
all = gensine info
CFLAGS =-Wall
LIBS = -lm
gensine: encode.o gensine.o write.o helper.o
gcc -o $# $^ $(LIBS)
info: read.o info.o decode.o helper.o
gcc -o $# $^ $(LIBS)
cs229towav: write.o read.o cs229towav.o decode.o encode.o helper.o
gcc -o $# $^ $(LIBS)
clean:
rm -rf *.o gensine info cs229towav
Edit:
Boddie, note that your confusion arose because you thought the makefile was a script - ie. that you were running your script named make when you typed make gensine. In fact make is a command like gcc somewhere else in the filesystem (on Linux etc, type which make to see where it is). The make command expects to find an input file containing build rules called makefile or Makefile in the current directory. If it doesn't find that file it uses some built-in rules instead - hence the cc gensine.c -o gensine which is nowhere in your makefile. If you want to, you can tell make the name of the makefile (so that it doesn't use the default names) with the -f switch, as #DanielFischer described in the comments.

Related

Make two c programs in one makefile

Is it possible to make two files in a single makefile? Essentially a program and a programtest. I have seen other answers, but their syntax went completely over my head. Right now my Makefile only makes one of the programs, and I cant figure out how to have it make both
Would it be possible for someone to provide a template for how a Makefile would be structured to compile two programs?
all: main test
test: objects/Math.o objects/Stack.o objects/Queue.o objects/myUnitTesting.o objects/test.o
gcc objects/test.o objects/Math.o objects/Stack.o objects/Queue.o objects/myUnitTesting -o test
main: objects/Stack.o objects/Queue.o objects/Math.o objects/Point.o objects/main.o
gcc objects/main.o objects/Stack.o objects/Queue.o objects/Point.o objects/Math.o -o main
objects/test.o: test.c
gcc -g -Wall -O -c -o objects/test.o test.c
objects/main.o: main.c
gcc -g -Wall -O -c -o objects/main.o main.c
objects/myUnitTesting.o: cs/myUnitTesting.c
gcc -g -Wall -O -c -o objects/myUnitTesting cs/myUnitTesting.c
objects/Math.o: cs/Math.c
gcc -g -Wall -O -c -o objects/Math.o cs/Math.c
objects/Stack.o: cs/Stack.c
gcc -g -Wall -O -c -o objects/Stack.o cs/Stack.c
objects/Queue.o: cs/Queue.c
gcc -g -Wall -O -c -o objects/Queue.o cs/Queue.c
objects/Point.o: cs/Point.c
gcc -g -Wall -O -c -o objects/Point.o cs/Point.c
clean:
rm -f objects/*o main
Then you only need to type:
make all
and it is going to compile your main.c and test.c files
You can multiple exes in one makefile, here is sample for building 2,
you need to do make all to build
prog1: prog1.o
gcc prog1.o -o prog1 2>>compile.log 1>&2
prog2: prog2.o
gcc prog2.o -o prog2 2>>compile.log 1>&2
all: prog1 prog2
.c.o:
gcc -o $# -c $*.c 2>>compile.log 1>&2
Here is a scenario where 2 targets are main1 and main2.
TARGET1 = main1
TARGET2 = main2
$(TARGET1): main1.o
gcc main1.o -o $#
$(TARGET2): main2.o
gcc main2.o -o $#
%.o: %.c
gcc -c $< -o $#
run1: $(TARGET1)
./$(TARGET1)
run2: $(TARGET2)
./$(TARGET2)
all: $(TARGET1) $(TARGET2)
./$(TARGET1)
./$(TARGET2)
Remember that the indentation is a <tab> character, not space characters.
The following command will compile and run main1 executable.
make run1
The following command will compile and run main2 executable.
make run2
The following command will compile and run main1 executable followed by main2 executable.
make all
It is possible.
Here is a simpler version of the Makefile:
all: program programtest
program:
gcc -o program program.c
programtest:
gcc -o programtest programtest.c
Then you just have to type make:
$ make
gcc -o program program.c
gcc -o programtest programtest.c

Makefile: make run command

Here is my my makefile. I know there is a shorter way to write it out, but I have a question on how to run it. My hw says I have to use the command: make run --- this command should cause the executable file to run using file redirection to read the input file data.
How would I go about setting that up?
Also i know the gcc is supposed to be tabbed.
test: main.o sum.o stack.o bSearch.o database.o db.o set.o parse.o bubble.o
gcc -o object main.o sum.o stack.o bSearch.o db.o set.o parse.o bubble.o
main.o: main.c sum.h
gcc -c main.c
sum.o: sum.c sum.h
gcc -c sum.c
stack.o: stack.c stack.h
gcc -c stack.c
bSearch.o: bSearch.c defs.h sortAndsearch.h
gcc -c bSearch.c
database.o: database.c defs.h parse.h
gcc -c database.c
db.o: db.c defs.h
gcc -c db.c
set.o: set.c set.h db.h
gcc -c set.c
parse.o: parse.c parse.h
gcc -c parse.c
bubble.o: bubble.c defs.h
gcc -c bubble.c
sortAndsearch.h: db.h
defs.h: set.h sortAndsearch.h
stack.h: set.h
clean:
rm *.o object
"run" is just like any other target in your Makefile such as "test" or "set.o" - but you have to add the rule to the Makefile for make to know what to do with it.
run:
./test < input.txt

makefile error missing separator error

I am trying to use make with my c program. It's a simple calculator program. I created the makefile but it is not being executed when i run make using the terminal.
here is my make file
calculatormade:
\tadd.o sub.o multiply.o divide.o Calculator_Main.o gcc add.o sub.o multiply.o divide.o Calculator_Main.o -o calculatormade
add.o:
\tadd.c gcc add.c -c
sub.o:
\tsub.c gcc sub.c -c
multiply.o:
\tmultiply.c gcc multiply.c -c
divide.o:
\tdivide.c gcc divide.c -c
Calculator_Main.o:
\tCalculator_Main.c head.h gcc Calculator_Main.c -c
clean:
\trm calculatormade add.o sub.o multiply.o divide.o Calculator_Main.o
The tab separator is misplaced. You should put on the first line the taget, colon and the files it is dependent on.
On the second line (that must start with tab) you need to build the build instructions. For exmple:
calculatormade: add.o sub.o multiply.o divide.o Calculator_Main.o
<TAB>gcc add.o sub.o multiply.o divide.o Calculator_Main.o -o calculatormade
add.o: add.c
<TAB>gcc add.c -c

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)

Makefile: No rule to make target despite giving target?

While trying to use Make I get the following error:
make: *** No rule to make target `paging.c', needed by `obj/paging.o'. Stop.
But I have given the makefile the rule for making the target. Here's my makefile:
--------
C_SOURCES= main.c monitor.c common.c descriptor_tables.c timer.c paging.c \
fs.c initrd.c task.c syscall.c --------
S_SOURCES= boot.s interrupt.s gdt.s process.s
C_OBJECTS=$(patsubst %.c, obj/%.o, $(C_SOURCES))
S_OBJECTS=$(patsubst %.s, obj/%.o, $(S_SOURCES))
CFLAGS=-c -nostdlib -nostdinc -fno-builtin -fno-stack-protector -m32 -Iheaders
LDFLAGS=-Tlink.ld -melf_i386 --oformat=elf32-i386
ASFLAGS=-felf
all: kern/kernel
.PHONY: clean
clean:
-rm -f obj/*.o kern/kernel
kern/kernel: $(S_OBJECTS) $(C_OBJECTS)
ld $(LDFLAGS) -o $# $^
$(C_OBJECTS): obj/%.o : source/%.c
gcc $(CFLAGS) $< -o $#
vpath %.c source
$(S_OBJECTS): obj/%.o : %.s
nasm $(ASFLAGS) $< -o $#
vpath %.s asem
NOTE: the -------- is not in the original makefile, they are just used to pick the rule I have used.
make output:
nasm -felf asem/boot.s -o obj/boot.o
nasm -fenasm -felf asem/boot.s -o obj/boot.o
nasm -felf asem/interrupt.s -o obj/interrupt.o
nasm -felf asem/gdt.s -o obj/gdt.o
nasm -felf asem/process.s -o obj/process.o
gcc -c -nostdlib -nostdinc -fno-builtin -fno-stack-protector -m32 -Iheaders source/main.c -o obj/main.o
gcc -c -nostdlib -nostdinc -fno-builtin -fno-stack-protector -m32 -Iheaders source/monitor.c -o obj/monitor.o
gcc -c -nostdlib -nostdinc -fno-builtin -fno-stack-protector -m32 -Iheaders source/common.c -o obj/common.o
gcc -c -nostdlib -nostdinc -fno-builtin -fno-stack-protector -m32 -Iheaders source/descriptor_tables.c -o obj/descriptor_tables.o
gcc -c -nostdlib -nostdinc -fno-builtin -fno-stack-protector -m32 -Iheaders source/timer.c -o obj/timer.o
make: *** No rule to make target `source/paging.c', needed by `obj/paging.o'. Stop.
Why is it coming out with the error despite giving it what it needs?
You will have to change the line
$(C_OBJECTS): obj/%.o : %.c
to
$(C_OBJECTS): obj/%.o : source/%.c
edit, in reflect of question change:
void page_fault(registers_t regs)
void page_fault(registers_t *regs);
Compare ;) The two should be the same. According to the code chunk from paging.c, the version in paging.h should be corrected (just remove the *).
Does the file paging.c exist in the same directory as the Makefile?
If it does not, Make will look for a rule to create it. Since there is no rule to create paging.c, it will give you this error.
The error is telling you that "make" cannot find the file "paging.c" anywhere in the vpath or in the current directory, and it has no rule to create "paging.c" from any other source file.
Make sure that you actually have "paging.c" where you think you do, and that it is actually called "paging.c" and not "paging.c " (extra space) or some other unicode special stuff that looks like "paging.c" when you print it out, but isn't.

Resources