Makefile with sub-directories - c++

I am trying to write a makefile for a C++ project, divided into directories:
makefile
src – (all the .cpp files)
include (all the .h files)
obj (all the .o files)
bin (create the executable there)
I've read a lot about the subject but either it is too simple and they list the files manually or it is too complicated and I am lost.
I tried to write the makefile in many different ways and this is the last one:
CC = g++
CFLAGS = -std=c++11 -c -g -Wall
TARGET = bin/evolveIt
LINKER = g++ -o
# linking flags here
LFLAGS = -Wall -I. -lm
# change these to set the proper directories where each files shoould be
SRCDIR = src
OBJDIR = obj
HDIR = include
BINDIR = bin
SOURCES := $(wildcard $(SRCDIR)/*.cpp)
INCLUDES := $(wildcard $(HDIR)/*.h)
OBJECTS := $(SOURCES:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)
rm = rm -f
$(BINDIR)/$(TARGET): $(OBJECTS)
#$(LINKER) $# $(LFLAGS) $(OBJECTS)
#echo "Linking complete!"
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.cpp
#$(CC) $(CFLAGS) -c $< -o $#
#echo "Compiled "$<" successfully!"
.PHONEY: clean
clean:
But now I have this error:
src/PopulationManager.cpp:4:31: fatal error: PopulationManager.h: No such file or directory
#include "PopulationManager.h"
^
compilation terminated.
Makefile:28: recipe for target 'obj/PopulationManager.o' failed
make: *** [obj/PopulationManager.o] Error 1
I know that I have to use -I when the headers are in a different directory, but it is already in the CFLAGS and LFLAGS and it doesn't change anything if I put it directly in INCLUDES like this:
INCLUDES := -I $(wildcard $(HDIR)/*.h)
There is no error in the program itself, it compiled fine before I put into different directories. The point of this makefile was to avoid writing relative paths in my source files like
include "include/PopulationManager.h"
Any idea of what's wrong with this makefile?

Related

build c++ project using Make from two source directories in Linux

I have a c++ project in Linux in which source files are in 2 directories as shown below. Currently, the Makefile only compiles the files in the source/ directory, but not those in "/" directory. I've tried many hacks to no avail. How do you instruct Makefile to compile the source files in "/" directory after compiling those in source/, and put them in the obj/ directory ?
I've tried many things to no avail...
A savvy hand is welcome !!
/
Makefile
file1.cpp
file2.cpp ...
source/
file30.cpp file31.cpp ...
obj/
file30.o file31.o ...
CC = g++
CXXFLAGS = -std=c++11 -Wall
LDFLAGS = -pthread
APPNAME = trading_app
EXT = .cpp
SRCDIR = source
OBJDIR = obj
SRC = $(wildcard $(SRCDIR)/*$(EXT))
OBJ = $(SRC:$(SRCDIR)/%$(EXT)=$(OBJDIR)/%.o)
DEP = $(OBJ:$(OBJDIR)/%.o=%.d)
RM = rm
DELOBJ = $(OBJ)
all: $(APPNAME)
$(APPNAME): $(OBJ)
#echo "building the executable..."
$(CC) $(CXXFLAGS) -o $# $^ $(LDFLAGS)
%.d: $(SRCDIR)/%$(EXT)
#$(CPP) $(CFLAGS) $< -MM -MT $(#:%.d=$(OBJDIR)/%.o) >$#
$(OBJDIR)/%.o: $(SRCDIR)/%$(EXT)
$(info $$OBJ is [${OBJ}])
$(CC) $(CXXFLAGS) -o $# -c $<
Well, first you search only for files in the SRCDIR directory:
SRC = $(wildcard $(SRCDIR)/*$(EXT))
but not for files in the current directory. So of course make won't try to compile source files in the current directory. If you want to build files in the current directory you need to add them to SRC.
Then you write a rule telling make how to compile files in the SRCDIR subdirectory and put them into the OBJDIR subdirectory:
$(OBJDIR)/%.o: $(SRCDIR)/%$(EXT)
but you don't have a rule telling make how to compile files in the current directory and put them into the OBJDIR subdirectory. If you want make to know how to do that you have to give it a rule in the makefile that will do it.

Handling Makefile dependencies in multiple subdirectories and outputting to seperate subdirectory

I've been reading through posts about Makefiles that use subdirectories, but can't seem to put all the pieces together properly. I have the following file structure:
program
|
- src
|
- include
|
- build
|
- bin
|
- Makefile
All my sources (.cpp) are in program/src/, all my headers (.hpp) are in program/include, I want all my object files and dependency files put into program/build, and I want my binary placed into program/bin. The following is what I currently have in my Makefile:
CXX = g++
BIN_DIR = bin
TARGET = $(BIN_DIR)/coreint
BUILD_DIR = build
SRC_DIR = src
INC_DIR = include
CXXFLAGS = -Wall -g
# Get all source files
SRCS := $(shell find $(SRC_DIR) -name *.cpp)
# Get all object files by replacing src directory with build directory and replace extension
OBJS := $(subst $(SRC_DIR), $(BUILD_DIR), $(SRCS:%.cpp=%.o))
# Get all depend files by replacing extensions
DEPS := $(OBJS:.o=.d)
# Get all includes by searching include directory
INCS := $(shell find $(INC_DIR) -name *.hpp)
# Append -I to the front of each include
INCS := $(foreach d, $(INCS), -I$d)
# Using VPATH to find files in src/ include/ and build/
VPATH = $(SRC_DIR):$(INC_DIR):$(BUILD_DIR)
all: $(TARGET)
$(TARGET): $(OBJS)
$(CXX) $(CXXFLAGS) $(LDFLAGS) $(OBJS) -o $(TARGET)
# Build object files and put in build directory
$(BUILD_DIR)%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $#
# Place dependency files in build directory
# automatically generate dependency rules
$(BUILD_DIR)%.d: %.cpp
$(CXX) $(CXXFLAGS) -MF"$#" -MG -MM -MD -MP -MT"$#" -MT"$(OBJS)" "$<"
# -MF write the generated dependency rule to a file
# -MG assume missing headers will be generated and don't stop with an error
# -MM generate dependency rule for prerequisite, skipping system headers
# -MP add phony target for each header to prevent errors when header is missing
# -MT add a target to the generated dependency
.PHONY: clean all
clean:
rm -f $(OBJS) $(DEPS) $(TARGET)
-include $(DEPS)
When I run make, I get the following error:
make: *** No rule to make target `build/assign.o', needed by `bin/coreint'. Stop.
Where assign.o is the first file in the build directory. Thank you in advance.
I was simply missing a '/' after my BUILD_DIR:
# Build object files and put in build directory
$(BUILD_DIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $#

-I flag in the makefile does not result in a header file being found

I have a file ./src/test.cpp:
#include "test.h"
void Hi() {
std::cout << "Hi, indeed..." << std::endl;
}
test.h is located in ./include folder.
This is my makefile:
CC = g++
CFLAGS = -Wall
INCLUDES = -I./include
SRCS = $(shell find ./src/ -name '*.cpp')
.PHONY: clean depend
OBJS = $(SRCS:.cpp=.o)
OBJS := $(OBJS:./src%=.%)
release: $(OBJS)
$(CC) $(CFLAGS) -o app_name $(OBJS)
VPATH = ./src
../%.o: %.cpp
$(CC) $(CFLAGS) $(INCLUDES) -c $*.cpp
depend: .depend
.depend: $(SRCS)
rm -f ./.depend
$(CC) $(CFLAGS) -MM $^ > ./.depend;
include .depend
As a result I get an error:
g++ -c -o test.o ./src/test.cpp
./src/test.cpp:1:18: fatal error: test.h: No such file or directory
compilation terminated.
<builtin>: recipe for target 'test.o' failed
make: *** [test.o] Error 1
Also the file .depend is completely empty.
How to resolve the issue? The makefile is in root directory:
./
makefile
./src/
test.cpp
main.cpp
./include/
test.h
What G.M. is trying to say is that you have defined a pattern rule that knows how to build a target matching a pattern ../%.o. But, when you ask make to build objects, they are of the form ./xxx.o; e.g., after:
SRCS = $(shell find ./src/ -name '*.cpp')
suppose SRCS contains ./src/foo.cpp. Now after this:
OBJS = $(SRCS:.cpp=.o)
OBJS := $(OBJS:./src%=.%)
OBJS will contain the value ./foo.o (by the way, a simpler way to get this behavior is to use the patsubst function: $(patsubst ./src/%.cpp,./%.o,$(SRCS))).
So, make will try to build the file ./foo.o. Since there's no explicit rule for this it will look for an implicit rule.
It sees your pattern rule, but that says how to build ../%.o which does not match the object file make wants to build ./foo.o, so your rule is ignored.
Then make will go look for some other implicit rules and it will find the built-in rule that knows how to build a .o file from a .cpp file, and it will use that. That rule doesn't use your variable $(INCLUDES), so your compile fails.
You need to either fix your OBJS settings to create filenames like ../foo.o instead of ./foo.o, if you really want your object files to appear in the parent directory, or else change your pattern rule to build %.o not ../%.o.

"Can not find file" makefile error

I am trying to compile a C++ program using make. I want it to read the source files from the src folder. Place the object files in the build folder, and put the exe in the bin folder.
I get the following error
/bin/wavfiletool.exe -g -O2 process_begin: CreateProcess(NULL,
/bin/wavfiletool.exe -g -O2, ...) failed. make (e=2): The system
cannot find the file specified.
UPDATE: The problem was I put g++ in for my compiler var instead of &(CC)...woops.
But now it says g++: fatal error: no input files
I am running make using a batch file that sets the environment variables.
SET PATH=C:\Make\GnuWin32\bin;C:\MinGW\bin
make %1
My makefile is as follows.
CC := g++
CFLAGS := -g -O2
BIN_DIR := /bin
BUILD_DIR := /build
SRC_DIR := /src
TARGET := wavfiletool.exe
SOURCES := $(wildcard $(SRC_DIR)/*.c)
OBJECTS := $(SOURCES:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)
$(BIN_DIR)/$(TARGET): $(OBJECTS)
$(G++) $# $(CFLAGS) $(OBJECTS)
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
#$(CC) $(CFLAGS) -c $< -o $#
You haven't set the $(G++) variable anywhere so the recipe line for the $(BIN_DIR)/$(TARGET) target is trying to run $# instead of the compiler.
Also you are missing -o on that compilation line so were $(G++) set to g++ correctly you would end up running:
g++ /bin/wavfiletool.exe -g -O2 $(OBJECTS)
which likely isn't what you want.
That being said you probably don't want to be writing directly into /bin either. Did you mean ./bin for a bin directory in the local directory?

Make with Autodependencies for C++

I have looked, and found a few answers that look like they're related to this question, but none seem to help.
It is the usual story - I have a folder of .hpp and .cpp files which I'd like to compile to .o files, and then only have files recompiled when files they depend on have been changed.
My current makefile is:
SRCS = $(shell find ../Includes/ -name "*.cpp")
DEPS = $(SRCS:.cpp=.d)
OBJS = $(SRCS:.cpp=.o)
all: $(DEPS) $(OBJS)
# Create the dependency files
%.d : %.cpp
clang++ -MM $< -o $# -c -std=c++11
# Include the dependency files
include $(DEPS)
# Compile the source files
%.o : %.cpp
clang++ -c -Wall -std=c++11 $< -o $#
I've run this a few times (so the dependency files exist before I run make, and should definitely exist when I include them). I've also tried adding %.d to the dependancies of %.o.
Basically all that happens at the moment is that 'touch'ing a .cpp causes the .o and .d files to be regenerated, and touching a .hpp file (that is listed in the .d files for other files) does nothing.
Example Dependency File:
SomeFile.o : ../Includes/SomeFile.cpp \
../Includes/SomeFile.hpp ../Includes/SomeOtherFile.hpp
Apart from the path issue, I find it more natural to create the dependencies along the way, i.e. with the -MD or -MMD flags. That way you don't need a rule to update the dependency file.
CPPFLAGS += -MMD
TARGET := hello
.DEFAULT: all
all: $(TARGET)
SRCS := $(shell find . -type f -name "*.cpp")
OBJS := $(SRCS:.cpp=.o)
DEPS := $(SRCS:.cpp=.d)
hello: $(OBJS)
$(LINK.cc) -o $# $^
-include $(DEPS)
It turns out that I was creating rules for:
SomeFile.o : ...
Whereas I needed a rule for:
../Includes/SomeFile.o : ...
Thanks to NovaDenizen who set me on the right path.