This is my absolute first time ever making a makefile, and I'm really trying to understand the process.
I'm trying to create a very simple makefile for a C++ project whose structure is as follows:
root folder
makefile
readme
src folder
...source files all here...
include folder
...header files for external libraries here...
lib folder
...external lib files all here...
bin folder
...output directory for built executable...
obj folder
...object files all here...
I followed the tutorial here.
Here's my makefile:
IDIR=include .
CC=g++
CFLAGS=-I$(IDIR)
ODIR=bin/obj
LDIR=lib
LIBS=none
SRC=src
_DEPS=hello.h
DEPS=$(patsubst %,$(IDIR)/,%(_DEPS))
_OBJ=file1.o file2.o
OBJ=$(patsubst %,$(ODIR)/%,$(_OBJ))
$(ODIR)/%.o: $(SRC)/%.cpp $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS) # $(LIBS)
test_proj: $(OBJ)
$(CC) -o $@ $^ $(CFLAGS)
.PHONY: clean
clean:
rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~
When I run make
on this, I get the following error:
g++ -o .o
g++: fatal error: no input files
compilation terminated.
<builtin>: recipe for target '.o' failed
mingw32-make.exe: *** [.o] Error 1
I'm using GNU Make 3.82.90 built for i686-pc-mingw32, if that matters at all.
Can anyone point out whatever ridiculous error I'm making?
is the first problem. Replace it by:
With your code
CFLAGS
is expanded as:It does not make sense, I'm afraid. The second problem is:
which should probably be:
and would expand as:
if you fix the first problem, else as:
which does not make sense neither. The cumulated effect of these two errors are strange recipes (I didn't try to expand them by hand) that probably trigger a make implicit rule with wrong parameters.
This is wrong. First, for C++ code, use
CXX
notCC
andCXXFLAGS
notCFLAGS
. Runmake -p
to understand the builtin rules of yourmake
.Then
-I$(IDIR)
does not "distribute" the-I
, andIDIR
is never used elsewhere. So I suggest to start yourMakefile
with:I won't improve your
Makefile
, but I do suggest to upgrade to GNUmake
version 4 if possible (and compilingmake
4.1 from its source code is worthwhile in 2015) for that purpose. If possible enable GUILE scripting in it.If you are forced to use
make
3.82 debug yourMakefile
usingremake
(with-x
); if you can afford amake
version 4 use its--trace
optionBTW, you might consider using automatic dependencies, that is generating dependencies by passing
-M
or-MG
(etc) flags ofg++
, see that.At last, a simple project for a small program (less than a hundred thousands of source lines) might just put all (a few dozens of) its files in the current directory (then the
Makefile
could be simpler); your proposed directory structure might be arcane for a simple project (but could worth the pain if you have millions of C++ source lines of code). I've given several simple examples ofMakefile
, e.g. this & that. And GNU make source code itself has a less complex file tree that what you want.BTW, I strongly disagree with the opinions of that answer (which I did upvote, since it is helpful). I don't feel that GNU make is senile, but I regret that, instead of using recent features available on recent versions (4.x) of
make
, many people prefer to use complex and arcaneMakefile
generators (likecmake
) instead of coding a cleverMakefile
(formake
version 4 specifically).At last, you could use other builders, e.g. omake,
icmake
, ....