Example makefile for building simple c project recompiling when headers change - c++

Does anyone have a complete makefile that can do the following:
Rebuilds the project if a HEADER file changes
The cpp files are listed in the makefile
The header files are NOT listed in the makefile
The header files are allowed to have different names than the cpp files
Some of the cpp files do not have header files
I have seen instructions for figuring out how to make the make tool figure out header dependencies, but none of these instructions provide anything remotely resembling a working example. A simple example would be as follows: main.cpp C1.cpp C1.h C2.cpp C2.h

CXX = g++
OBJECTS := main.o C1.o C2.o
all: $(OBJECTS)
%.o : %.cpp
$(CXX) $(CPPFLAGS) -Wall -MMD -c $< -o $#
-include *.d
EDIT: As TobySpeight points out, this won't work if you build an object file, rename or delete one of the prerequisite source or header files, then try to rebuild the object file; the .d file will still require the missing file, and the build will fail. I neglected to include lines to deal with that case:
%.h: ;
%.cpp: ;
(This is effective, but crude. The more precise approach is to put some sed commands in the %.o rule, so as to add specific null rules to the .d file, one for each prerequisite, but the sed commands are ugly, and the approach above is good enough for almost all cases.)

You can also use CMake for this. Everything you need to write is:
add_executable (exec main.cpp C1.cpp C2.cpp)

Related

Makefile to get source files in multiple subdirectories

I am creating a custom Makefile to to build a C++ Linux application. I have my cpp source files in a folder called src on the same level as the Makefile. So far I have been able to build my object files with the following :
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp | $(OBJ_DIR)
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $#
Now my project is starting to get a bit more complicated and I want subdirectories within src , such as src/common , and also, not every file is a cpp file now but also a c file.
I guess having a separate Makefile for each subdirectory is the best way but I am trying to keep this simple for now with just one Makefile.
I tried the following but doesn't work
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(SRC_DIR)/common/%.cpp $(SRC_DIR)/common/%.c | $(OBJ_DIR)
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $#
I could have the Makefile do a shell find to find all cpp and c files but also trying to avoid this.
I'd appreciate any recommendations.
This:
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(SRC_DIR)/common/%.cpp $(SRC_DIR)/common/%.c | $(OBJ_DIR)
cannot work; what it says that if make wants to build some file $(OBJ_DIR)/XXX.o and there is no explicit rule, then if and only if ALL the prerequisites $(SRC_DIR)/XXX.cpp, $(SRC_DIR)/common/XXX.cpp, and $(SRC_DIR)/common/XXX.c exist or can be created by make, then the rule will match.
If the same target could be built from multiple different prerequisites you must create multiple rules, one per prerequisite.
Also, it doesn't make sense to compile both C files (.c) and C++ files (.cpp) using the same recipe. C++ compilers use the variables CXX and CXXFLAGS and C compilers use the variables CC and CFLAGS.
As for avoiding find, you can't avoid informing make what files you want to be compiled, in some manner. You either have to list them in your makefile explicitly, or else use some method to generate them dynamically. There's no way around this. You don't have to use find if you don't want to; for example if you know that all the files will be either one or two directories down you could use wildcard, like:
SRCS := $(wildcard $(SRC_DIR)/*.cpp $(SRC_DIR)/*.c $(SRC_DIR)/*/*.cpp $(SRC_DIR)/*/*.c)

Managing Dependency Complexity in Make Files

I am working on my first open source C++ project: https://github.com/jehugaleahsa/spider-cpp.
I am managing my own Makefile and I have "best practices" question regarding how to manage dependencies. Right now, I make each .o file dependent on each of the included header files in the .cpp file. So:
code.o: code.cpp code.hpp dep1.hpp de2.hpp
g++ -c code.cpp
First of all, I am pretty sure Make supports a shorthand for creating object files. If someone would show an example of this, I'd appreciate it.
Next, is there a way to avoid listing every included header as a dependency? I want to make sure if I change a dependency, that the changes are still compatible. Listing the included headers is tedious and easy to mess up.
OP:
First of all, I am pretty sure Make supports a shorthand for creating object files. If someone would show an example of this, I'd appreciate it.
From here:
OBJS := foo.o bar.o
#Your program should have the objects as dependencies, and link them
proggie: $(OBJS)
gcc $(OBJS) -o proggie
# compile
%.o: %.c
gcc -c $(CFLAGS) $*.c -o $*.o
OP:
Next, is there a way to avoid listing every included header as a dependency
Lower down on the same page, see these lines:
# pull in dependency info for *existing* .o files
-include $(OBJS:.o=.d)
# compile and generate dependency info
%.o: %.c
gcc -c $(CFLAGS) $*.c -o $*.o
gcc -MM $(CFLAGS) $*.c > $*.d
Basically what this does is use gcc's -MM option to obtain a list of header files, and now we can depend on them. Thus we output a file with a list of such header files to a .d file, and then next time, we add the list of files as a dependency, which is what the -include command does. The "-" avoids error if the dependency .d files don't exist yet.
Note, you should modify the above to account for .cpp files
Yes, make supports shorthand for creating object files. This is called rules. And yes, there is a way to avoid listing every included header as a dependency. g++/gcc has -MM option which will generate the full list of dependencies.
Unfortunately, there is no simple explanation on how to do it which I could put here.. You have to read docs and play with make utility. I found this book very helpful: "Managing Projects with GNU Make". There is a doc on GNU site but I found it a bit harder to read. www.gnu.org/software/make/manual/make.html

Makefile using a library

I have made a project in Xcode who implements an algorithm in just 1 c++ file. To compile it needs an library who is in a directory called libgambit in an other directory. The directory structure looks like this:
lib/
libgambit/libgambit.cc
libgambit.h
game.cc
game.h
...
src/Game\ Theoretic\ Analysis/convertion.cc
convertion.h
Makefile
So what I need is a makefile who first builds everything whats in libgambit and uses the object files who result from that to build and link convertion.cc. The executable should then be in the same folder as the makefile.
It seems a pretty easy question but I'm suffering on it for 2 days now.
There's more than one way to do it. Here is a crude but effective way:
LIBSRCS := $(wildcard $(PATHTOLIB)/lib/libgambit/*.cc)
LIBOBJS := $(LIBSRCS:.cc=.o)
convertion: convertion.o $(LIBOBJS)
#g++ -Wall $^ -o $#
%.o: %.cc
#g++ -Wall -Ilib/libgambit -c $< -o $#
This does not track dependencies very well (if you alter a header file, Make won't notice that some objects must be rebuilt), but it is good enough for now. Let us know if you want to try advanced dependency handling.
You can use the Makefile developed here. It allows you to add new files and directories to the build without changing the Makefile.

how to write makefile to take care of changes in the header file

Actually i have a library 'cryptopp' and what i want is that when i make any change to a file and issue the make command it should take care of the changes made in any file in the source directory. well, the GNUMakefile of cryptoopp takes care of the changes 'if' made in the '.cpp' files but not for the changes made in a '.h' file.
So what changes can i make in the 'GNUMakefile' of cryptopp so that it looks at all the modified header files and recompiles all the files dependent on the 'modified' header file.
If you are building with g++ you can let g++ generate dependancy makefiles.
You can include these in your main makefile.
Use the -M and -M* arguments to use this feature. (see http://gcc.gnu.org/onlinedocs/gcc-4.6.1/gcc/Preprocessor-Options.html#Preprocessor-Options)
You have to add all the dependencies to your Makefile:
mycode.o: mycode.cpp mycode.h somelib.h resources.h
$(CXX) -c -o $# $< $(CXXFLAGS) $(INCLUDES)
If you already have a generic pattern matching command line, you don't have to say the command again, you can just list the dependencies:
%o: %.cpp
$(CXX) -c -o $# $< $(CXXFLAGS) $(INCLUDES)
mycode.o: mycode.cpp mycode.h somelib.h resources.h
yourcode.o: yourcode.cpp yourcode.h mycode.h somethingelse.h
# ...
In general, this is a terrible and unscalable mess. You'll almost definitely want a higher-level build system to generate the Makefile for you. Even for very small projects keeping the header dependencies up to date in the Makefile is such a pain that it is simply not worth it.
There are several popular portable build environments. I personally like cmake a lot, which includes discovery if you changed the build settings (say from Debug to Release) and will always build all the necessary files (for example, if you change the cmake master file and type "make" it'll automatically run cmake again for you first).
For a Unix-only solution you could try makedepend, or the infamous autotools, though that's a whole other headache...
You might try 'makedepend' if it's installed on your system. The easiest way is to add a target to your makefile. Something like:
depend:
makedepend *.cc
You might have to replace the '*.cc' with a list of your source files. Then you can regenerate all the dependencies with 'make depend' command. You might want to redirect error messages to /dev/null since it always seems to generate a lot of noise.

any building tool can automatically understand file dependencies in C++ project?

I have a project with 50+ .h files and 50+ .cpp files. I'm using make to build a project, which looks something like this (it's just a piece of an entire file):
HEADERS := $(shell find $(INCLUDE) -name "*.h")
%.obj: %.cpp $(HEADERS)
$(CPP) $(CPPFLAGS) -fPIC -o $# -g -c $<
When I'm making changes to one .h file, the whole project has to be re-compiled. It's annoying and time-consuming. But I don't want to hard-code file dependencies inside Makefile, since it's even more time-consuming. I would like to have some make-like tool, which will find dependencies right inside my .cpp/.h files, automatically. Any suggestions? Thanks in advance!
There are many options, but nothing that works exactly like make. Many build systems will generate the Makefiles with dependencies for you though. CMake and Automake are two commonly used systems that work like that. You define your project file in a meta-language and it will generate the Makefiles.
Scons is good in finding the right sources that need to be recompiled.
It scans the files and the headers and builds up an internal dependency tree.
www.scons.org
If you are using gcc then you can use the -M option. It is designed to do exactly what you want i.e. generate a Makefile rule describing the dependencies.
Simplest way:
depend:
g++ -M *.cpp >.depends
-include .depends
Better way:
SRC=foo.cpp bar.cpp ...
OBJ=$(patsubst %.cpp,%.o,$(SRC))
DEPS=$(patsubst %.o,.deps/%.o.dep,$(OBJ))
all: .deps
.deps:
mkdir -p .deps
.cpp.o:
$(CXX) $(CXXFLAGS) -MD -MF .deps/$#.dep -c -o $# $<
-include $(DEPS)
So compiler will generate all dependencies for each file during build automatically.
Or even better: use Autotools, CMake or other build system that does this job for you.
Jam.
Boost.Build.
The latter is based on a (massively) enhanced version of the former.