i was wondering if anyone have sometime to answer some questions about GNU makefiles…
- how to create a directory if it doesn’t exists (“./obj”) for output?
- i have one makefile, but i got 2 build methods “Debug” and “Release”, can i have both in 1 makefile and how to tell it which one to build?
- ive been using Code::Blocks which builds only changed files, but my makefile builds them everytime i call make command, without touching any files. how can i make it build changed files only?
here is my current makefile
OBJPATH=./obj
COMPILER=gcc
Output: main.o Base64.o
$(COMPILER) -o Output.exe $(OBJPATH)/main.o $(OBJPATH)/Base64.o
strip Output.exe
main.o: main.c main.h
$(COMPILER) -c main.c -o $(OBJPATH)/main.o
Base64.o: Base64.c Base64.h
$(COMPILER) -c Base64.c -o $(OBJPATH)/Base64.o
thanks.
For the first question, you can put a fake target before any of the others, along the lines of:
That will automatically execute everything in the preamble (you have to make it the first dependency in every rule) before it builds anything else. The
-at the start of themkdirignores failures if, for example, the directory already exists.For the second question, you can provide something like:
and actually put the debug and release code in separate subdirectories. That way, you can build either with
make releaseormake debugand build them both withmake all.Third question: Your makefile builds every time because the rules tell it to. For example,
Output: main.o Base64.owill always try to build sinceOutputnever exists (the correct target seems to beOutput.exe).Similarly your object file rules will always execute since neither
main.onorBase64.oare updated by their statements (they update the files in theobjdirectory instead).You may be able to fix that case by making the target
$(OBJPATH)/main.obut, to be honest, I don’t usually worry about separating objects and executables into separate directories. I tend to just lump them all into one directory and letmake -cleanclean them up.So the makefile I would start with would be:
In response to your comment question:
GNU Make may be more powerful than the ones I’m used to but you can do that by setting an environment variable then re-running make as per the following:
which outputs:
You can see the two separate variables marked with
<==above.As I said, there’s probably an easier way to do it with GNU Make but that’ll get you started.