I have the following source files:
% ls
data_lexicon.c data_lexicon.h lex.l makefile
And the following makefile:
% cat makefile
CC = cc
CFLAGS = -Wall -std=c89
LDFLAGS = -ll
OBJFILES = lex.o data_lexicon.o
TARGET = lexical_analyzer_1
all: $(TARGET) lex.c
lex.c: lex.l data_lexicon.h
lex -olex.c lex.l
$(TARGET): $(OBJFILES)
$(CC) $(CFLAGS) -o $(TARGET) $(OBJFILES) $(LDFLAGS)
clean:
rm -f $(OBJFILES) lex.c $(TARGET)
If I do make all
I get:
% ls
data_lexicon.c data_lexicon.o lex.l
lexical_analyzer_1 data_lexicon.h lex.c
lex.o makefile
So far so good.
However, I would like to move the source files (data_lexicon.c, data_lexicon.h, lex.l) to a folder src
and generate the intermediate files (data_lexicon.o lex.c, lex.o) into a obj
folder.
I create both folders but I do not understand how the makefile
file shall be configured.
I am using FreeBSD make, so the more portable the solution given the better.
However, I would like to move the source files (data_lexicon.c, data_lexicon.h, lex.l) to a folder src and generate the intermediate files (data_lexicon.o lex.c, lex.o) into a obj folder.
It never ceases to amaze me how people insist on making extra work for themselves. You can certainly do what you describe, but it will require writing explicit rules for the object files.
First of all, however, you need to understand that make
itself doesn't really know anything about directories. (Traditional make
doesn't, anyway. GNU make
and perhaps others know a little about them.) That is, it doesn't have any sense of varying directories against which it resolves file names. Rather, every target name is resolved against make
's working directory. If you want to refer to something in a subdirectory, then you must say so. To begin with:
OBJFILES = obj/lex.o obj/data_lexicon.o
Similar goes for target and prerequisite names in rules:
obj/lex.c: src/lex.l src/data_lexicon.h
lex -o$@ src/lex.l
That's also one reason to favor make
's automatic variables, such as the $@
in the above rule representing the name of the target being built.
Your makefile presently relies on make
's built-in rule for building object files from corresponding C source files, but "corresponding" means target and prerequisite names are identical, including any path components, except for the suffixes (.c
vs .o
). You will no longer have that correspondence for data_lexicon.o
, so you will need to write an explicit rule for it building it. This part is left as an exercise.