Generic Makefile - c++

I am looking for a generic makefile, which will will build all C++ files in the current directory and all sub-directories (e.g, source, test files, gtest, etc)
I have spent a few hours trying out several and finally settled on the solution from make file with source subdirectories.
I need to make three changes to it:
Gtest uses *.cc for its C++ files and I have others which use *.cpp
I need to be able to define multiple search paths.
Add compiler flags, like -W all
I have managed to break the makefile, shown below, such that running make gives me
make: *** No rule to make target %.cpp=%.o', needed bymyProgram'.
Stop.
How can I make it do those three things?
# Recursively get all *.cpp in this directory and any sub-directories
SRC = $(shell find . -name *.cc) $(shell find . -name *.cpp)
INCLUDE_PATHS = -I ../../../ -I gtest -I dummies
#This tells Make that somewhere below, you are going to convert all your source into
#objects
# OBJ = src/main.o src/folder1/func1.o src/folder1/func2.o src/folder2/func3.o
OBJ = $(SRC:%.cc=%.o %.cpp=%.o)
#Tells make your binary is called artifact_name_here and it should be in bin/
BIN = myProgram
# all is the target (you would run make all from the command line). 'all' is dependent
# on $(BIN)
all: $(BIN)
#$(BIN) is dependent on objects
$(BIN): $(OBJ)
g++
#each object file is dependent on its source file, and whenever make needs to create
# an object file, to follow this rule:
%.o: %.cc
g++ -c $(INCLUDE_PATHS) $< -o $#
[Update] Thanks for the help so far. To address a few of the comments, I have no control over the mixed *.cc and *.cpp fiel extensions, and I can say that there won't ever be a source file in the directory tree which I do not wish to include in the build.
I am still having trouble with the SRC, as no input files are found. I guess that I should look more into the find command as it has been a while since I used Linux.

That is a rather poor makefile: it does not build header dependencies for you, so you are likely to end up with corrupted builds.
I shamelessly recommend this one.

Etan points out your problem. But you don't have to perform two replacements, just:
OBJ := $(addsuffix .o,$(basename $(SRCS)))
And, you should always be using :=, not =, for assignment when using the shell function.

Related

patsubst in makefile doesnt replace the full filepath

Im currently trying to get my makefile independend from my folder structure. So far i worked with a single specific folder containing all my .cpp files. My .o files are all placed in a seperate OBJ/ folder. However i now want my makefile to automatically grab all .cpp files from all subdirectories (any depth if possible) but still place all .o files the one same OBJ folder. This is how my makefile looks at the moment:
CC = g++ -g
SRC = Src/
OBJ = Obj/
BIN = Bin/
INC = -I Lib/GLFW/include/\
-I Lib/GLAD/include/\
-I Lib/STB/\
-I Lib/GLM/\
-I Src/Header/
LIB = -L Lib/GLFW/lib-mingw-w64 -lglfw3 -lopengl32 -lglu32 -lgdi32
EXE = $(BIN)Test.exe
SOURCEFILES = $(wildcard $(SRC)**/*.cpp)
OBJECTFILES = $(patsubst $(SRC)%.cpp,$(OBJ)%.o,$(SOURCEFILES))
all: $(SOURCEFILES) $(EXE)
$(EXE) : $(OBJECTFILES)
$(CC) -o $# $^ $(LIB)
$(OBJ)%.o: $(SRC)%.cpp
$(CC) -c $< $(INC) -o $#
It somewhat does what i want, but for some reason it currently is required to have the same folder structure of my SRC/ directory in OBJ/ aswell: If my .cpp file is SRC/foldername/name.cpp my makefile wants to create the .o as OBJ/foldername/name.o. I want it to be OBJ/name.o for all files regardless of the structure of SRC/ . What do i need to change to achieve that?
My second question is about the include path. As it can be seen in the makefile, all my header files are in a single directory Src/Header/. Is it possible to somehow also automatically get and link the right .h files from Src/ and it's subdirectories?
If you want to flatten paths, you can use notdir.
Unfortunately, because %.o is "magic", you can't just wrap it in a $(notdir).
By the way, as a matter of style, I'd leave the trailing slash out of those variables and use it in the expressions instead; it'll be much easier to read, and more flexible too.
This works for me:
SRC=srcPath
OBJ=objPath
SOURCEFILES = $(wildcard $(SRC)/**/*.cpp)
OBJECTFILES = $(addprefix $(OBJ)/, $(notdir $(patsubst $(SRC)/%.cpp, %.o, $(SOURCEFILES))))
all:
echo $(OBJECTFILES)
More pleasing alternatives surely exist, but the point is that you can use notdir to build your solution.
Flattening your object files in one single directory is not necessarily a very good idea. Your Makefile is getting more complex (see below) and there is a name collision possibility if, by accident, you have two source files with the same base name.
Anyway, it is what you want, and here is a possible solution:
SRC = Src
OBJ = Obj
SOURCEFILES = $(wildcard $(SRC)/**/*.cpp)
# $(1): full path to source file
define CompileRule
$$(OBJ)/$$(patsubst %.cpp,%.o,$$(notdir $(1))): $(1)
$$(CC) -c $$< $$(INC) -o $$#
endef
$(foreach f,$(SOURCEFILES),$(eval $(call CompileRule,$(f))))
It iteratively instantiates custom compilation rules for each of your source files. See the GNU make manual for a complete explanation.
I am not sure I fully understand your second question but if you want to find all header files in Src and build the list of -I<dir> compile options, you can probably try something like:
HEADERFILES := $(wildcard $(SRC)/**/*.h)
HEADERDIRS := $(sort $(dir $(HEADERFILES)))
INCLUDES := $(patsubst %,-I%,$(HEADERDIRS))
But it is very sub-optimal because every directory containing header files will be involved as -I<dir> in the compilation of every source file.
Last but not least, your next step could be "how do I automatically get the list of all header files a source file depends on?". If it is, you should probably have a look at this post about Auto-Dependency Generation.

Gnu Make: how to handle sub-projects

ProjFolder
\
Subfolder
sources.cpp
makefile
makefile
Subfolder is supposed to be a separate external repo, pulled in when checking out the project. When I call make all to the top-level makefile, the following recipes get executed:
all: $(NAME).elf $(NAME).s19 $(NAME).hex
$(NAME).elf: $(OBJECTS) $(LDSCRIPT) Subfolder/lib.a
make -C CppAudioPeriphs all
# echo "...linking"
$(CC) $(OBJECTS) Subfolder/lib.a $(LDFLAGS) $(LIBS) -o $#
As you can see, if the final product of Subfolder - the file lib.a is changed, the Subfolder makefile gets called in order to remake it, and then all product get linked into the final flash image.
The problem is the order. I want to always first call the sub-makefile. It knows when and how to remake lib.a. And THEN check if lib.a is modified to determine if to remake $(NAME).elf.
Here is one solution.
.PHONY all $(NAME).elf
This just instructs make to remake $(NAME).elf no matter what. I have used this solution in the past for tiny projects, but for the current one it is not acceptable.
As pointed out by MadScientist (and who better) I missed the obvious solution to this problem.
The solution is to FORCE the Subfolder/lib.a target to always be attempted. And as long as the Subfolder makefile only updates lib.a when something has changed the rest will fall out correctly.
So you want the following for your Subfolder/lib.a target. The rest can stay as-is. The trick here, as indicated before, is that you can force make to run the Subfolder/lib.a target itself but if the timestamp on Subfolder/lib.a the file doesn't change then things that list Subfolder/lib.a as a prerequisite will not need to be rebuilt.
FORCE: ;
Subfolder/lib.a: FORCE
$(MAKE) -C $(#D) target-to-build-lib.a*
You might try putting your stuff in a subfolder also (e.g. Mystuff) with its own makefile. Then you can write a top-level makefile along the lines of
all: Mystuff
Mystuff: Subfolder
Subfolder Mystuff:
${MAKE} -C $#
But then, Recursive Make Considered Harmful :)

How to make */* for many folders of self-contained cpp files?

I'm playing around some tutorial code from this OpenCV 2 Cookbook. The code doesn't come with any Makefiles, and I'd like to create a Makefile that can Make all of the files in the codebase. My plan is to compile all the files with profiling, and then make a script that runs all the executables and collects the gprof results. Then, I can get some intuition for the computation time of various OpenCV functions.
The codebase is arranged like this: tutorial_code/Chapter[1-10]/*.cpp
Each .cpp file is self-sufficient and can be compiled without linking against other modules in this codebase. (There are a few small header-only libraries, though.)
Here are a couple things that I'm stuck up on:
Typically, the $(EXEC) in a Makefile represents a file that is the culmination of much of the building effort. However, in my case, I want to create a separate $(EXEC) for each .cpp file. I think I'm close to getting this right, but so far my Makefile just generates *.o but not *.out
I understand that SOURCES = $(wildcard *.cpp) is a way to "collect" the set of cpp files in the current directory. It would make sense that SOURCES = $(wildcard */*.cpp) would drill down and grab all .cpp files in the subdirectories. It doesn't seem to work, though.
Starting from this tutorial, I set up a Makefile that implements the proposed functionality. It doesn't quite work... $(wildcard */*.cpp) doesn't seem to drill down into directories, and I'm not sure how to do something like $< and $# to refer to basefilename.o and to create basefilename.out.
CC = g++
CC_FLAGS = -w `pkg-config opencv --cflags`
LINK = g++
LINKOPTS = -pg `pkg-config opencv --libs`
SOURCES = $(wildcard */*.cpp)
OBJECTS = $(SOURCES:.cpp=.o)
EXEC = $(SOURCES:.cpp=.out)
%.out: %.o
$(LINK) $< $(LINKOPTS) -o $#
%.o: %.cpp
$(CC) -c $(CC_FLAGS) $< -o $#
clean:
rm -f $(EXEC) $(OBJECTS)
I'm fairly familiar with Makefiles and OpenCV, and I haven't had a problem compiling my own projects by hand-coding the lists of dependencies, objects, etc in Makefiles. However, for the matter at hand, it'd be fantastic to just automatically make everything without much user intervention.
Feel free to comment, email, or message me for a copy of the codebase that I'm trying to compile.
I've also thought of making a script that iterates through the tutorial_code/Chapter[1-10] directories and creates one Makefile for each directory. Then, I'd make an other function in the script to call Make once in each directory. The idea of doing one grand Makefile sounds like more fun, though.
EDIT: This does work if I use SOURCES = $(wildcard *.cpp) and place the Makefile in the same directory where cpp files are located. However, I'm still trying to figure out how to have $(wildcard */*.cpp) drill down into subdirectories.
EDIT 2: The Makefile shown above now works properly. To see the earlier version, feel free to scroll through the edit history.
You can write a version of wildcard that works recursively to any depth using only make functions:
find-recursive = \
$(wildcard $1/$2) \
$(foreach f,$(wildcard $1/*/.),\
$(call find-recursive,$(patsubst %/.,%,$f),$2))
SOURCES = $(call find-recursive,.,*.cpp)

How to get cpp files from different directories compiled into one folder?

I have a number of C++ files distributed in several folders.
a_library/
file1.cpp
file2.cpp
category1/
file3.cpp
file4.cpp
They are guaruanteed to be uniquely named. I want to compile all those C++ files to seperate Object-files in the obj/ directory.
I have a list of all source-files with relative path, and their corresponding destination-names.
a_library/file1.cpp
a_library/file2.cpp
a_library/category1/file3.cpp
a_library/category1/file4.cpp
obj/file1.obj
obj/file2.obj
obj/file3.obj
obj/file4.obj
How can I make a rule that will convert a C++ file from the first list to a object-file from the second one?
These attempts do not work:
obj/%.obj: %:cpp
# ...
%.obj: %.cpp
# ...
.cpp.obj:
# ...
I would like to not write rules like this:
obj/%.obj: a_library/%.cpp
# ...
obj/%.obj: a_library/category1/%.cpp
# ...
Try setting VPATH:
VPATH = a_library:a_library/category1
obj/%.o: %.cpp
$(CXX) -c $(CPPFLAGS) $(CFLAGS) $(CXXFLAGS) -o $# $<
And to add complete file list (I would recommend you explicitely list the files, do not use $(wildcard ...) function) and linking of the application:
files := main.cpp $(wildcard a_library/*.cpp) a_library/category1/file.cpp
obj/application: $(patsubst %.cpp,obj/%.o,$(notdir $(files)))
$(CXX) $(CFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $# $+
The $(wildcard) has an annoying tendency to pick up anything in the directories, like one-off test files or temporaries (if they happen to have a fitting name: ~file.cpp).
One solution I can think of: just build them inplace with a simple rule and then make a "collection phase" moving the ".o" files to a single folder.
Make a "collect_objs" target which depends on your $(OBJS) and then your "main" target must depend on "collect_objs".
The traversal can be done using shell
dirs := $(shell find ./ -type d)
collect_objs: $(dirs)
for d in $+; do \
mv *.o YourDestDir/*.o
done
Of course, this implies using UnxUtils package (with 'find' and 'mv') or Cygwin since you are on Windows.
The other option is to generate the targets for each of your .c/.cpp file explicitly, using some tool. Grab python, traverse source directories and for each .c/.cpp file write
obj/file_name.o:
gcc -c path/fo/file_name.c -o obj/file_name.o
Use cmake to make the build configuration for you.
Some time ago I set up a simple example project on github.
The standard way is to have a Makefile in each folder and call recursively with include
This was my first two hits on 10^100:
http://owen.sj.ca.us/~rk/howto/slides/make/slides/makerecurs.html
http://www.gnu.org/savannah-checkouts/gnu/make/manual/html_node/Recursion.html
Not strictly related to this question as it doesn't have to do with Make, though I'd like to show how I compile my projects now, 3 years later. Craftr is a Python based meta build system that encourages indirect out-of-tree builds (eg. a build in the working tree). Building object files and cresting a static library is as easy as
# craftr_module(my_project)
from craftr import *
from craftr.ext.platform import cxx, ar
objects = cxx.compile(
sources = path.platform('**/*.cpp'),
)
lib = ar.staticlib(
output = 'myproj',
inputs = [objects],
)
Running craftr -eb will result with the following structure of build products
Craftfile
file1.c
file2.c
category1/
file3.c
file4.c
build/
my_project/
obj/
file1.o
file2.o
category1/
file3.o
file4.o
libmyproj.a

Simple makefile generation utility?

Does anyone know of a tool that generates a makefile by scanning a directory for source files?
It may be naive:
no need to detect external dependencies
use default compiler/linker settings
You can write a Makefile that does this for you:
SOURCES=$(shell find . -name "*.cpp")
OBJECTS=$(SOURCES:%.cpp=%.o)
TARGET=foo
.PHONY: all
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $#
.PHONY: clean
clean:
rm -f $(TARGET) $(OBJECTS)
Just place this in root directory of your source hierarchy and run make (you'll need GNU Make for this to work).
(Note that I'm not fluent in Makefileish so maybe this can be done easier.)
CMake does it and it even creates makefiles and Visual Studio projects. http://www.cmake.org/
All you need to do is creating a CMakeLists.txt file containing the follwing lines:
file(GLOB sources *.h *.c *.cxx *.cpp *.hxx)
add_executable(Foo ${sources})
Then go into a clean directory and type:
cmake /path/to/project/
That will create makefiles on that clean build directory.
This is what I would use for a simple project:
CC = $(CXX)
CXXFLAGS += -ansi -pedantic -W -Wall -Werror
CPPFLAGS += -I<Dir Where Boost Lives>
SOURCES = $(wildcard *.cpp)
OBJECTS = $(patsubst %.cpp,%.o,$(SOURCES))
all: myApp
myApp: $(OBJECTS)
The only restriction is that if you are building an executable called myApp. Then one of the source files should be named myApp.cpp (which is where I put main).
There's a very old script called 'makedepend' that used to make very simple makefiles. I've since switched over to cmake for almost everything.
Here's the wiki article http://en.wikipedia.org/wiki/Makedepend, note the list of Alternatives at the bottom including depcomp in automake, and the -M flag in gcc.
EDIT: As someone pointed out to me in another question, gcc -MM *.cpp > Makefile produces a rather nice simple makefile. You only have to prepend your CPPFLAGS and a rule for constructing the entire binary... which will take the form:
CPPFLAGS=-Wall
LDFLAGS=-lm
all: binary_name
binary_name: foo.o bar.o baz.o biff.o
no need to detect external dependencies
use default compiler/linker settings
Why script then? Provided that all your project source files are *.cpp and in current directory:
all: $(notdir $(CURDIR))
$(notdir $(CURDIR)): $(subst .cpp,.o,$(wildcard *.cpp))
$(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $#
The Makefile would build the all the source files with default compiler/linker settings into an executable named after the name of the current directory.
Otherwise, I generally recommend people to try SCons instead of make where it is much simpler and intuitive. Added bonus that there is no need to code manually clean targets, source/header dependency checking is built-in, it is natively recursive and supports properly libraries.
As described in the linked discussion, HWUT is a tool that
can generate pretty Makefiles, searching for dependencies and include files in directories that you tell it. On windows you need to install MinGW and Ctags. Under Linux gcc and ctags are most likely present. It is OpenSource and free to use.
Especially, when generating Unit Tests for some already existing modules of some larger project with bad cohesion, this feautures easily spares you hours or even days.