Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile all CPP files using makefile under MinGW

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

like image 303
emesx Avatar asked Oct 28 '12 14:10

emesx


People also ask

How do I run a makefile with Mingw?

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.

Does C++ use makefile?

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++.

Can G ++ compile C code?

gcc is used to compile C program. g++ can compile any . c or . cpp files but they will be treated as C++ files only.

Where are makefiles stored?

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.


2 Answers

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.

like image 169
Olaf Dietsche Avatar answered Oct 06 '22 01:10

Olaf Dietsche


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/
like image 39
Brian Cain Avatar answered Oct 06 '22 02:10

Brian Cain