Creating multiple executables in Makefile - makefile

Im fairly new to makefiles. I want to compile multiple executables through my makefile, and it was to my understanding that having a target with multiple entries would run the recipe for that target through all entries. My example is:
$(EXE): $(OBJS)
g++ -o $# $< -L$(LIBPATH) -lOSApi -lrt -lpthread
My EXE variable contains all files that should be created, something like: prog1 prog2 and so on. My OBJS contains prog1.o prog2.o and so on.
When running make i create all .o files perfectly, but i only create one executable. I have tried replacing $# with $(EXE) and such, but no luck so far.
Any help would be appreciated.
EDIT:
I found the solution through MadScientist, who suggested to add an all target, and then changing my executable target to:
$(EXE): % : %.o
g++ -o $# $< -L$(LIBPATH) -lOSApi -lrt -lpthread
.PHONY: all clean
all: $(EXE)
Which to my understanding makes every target in my EXE target dependant on its corresponding .o file.

It would help greatly if you provided a full (small) sample. In the question you don't show us what the definition of EXE or OBJS is which makes it hard to say exactly.
Also, please be sure to format your question correctly.
By default make only builds the FIRST target in the makefile. It doesn't build ALL the targets in the makefile. So, if EXE contains multiple targets and the first rule in your makefile is $(EXE) : ... then only the first target in that list will be built.
You should add a new target before the above, saying that you want the default to build all the exe's. You can call it anything you like but the convention is to call it all:
all: $(EXES)
(you can also add a .PHONY: all for safety). Now the first target in the makefile is all, and as prerequisites it will build all the targets in the EXES variable.

Related

Delete targets with recipes failed in Makefile

I tried to use .DELETE_ON_ERROR target in makefile in order to delete both $(OBJ)
and executable files if the recipe fails, but it doesn't work. If I put an error inside any object file than while compiling the pattern rule an error occurs and it stops. The old object file is still on its place but I expect .DELETE_ON_ERROR to remove it.
Can anyone test the code? Can -include $(DEP) or flag -DDBG influence? The goal is to delete both the .o file that failed and the executable.
OUTPUT = executable
CPP := $(shell find $(SRC) -type f -name "*.cpp")
OBJ := $(CPP:.cpp=.o)
DEP := $(OBJ:.o=.d)
CXX := g++
CXXFLAGS =-MMD -MP -DDBG
INCLUDES = -I.
.DELETE_ON_ERROR :
$(OUTPUT): $(OBJ)
$(CXX) $^ -o $#
%.o: %.cpp
$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $#
-include $(DEP)
.PHONY : clean
clean:
rm -rf $(OBJ) $(DEP)
EDIT: According to the Ondrej K. solution to fix this problem you need to add #touch command before compilator in order to make the object files changed (the docs read "delete the target of a rule if it has changed".). So, the code should look like this:
%.o: %.cpp
#touch $#
$(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $#
Not sure what failure you're seeing, but I am afraid there really isn't a good way for you to do that. .o files and executable ($(OUTPUT)) are separate rules. If the latter fails, former is already out of consideration. See the documentation:
.DELETE_ON_ERROR:
If .DELETE_ON_ERROR is mentioned as a target anywhere in the makefile, then make will delete the target of a rule if it has changed and its recipe exits with a nonzero exit status, just as it does when it receives a signal. See Errors in Recipes.
In other words, if your the target producing a binary object failed after .o target itself got updated, make would prune the changed file. But if your executable did not link, it won't go back and delete object files.
Not sure it'd be nice, but if you really needed to, you could probably achieve this by refactoring your makefile to basically have direct exec + objs from source prerequisites rule with a single recipe. Obvious downside, such rule would mean single .c file change causing all files being recompiled (basically negating substantial benefit of using make).
EDIT: I'll expand on the comment a bit to clarify. What you seem to want is: in case there is a broken .c file and compilation fails, remove the old .o file. That is quite clearly not how .DELETE_ON_ERROR works though. If the .o file already got updated, and then the rule failed, it would remove it ("delete the target of a rule if it has changed"), but in case of a mentioned syntactical problem, the compiler would fail before it would produced an .o file.
So, if for instance you updated your (pattern) rule for compilation so that it first touches (effectively updates timestamp) on the .o file and then tries to compile. After the compiler call and rule failed make would consider the target of the failed root to have been updated and remove it. Alternatively you could also change to rule to first try to rm the expected '.o' file in which case you actually wouldn't need to use .DELETE_ON_ERROR (and if there is no change in the relevant sources, the rule does not get used, so it's actually not as terrible as it sounds). Either way is not exactly very clean, but leads towards the behavior I understand you're describing.
It is possible that the Compiler crashes while writing the Output file. In this case, there is a corrupt output file that is newer than its sources. Make will stop due to the error, but on next run, it won't recompile the output file as it is newer than ist sources - and the make will fail again and again in the build step.
With the .DELETE_ON_ERROR rule, make will delete the Output file if the compiler (or whatever build step failed) exits with an error after touching (and corrupting) the Output file, so it will be recompiled on next run. (if the Compiler failed without touching the old output file, it will always be recompiled on next run anyway)

GNU make in newly created subdirectory

First - I know there are a lot of discussions similar to this, but I've spent hours without them working for me.
My makefile first creates a directory named by the current date and time. I then have the makefile append to a header file a line which creates a string with this directory name. For this reason, I first need to copy all the source files (including the header) into the newly created subdirectory, so that I can preserve the original header and only modify the header (in the subdirectory) which will be used for compilation. I would then like to build in that new directory.
My trouble is getting make to properly build the .o files in the new subdirectory. The solution I've found is to have
$(NOW)%.o: $(NOW)%.cpp
$(CC) -c $(FLAGS) $<
where $(NOW)$ is the subdirectory name. The issue is that my $(FLAGS) seem to be ignored: the output is, roughly
g++ -c -o <.o file> <.cpp file>
(Yes, there is actually extra introduced space between g++ and -c.) Whereas building in the top level directory a la
%.o: %.cpp
$(CC) -c $(FLAGS) $<
correctly outputs
g++ -c <my flags> -o <.o file> <.cpp file>
To summarize, I am unable to compile normally by transferring the source files to a newly-created subdirectory and building the .o files in that directory. TYIA.
Ad John points out, there's no way to definitively diagnose your problem with the tiny bit of makefile you provided, because the error is not in the code you provided, it's in some other part of your makefile. You need to provide a SSCCE ideally, but if not that then at least we need to see how the NOW variable is set and the linker rule so we know what make is trying to build.
I should also point out that by convention you should not use CC to hold the C++ compiler; the CC variable holds the C compiler. Use CXX for the C++ compiler and CXXFLAGS for the C++ compiler flags.
One possibility is that you are assigning the NOW variable using a recursive assignment so that the timestamp is recreated every time the variable is evaluated; it could be that the timestamp changes over the lifetime of the makefile.
The other very common problem is that you created the pattern rule, but make is not using it because the targets make wants to build don't match the pattern.
So for example, if your link line looks like this:
SRCS = foo.cpp
OBJS = $(SRC:.cpp=.o)
myprog: $(OBJS)
$(CXX) ...
$(NOW)%.o : $(NOW)%.cpp
$(CXX) ...
then your pattern will not be matched because make is trying to build the file foo.o and your rule tells it how to build $(NOW)foo.o which are not the same thing.

Compile all source files into executables

I know that makefile is used for a project where files are related. But I want to use it in a different way.
Since I always write lots of test files, I need to type a bunch of flags every time I compile them, that's so troublesome. I just want to write a makefile that compiles all source files into executables with their corresponding names - like a.c to a and b.c to b, etc. so that I can get executables by simply typing make instead of the whole gcc ...
Is there any simple way to do it?
Make has a built in implicit rule like this:
% : %.c
$(CC) -o $# $(CFLAGS) $<
$(CFLAGS) would contain all your options.
Then, doing
make foo
Would try to produce foo from foo.c (if it existed).
To be able to compile all of them in one go, add another rule:
all: $(patsubst %.c,%,$(wildcard *.c))
This new rule, called 'all', has the list of your executables as its prerequisite. The wildcard function lists all .c files in the directory, and the patsubst removes the .c from each of them, leaving a list of the executables that would be produced from each .c file.
So doing
make all
causes it to try to compile each .c file into the corresponding executable.
Alright understood. I'm not too sure if you'll understand the syntax. I'll try to explain as much as I can.
you'll make a file called Makefile no extensions.
DIR=$(HOME)/../"Your directory"
all: "Whatever driver you may have"
purify: purify g++ -o "Your file" -Wall -pedantic -g "objective file .o extension"
# Makes clean file
clean:
rm -f *.o "Drivers"
new:
make clean
make
make has built in implicit rules to do that. Just type make a or make b or make a b or whatever you want. Add and export an environment variable called CFLAGS if you want to add any special options.

Canonical 'simple project' makefile

Your small C/C++ project has reached a point where it's no longer practical to have all your code in one file. You want to split out a few components. So you make a src/ directory, and then... you have to write a real Makefile. Something more than hello: hello.o. Uh-oh... was it $# or $< or $^? Crap. You don't remember (I never do).
Do you have a 'one-size fits all' simple Makefile that can deal with straightforward source trees? If so, what's in it and why? I'm looking for the smallest, simplest Makefile that can compile a directory full of C files nicely without me having to edit the Makefile every time I add a file. Here's what I have so far:
CXX = clang++
CXXFLAGS = ...
LDFLAGS = ...
EXENAME = main
SRCS = $(wildcard src/*.cc)
OBJS = $(patsubst src%.cc,build%.o, $(SRCS))
all: $(EXENAME)
build/%.o: src/%.cc
#mkdir -p $(dir $#)
$(CXX) -c -o $# $^ $(CXXFLAGS)
$(EXENAME): $(OBJS)
$(CXX) -o $# $^ $(LDFLAGS)
clean:
rm -rf $(EXENAME) build/
This Makefile builds all the .cc files in the src/ directory into .o files in the build/ directory, then links them up into the parent directory.
What would you do differently?
I would reconsider you decision not to have an explicit list of sources-- I think it may cause you trouble in the long run. But if that's your decision, this makefile is pretty good.
In the %.o rule I would use $< instead of $^, so that later you can add dependencies like
build/foo.o: bar.h
And when you're ready, you can take a look at Advanced Auto-Dependency Generation.
I've never used CMake, so I really can't say anything about that. The best that I can offer is a program that we have at school called 'makemake', which automatically makes Makefiles - http://www.cs.rit.edu/~swm/makemake/ It's not a very advanced program, but it gets the job done. On the plus side, it's incredibly easy to use - simply do 'makemake > Makefile' in the directory and you have a Makefile which will build and link all the source files in that directory(C and C++). On the bright side, if you ever add more files, you just run makemake again and you have a new makefile. On the downside, there's no way to keep any custom targets that you've done from one generated makefile to the next.
As for 'one size fits all' makefiles, while you could definitely do that, it takes away from the purpose of the 'make' command in the first place - which is to keep track of the files last modified time, and thus only re-compile the files that have recently changed, or depend on header files that have just changed(although to generate the correct you can use 'makedepend' - http://www.x.org/archive/X11R7.5/doc/man/man1/makedepend.1.html ). You could use what you currently have plus makedepend in order to make a self-updating makefile.
Use automake tools. Its easy to make changes and less burden to the developer. Its as simple as specifying the SOURCES, LDLIBS, LDFLAGS as variables. At first it may seem like a bit weird. But it becomes your favorite as you do more on it.

gnu make: match-anything: dependance on existence of prerequisites

Please consider the following Makefile:
CC = g++
CFLAGS = -c -O -Wall
EFLAGS = -O -Wall -lm -o
UTILITIES = error.o stream_manip.o mat_ops.o GaussElim.o
UTILITIES += abstractmatrix.o dvector.o dmatrix.o ConjGrad.o
# All objects
%.o: %.cpp %.hpp
$(CC) $(CFLAGS) $<
# Executables (doesn't have extension)
% : %.cpp $(UTILITIES)
$(CC) $(EFLAGS) % $< $(UTILITIES)
# Specific executable
#TS_CG : TS_CG.cpp $(UTILITIES)
#$(CC) $(EFLAGS) $# $#.cpp $(UTILITIES)
The match-anything rule (for executables) is supposed to enable me to type the following in a terminal:
make TS_CG
and have make compile the executable called TS_CG. However, make doesn't use my match-all target. Instead it uses its default compilation rule.
On the other hand, if all the objects listed in UTILITIES exist, it does use my match-all target. Hence it seems the matching depends on the existence of the prerequisites.
Apparently:
When a rule is terminal, it does not apply unless its prerequisites actually exist.
(according to
make manual ).
But my rule is not terminal; it is not marked by a double colon!
So why does this still seem to apply?
I might also ask if anyone has a better solution for differentiating between object targets and executable targets, as I have tried to do in my file.
I'm surprised that Make is able to build TS_CG when the UTILITIES don't already exist, since I wouldn't expect it to know that TS_CG needs them.
Anyway, when Make is trying to find a rule for TS_CG, all it finds are implicit rules (nothing specific to TS_CG). In particular, it has %: %.cpp $(UTILITIES), which you provided, and %: %.cpp, which is built in. If $(UTILITIES) all exist, then it will use the first rule, otherwise it will move down the list, looking for a rule whose prerequisites do exist, and find the second. Only if it fails to find any rule whose prerequisites exist will it resort to looking for rules to build the prerequisites.

Resources