Home > Blockchain >  Makefile with multiple separate *.cpp files to output separate *.exe files in different dir
Makefile with multiple separate *.cpp files to output separate *.exe files in different dir

Time:07-15

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.

  • Related