I have the following directory:
Makefile
src/
main.c
dummy.raw
(main.o) (<- to be built)
(dummy.txt) (<- to be built)
build/
(main) (<- to be built)
And the following Makefile:
C_FILES=$(wildcard src/*.c)
O_FILES=$(C_FILES:%.c=%.o)
main: build/main
build/main: $(O_FILES)
gcc $(O_FILES) -o build/main
src/%.o: src/%.c src/dummy.txt
echo "Compiling using my rule"
gcc -c $< -o $#
src/%.txt: src/%.raw
touch $#
#echo "Created dummy file"
clean:
rm -f src/*.o
rm -f src/*.txt
rm -f build/*
The problem is that make seems to ignore my rule for producing .o files and use its own built-in version ; in particular, it does not build dummy.txt. Here's a sample output:
$ make clean
rm -f src/*.o
rm -f src/*.txt
rm -f build/*
$ make
cc -c -o src/main.o src/main.c
gcc src/main.o -o build/main
make only starts using the rule in the Makefile if I build the .txt file myself using make src/dummy.txt.
Why is make behaving this way?
How do I correct my Makefile to force make to build the intermediate dummy.txt?
Thanks!
The trouble is that your method invokes a chain of pattern rules, one to build src/main.o and one to build src/dummy.txt, and Make will prefer an implicit rule to a chain of pattern rules.
There are a couple of ways to solve this. Two simple ones:
You could invoke Make with the ‘-r’ a.k.a. ‘--no-builtin-rules’ option:
make -r
Or you could hard-code the rule for src/dummy.txt:
src/%.txt: src/%.raw
touch $#
#echo "Created dummy file"
src/dummy.txt: src/dummy.raw
Related
I have a python script that needs to run before any other rule because it generates a few .c files that I want to compile. But there lies the problems.
In my make file I have a rule to make the depends
SRC = autogenerated_file1.c autogenerated_file2.c
depend dep: .depend
include .depend
But the problem is the files dont exist when the make file is run to make the depends, I need the python script to run first, how would I set up a rule to run before the include of the depends.
Any help would be greatly appreciated.
I simplified my makefile and provided it here:
SUBDIRS = ../modules/mod1 \
../modules/mod2 \
../modules/mod3
CFLAGS=-g -Wall
ARFLAGS=rs
CFLAGS:=$(CFLAGS) -I.
APPLICATION_FILES = main.c autogen1.c autogen2.c
APPLICATION_OBJ=$(APPLICATION_FILES:.c=.o)
-include $(APPLICATION_FILES:.c=.d)
.PHONY: dummy
dummy:
cd ../scripts && \
python autgen_files.py
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $#
clean :
rm -f *.o *.elf *.d
-for d in $(SUBDIRS); do (cd $$d; $(MAKE) clean ); done
%.fin: dummy $(SUBDIRS) %.elf
$(SUBDIRS):
$(MAKE) -C $#
%.d : %.c
$(CC) -MM $(CFLAGS) $*.c > $*.d
%.elf: $(APPLICATION_OBJ)
$(CC) -Tapp.ld $(CFLAGS) -o $# $^
The problem here is the autogen1.c and autogen2.c are not available at the start of make. And if I do what I provided above I get caught it a loop of recursive make.
I should say the way I start the build is "make test.fin"
If the python script generates the file .depend (that's my understanding but I'm not entirely sure), then add this rule:
.depend: script.py
$<
This way make will know that .depend is also a target that needs to be made, and will run script.py if it's newer than .depend or if .depend does not exist. Tweak to taste.
Note that this might only work with GNU Make.
I've downloaded a basic makefile which I'm trying to edit to allow debugging of the program in linux, however even after adding the -g flag to the makefile, the terminal just displays [ No Source available ] when running the gdbtui command instead of the debugging information as expected.
Here's the makefile in question:
CC=gcc
EXE=myprog
CFLAGS=
LDFLAGS=
OPTCFLAGS=-O2
DEBUGCFLAGS=-g
OBJ=main.o util.o
# Default Target, dependency on $(EXE) target
all: $(EXE)
# Optimised target, add OPTCFLAGS
opt: CFLAGS+=$(OPTCFLAGS)
opt: $(EXE)
# Debug target, add DEBUG Flags
debug: CFLAGS+=$(DEBUGCFLAGS)
debug: $(EXE)
$(EXE): $(OBJ)
$(CC) $(LDFLAGS) -o $# $^
%.o:%.c
$(CC) $(CFLAGS) -c $<
.PHONY: clean test
clean:
rm *.o
rm $(EXE)
Thanks for all the help in advance.
Your makefile is OK for make debug.
gdbtui is reporting [ No Source Available ] right after you run gdbtui myprog
just because you have not yet started gdb so no debugging information
has yet been read from myprog
At this point you will see gdbtui prompting you:
---Type <return> to continue, or q <return> to quit---
Type <return>; then gdb still start; the source code will appear, and gdb will wait for
your debugging commands.
Apart from the oddness #MadScientist has noted about the default target,
there is this small bug in your makefile: The clean recipe:
clean:
rm *.o
rm $(EXE)
should be:
clean:
rm -f *.o
rm -f $(EXE)
or simply:
clean:
rm -f *.o $(EXE)
Without the -f (force) option, if you were to delete the object files
without deleting myprog and then run make clean, it will fail at rm *.o
and not run rm $(EXE).
You didn't show the commands you're using to run make. This makefile has the default target (all) not adding any flags at all (which is an odd decision).
In order to build an optimized version you have to run make clean followed by make opt.
To build a debug version of you have to run make clean followed by make debug.
What did you actually do?
I am trying to write a make file that:
1) Turns the files myftpserver.c and myftpclient.c into myftpserver.o and myftpclient.o by just typing the command 'make'.
2)I'm also adding a 'clean' target for cleaning up the directory (removing all temporary files, object files and executable files)
3)using gcc compiler.
My current version is not working:
CC=gcc
myftpserver: myftpserver.o
$(CC) -o myftpserver.o
myftpclient: myftpclient.o
$(CC) -o myftpclient.o
clean: ? // not sure what to put here
This is my first time making a makefile. I've tried several other combinations but none seems to work. What am I doing wrong?
Make has rules built-in for basic C files, so you don't need to tell it how to build myftpserver.o or myftpclient.o. This Makefile should work correctly, and properly includes .PHONY so the clean rule won't get disabled in the presence of a file named "clean"
CC:=gcc
.PHONY: clean all
all: myftpserver myftpclient
myftpserver: myftpserver.o
myftpclient: myftpclient.o
clean:
rm -f *~ *.o myftpserver myftpclient
To test:
$ make --dry-run
gcc -c -o myftpserver.o myftpserver.c
gcc myftpserver.o -o myftpserver
gcc -c -o myftpclient.o myftpclient.c
gcc myftpclient.o -o myftpclient
Hope this helps!
You want instructions for compiling your .o file, and the rm shell command to clean:
CC=gcc
myftpserver: myftpserver.o
$(CC) -o myftpserver myftpserver.o
myftpclient: myftpclient.o
$(CC) -o myftpclient myftpclient.o
myftpserver.o: myftpserver.c
$(CC) myftpserver.c
myftpclient.o: myftpclient.c
$(CC) myftpclient.c
clean:
rm -f *~ *# *.o myftpserver myftpclient
I want to make a make file for my lexical analyzer using flex ,I have tried to many templates of make files but it did not work so please help me build one here is the lines to compile the code:
lex -t lexical.l > lexical.c
cc -c -o lexical.o lexical.c
cc -o lexy lexical.o -ll
If you're using GNU make you don't need a makefile at all. Built-in rules cover your use case.
Let's print built-in rules and see whether make knows how to transform '%.l' to '%.c'.
$ make -p | grep -A6 '\.l\.c'
make: *** No targets specified and no makefile found. Stop.
.l.c:
# Implicit rule search has not been done.
# Modification time never checked.
# File has not been updated.
# recipe to execute (built-in):
#$(RM) $#
$(LEX.l) $< > $#
It does. In a similar way you can check that GNU make knows how to build '%.o' from '%.c' and a '%' executable from '%.o'.
Assuming that there's a lexical.l in the current directory and there's no makefile let's see how would make build lexical.
$ make -n lexical
rm -f lexical.c
lex -t lexical.l > lexical.c
cc -c -o lexical.o lexical.c
cc lexical.o -o lexical
rm lexical.c lexical.o
Great. All we miss is the -ll flag for linking you asked for. Let's add it to LDLIBS.
$ make -n lexical LDLIBS=-ll
rm -f lexical.c
lex -t lexical.l > lexical.c
cc -c -o lexical.o lexical.c
cc lexical.o -ll -o lexical
rm lexical.c lexical.o
Voilà! As a result your makefile can be as short as
LDLIBS=-ll
all: lexical
A starting point would be
LEX = lex
.l.c:
$(LEX) -t $< >$#
.c.o:
$(CC) -o $# -c $<
lexy: lexical.o
$(CC) -o $# $^ -ll
This needs to be extended with clean rules, dependency tracking and so on, but I think you should be able to get the idea how Makefiles work.
GNU make has already defined the necessary rules for this. Just put this in a file named Makefile
LDLIBS = -ll
lexy: lexical.o
lexical.o: lexical.l
and run
$ make
and you're done.
I am currently learning C and now I am upto the tutorial where I need to write the Makefile but I am difficulty writing a Makefile for multiple sources. Can someone tell me how I can correct my code for the Makefile for multiple sources? All of the files are in the same directory and there are a total of 3 C source files as indicated by filename1/2/3 etc. I am trying to build 3 separate programs with 3 source files in a single makefile
OPT = -O4
all: filename1
filename1: filename1.o
gcc $(OPT) -o filename1 filename1.o
filename1.o: filename1.c
gcc $(OPT) -c filename1.c
filename2: filename2.o
gcc $(OPT) -o filename2 filename2.o
filename2.o: filename2.c
gcc $(OPT) -c filename2.c
filename3: filename3.o
gcc $(OPT) -o filename3 filename3.o
filename3.o: filename3.c
gcc $(OPT) -c filename3.c
clean:
rm -f *.o
rm -f filename1
rm -f filename2
rm -f filename3
Or is my code fine for what I want it to do?
Okay, so there doesn't appear to be anything wrong with the makefile, given that you're making three different programs. It should work.
Some suggestions for making it a little more usable:
1) Declare the "all" and "clean" targets to be phony. This will prevent Make from trying to make files called "all" and "clean".
.PHONY: all clean
2) You probably want your "all" target to build all three of your programs, not just one, so change that to:
all: filename1 filename2 filename3
3) If you end up using this to make more than three programs, and they all share similar build procedures, you can collapse your rules into a smaller set using pattern matches. See Martin Beckett's answer for an example. But, that's not necessary.
Your makefile should work, but it could be simplified.
The make utility supports implicit rules. This can simplify common operations, such as compiling a C source code file into an object file and compiling an object file into an executable.
CC=gcc
CFLAGS=-O4
all: filename1 filename2 filename3
%.o: %.c
$(CC) $(CFLAGS) -c $<
%: %.o
$(CC) $(CFLAGS) -o $* $<
clean:
rm -f *.o
rm -f filename1
rm -f filename2
rm -f filename3
For three separate programs built from three files like that, you could simply use:
PROGRAMS = filename1 filename2 filename3
all: ${PROGRAMS}
clean:
rm -f ${PROGRAMS} ${PROGRAMS:=.o}
You might add:
CFLAGS = -O4
to get that level of optimization. You might use a macro instead of the rm command; generally, mature makefiles use a lot of macros:
RM_F = rm -f
If you're targeting GNU Make, you could add:
.PHONY: all clean
And the list goes on.
The key point is that make knows how to build single-file programs already, and it knows how to compile C source into an object file, so you don't have to train it to do that.
Use pattern matching:
PROGS = filename1 filename2 filename3
all: $(PROGS)
# cancel implicit program rule
%: %.c
%: %.o
$(CC) $(LDFLAGS) $^ -o $#
%.o: %.c
$(CC) $(OPT) $(CFLAGS) $^ -c -o $#
clean:
rm -f $(PROGS) *.o
.PHONY: all clean
FWIW,
HTH
'A Generic Makefile for Building Multiple main() Targets in $PWD'
Makefile to compile multiple c programs?