How to make a Makefile that includes my header? - c

I am new to c programming, and I am having a problem with making Makefile for it.
I did like
CC = gcc
CFLAGS = -fsanitize=address -g -Wall -Wvla
OUTPUT = prac
all: $(OUTPUT)
mymalloc.o: mymalloc.c mymalloc.h
$(CC) $(CFLAGS) -c $# mymalloc.c
%: %.c
$(CC) $(CFLAGS) -o $# mymalloc.o $^
and I try to make file with just typing "make"
But it keep says
gcc -fsanitize=address -g -Wall -Wvla -o prac mymalloc.o prac.c
clang: error: no such file or directory: 'mymalloc.o'
make: *** [prac] Error 1
whenever I try to make it , did I do something wrong?
Thank you.
Edit)
I got it right with using this!
CC = gcc
CFLAGS = -fsanitize=address -g -Wall -Wvla
DEPS = mymalloc.h
OBJS = prac.o mymalloc.o
%.o: %.c $(DEPS)
$(CC) $(CFLAGS) -c -o $# $<
prac: $(OBJS)
$(CC) $(CFLAGS) -o $# $^

You need to make the executable dependent on mymalloc.o:
%: %.c mymalloc.o
$(CC) $(CFLAGS) -o $# mymalloc.o $^
The dependency tells make that it needs to execute the rule for creating mymalloc.o.
Also your rule for making mymalloc.o is wrong. You need -o before $#:
mymalloc.o: mymalloc.c mymalloc.h
$(CC) $(CFLAGS) -c -o $# mymalloc.c
Otherwise it's trying to use the output file as one of the input files.

Related

makefile not changing input filename

I am trying to make a C program and have the following makefile:
CC=clang
CFLAGS=-std=c99 -Wall -pedantic
LDFLAGS=
LDLIBS=
OUT=nes_slop
SRC_DIR=src/
OBJ_DIR=obj/
SRCS=$(wildcard $(SRC_DIR)*.c)
OBJS=$(addprefix $(OBJ_DIR),$(notdir $(SRCS:.c=.o)))
MAKE=make
CLEAR=TRUE
all: clean $(OUT)
clean:
rm -i $(OUT) $(OBJS) -f
$(OUT): $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $(OUT)
$(OBJS): $(SRCS)
$(CC) -c $(CFLAGS) $(LDLIBS) $< -o $#
It was all well and good until I had more than 1 .c file:
clang -c -std=c99 -Wall -pedantic -lncurses src/gamestate.c -o obj/gamestate.o
clang -c -std=c99 -Wall -pedantic -lncurses src/gamestate.c -o obj/main.o
so, somehow the source file is not being updated, it's always gamestate.c... what's wrong with my makefile? any help is appreciated, thank you
In short, your rule should look something like this:
$(OBJS): %.o: %.c
$(CC) -c $(CFLAGS) $(LDLIBS) $< -o $#
You may also want to read this for how to generate automatic dependencies (so if you change a header file, your c files will automatically regenerate as needed) There's a TL;DR section at the top of that page, if you're not interested in the details.

Creating a makefile with different tests

I'm trying to understand if I have create the Makefile right. I have the following files:
Student.h Student.C University.h University.c list.h IDCard.h IDCard.c union.h
Also I have a library mylib which I use the list.h and union.h from.
Furthermore, I have the following hierarchy:
- University
- Student
- list
- IDCard
- union
This means that University imports Student and union and Student import list and IDCard.
The steps I need to follow:
Use the make command to create testing1.exe - release mode without asserts. This file is the runnable of the given testing1.c.
Use make testing2.exe for creating test2.exe - release mode without asserts. This file is the runable of testing2.c.
Use make testing2_debug.exe for creating testing2_debug.exe - debug mode, with asserts. This file is the runable of test2.c.
Use make test for creating test.exe - release mode without asserts. This file is runnable of test.c.
Use make clean to clean so the rebuild will succeed.
The Makefile I wrote looks like:
CC = gcc
OBJS = IDCard.o Student.o University.o
DEBUG_OBJS = IDCard_debug.o Student_debug.o University_debug.o
SOURCE = IDCard.c Student.c University.c
HEADER = IDCard.h Student.h University.h list.h union.h
CFLAGS = -std=c99 -Wall -pedantic-errors -Werror -DNDEBUG -L. -mylib
EXEC = testing.exe testing1.exe testing2.exe testing2_debug.exe
testing_O = testing1.o testing2.o testing2_debug.o testing.o
#make testing1.exe
testing1.exe : $(OBJS) $*.o
$(CC) -o $# -DNDEBUG $(OBJS) -L. mylib
#make testing2.exe
testing2.exe : $(OBJS) $*.o
$(CC) -o $# -DNDEBUG $(OBJS) -L. mylib
#testing2_debug.exe
testing2_debug.exe : $(DEBUG_OBJS) $*.o
$(CC) -o $# -DNDEBUG $(OBJS) -L. mylib
#make testing.exe
testing.exe : $(OBJS) $*.o
$(CC) -o $# -DNDEBUG $(OBJS) -L. mylib
testing1.o : testing1.c Student.h University.h
$(CC) -c -DNDEBUG $(CFLAGS) $*.c
Student.o : list.h IDCard.h Student.c Student.h
$(CC) -c -DNDEBUG $(CFLAGS) $*.c
University.o : union.h University.c University.h
$(CC) -c -DNDEBUG $(CFLAGS) $*.c
IDCard.o : IDCard.h
$(CC) -c -DNDEBUG $(CFLAGS) $*.c
testing2_debug.o : testing2.c Student.h University.h
$(CC) -c -g $(CFLAGS) $*.c -o $#
Student_debug.o : list.h IDCard.h Student.c Student.h
$(CC) -c -g $(CFLAGS) $*.c -o $#
University_debug.o : union.h University.c University.h
$(CC) -c -g $(CFLAGS) $*.c -o $#
IDCard_debug.o : IDCard.h
$(CC) -c -g $(CFLAGS) $*.c -o $#
clean :
rm -f $(OBJS) $(DEBUG_OBJS) $(EXEC) $(testing_O)
I'm a bit new to creating Makefiles so I'm try to make as few mistakes as possible. Does my Makefile do what I need? Can it be simplified? Does it follow the conventions?
$*.o shouldn't be a dependency. $(OBJS) already covers that.
As a general rule, you can avoid targets for individual object files.
Here's an example target that may need modification to suit your needs:
%.o: %.c %.h
<tab>$(CC) -DNDEBUG -c $(CFLAGS) -o $# $<
%_debug.o: %.c %.h
<tab>$(CC) -c -g $(CFLAGS) -o $# $<
This requires the header file to have the same base name as the source file.
Another option that may work is listing off the header file dependencies of each object file and then doing the matching:
testing1.o: Student.h University.h
Student.o: list.h IDCard.h Student.h
University.o: union.h University.h
IDCard.o: IDCard.h
testing2_debug.o: Student.h University.h
Student_debug.o: list.h IDCard.h Student.h
University_debug.o: union.h University.h
IDCard_debug.o: IDCard.h
%.o: %.c
<tab>$(CC) -DNDEBUG -c $(CFLAGS) -o $# $<
%_debug.o: %.c
<tab>$(CC) -c -g $(CFLAGS) -o $# $<
A similar rule can be followed for .exe files:
%.exe: $(OBJS)
<tab>$(CC) -DNDEBUG $(CFLAGS) $^ -o $# -L. -lmylib
%_debug.exe: $(DEBUG_OBJS)
<tab>$(CC) -g $(CFLAGS) $^ -o $# -L. -lmylib
Also, make sure to replace <tab> in these examples with hard tabs for your Makefile to be valid.
IDCard.o : IDCard.h
$(CC) -c -DNDEBUG $(CFLAGS) $*.c
but .h files aren't compiled
As a general style form list .c dependencies before .h dependencies.
EDIT: Community Wiki. If it weren't for the clarifying comment by OP I would now delete this post.

Understanding Makefile syntax

Can someone help me understand the below makefile?
I have comment on the bits I am not sure on. I have used make files but not extensively and I do not believe I have followed good practises so any advice is welcome.
CC=gcc #is CC, libs, deps, obj, etc predefined keywords or could I use something else
CFLAGS=-I. -g -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse #same with CFlags
LIBS = -luuid -lfuse -pthread
DEPS = fs.h unqlite.h
OBJ = unqlite.o fs.o
TARGET1 = test
TARGET2 = test2
TARGET3 = test3
TARGET4 = test4
TARGET5 = main
all: $(TARGET1) $(TARGET2) $(TARGET3) $(TARGET4) $(TARGET5)
%.o: %.c $(DEPS) #not sure on this line
$(CC) -c -o $# $< $(CFLAGS) #same here
$(TARGET1): $(TARGET1).o $(OBJ)
gcc -o $# $^ $(CFLAGS) $(LIBS) #what are $# and $^
$(TARGET2): $(TARGET2).o $(OBJ)
gcc -o $# $^ $(CFLAGS) $(LIBS)
$(TARGET3): $(TARGET3).o $(OBJ)
gcc -o $# $^ $(CFLAGS) $(LIBS)
$(TARGET4): $(TARGET4).c
gcc -o test test.c
$(TARGET5): $(TARGET5).c
gcc -o uuid uuid.c -luuid
.PHONY: clean
clean:
rm -f *.o *~ core $(TARGET1) $(TARGET2) $(TARGET3) $(TARGET4) $(TARGET5)
CC, CFLAGS, LIBS, DEPS, OBJ and TARGETs are not predefined keywords. They are variables. You can change the name into any you feel appropriate. Just make sure you also change their reference names: $(CC) $(CFLAGS) etc.
%.o: %.c $(DEPS) -
It is a pattern rule: https://www.gnu.org/software/make/manual/html_node/Pattern-Rules.html
In brief, it says: any .o file depends on .c file with the same prefix and $(DEPS) (which are fs.h and unqlite.h)
$#, $<, $^ are automatic variables for the rules: https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html#Automatic-Variables
If works the following way: when making test.o object file from source, the rule
%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
Is interpreted as:
test.o: test.c fs.h unqlite.h
gcc -c -o test.o test.c -I. -g -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse
Then, when making test binary, the rule
$(TARGET1): $(TARGET1).o $(OBJ)
gcc -o $# $^ $(CFLAGS) $(LIBS)
Becomes:
test: test.o unqlite.o fs.o
gcc -o test test.o unqlite.o fs.o -I. -g -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse -luuid -lfuse -pthread
So, we can see, CFLAGS reference is useless in the rule, as it defines compilation flags, and the rule actually performs linking. So the right one would be:
$(TARGET1): $(TARGET1).o $(OBJ)
gcc -o $# $^ $(LDFLAGS) $(LIBS)
Where LDFLAGS would be defined to some useful value, or can be left empty:
LDFLAGS =

C - Makefile possibly missing a line

I'll say first I don't have as much experience which makefiles as I wished, this is actually my first.
The error I currently get is:
Makefile:1: missing separator. Stop.
This happens when I try to run the make command.
As far as I know this means that I'm missing a hard tab at the first line it tries to run, I think at least.
I'm not missing a hard tab though as far as I know, so I'm assuming I'm just missing a whole line somewhere.
CFLAGS = -ansi -Wall -pedantic
HEADERS = menu.h file1.h file2.h file3.h file4.h
OBJECTS = menu.o file1.o file2.o file3.o file4.o
CC = gcc
all:runprog
runprog:$(OBJECTS)
$(CC) $(OBJECTS) -o runprog
menu.o:menu.c $(HEADERS)
$(CC) $(CFLAGS)
file1.o:file1.c $(HEADERS)
$(CC) $(CFLAGS)
file2.o:file2.c $(HEADERS)
$(CC) $(CFLAGS)
file3.o:file3.c $(HEADERS)
$(CC) $(CFLAGS)
file4.o:file4.c $(HEADERS)
$(CC) $(CFLAGS)
clean:rm -f *.o runprog
The clean target has its code in the place of dependencies. Also, your code uses spaces instead of tabs. Additionally, you forgot to add the .c files to the CC command lines. Moreover, you can simplify all the rules to
CFLAGS = -ansi -Wall -pedantic
HEADERS = menu.h file1.h file2.h file3.h file4.h
OBJECTS = menu.o file1.o file2.o file3.o file4.o
CC = gcc
all:runprog
runprog:$(OBJECTS)
$(CC) $(OBJECTS) -o runprog
%.o: %.c $(HEADERS)
$(CC) -c -o $# $< $(CFLAGS)
clean:
rm -f *.o runprog

gcc - file not recognized: File format not recognized

I'm trying to get a small project compiled but am getting this error, I've been searching around and people get this error mainly because of incorrect file extension, but I don't really think that's the cause here:
gcc -c -W -Wall -ggdb -I. router.c -o router.o
router.c:106: warning: unused parameter ‘hname’
router.c: In function ‘flood_neighbors’:
router.c:464: warning: unused variable ‘bytes_rcvd’
router.c: At top level:
router.c:536: warning: unused parameter ‘fd’
gcc -c -W -Wall -ggdb -I. link_info.h -o link_info.o
gcc -c -W -Wall -ggdb -I. route.h -o route.o
gcc -c -W -Wall -ggdb -I. sequence.h -o sequence.o
gcc -W -Wall -ggdb -I. router.o link_info.o route.o sequence.o -o router
link_info.o: file not recognized: File format not recognized
collect2: ld returned 1 exit status
make: *** [router] Error 1
and my make file looks like:
CC = gcc
INC = -I.
FLAGS = -W -Wall -ggdb
router: router.o link_info.o route.o sequence.o
$(CC) $(FLAGS) $(INC) $^ -o $#
router.o: router.c
$(CC) -c $(FLAGS) $(INC) $< -o $#
sequence.o: sequence.h sequence.h
$(CC) -c $(FLAGS) $(INC) $< -o $#
link_info.o: link_info.h link_info.c
$(CC) -c $(FLAGS) $(INC) $< -o $#
route.o: route.h route.c
$(CC) -c $(FLAGS) $(INC) $< -o $#
What I'm confused on is the rules for three object files are of the same format, but why only the link one yells? Thanks a lot!
I would like to suggest few edits in your makefile.
CC = gcc
INC = -I.
FLAGS = -W -Wall -ggdb
router: router.o link_info.o route.o sequence.o
$(CC) $(FLAGS) $(INC) $^ -o $#
router.o: router.c
$(CC) -c $(FLAGS) $(INC) $< -o $#
sequence.o: sequence.h sequence.h //Where is the c file ?
$(CC) -c $(FLAGS) $(INC) $< -o $#
link_info.o: link_info.h link_info.c //Change the order. Put c file first and then the header
$(CC) -c $(FLAGS) $(INC) $< -o $#
route.o: route.h route.c //Same as above
$(CC) -c $(FLAGS) $(INC) $< -o $#
With recent versions of make you can remove all the object rules because make uses a default rule to build an object from .c or .cpp files. Just leave the rule to build the final executable in place.
For example, change the file so it contains this line only:
router: router.o link_info.o route.o sequence.o
$(CC) $(FLAGS) $(INC) $^ -o $#
Move link_info.o to the end of the list in the router: dependencies and I suspect you'll blow up on route.o instead.
You seem to be compiling a headers as C files. I have no idea what GCC does in that case. In your makefile rules, the .c file must be the first dependency if you are going to use $< to generate the source file to compile.
The link_info: and route: rules have the .c and .h files reversed and the sequence: rule lists the .h file twice!

Resources