So far, I have a Makefile that looks like this:
# Program list:
# a.cpp, a.h,
# b.cpp, b.h,
# c.cpp. c.h,
# d.cpp, d.h,
# commonA.cpp, commonA.h,
# commonB.cpp, commonB.h,
# mainA.cpp, mainB.cpp,
# mainC.cpp, mainD.cpp.
CXX=g++
CXXFLAGS = -std=c++11 -g -Wall
prog1: mainA.cpp a.cpp
$(CXX) $(CXXFLAGS) programOne mainA.cpp a.cpp
prog2: mainB.cpp b.cpp
$(CXX) $(CXXFLAGS) programTwo mainB.cpp b.cpp
prog3: mainC.cpp c.cpp commonA.cpp
$(CXX) $(CXXFLAGS) programThree mainC.cpp c.cpp commonA.cpp
prog4: mainD.cpp d.cpp commonA.cpp commonB.cpp
$(CXX) $(CXXFLAGS) programFour mainD.cpp d.cpp commonA.cpp commonB.cpp
# etc...
I've had a look at the make GNU documentation, and it's fairly daunting - I've tried to understand as much as I can from it. I was wondering given my example how would I be able to shorten this even more than what it currently is? Is there a good rule to use that could make all the object files for each of the files in the program list above, and then I include the particular objects for each part? Any help is much appreciated!
Here's a tip: make has built-in rules that know how to create all kinds of different targets. Taking advantage of them will give you the shortest possible makefile.
Here's another tip: make uses string comparison to match up targets, prerequisites, and rules. So choosing the names of your files and programs wisely will give the best chance of taking advantage of make's built-in rules.
For example, you know already that a source file foo.cpp will be compiled into an object file foo.o. Make has a built-in rule that will handle that for you. If you also choose to name one of your source files so that it maps to the name of the program you want to create, you can take advantage of a built-in rule that will link your program as well.
As mentioned in the comments above, your rules are broken because the makefile target is named one thing (e.g., prog1) but the link line generates a different thing: programOne (here I'm assuming you simply forgot the -o option in your link line when you posted your code... please remember that when asking for help on SO--or really anywhere--it's best to create a SSCE). That should never happen for a non-special target; every rule should create a file with the identical name as the target.
Typically for C/C++ programs, the source file containing main() is named the same as the program you want to create. So for example if you want to create a program programOne then the source file containing main() should be named programOne.cpp.
If you follow these recommendations, then your entire makefile can be just:
CXX = g++
CXXFLAGS = -std=c++11 -g -Wall
all: programOne
programOne: programOne.o a.o
and that's it. Make knows how to build those targets for you so you don't have to tell it. If you want more programs, just add them as well:
all: programOne programTwo
programOne: programOne.o a.o
programTwo: programTwo.o b.o
The one issue left is header files prerequisites. If you want you can declare them yourself like this:
programOne.o: programOne.h a.h
etc. That's very simple but tedious to maintain. If you want to get make to configure them for you you can, but it's not simple. See this discussion for some ideas.
Related
While working on a C++ project, I noticed that I was making changes to one of the header files linked in my main code, but the make utility was not registering it. I had to force it to compile differently given the changes using "make - B".
I want to know why this is the case; is it because of how my makefile is written, how my files depend on each other, both, or neither?
Here is my makefile:
CXXFLAGS = -Wall -Werror -std=c++11 -pedantic -Wvla -g
//CXXFLAGS = -std=c++11
all: main.o game.o zombie.o
g++ $(FLAGS) game.o main.o zombie.o -o main $(CXXFLAGS)
game: game.cpp
g++ $(FLAGS) -c game.cpp $(CXXFLAGS)
zombie: zombie.cpp
g++ $(FLAGS) -c zombie.cpp $(CXXFLAGS)
main: main.cpp
g++ $(FLAGS) -c main.cpp pairing_heap.h $(CXXFLAGS)
I made a change to pairing_heap.h which is #included in my main file.
Why did make not notice that it should compile again? Because I feel like this is a conceptual misunderstanding, I felt that it was not necessary to include the changes I made or the output difference when I did "make - B". They were simple things like cout's and cerr's included in the new pairing_heap.h that were not being picked up until forced.
Let me know if I need to provide any more information.
Thank you.
You are listing pairing_heap.h in the recipe for main, which does not make it a dependency of main (besides, you should never pass headers to the compiler like this), for that you need to write the rule as follows:
main: main.cpp pairing_heap.h
g++ $(FLAGS) -c main.cpp $(CXXFLAGS)
There are a number of other things that are incorrect in your file, such as the fact that your targets are not actual files (main: should be main.o: etc.), and you aren't making use of automatic variables or pattern rules, but it's probably easier to just replace everything with the following
CPPFLAGS := -MMD -MP
CXXFLAGS := -Wall -Werror -std=c++11 -pedantic -Wvla -g
SOURCES := $(wildcard *.cpp)
main: $(SOURCES:.cpp=.o)
-include $(SOURCES:.cpp=.d)
which leverages make's implicit rules and gcc's/clang's auto dependency generation to make an executable called main.
Make doesn't really know anything about any particular programming language or tool, so it doesn't understand that C/C++ files depend on headers as well as source files. It just has rules of the form
target: dependencies
actions
All it knows from this is that the file target depends on the files listed in dependencies, and if any of those files are newer, the commands in actions should be run to update target. That's really it -- everything that make does comes from this simple idea of target files, dependencies, and actions.
Now there is more to it -- make has a bunch of built-in rules for common things you often want to do, as well as ways to specify 'pattern' rules -- rules where the target contains a wildcard, so can be used for many different targets that depend on other files with related names.
Now in your case, you have the rule:
all: main.o game.o zombie.o
g++ $(FLAGS) game.o main.o zombie.o -o main $(CXXFLAGS)
which says to remake the file all, if its older than the files main.o, game.o or zombie.o it should run the command. That's the first rule in the file, so it is what gets built by default when you type make.
Now, you probably don't have a file called all (if you did make probably wouldn't do anything), but that's generally fine, as if it doesn't exist, its obviously not up to date, so the command needs to run.
When a command needs to run, it also checks any of the dependencies to see if they in turn have dependencies that are older (so need to be rebuilt). Since these files all end in .o, they match a built-in rule that knows how to build them from a file with the same name, except ending with .cpp, so its runs those actions if (and only if) the .cpp file is newer.
Now, you say, "what about my other rules -- what do they do?" Well it turns out they don't do anything. They are rules to build files named game, zombie, and main, and since you never ask to build those files and nothing else depends on them, they do nothing. You might as well delete them.
You also ask "How do I make it rebuild if the header file changes?" Well, if you add a rule with no actions (just target and dependencies) it will just add those dependencies to another rule (built-in in this case) that does have an action. So if you add a line like:
main.o: pairing_heap.h
(with no action), make will add this dependency to the built-in rule that know how to build main.o from main.cpp and will run that rule (recompiling main.cpp) if either main.cpp or pairing_hep.h is newer than main.o -- which is exactly what you want.
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
I have a makefile in my src directory.
The makefile should build the data structures, which are in DataStructures/, and then iterate over all cpp files in calculations/ and create a corresponding .so file in ../bin/calculations
I tried the following syntax:
DAST = DataStructures/
COMPS = computations/
BIN = ../bin/
OBJECTS = ${DAST}Atom.o ${DAST}Molecule.o
COMPILE = g++ -Wall -g -c -std=c++0x -I/usr/local/include/openbabel-2.0 LINK = g++ -Wall -g -std=c++0x ${OBJECTS} -lopenbabel -I/usr/local/include/openbabel-2.0
all: ${BIN}main ${DAST}Molecule.o ${DAST}Atom.o ${BIN}${COMPS}%.so
${BIN}main: ${OBJECTS} main.cpp
${LINK} main.cpp -o ${BIN}main
${DAST}Molecule.o: ${DAST}Molecule.h ${DAST}Molecule.cpp
${COMPILE} ${DAST}Molecule.cpp -o ${DAST}Molecule.o
${DAST}Atom.o: ${DAST}Atom.h ${DAST}Atom.cpp
${COMPILE} ${DAST}Atom.cpp -o ${DAST}Atom.o
${BIN}${COMPS}%.o: ${COMPS}%.cpp
gcc -Wall -fPIC -c -lopenbabel $< -I/usr/local/include/openbabel-2.0 -std=c++0x
${BIN}${COMPS}%.so: ${COMPS}%.o
gcc -shared -Wl,-soname,libcsmtest.so.1 -o libcsmtest.so $#
clean:
rm -rf ${OBJECTS}
.PHONY: all clean
But it obviously doesn't work, as I get the following output:
shai#ubuntu:~/csm/csm2/src$ make all
make: *** No rule to make target `../bin/computations/%.so', needed by 'all'. Stop.
thanks
You need to specify in the all: target, the prerequisites explicitly.
In Makefile parlance, % is a wildcard that can be used in automatic rules. However, the all: target is a simple target with no such wildcard, thus ${BIN}${COMPS}%.so is wrong in that context.
Please note that when I say 'wildcard' in this context, this wildcard matches the target against the prerequisites, not against the filesystem like * do in glob expressions.
Also, while your hart is in the right place, as a matter of style, your Makefile can be better:
Intermediary objects, should not be prerequisites of the all target, but only the final targets you wish to ship.
There is a mix of automatic and simple rules to specify the creation of objects.
Typically one doesn't write an automatic rule for %.so, because a library is often constructed from more than one object.
The dependencies between an object and header files is a complex issue. In short you need to specify that the resulting object depends on the *.cpp (or .c) as well as all the headers included (directly and indirectly) by the *.cpp file.
By convention, that is well supported by GNU make, instead of using ${COMPILE} as you do, one should use $(CXX) for your C++ compiler, and $(CXXFLAGS) for the standard flags you wish to pass to that compiler.
You need something like
SOBJECTS = ...
all: ${BIN}main ${SOBJECTS}
...
You need a way to gather all the *.so names in the variable SOBJECTS. You can do this manually, or use some of make's internal functions to scan the source directory.
Also notice that I removed the two *.o files as dependencies from the all target. They are not final goals of the build (I assume), so you don't need to mention them there.
Besides this there are other stylistic points which I would do differently, but at the moment they are not causing immediate problems, so I won't digress, but I advise you to have a look at some tutorials to see how things are done generally.
For starters, look at Paul's Rules of Makefiles, and How Not to Use VPATH.
I have recently begun writing unit tests (using GoogleTest) for a C++ project. Building the main project is fairly simple: I use GCC's -MM and -MD flags to automatically generate dependencies for my object files, then I link all of the object files together for the output executable. No surpirses.
But as I'm writing unit tests, is there a way to have make or GCC figure out which object files are needed to compile each test? Right now, I have a fairly naive solution (if you can call it that) which compiles ALL available object files together for EVERY unit test, which is obviously wasteful (in terms of both time and space). Is there a way (with make, gcc, sed, or whatever else) to divine which object files are needed for a given unit test in a fashion similar to how dependencies are generated for the original source files?
It sounds like you have two groups of source files: one that actually implements your program, and another that's all the unit tests. I assume each unit test has its own main function, and unit tests never need to call each other.
If all that's true, you can put all the files from the first group in a static library, and link each of the unit tests against that library. The linker will automatically pull from the library only the object files that are needed.
In concrete Makefile terms:
LIBRARY_OBJECTS = a.o b.o c.o d.o # etc
UNIT_TESTS = u1 u2 u3 u4 # etc
UNIT_TEST_OBJECTS = $(UNIT_TESTS:=.o)
libprogram.a: $(LIBRARY_OBJECTS)
ar cr $# $?
$(UNIT_TESTS): %: %.o libprogram.a
$(CC) $(CFLAGS) -o $# $< -lprogram
You should look to a higher abstraction of project management, like Cmake or GNU Automake.
In your Makefile
SOURCES.cpp = a.cpp b.cpp ...
OBJECTS = $(SOURCES.cpp:%.cpp=%.o)
all: program
program: $(OBJECTS)
$(LINK) -o $# $(OBJECTS)
Maybe, depending on how orderly your test system is.
If there's a nice one-to-one relationship between header and source files, then you can use some text-converting functions (or a call to sed) to convert the machine-generated rule you already have:
foo.o: foo.cc foo.h bar.h gaz.h
into a rule for the corresponding test:
unit_test_foo: unit_test_foo.o foo.o stub_bar.o stub_gaz.o
Or if you use a lot of stubs without corresponding headers (which is a warning sign) you can link with every stub except stub_foo.o. These object files are small and don't change often, so it's cheap.
I know I am doing it wrong, but I can't figure out how to organize this makefile. I define my util source files, and use some functions to define the .o files from them here:
UTIL_SRC = utils/src/foo.cpp utils/src/bar.cpp utils/src/baz.cpp
UTIL_OBJS = $(patsubst utils/src/%.cpp,utils/obj/%.o,$(UTIL_SRC))
This is the target that I use these files for:
lib : lib/libutils.a
lib/libutils.a : $(UTIL_OBJS)
rm -f lib/libutils.a
ar -c -q lib/libutils.a $(UTIL_OBJS)
Then, when I get to the rule to compile these babies, I would love to just have one command that would iterate through each UTIL_OBJS file and each UTIL_SRC file. Instead I have resorted to this monstrosity, which defeats the purpose of storing them in variables.
$(UTIL_OBJS) : $(UTIL_SRC)
g++ $(UTIL_FLAGS) utils/src/foo.cpp -o utils/obj/foo.o
g++ $(UTIL_FLAGS) utils/src/bar.cpp -o utils/obj/bar.o
g++ $(UTIL_FLAGS) utils/src/baz.cpp -o utils/obj/baz.o
Can I condense this down to one line? How? Thanks, great ones!
It's usually easier to work with implicit rules. There are a lot of predefined ones, where you'll only need to specify variables.
CXX=g++
CXXFLAGS=$(UTIL_FLAGS)
Then you need to define an executable, like this
myutil: $(UTIL_OBJS)
Since you're not storing your objects in the same directory, you'll need to specify a new implicit rule as well though (otherwise, we'd be done now).
utils/obj/%.o: utils/obj/%.cpp
% is a pattern-match, it'll match the same text on both left and right side, so this rule will make foo.o out of foo.cpp.
Try if that'll work without the command (it might have grabbed that from another rule, I'm not sure), otherwise let it say:
utils/obj/%.o: utils/obj/%.cpp
$(CXX) $(CXXFLAGS) -o $# $^
$# is the target of the rule (e.g. foo.o), and $^ is all files on the right hand side.
I'm writing this off the top of my head, without the possibility to test it, so please let me know how it turned out.. :)
To make it even more elegant, you can include a dependency file
include .depend
If you're running GNU make, it'll try to make the .depend file if it can't find it (with old school make, you need to create it yourself first, it can be just a dummy though, if you'd like to manage it through the makefile)
.depend: $(UTIL_SRC)
$(CXX) -MM -o $# $^
The dependency file will contain lines for each .cpp file, telling make what header files it needs, which will allow make to recompile the necessary files when you change something. This doesn't help with your original question though, just thought it might come in handy.
EDIT:
As a response to your edit. You could probably drop the commands for creating the .a-file as well, that too is already available as an implicit rule. Not sure exactly how it works though, haven't used it much. I do know that there are a bunch of quirks in make for dealing with .a(rchive?)-files.
I think you could use this:
$(UTIL_OBJS) : $(UTIL_SRC)
g++ $(UTIL_FLAGS) $(# : .o = .cpp) -o $#
again, I'm not quite sure... especialy about the $(# : .cpp = .o) part