Reputation: 5606
I'm writing C++ project made of few files on Linux. The project have no subdirectories.
I wanted like to have some as simple as possible, generic build script.
By generic, I mean that I don't want to hardcode file names, so that when I put new .cpp
file into project, I don't have to modify build script. It should find and compile all modyfied source files in current directory, and link object files into executable. Nothing more.
I don't care about tool you'll use, since I don't know any yet.
I don't want to learn a tool from basics to write something as simple as that. For now, I just need a code, I'll learn when I'll need something more fancy.
make
:a.out: %.o
$(CXX) %.o
%.o: %.cpp
$(CXX) -Wall -c %.cpp
with no success:
make: *** Brak reguł do zrobienia obiektu `%.o', wymaganego przez `a.out'. Stop.
my translation of this message:
make: *** No rules to make object `%.o', required by `a.out'. Stop.
Before someone will ask, I'll answer: yes, my makefile is indented with 1 tab, not with spaces.
make -d
prints out 664 lines, so I won't paste it here.
scons
:Program("main.cpp")
It's copyed from some StackOverflow answer, but it is definietly intended to build a executable from one source file, because I get linker errors when I want use it.
I ended us using bash:
g++ -Wall *.cpp
Simple. Does the job well... for now. I don't think it's elegant and I know it's probably inefficent, because it recompiles everything, even unmodyfied files.
Upvotes: 0
Views: 3716
Reputation: 5606
SRC := $(wildcard src/*.c)
DEP := $(SRC:src/%.c=lib/%.d)
OBJ := $(SRC:src/%.c=lib/%.o)
CFLAGS := -Wall -Wextra -O2 -MMD
# Executable
lib/mines: lib/assets.o $(OBJ)
${CC} $^ -o $@
# Object files
lib/%.o:: src/%.c
${CC} -c $< -o $@ ${CFLAGS}
# Dependencies
# http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/
-include $(DEP)
.PHONY: clean
clean:
rm lib/*
Upvotes: 0
Reputation: 1
I guess that you have a directory full of single-source C++ programs (e.g. each program has one single C++ source file) named .cpp
(e.g. foo.cpp
& bar.cpp
), each independently compiled to an executable (e.g. foo
& bar
). You might try the following (untested) Makefile
for GNU make
.
CXX= g++
CXXFLAGS= -Wall -Wextra -g -O
RM= rm -vf
SOURCES= $(wildcard *.cpp)
BINARIES= $(patsubst %.cpp, %, $(SOURCES))
.PHONY: all clean
all: $(BINARIES)
clean:
$(RM) *~ *.o $(BINARIES)
Read the documentation of GNU make
and try make -p
to find the builtin rules. See also these two examples of Makefile
-s: this & that
If on the contrary you want one single executable myprogram
from all the *.cpp
files (like foo.cpp
& bar.cpp
etc....), you still can use $(wildcard *.cpp)
in your Makefile
(and you'll better not name a.out
your executable, but something more meaningful), something like (in addition of common stuff like CXXFLAGS=
above):
SOURCES= $(wildcard *.cpp)
OBJECTS= $(patsubst %.cpp, %.o, $(SOURCES))
all: myprogram
myprogram: $(OBJECTS)
$(LINK.cc) $^ -o $@ $(LIBES)
In all cases, using $(wildcard *.cpp)
is enough to have a Makefile
generic enough on the list of sources. You may want to generate autodependencies (using gcc -M
things, to some of your header files), see this.
Notice that you might have some C++ source or header files generated by some other means (e.g. your own awk
or python
script, or a _timestamp.c
file generated with date
, or some C++ files produced by a code generator like GNU bison or gperf, etc, etc...). Then you need to add specific rules into your Makefile
.
So in practice, I don't believe in fully generic build files, but I am trying to show you that a Makefile
can be almost generic and short. At some time you'll adapt it to your particular needs.
Upvotes: 2