How to compile "not-main" (only .hpp) files with makefile in C++? - c++

I'm developing a parallel project with a Main.cpp and a set of .hpp files. I've found the Makefile below suitable to compile, deploy and execute my project on a Xeon Phi. The problem here is that if I edit only one of the .hpp (so not Main.cpp) then when I execute make compile obviously nothing happens (so I have to execute make clean before). Can you help me to change it so if I edit file.hpp then it will compile it? Thanks!
FF_ROOT = /home/luca/fastflow
BOOST_ROOT = /home/luca/boost_1_59_0
CC = icpc -mmic
CXX = $(CC) -std=c++11 -DNO_DEFAULT_MAPPING
INCLUDES = -I $(BOOST_ROOT) -I $(FF_ROOT)
CXXFLAGS =
LDFLAGS = -pthread
OPTFLAGS = -O3 -finline-functions -DNDEBUG -g -O0
TARGETS = \
Main \
.PHONY: all clean copy exec cleanall
.SUFFIXES: .cpp
%: %.cpp
$(CXX) $(CXXFLAGS) $(INCLUDES) $(OPTFLAGS) -o $# $< $(LDFLAGS)
all: compile
compile: $(TARGETS)
copy:
scp $(TARGETS) mic0:
exec:
ssh mic0 './$(TARGETS) $(ARGS)'
clean:
rm -f $(TARGETS)
cleanall : clean
\rm -f *.o *~

Your Makefile is blatantly not sufficient. At the moment it only contains the commands to translate from one input to the next, but it's missing the crucial ingredient of any build system: Dependencies.
Dependencies are hard to maintain by hand. You could add main: a.hpp b.hpp etc by hand, but that doesn't scale and you forget to update it when you refactor. That's why make is not usually something the user should use directly. make is a bit like assembler: it's the final level at which build rules are expressed, but creating the build rules is best left to a higher-level system (e.g. automake or cmake or any of the other competitors in the field; or even the old makedepend).
As a side note, you really don't want to build the binary directly from source, that defeats almost all points of having a Makefile. You really want to break your project into separately compiled translation units, so that you only rebuild the minimal amount after a change.
OBJS := a.o b.o c.o
main: $(OBJS)
$(CXX) $(CXXFLAGS) $(LDFLAGS) $< -o $#
.cc.o:
$(CXX) $(CXXFLAGS) -c $< -o $#
# Dependencies! This is in addition to the implied "foo.o: foo.cc" above.
a.o: a.h b.h tools.h
b.o: b.h tools.h
c.o: c.h b.h weirdstuff.h
Many tutorials explain all this.

Add a rule for the source file where it depends on all (local, not system) header files.
Like
Main.cpp: SomeHeaderFile.hpp SomeOtherHeaderFile.hpp

Related

When do files in C++ with direct & indirect dependencies have to be recompiled and when is a new linking of the executable sufficient? [duplicate]

I have the following makefile that I use to build a program (a kernel, actually) that I'm working on. Its from scratch and I'm learning about the process, so its not perfect, but I think its powerful enough at this point for my level of experience writing makefiles.
AS = nasm
CC = gcc
LD = ld
TARGET = core
BUILD = build
SOURCES = source
INCLUDE = include
ASM = assembly
VPATH = $(SOURCES)
CFLAGS = -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions \
-nostdinc -fno-builtin -I $(INCLUDE)
ASFLAGS = -f elf
#CFILES = core.c consoleio.c system.c
CFILES = $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
SFILES = assembly/start.asm
SOBJS = $(SFILES:.asm=.o)
COBJS = $(CFILES:.c=.o)
OBJS = $(SOBJS) $(COBJS)
build : $(TARGET).img
$(TARGET).img : $(TARGET).elf
c:/python26/python.exe concat.py stage1 stage2 pad.bin core.elf floppy.img
$(TARGET).elf : $(OBJS)
$(LD) -T link.ld -o $# $^
$(SOBJS) : $(SFILES)
$(AS) $(ASFLAGS) $< -o $#
%.o: %.c
#echo Compiling $<...
$(CC) $(CFLAGS) -c -o $# $<
#Clean Script - Should clear out all .o files everywhere and all that.
clean:
-del *.img
-del *.o
-del assembly\*.o
-del core.elf
My main issue with this makefile is that when I modify a header file that one or more C files include, the C files aren't rebuilt. I can fix this quite easily by having all of my header files be dependencies for all of my C files, but that would effectively cause a complete rebuild of the project any time I changed/added a header file, which would not be very graceful.
What I want is for only the C files that include the header file I change to be rebuilt, and for the entire project to be linked again. I can do the linking by causing all header files to be dependencies of the target, but I cannot figure out how to make the C files be invalidated when their included header files are newer.
I've heard that GCC has some commands to make this possible (so the makefile can somehow figure out which files need to be rebuilt) but I can't for the life of me find an actual implementation example to look at. Can someone post a solution that will enable this behavior in a makefile?
EDIT: I should clarify, I'm familiar with the concept of putting the individual targets in and having each target.o require the header files. That requires me to be editing the makefile every time I include a header file somewhere, which is a bit of a pain. I'm looking for a solution that can derive the header file dependencies on its own, which I'm fairly certain I've seen in other projects.
As already pointed out elsewhere on this site, see this page:
Auto-Dependency Generation
In short, gcc can automatically create .d dependency files for you, which are mini makefile fragments containing the dependencies of the .c file you compiled.
Every time you change the .c file and compile it, the .d file will be updated.
Besides adding the -M flag to gcc, you'll need to include the .d files in the makefile (like Chris wrote above).
There are some more complicated issues in the page which are solved using sed, but you can ignore them and do a "make clean" to clear away the .d files whenever make complains about not being able to build a header file that no longer exists.
You could add a 'make depend' command as others have stated but why not get gcc to create dependencies and compile at the same time:
DEPS := $(COBJS:.o=.d)
-include $(DEPS)
%.o: %.c
$(CC) -c $(CFLAGS) -MM -MF $(patsubst %.o,%.d,$#) -o $# $<
The '-MF' parameter specifies a file to store the dependencies in.
The dash at the start of '-include' tells Make to continue when the .d file doesn't exist (e.g. on first compilation).
Note there seems to be a bug in gcc regarding the -o option. If you set the object filename to say obj/_file__c.o then the generated _file_.d will still contain _file_.o, not obj/_file_c.o.
This is equivalent to Chris Dodd's answer, but uses a different naming convention (and coincidentally doesn't require the sed magic. Copied from a later duplicate.
If you are using a GNU compiler, the compiler can assemble a list of dependencies for you. Makefile fragment:
depend: .depend
.depend: $(SOURCES)
rm -f ./.depend
$(CC) $(CFLAGS) -MM $^>>./.depend;
include .depend
There is also the tool makedepend, but I never liked it as much as gcc -MM
You'll have to make individual targets for each C file, and then list the header file as a dependency. You can still use your generic targets, and just place the .h dependencies afterwards, like so:
%.o: %.c
#echo Compiling $<...
$(CC) $(CFLAGS) -c -o $# $<
foo.c: bar.h
# And so on...
Basically, you need to dynamically create the makefile rules to rebuild the object files when the header files change. If you use gcc and gnumake, this is fairly easy; just put something like:
$(OBJDIR)/%.d: %.c
$(CC) -MM -MG $(CPPFLAGS) $< | sed -e 's,^\([^:]*\)\.o[ ]*:,$(#D)/\1.o $(#D)/\1.d:,' >$#
ifneq ($(MAKECMDGOALS),clean)
include $(SRCS:%.c=$(OBJDIR)/%.d)
endif
in your makefile.
Over and above what #mipadi said, you can also explore the use of the '-M' option to generate a record of the dependencies. You might even generate those into a separate file (perhaps 'depend.mk') which you then include in the makefile. Or you can find a 'make depend' rule which edits the makefile with the correct dependencies (Google terms: "do not remove this line" and depend).
Simpler solution: Just use the Makefile to have the .c to .o compilation rule be dependent on the header file(s) and whatever else is relevant in your project as a dependency.
E.g., in the Makefile somewhere:
DEPENDENCIES=mydefs.h yourdefs.h Makefile GameOfThrones.S07E01.mkv
::: (your other Makefile statements like rules
::: for constructing executables or libraries)
# Compile any .c to the corresponding .o file:
%.o: %.c $(DEPENDENCIES)
$(CC) $(CFLAGS) -c -o $# $<
None of the answers worked for me. E.g. Martin Fido's answer suggests gcc can create dependency file, but when I tried that it was generating empty (zero bytes) object files for me without any warnings or errors. It might be a gcc bug. I am on
$ gcc --version gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-16)
So here's my complete Makefile that works for me; it's a combination of solutions + something that wasn't mentioned by anyone else (e.g. "suffix replacement rule" specified as .cc.o:):
CC = g++
CFLAGS = -Wall -g -std=c++0x
INCLUDES = -I./includes/
# LFLAGS = -L../lib
# LIBS = -lmylib -lm
# List of all source files
SRCS = main.cc cache.cc
# Object files defined from source files
OBJS = $(SRCS:.cc=.o)
# # define the executable file
MAIN = cache_test
#List of non-file based targets:
.PHONY: depend clean all
## .DEFAULT_GOAL := all
# List of dependencies defined from list of object files
DEPS := $(OBJS:.o=.d)
all: $(MAIN)
-include $(DEPS)
$(MAIN): $(OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS)
#suffix replacement rule for building .o's from .cc's
#build dependency files first, second line actually compiles into .o
.cc.o:
$(CC) $(CFLAGS) $(INCLUDES) -c -MM -MF $(patsubst %.o,%.d,$#) $<
$(CC) $(CFLAGS) $(INCLUDES) -c -o $# $<
clean:
$(RM) *.o *~ $(MAIN) *.d
Notice I used .cc .. The above Makefile is easy to adjust for .c files.
Also notice importance of these two lines :
$(CC) $(CFLAGS) $(INCLUDES) -c -MM -MF $(patsubst %.o,%.d,$#) $<
$(CC) $(CFLAGS) $(INCLUDES) -c -o $# $<
so gcc is called once to build a dependency file first, and then actually compiles a .cc file. And so on for each source file.
I believe the mkdep command is what you want. It actually scans .c files for #include lines and creates a dependency tree for them. I believe Automake/Autoconf projects use this by default.

Write makefile for .cpp and .hpp c++

I need help to create a proper makefile (supporting incremental compilation) for multiple .hpp and .cpp files.
I've been looking for information about how to create a proper makefile, but I'm not really sure on how to do it.
I have the following files:
2048.cpp, game.cpp, game.hpp, gameutils.cpp, gameutils.hpp, menu.cpp, menu.hpp, saveandback.cpp, saveandback.hpp and tile.hpp
Right now I'm using the following makefile:
all: 2048.cpp tile.hpp menu.hpp menu.cpp gameutils.hpp gameutils.cpp saveandback.hpp saveandback.cpp game.hpp game.cpp
g++ -g -W -Wall --pedantic -DNDEBUG 2048.cpp -o power
clean:
$(RM) power
Thank you for your help.
Caveat: I haven't used make in a while so I may be a little rusty on POSIX vs. GNU-make specific stuff. There may also be new features released in the last few years that I'm not aware of. Please feel free to give corrections. Also most of this is from memory.
There are a few things missing from your knowledge set here that you can use to create a decent makefile that only re-compiles things when needed:
Generic Rules - These can be used to provide a generic rule for building a filename with one suffix from another. E.g. the following defines a rule for creating any *.o from its corresponding *.cpp:
%.o: %.cpp
stuff
In POSIX make these rules are actually specified as:
.cpp.o:
stuff
I'm using GNU syntax below but you can (and might want to) replace with POSIX syntax (moot if you leave them out and use the implicit rules, though, see below).
Automatic Variables
$< will expand to the input of the rule.
$# will expand to the target of the rule.
Variables - You can declare variables and give them values, e.g.:
SOURCES=2048.cpp gameutils.cpp saveandback.cpp
Etc.
Text Replacement - You can use text replacement functions to replace suffixes, e.g.:
OBJECTS=$(SOURCES:.cpp=.o)
Will set OBJECTS equal to SOURCES but with the .cpp's changed to .o.
Multiple Rules - If multiple rules are specified for the same target, their prerequisites are merged.
Phony Targets
Putting that all together you can get a start, leaving out header dependencies for now:
SOURCES=2048.cpp menu.cpp gameutils.cpp saveandback.cpp game.cpp
OBJECTS=$(SOURCES:.cpp=.o)
power: $(OBJECTS)
g++ $(OBJECTS) -o $#
%.o: %.cpp
g++ -c $< -o $#
And it's traditional to define an all rule, which is a phony target since there isn't actually a file named "all":
.PHONY: all
SOURCES=2048.cpp menu.cpp gameutils.cpp saveandback.cpp game.cpp
OBJECTS=$(SOURCES:.cpp=.o)
all: power
power: $(OBJECTS)
g++ $(OBJECTS) -o $#
%.o: %.cpp
g++ -c $< -o $#
Now, make actually has some default rules already, including one for %.o: %.cpp, and also it has some default variables. So you can reduce the above to this if you'd like (personally I prefer to explicitly specify rules, but that's just me):
.PHONY: all
SOURCES=2048.cpp menu.cpp gameutils.cpp saveandback.cpp game.cpp
OBJECTS=$(SOURCES:.cpp=.o)
all: power
power: $(OBJECTS)
$(CXX) $(CXXFLAGS) $(OBJECTS) -o $#
Now, as for your headers, keeping in mind the multiple rules thing, you can simply add those prerequisites by hand based on their includes, e.g.:
.PHONY: all
SOURCES=2048.cpp menu.cpp gameutils.cpp saveandback.cpp game.cpp
OBJECTS=$(SOURCES:.cpp=.o)
all: power
power: $(OBJECTS)
$(CXX) $(CXXFLAGS) $(OBJECTS) -o $#
2048.o: menu.hpp game.hpp
menu.o: menu.hpp
game.o: game.hpp
And so on. You probably also want a "clean" rule, another phony target, and it doesn't hurt to put your binary name in a variable since you use it in a few places, e.g.:
.PHONY: all clean
SOURCES=2048.cpp menu.cpp gameutils.cpp saveandback.cpp game.cpp
OBJECTS=$(SOURCES:.cpp=.o)
BINARY=power
all: $(BINARY)
clean:
$(RM) $(BINARY) $(OBJECTS)
$(BINARY): $(OBJECTS)
$(CXX) $(CXXFLAGS) $(OBJECTS) -o $#
And actually if you pass -MM to gcc it'll generate Makefile dependencies automatically for you, based on the source file's includes. See here for details and an example.

Confused how my Makefile is remaking object files

My make file is failing to find my include directory when it tries to remake object files. For example, when I call make tests I get the output:
g++ -c -o sdl_class.o sdl_class.cpp
sdl_class.cpp:9:23: fatal error: sdl_class.h: No such file or directory
#include <sdl_class.h>
^
compilation terminated.
make: *** [sdl_class.o] Error 1
My Makefile is this:
#Originally from: http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/
#But will be heavily modified
IDIR =../include
CC=g++
CFLAGS=-w -I$(IDIR)
#ODIR=obj
LDIR =../lib
LIBS=-lSDL2
_DEPS = sdl_class.h SDL_image.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
OBJ = sdl_class.o tests.o
#OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
%.o: %.cpp $(DEPS)
$(CC) -c -o $# $< $(CFLAGS) $(LIBS)
tests: sdl_class.o tests.o
$(CC) -o $# $^ $(CFLAGS) $(LIBS)
all: $(OBJ)
$(CC) -o $# $^ $(CFLAGS) $(LIBS)
.PHONY: clean
clean:
rm -f *.o *~ core $(IDIR)/*~
My understanding is that when I call make tests, that it should attempt to remake the sdl_class.o file. This should then call the %.o rule, which should try to make the object file by calling something like:
g++ -c -o sdl_class.o sdl_class.cpp -w -I../include -lSDL2
However, this is not the case as it looks like it is calling $(CC) -c -o $# $< $(CFLAGS) $(LIBS), as you can see from above.
Do I have a fundamental misunderstanding about how make builds its rules? Seems likely, this is my first Makefile. Perhaps I am confused on how compilation works in general, as I'm somewhat new to that as well.
I would say that the problem is that one or more of the files ../include/sdl_class.h or ../include/SDL_image.h does not exist. Because of that, make is deciding that your pattern rule does not match (because not all the prerequisites can be found or made) and it defaults to the built-in rule to create object files from .cpp files.
The built-in rules use the make variables CXX for the C++ compiler and CXXFLAGS for the C++ flags: the CC and CFLAGS variables are used for the C compiler. That's why your settings for CFLAGS are being ignored.
If you run make -d sdl_class.o you'll see which file make is looking for and why it decides to not use your pattern rule.
If you rewrite your rules like this it will work better:
%.o: %.cpp
$(CC) -c -o $# $< $(CFLAGS)
sdl_class.o tests.o: $(DEPS)
because make will now complain that the relevant files can't be found or created.
There are other issues, of course. You shouldn't be passing $(LIBS) to your compile command; that belongs only in your link line. And, you should probably stick to the standard variables CXX for the C++ compiler, CPPFLAGS for preprocessor flags like -I and -D, and CXXFLAGS for C++ compiler flags. Also, linker library flags like -L../lib go in LDFLAGS and linker libraries like -lSDL2 go in LDLIBS.
CC/CCFLAGS are for C compilation. You should use CXX and CXXFLAGS for C++. They are used in built-in rules and in the LINK.cc macro, making the Makefile much simpler, and thus less error prone.
CXXFLAGS = -Wall ...
prog : foo.o bar.o
$(LINK.cc) -o $# $^
see Default linker setting in Makefile for linking C++ object files

Why does GNU make always re-link my project?

I have the following Makefile in a directory full of .cpp and .h files:
CFLAGS=-g -std=c++0x -Wall -pedantic -Wextra -D __STDC_LIMIT_MACROS -D __STDC_FORMAT_MACROS -O0
CXX=g++
LDFLAGS=-lgmp -lmathsat -lz3
all: Foo.o Bar.o
$(CXX) $(CFLAGS) -o myexe Foo.o Bar.o $(LDFLAGS)
depend: .depend
.depend: $(wildcard *.cpp)
rm -f ./.depend
$(CXX) $(CFLAGS) -MM $^ > ./.depend
include .depend
%.o: %.cpp
$(CXX) $(CFLAGS) $(INCLUDE) $< -c
clean:
rm -f *.o myexe
When I hit make, it invariably executes the last step (linking) even when none of the .o files have changed. How can I prevent make from doing that? I'd expect make to output Everything up-to-date or something similar.
I'm on a i686 GNU/Linux machine with GNU Make 3.82 and g++ version 4.8.2.
Make relinks your project because it tries to build all. The rule for all does not create any file named all. Instead it produces myexe. Next time you run make, it will see that there's no all, but there's a rule to build one, so it dutifully executes that rule which happens to link myexe every time you run make.
In order to fix your problem you need to change your makefile to look roughly like this:
all: myexe
echo Build done
myexe: <myexe dependencies go here>
$(CXX) $(CFLAGS) -o myexe $(wildcard *.o) $(LDFLAGS)
Make always tries to build the top rule. For you, this is all. Since your all rule doesn't actually make an all file it will always be run.
Your probably want your all rule to be a myexe rule and, if you want an explicit all rule, have a dependency only rule: all: myexe.
(With GNU Make, you might want to explicitly declare those targets which aren't supposed to generate a real file with a .PHONY rule. e.g. .PHONY: all depend clean.)
make is a rule-based expert system.
You give it a heap of rules and a target (default target is the first one listed), and then it builds a complete dependency tree.
All parts are rebuilt iff they are non-existent resp. older than their dependencies, recursively.
The rule you are stumbling over is this: Because the target all does not create an output file all, make invokes the non-existent-or-outdated rule.
You can correct this by making the target all not do any work but instead just depend on the output file. Marking it .PHONY is also a good idea.

Makefile - Dependency file in a folder "No such file or directory"

I've got a Makefile that works good so far. Although, as it started growing, recompiling all the sources every time began to take too long. Here's a snippet from the working version:
CC=$(CROSS_COMPILE)g++
CFLAGS=-Wall -I./include -pg -O2
VPATH=./src:./include
all: dotgazer.cpp dotgazer/Dot.cpp
$(CC) $(CFLAGS) $^ -o dotgazer.out `pkg-config --libs opencv`
There are a lot more dependencies, but these two are enough to show what the problem is. I'm trying to move the compilation stage of each cpp file to a separate target. When it comes to the top-level file (dotgazer.cpp) it's not a problem and a general rule %.o: %.cpp works fine. But I can't get the second dependency to work. Here's how it looks now:
CC=$(CROSS_COMPILE)g++
CFLAGS=-Wall -I./include -pg -O2
VPATH=./src:./include
all: dotgazer.o dotgazer/Dot.o
$(CC) $(CFLAGS) $^ -o dotgazer.out `pkg-config --libs opencv`
%.o: %.cpp
$(CC) -c $(CFLAGS) $^ -o $#
dotgazer/Dot.o: dotgazer/Dot.cpp
$(CC) -c $(CFLAGS) $^ -o $#
I've tried different variations of the Dot.o rule but none of them seems to work. The error I get with the one above is:
Fatal error: can't create dotgazer/Dot.o: No such file or directory
How should I do that? I'd most prefer to have the .o files in the same folders as their sources. Also, I'd be thankful for general rules (like %.o: %.cpp) as there are lots of source files and I don't want the Makefile to get too bloated. Thank you!
I think your Makefile is a bit to specific and thus error-prone. I suggest to look at my following example that is way more generic than yours.
My example takes advantage of make's catalouge of implicit rules. For cpp-files exists a generic implicit rule already. So why should one not use it!?
The reference manual describes it as follows:
Compiling C++ programs
n.o is made automatically from n.cc, n.cpp, or n.C with a recipe of the form $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c.
So if you have %.o files as prerequisites like in the rule dotgazer.out: $(OBJS) make applies above implicit rule to all those files automatically. Assumed you have set valid values for CXX, CPPFLAGS and/or CXXFLAGS.
Furthermore you usually don't need to add your sources by hand to a variable. Most of the time all the sources in your project's directory tree are needed to build the executable. If it's not the case you should consider to build a appropriate tree that reflects this.
Since find is responsible to assign the sources to CPPFILES we don't need to set VPATH either. Due to our usage of find and patsubst we have only one explicit file name in our Makefile. That make working on a real project with plenty of different sources much more smooth.
Of course you don't need the all and the clean rule. I just added these for convenience.
CXX=$(CROSS_COMPILE)g++
CPPFLAGS=-I./include
CXXFLAGS=-Wall -pg -O2
LDLIBS=`pkg-config --libs opencv`
CPPFILES=$(shell find . -name "*.cpp")
OBJS=$(patsubst %.cpp, %.o, $(CPPFILES))
all: dotgazer.out
#echo $(CPPFILES)
#echo $(OBJS)
dotgazer.out: $(OBJS)
$(CXX) $(CXXFLAGS) -o $# $^ $(LDLIBS)
clean:
rm -f $(OBJS)