I am stuck, writing my Makefile. Directory structure:
.\
Makefile
.\src\*.cpp(s)
.\bin
I want to run one Makefile
that compiles each of the *.cpp
file(s) in source, and for each *.cpp/*.exe
is generated. Each *.cpp
file is a separate program with its own main()
.
.PHONY: all
CXX = g
CXXFLAGS = -g -Wall
SRC := $(wildcard src/*.cpp)
OBJS := $(SRC:.cpp=.o)
BIN := bin
all: $(BIN)
$(BIN): $(OBJS)
$(CXX) $(CXXFLAGS) -o (BIN) $(OBJS)
Desire: What I want to achieve with one Makefile
.
Run: make
Output (Terminal):
g -g -Wall -c -o src/program1.o src/program1.cpp
g -g -Wall -c -o src/program2.o src/program2.cpp
g -g -Wall -c -o src/program3.o src/program3.cpp
g -g -Wall -c -o src/program4.o src/program4.cpp
Output (in /bin/)
program1.exe
program2.exe
program3.exe
program4.exe
CodePudding user response:
Try something like:
SRC:=${wildcard src/*.cpp}
OBJ:=$(patsubst %.cpp,%.o,${patsubst src/%,bin/%,${SRC}}}
to get the list of the object files, and the rule:
obj/%.o : src/%.cpp
${CXX} -o $@ -c $<
for compiling into the right location.
EDIT You have now clarified that each file is a separate main.
SRC:=${wildcard src/*.cpp}
BIN:=$(patsubst %.cpp,,${patsubst src/%,bin/%,${SRC}}}
to get the list of the object files, and the rule:
bin/% : src/%.cpp
${CXX} -o $@ $<
will write each output as an executable in bin
. To kick it off:
all : ${BIN}
CodePudding user response:
The introductory parts of the GNU make manual describe that all: $(BIN)
creates a target all
that depends on a target bin
. That means make will try to create bin
. Then you have $(BIN): $(OBJS)
which says bin
depends on all the object files, so make will try to create all the object files. Then there's a recipe for that rule that says, after you've created the object files run this command, which links together all the object files into a single program (bin
).
So make is doing exactly what you asked it to do.
The problem is that is apparently not what you want it to do.
In your question you write, then take the original filenames of each *.cpp and add that to the executable which I don't fully understand, but I assumed that you want to link all the objects into a single executable, which is what your makefile does.
But then later you write: How can I output to bin directory and generate the correct executables?, but you never define what "correct executables" means, and this makes it sound like you want to turn each individual object file into its own executable; that's clearly not what your makefile does.
So before you can tell make what you want, first you have understand clearly what you want so you can write it in your makefile. And if you need us to help you write it into your makefile, you need to explain it clearly in your question so we can understand it.
Cheers!
ETA
OK so you want every source file to compile into an object file, then every object file to compile to a separate binary.
First compute the names of all the binaries you want to build:
SRCS := $(wildcard src/*.cpp)
BINS := $(SRCS:src/%.cpp=bin/%)
Now make a rule that depends on all the binaries:
all: $(BINS)
Now make a pattern rule that tells make how to build each one of those binaries:
bin/% : src/%.o
$(CXX) $(CXXFLAGS) -o $@ $^ $(LDLIBS)
Now you're actually done, because make already has a built-in rule that knows how to build a .o
file into the same directory where the .c
file lives, so it can figure out how to build the src/x.o
files on its own.