Makefile doesn't clean object files - c

Here is the makefile:
OBJS = main.o hashFunction.o input.o list.o list_inverted_index.o memory.o operations.o sort.o
SOURCE = main.c hashFunction.c input.c list.c list_inverted_index.c memory.c operations.c sort.c
HEADER = hashFunction.h input.h list.h list_inverted_index.h memory.h operations.h sort.h
OUT = myexe
CC = gcc
FLAGS = -g -c -Wall
# -g option enables debugging mode
# -c flag generates object code for separate files
all: $(OBJS)
$(CC) -g $(OBJS) -o $(OUT)
# create/compile the individual files >>separately<<
main.o: main.c
$(CC) $(FLAGS) main.c
hashFunction.o: hashFunction.c
$(CC) $(FLAGS) hashFunction.c
input.o: input.c
$(CC) $(FLAGS) input.c
list.o: list.c
$(CC) $(FLAGS) list.c
list_inverted_index.o: list_inverted_index.c
$(CC) $(FLAGS) list_inverted_index.c
memory.o: memory.c
$(CC) $(FLAGS) memory.c
operations.o: operations.c
$(CC) $(FLAGS) operations.c
sort.o: sort.c
$(CC) $(FLAGS) sort.c
# clean house
clean:
rm -f $(OBJS) $(OUT)
# do a bit of accounting
count:
wc $(SOURCE) $(HEADER)
I tried to append this *.o to the clean section (because of this answer), but it didn't work.

I had to modify the makefile as such:
all: $(OBJS)
$(CC) -g $(OBJS) -o $(OUT)
make clean

You might lack a
.PHONY: all clean count
rule. The .PHONY: target and rule should appear near the start of the Makefile, just after the variables definition (in your case, below the definition of FLAGS).
If you happen to have all or clean files (check with ls -l clean all in a terminal), you need to remove them using rm
You'll clean using make clean command.
See also this answer for useful hints (about remake -x & make --trace)
BTW, your FLAGSĀ  should probably be CFLAGS (see output of make -p)
Read the documentation of make

You should not normally need or want to "clean object files". The whole point of using Make, is that you don't clean up but stay dirty!
If you always want to clean everything up and start each build from scratch, then don't bother using Make, but write a shell script instead.

Related

Makefile Structure

I'm making a program in C and I want to know how to structure and run my program using a Makefile.
I have three files:
main.c
count.c
bin2csv.c
I also have these headers:
bin2csv.h
count.h
struct.h
This is my makefile:
CC = gcc
OBJS = main.o count.o bin2csv.o
HEADERS = struct.h count.h bin2csv.h
APP_NAME = project2
all: $(APP_NAME)
$(APP_NAME): $(OBJS) $(HEADERS)
$(CC) $(OBJS) -o $(APP_NAME)
main.o:
$(CC) -c main.c
count.o:
$(CC) -c count.c
bin2csv.o:
$(CC) -c bin2csv.c
clean:
rm -f *.o $(APP_NAME)
My questions are as follows:
What is happening in this make file? It goes through the hierarchy and compiles these .c files into object files, including the headers?
How would I run and compile my program?
I attempted to make a change in main.c, by adding a print statement, but I figure compiling using gcc would throw off the makefile. I know I can use the command make I don't believe anything changed.
You need to say that the .o files depend on the .c files:
main.o: main.c <---- HERE
$(CC) -c main.c
count.o: count.c <---- HERE
$(CC) -c count.c
bin2csv.o: bin2csv.c <---- HERE
Otherwise, make has no reason to think it needs to re-make the .o files.
To prevent re-make (so add dependecies), I recomand you to use a variable to list your .c files instead of .o ones and deduce objects name:
SRC= main.c \
count.c \
bin2csv.c
OBJS= $(SRC:.c=.o)
OBJS will contain your .o filenames, and you can use it in same way that you're doing:
$(APP_NAME): $(OBJS) $(HEADERS)
$(CC) -o $(APP_NAME) $(OBJS)
And clean rule
clean:
rm -f $(OBJS) $(APP_NAME)
If you want change headers files you can add -I to gcc to add specific headers directory:
HEADERS_DIR= $(PROJECT_ROOT)/include
$(CC) -I $(HEADERS_DIR) -o $(APP_NAME) $(OBJS)

Make different executables one library used by all

I have a project with the following structure:
- main1.c
- main2.c
- main3.c
- lib.h
- lib.c
All the mains use the import lib.
How can I write a Makefile that creates 3 executables (one per each main)?
First Approach
I created a Makefile that does that, but you'd need to append the name of the executable after calling the make command (i.e. make main1, make main2, etc), However if I try using only make (without arguments), it only makes the first main (main1).
CC=gcc
CFLAGS=-g -O2 -Wall
LDFLAGS=-framework OpenCL
DEPS=lib.h
OBJS=main1.o main2.o main3.o
%.o: %.c $(DEPS)
$(CC) $(CFLAGS) -c -o $# $<
main1: lib.o main1.o
$(CC) $(CFLAGS) -o $# $^
main2: lib.o main2.o
$(CC) $(CFLAGS) -o $# $^
main3: lib.o main3.o
$(CC) $(CFLAGS) -o $# $^ $(LDFLAGS)
clean:
rm -f *.o main1 main2 main3
Makefile
https://www.gnu.org/software/make/manual/html_node/Goals.html
By default, the goal is the first target in the makefile (not counting
targets that start with a period). Therefore, makefiles are usually
written so that the first target is for compiling the entire program
or programs they describe.
So just add the below line as the first target in your makefile:
all: main1 main2 main3

I need some assistance with Makefile in my project

I'm trying to make a Makefile but I'm having some problems
first I have
2 source files: ~/main.c ~/lib/library.c
1 header file: ~/include/library.h
main.c and library.c both share the same header file library.h
# Compiler options
CC = gcc
INC = -I../include
CFLAGS = -Wall -g -c $(INC)
LIB = -L../lib
LFLAGS = -Wall -g $(LIB)
# Dependencies
LIBS = -libmylib
OBJS = main.o
SRCS = $(OBJS:.o=.c)
EXEC = a.out
# Other rules
RM = rm -rf
TAGS = tags
BAK = Makefile.bak
all: $(EXEC)
#echo ------------------------ Compile Complete ----------------------------
.PHONY: clean depend
$(EXEC): $(OBJS)
$(CC) $(LFLAGS) -o $# $^ $(LIBS)
.c.o:
$(CC) $(INC) -M $^
$(CC) $(CFLAGS) -o $# $<
clean:
$(RM) *.o *~ $(EXEC) $(TAGS) $(BAK)
depend: $(SRCS)
makedepend $(INC) $^
it keeps saying that I it can't make a rule out of library.o
plus I have another question
I acknowledge the fact that when Makefile comes in to action after calling 'make',
and subsequently go to the line .c.o or %c: %o(in GNU enhanced version) and make
.o files. but why doesn't it also call clean and depend automatically?
I've edited some things from the previous version of Makefile
this time, (well pretty similar to the previous problem) even though I
clarified the library path(-I../lib),
the Makefile cannot find the archive file (which I created as libmylib.a in ../lib dir)
now it's driving me crazy
but why doesn't it also call clean and depend automatically?
Because make only builds the target you tell it. If you don't specify one, the first target is built, which in many cases, such as yours, is the 'all' target.

How to use makefile to compile all sources (some only to object files)?

I'm getting an "undefined reference to main" error on one of my files when trying to compile. I know this is because this file doesn't have a main method. This is just an implementation file for some helper methods, so I only want it compiled to an object file not an executable. I know how to do this if I explicitly tell the makefile what to do for each file, but I'm trying to write a makefile that will compile all of my sources at once. I tried using the -c flag, but then it compiled all of my files to only object files rather than executables. How in the world do I do this?
Here it is:
CC = gcc
CFLAGS = -g -Wall
SRCS = ./src/server.c ./src/client_slave.c ./src/sockaddrAL.c
EXECS = ./bin/server ./bin/client_slave
OBJS = $(SRCS:.c=.o)
all: clean $(SRCS) server client
server: $(OBJS)
$(CC) $(CFLAGS) ./src/server.o -o ./bin/server
client: $(OBJS)
$(CC) $(CFLAGS) ./src/client_slave.o -o ./bin/client_slave
.c.o:
$(CC) $(CFLAGS) -c $< -o $#
clean:
#rm -f $(EXECS) $(OBJS)
You should add the -c flag to the rule that builds .o files (your .c.o suffix rule) and not add it to the rule that builds the executables (the $(EXECS) rule).
CC = gcc
CFLAGS = -g -Wall
EXECS = ./bin/server ./bin/client_slave
all: $(EXECS)
./bin/%: ./src/%.o ./src/sockaddrAL.o
$(CC) $(CFLAGS) -o $# $^
.c.o:
$(CC) $(CFLAGS) -c $< -o $#
clean:
#rm -f $(EXECS) $(OBJS)
You didn't show sockAddrAL at all in your question so I assumed it belonged in both executables. Also note that the above syntax assumes GNU make. If you want to use only features available in POSIX standard make you pretty much have to write it all out.
Let implicit rules be your friend. Your entire Makfefile should just be:
CC = clang
CFLAGS = -O0 -g -Wall
SRCS = server.c client_slave.c sockaddrAL.c
OBJS = $(SRCS:.c=.o)
EXECS = server
server: $(OBJS)
clean:
#rm -f $(EXECS) $(OBJS)
Invoke it from the src directory.

make file, Is this look ok?

all: run
run: test.o list.o matrix.o smatrix.o
gcc test.o list.o matrix.o smatrix.o -o matrix-mul
list.o: list.c list.h
gcc -g -c list.c
matrix.o: matrix.c matrix.h
gcc -g -std=c99 -c -o matrix.o matrix.c
smatrix.o: smatrix.c smatrix.h
gcc -g -c -o smatrix.o smatrix.c
test.o: test.c test.h
gcc -g -c test.c
I was having lots of problems to make a makefile and I finally got this working. And I just want to make sure these are ok (not just for making program running but in term of a good make file)
One question is that why do matrix.o and smatrix.o have .o files in the line gcc -g -c ... where as list.o and test.o don't have that line..
I had to add -std=c99 because I was getting some weird for loop error but still don't understand why I need to put matrix.o in the line..
The file is OK-ish. It is not very easily maintainable.
This website has a really good tutorial on how to make nice makefiles:
http://mrbook.org/blog/tutorials/make/
Especially look at the last example:
CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=main.cpp hello.cpp factorial.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=hello
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $#
.cpp.o:
$(CC) $(CFLAGS) $< -o $#
This should show you how to enhance maintainability (add extra files to SOURCES, and the rest is done automatically.
The below file supports make all make depend and make clean - you only need to change the first lines. Remember to make depend if you change includes in any file.
TARGET:=matrix-mul
SOURCES:=test.c list.c matrix.c smatrix.c
OBJECTS:=$(SOURCES:%.c=%.o)
CC=gcc
CFLAGS=-g -std=c99 -Wall
LD=gcc
LDFLAGS=
# First target - simply say that we want to produce matrix-mul
all: $(TARGET)
# To create the target we need all .o files, and we link with LD/LDFLAGS
# $# is the file we're making, aka matrix-mul
$(TARGET): $(OBJECTS)
$(LD) -o $# $(OBJECTS) $(LDFLAGS)
#Creating a .o from a .c
# $< is the c file, $# is the corresponding .o file
.c.o:
$(CC) $(CFLAGS) -c $< -o $#
# Regenerate dependencies
depend:
$(CC) $(CFLAGS) -MM $(SOURCES) > .depend
# Remove produced files
clean:
rm -rf $(OBJECTS) $(TARGET) .depend
# If there's no dependency file, create it
.depend: depend
# Include the autogenerated dependency file
include .depend
EDIT: If you want this even more generic, you can replace the SOURCE:= line with:
SOURCES:=$(wildcard *.c)
This makefile will then simply build TARGET from all .c files in the current directory.
One thing I would highly suggest here would be to add a clean target that deletes all your intermediate files (probably all the .o files), like so:
clean:
rm *.o
For extra credit, put all your *.o files in a make variable, and use that variable as the target of the run rule, and after the rm command above.
The reason I want you to do this is for debugging purposes. It could be that you have one of the above rules wrong, but since you already built all your .o files once, it is just picking up an old one every time. If you do a make clean before your build, it will catch that.

Resources