I'm extremely new to Makefiles, and I'm currently trying to build my first one on a project I'm starting.
The problem I'm having is having it automatically know how to handle all my .cpp files without defining rules for each one.
I also want my object files to all be put in one folder which is $(PLATFORM)/obj/ where PLATFORM=win32 in this case.
The follwing is what I'm using for a Makefile, executing it with mingw32-make.exe
CXX=g++
CXXFLAGS=-c -Wall -DALLEGRO_STATICLINK
LDFLAGS=
PLATFORM=win32
SOURCES=main.cpp
EXECUTABLE=app.exe
OBJDIR=$(PLATFORM)/obj/
OBJECTS= $(SOURCES:%.cpp=$(OBJDIR)%.o)
all: $(EXECUTABLE)
%.o: %.c
$(CXX) $(CXXFLAGS) $< -o $#
$(EXECUTABLE): $(OBJECTS)
$(CXX) $(OBJECTS) $(LDFLAGS) -o $(EXECUTABLE)
I'm getting the error:
mingw32-make: * No rule to make target win32/obj/main.o', needed by
app.exe' . Stop.
I'm not sure what I'm doing wrong, I've been looking around at other examples of makefiles and they seem to have a similar structure, so I'm not sure whats wrong with mine. I'm looking for an explanation of why this is happening, and advice on how to fix it.
Also, any comments on my style, suggestions for making it more clean/standardized would be great as well. While learning to make makefiles, I want to make sure I'm learning properly.
Thanks
make sees that it needs to create win32/obj/main.o, but can't see any rule to tell it how to do that.
You have three rules, one for all, one for %.o and one for $(EXECUTABLE). The first one and the last one will not tell make how to create win32/obj/main.o.
The second rule probably should, but it says this: if you want to create <something>.o, then first make sure that there's a file called <something>.c (if it doesn't exist, try to find a rule to make it). Then run the following command: $(CXX) ...
But the file <something>.c doesn't exist, because your files end with .cpp. So this rule fails. make can't find any other rule to build win32/obj/main.o, so it gives up.
In summary, you need to change the rule so that %.o depends on %.cpp, and then make will be able to run the command to create the object file. So the rule should be:
%.o: %.cpp
$(CXX) $(CXXFLAGS) $< -o $#
By the way, make also has predefined implicit rules. Because you give an explicit rule for %.o you're actually overriding the predefined rule. I suggest you try at some point not to give this rule at all (but still define CXX and CXXFLAGS) and see what happens. See this for details.
I don't want to dissuade you from using manual makefiles, but if you want to eliminate the problem altogether, there are autotools available that will generate the makefiles for you. Since you're using Windows, I suspect you're using cygwin (or perhaps MingGW). For cygwin, just download the autotools binary package. If you're using eclipse for your IDE (which I strongly promote), you can configure your environment to pick up on the autotools. This way, you just focus on writing the code. All configurability options still exist, but you don't have to know make.
Related
I'm quite new to makefiles, and I'm wondering what exactly is the role of the library in this format:
app: app.o mylibrary.a
$(LD) -o $# $(LDFLAGS) app.o mylibrary.a
What I usually see would be something like this:
app: app.o
$(LD) -o app $(LDFLAGS) $^ mylibrary.a
My understanding for this format is that the executable will be made from the app.o file, which has a dependency on mylibrary.a.
I can't quite understand the difference/meaning of the first version though.
Where the $# is the target is substituted, in the first case that would be app.
Although they aren't defined in the question, the $(LD) and $(CFLAGS) are usually defined as the c-compiler and the flags to use in the compiler.
E.g. something like CFLAGS = -g -Wall -std=c99 -lstdc++ would be a defined line at the top of the Makefile.
I'd usually write these as the first two parts of the command to run for the target.
The $^ indicates to substitute everything that is listed as a dependency of the target. In the first row the dependencies are app.o mylibrary.a whereas in the second it is only app.o. These ($^, $#)are usually used to simplify the writing of make rules.
The choice of whether to use the wildcards-as these are called-is really your own choice. I usually use them because they make it easier to write and maintain.
So to answer your question the main difference is where you explicitly need to place the name of the file.
Additional note on dependencies
The files in the line where there are dependencies of the target listed are used by make to determine which targets need to be rerun. Make does a topological sort of the dependencies and if something changes-based on last touched time of file-the make command will rerun the target if it is within the path of the make target that is being called.
I seem to be having an issue getting my makefile to build my C++ file correctly. My makefile code is below; the file I am trying to compile is named "avl.cc" (which is working and compiles properly).
CC=g++
CFLAGS=-g -O2
PROGS=avl
all: $(PROGS)
$#:
$(CC) $(CFLAGS) $# $#.cc
.PHONY: clean
clean:
rm $(PROGS)
However, when I enter the command make or make all, I get
c++ avl.cc -o avl
And the debugging symbols I want from the -g flag don't come up. A similar makefile (only changing the PROGS variable) worked for a similar project, so I am not sure what I'm doing wrong. Does anyone have any tips? Thanks!
From Makefile documentation about automatic variables:
It’s very important that you recognize the limited scope in which
automatic variable values are available: they only have values within
the recipe. In particular, you cannot use them anywhere within the
target list of a rule; they have no value there and will expand to the
empty string.
This means you cannot use $# as a rule, which means the default c++ compilation rule of Makefile is used, and since you did not use the correct variable names for c++ compilation, they are also ignored.
You can replace CC by CXX and CFLAGS by CXXFLAGS to work with c++.
You don't have a target for 'avl', so make uses a default rule.
Try changing the makefile to this:
CC=g++
CFLAGS=-g -O2
PROGS=avl
all: $(PROGS)
$(PROGS):
$(CC) $(CFLAGS) -o $# $#.cc
.PHONY: clean
clean:
rm $(PROGS)
I had the exact same question but a much different source of the problem. There were typos or misnamed files in my makefile. Make found no rules for such files but tried to compile targets with the c++ compiler. This made the process seem like it was ignoring my rules and imposing its own, switching compilers since I needed g++. Finally I tried using the -r option, and then the resulting different error messages allowed me to figure out what was really wrong. Below is the entry from the make man page for option -r.
-r, --no-builtin-rules
Eliminate use of the built-in implicit rules. Also clear out the default
list of suffixes for suffix rules.
To generate dependency files I can use something like this to generate dependency files:
-include $(patsubst %.cpp,build/%.d,$(SRC))
build/%.o: %.cpp
$(CC) $(CXXFLAGS) -c -o $# $<
$(CC) $(CXXFLAGS) -MM -MT $# -MF $(patsubst %.o,%.d,%#) $<
This generates everything and puts both the object and dependency files into the build dir where I want them. But this makes two dependency lines for the <file>.o targets, one from the -include rule and with all the header dependencies, and one which is from the pattern rule. Will this get interpreted correctly, i.e. when a header is modified, the object will be recompiled via the command specified for the pattern rule?
Edit: So this approach does in fact work quite well. I guess I'd like somebody to provide an answer which gives me some insight into what it is exactly that make does in these situations. For instance, what if a different command was given for both rules for the same target? My guess would be that it gives an error since it wouldn't be obvious which command to execute.
You should add one more pattern rule to express the dependency between the .cpp and .d files and use that rule to create the .d files (second line in the pattern rule of your question) instead of creating the .d files unconditionally. It might make sense to introduce another dependency between all .h and .cpp files and all .d files to force re-creating the .d files if a header or source file changes.
Here's the separate rule for .d files (hope I got it right):
-include $(patsubst %.cpp,build/%.d,$(SRC))
build/%.o: %.cpp
$(CC) $(CXXFLAGS) -c -o $# $<
build/%.d: %.cpp
$(CC) $(CXXFLAGS) -MM -MT $# -MF $<
Edit: So this approach does in fact
work quite well. I guess I'd like
somebody to provide an answer which
gives me some insight into what it is
exactly that make does in these
situations.
I'm afraid currently it would only work by chance (or you have not given all relevant pieces from the make file). See, you have not expressed any dependency between .d files and .cpp files. This, however, is needed so that your .d files get updated before inclusion as make file fragment.
For instance, what if a
different command was given for both
rules for the same target? My guess
would be that it gives an error since
it wouldn't be obvious which command
to execute.
With that syntax it wouldn't make a difference. But there are some special cases where splitting the rules into two (though otherwise identical rules) has merit. I strongly recommend you get the book "Managing Projects with GNU Make" to get a grip on the various ways of working with GNU Make. The only other recommendation in connection with GNU Make is to read to read the paper here.
Yes, you can specify several rules for one file, and they get merged into one.
See the GNU Make documentation.
[...] There can only be one recipe to be executed for a file. [...]
An extra rule with just prerequisites can be used to give a few extra prerequisites to many files at once.
And I second that there should be separate rule for .d files. It's names in many projects are deps or depend.
POSIX 7 also says that multiple lines for a given target work http://pubs.opengroup.org/onlinepubs/9699919799/
A target that has prerequisites, but does not have any commands, can be used to add to the prerequisite list for that target. Only one target rule for any given target can contain commands.
so long as only one has the commands.
I've been working on a makefile that uses secondary expansion not knowing that this feature only exists since version 3.81 of GNU make. Unfortunately, there are some old machines around here that only have make 3.79.1 installed and on these machines, the makefile doesn't work, of course. Is there an alternative to secondary expansion?
The rule for a C++ program where I use it looks like the following:
.SECONDEXPANSION:
# Pattern rule for linking
%_$(SYSTEM) : $$(%_ofiles) $(EXEC)/%_$(SYSTEM).o
$(LD) $(LDFLAGS) -o $# $^ $(LIBS)
# Example for an ofiles variable
prog1_ofiles = $(C1) $(C2)
C1 = $(OFILES)/C1.o
C2 = $(OFILES)/C2.o
I know - the best solution would be to install a current make version. But our system administrator was not enthusiastic about it ;) So I'm looking forward to your suggestions.
Btw, does anyone know where to get the documentation of GNU make 3.79.1 - I couldn't find it anywhere.
Just add make-3.81 sources in your source tree. Your main Makefile first should compile make-3.81 using whatever make is available and then use make-3.81 for compiling everything else.
What about a function/macro? Using eval would achieve the same result as the secondary expansion. Certainly not as clean, but less typing than all the explicit rules.
define PROGRAM_template
$(1)_$(SYSTEM) : $$($(1)_ofiles) $(EXEC)/$(1)_$(SYSTEM).o
$(LD) $(LDFLAGS) -o $# $^ $(LIBS)
endef
$(foreach target, prog1 prog2 prog3, \
$(eval $(call PROGRAM_template, $(target)))
Maybe you can wrap $$(%_ofiles) with eval in your original code and omit the foreach. Not sure...
No $(eval)?, bah! You will have to write some shell to emit the specific make syntax into file.mk (say), and then include that into the Makefile. You bootstrap the process by telling make that the Makefile depends on file.mk. Make first has to update Makefile before anything else. So it will create file.mk, include it, and restart itself.
For your case it looks like file.mk will just contain dependencies and no recipes. A brief sketch:
%_${SYSTEM}: ${EXEC}/%_${SYSTEM}.o
$(LD) $(LDFLAGS) -o $# $^ $(LIBS)
file.mk:
echo '%_${SYSTEM}: ${prog1_ofiles}' >$#
Makefile: file.mk
include file.mk
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