Why is this item always executed in the Makefile? - c

I wrote the following Makefile. But when I execute the make command, the sentence gcc -shared -o ../lib/libCfunc.so objFile/cacheOp.o objFile/fileOp.o objFile/linuxOp.o objFile/commonFunc.o is always executed. Even if I did not modify any files, and executed multiple make commands consecutively.
Doesn't objFile depend on $(libObjs)? Why is only this sentence being executed all the time?
cc=gcc
CFLAGS=-g -O0 -fPIC -lm
libObjs=objFile/cacheOp.o objFile/fileOp.o objFile/linuxOp.o objFile/commonFunc.o
all: objFile test
test: testFunc.c
$(cc) $^ -lCfunc -o $# $(CFLAGS)
objFile: $(libObjs)
gcc -shared -o ../lib/libCfunc.so $(libObjs)
objFile/cacheOp.o: Bodyer/cacheOp.c Header/cacheOp.h Header/cacheDetails.h
$(cc) -c $< -o $# $(CFLAGS)
objFile/fileOp.o: Bodyer/fileOp.c Header/fileOp.h
$(cc) -c $< -o $# $(CFLAGS)
objFile/linuxOp.o : Bodyer/linuxOp.c Header/linuxOp.h
$(cc) -c $< -o $# $(CFLAGS)
objFile/commonFunc.o : Bodyer/commonFunc.c Header/commonFunc.h
$(cc) -c $< -o $# $(CFLAGS)
.PHONY : clean
clean :
-rm $(libObjs)

The objFile file doesn't exist, so Make tries to build it.
Since your rule doesn't actually create a file called objFile, the next time you run Make, the objFile file still doesn't exist, so Make tries to build it again. And so on.

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.

How to make a Makefile that includes my header?

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.

The compile file doesn´t seem to be working

I wanted to ask if the following Makefile is correctly written, because the programme doesn´t seem to compile correctly but I´m not sure if the makefile or the code is the problem :
CC = /usr/bin/gcc
CFLAGS = -g -Wall -Wextra -Werror -pthread
DEPS = config.h shmHandling.h gameboard.h thinker.h strTools.h performConnection.h main.h
OBJ = main.o config.o shmHandling.o gameboard.o thinker.o strTools.o performConnection.o
# Link all .o files to program
%.o: %.c $(DEPS)
#echo "-----------------------"
#echo "Linking object files"
$(CC) -o -c $# $< $(CFLAGS)
sysprak-client: $(OBJ)
$(CC) -o $# $^ $(CFLAGS)
# Compile everything and run it with CL params
.PHONY: play
play: sysprak-client
#echo "-----------------------"
#echo "Launching sysprak-client with GameID: $(GAME_ID)"
./sysprak-client -g $(GAME_ID) -p $(PLAYER)
.PHONY: clean
clean:
-rm *.o $(OBJ)
Thanks!
This recipe:
$(CC) -o -c $# $< $(CFLAGS)
shall be:
$(CC) -o $# -c $< $(CFLAGS)
The -o option must be followed by the output file name and $# expands exactly as the name of the target object file. So -o $# is correct while -o -c is not.
Note: the comment before the rule it is part of is wrong. The rule compiles the C source files to object files. It is the following rule that Link all .o files to program. Same with the echo command. You should probably rewrite all this as:
# Compile each .c to .o
%.o: %.c $(DEPS)
#echo "-----------------------"
#echo "Compiling $<"
$(CC) -o $# -c $< $(CFLAGS)
# Link all .o files to program
sysprak-client: $(OBJ)
#echo "Linking object files"
$(CC) -o $# $^ $(CFLAGS)
# Run with CL params
.PHONY: play
play: sysprak-client
#echo "-----------------------"
#echo "Launching sysprak-client with GameID: $(GAME_ID)"
./sysprak-client -g $(GAME_ID) -p $(PLAYER)

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 =

Resources