The directory structure of my C++ project is
/..
makefile <- the makefile is in root
/include <- subdirectory that has to be included while compiling
/obj <- target place for all *.o and final executable
/src <- sources
And my current makefile is:
CC=g++
CFLAGS=-c -Wall -std=c++11
INC=-Iinclude
SRC=src
TGT=obj
all: myapp
myapp: myapp.o
$(CC) $(TGT)/myapp.o -o $(TGT)/myapp
myapp.o:
$(CC) $(CFLAGS) $(INC) $(SRC)/myapp.cpp -o $(TGT)/myapp.o
clean:
rm -rf $(TGT)
mkdir $(TGT)
This worked for my first file. I am a total makefile novice - please help me compile all files under the /src
directory and link them to an executable in /obj
directory.
the makefile has to work under Windows, I am using MinGW and MSYS
Before running a Makefile in Windows, it is required to install the make command first by using the “Mingw-get install mingw32-make” command on the Command Prompt. Then, create a Makefile, remove the “. txt” extension, and use the “make” command to run the specified Makefile in Windows.
Given a C++ program and the task is to break the entire program in the form of Makefile. It is basically used to create . cpp file and . h file for each class/functions and its functionalities and later link them all through a Makefile command available in C++.
gcc is used to compile C program. g++ can compile any . c or . cpp files but they will be treated as C++ files only.
some projects put their makefile in src/ subdirectory of the root directories of the projects, some projects put their makefiles in the root directory of the project.
Add a list of your source files:
SOURCES = $(wildcard $(SRC)/*.cpp)
and a list of corresponding object files:
OBJS = $(addprefix $(TGT)/, $(notdir $(SOURCES:.cpp=.o)))
and the target executable:
$(TGT)/myapp: $(OBJS)
$(CXX) $(LDFLAGS) $(OBJS) -o $@
The rule for building the objects:
$(TGT)/%.o: $(SRC)/%.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@
Now you must specify are the options for g++:
INCLUDES = -Iinclude
CXXFLAGS = -Wall -std=c++11 $(INCLUDES)
And everything together:
SRC=src
TGT=obj
INCLUDES = -Iinclude
CXXFLAGS = -Wall -std=c++11 $(INCLUDES)
SOURCES = $(wildcard $(SRC)/*.cpp)
OBJS = $(addprefix $(TGT)/, $(notdir $(SOURCES:.cpp=.o)))
$(TGT)/%.o: $(SRC)/%.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@
$(TGT)/myapp: $(OBJS)
$(CXX) $(LDFLAGS) $(OBJS) -o $@
It is important, that in front of $(CXX) ...
there must be a "tab" character, not spaces.
You can use VPATH
for separating source and object files:
src/myapp.c
obj/Makefile
Take your existing Makefile
, move it into obj/
, omit references to $(TGT)
and $(SRC)
and add the following:
VPATH=../src
Note that if you are trying to do multi-architecture builds, VPATH
is not ideal.
BTW, you're not capitalizing on builtin rules. Where you have
CC=g++
CFLAGS=-c -Wall -std=c++11
myapp: myapp.o
$(CC) $(TGT)/myapp.o -o $(TGT)/myapp
myapp.o:
$(CC) $(CFLAGS) $(INC) $(SRC)/myapp.cpp -o $(TGT)/myapp.o
you could instead use:
CXXFLAGS=-Wall -std=c++11
CXXFLAGS+=$(INC)
LDLIBS+=-lstdc++
myapp: myapp.o
So, to sum it all up, your new obj/Makefile
should look like this:
VPATH=../src
INC=-I../include
CXXFLAGS=-Wall -std=c++11
CXXFLAGS+=$(INC)
LDLIBS+=-lstdc++
myapp: myapp.o
You can create another Makefile
up from obj/
to recurse down into this new one, if necessary:
all: obj/myapp
obj/myapp:
mklink obj/Makefile ../Makefile
$(MAKE) --directory=obj/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With