Makefiles, how can I use them? [closed]

^ This is not a duplicate question ^

Updated:

I'm fairly new to programming and I've only now just come across makefiles.

I've downloaded a bunch of tutorials and source code from a variety of places over the last few months; until now I've only been using VS solutions and been avoiding them.

I've seen multiple methods of using Makefiles on google, but they all differ in complexity...

I don't have a clue about them or how to use them. Thanks.

Edit (re-worded):

To summarise, due to the obvious confusion, my questions are (and always were):

1) Is there a good tutorial that comes recommended or is it easy to get started with Makefiles?
2) How do you launch and run an existing Makefile? And, 
3) Do Makefiles hold any vital data about the program or could I just use the `.h` and `.cpp` files that come with them in a new solution built from scratch?

Solution 1:

The question of when to use a Makefile is a matter of opinion. Certainly you can use some alternative builder (like e.g. omake or ninja, but there are many others). You certainly want some building system as soon as you have more than one translation unit in your software. If using make the Makefile describes the build process by detailing dependencies. Often, building you program is just done thru the simple make command.

Read more about C++ programming, and some C++ reference, for the terminology (perhaps also the C++11 standard n3337). See also this draft report.

Some utilities, e.g. cmake, qmake, automake, etc... are Makefile generators. They generate a complex Makefile which is usually not using all the features of GNU make.

If you decide to use make, I recommend using GNU make (this is also an opinion). In that case, read carefully its documentation, which I find quite readable and which contains a good tutorial. Don't forget to use a recent version: the version 4.0 of GNU make was released in october 2013 and brings a lot of interesting new features (plugins, and most importantly extensibility thru guile) whih are interesting for complex builds.

To debug complex Makefile-s consider using remake (notably as remake -x).

In practice, GNU make has a lot of built-in rules. You get them with make -p; so use them.

You may also choose to code for the POSIX make utility (which is a standard specification, but less powerful than GNU make, which can be configured to follow the POSIX spec).

How to code a Makefile is a matter of taste, and of software complexity. If you have 2 or 3 *.cc files with a single .h common header, you don't want all the fancy tricks (e.g. automatic dependencies, as provided by GCC and make) that are worth using on a software of many hundreds source files (and sometimes C++ source code is generated, e.g. by ANTLR, or by GNU bison, or by SWIG, by Qt moc, or by your own metaprogramming script, so the build system has to know that; for an example, see also RefPerSys).

Here is a tiny GNU Makefile to help you:

## file Makefile
CXX= g++
CXXSOURCES= main.cc other.cc
CXXOBJECTS= $(patsubst %.cc, %.o, $(CXXSOURCES))
OPTIMFLAGS= -g -O
PACKAGES= glib-2.0
PKGCONFIG= pkg-config
CXXFLAGS= -std=c++11 -Wall $(OPTIMFLAGS)
CPPFLAGS:=  $(shell $(PKGCONFIG) --cflags $(PACKAGES))
LIBES:= $(shell $(PKGCONFIG) --libs $(PACKAGES)) -ldl
.PHONY: all clean

all: myprog
myprog: $(CXXOBJECTS)
    $(LINK.cc) -rdynamic $^ $(LIBES) -o $@

$(CXXOBJECTS): yourheader.h

clean:
    $(RM) *.o *.so *.orig *~ myprog core* *.hh.gch
## eof Makefile

I don't claim it is a perfect example (it is not). Be careful, tabulations are significant for make and I am not able to type them above. You'll use make all (or just make) to build your program, and make clean to remove non-source files.

For obscure reasons, sometimes Makefile may be generated using autotools or cmake. For simple programs, it might not worth the effort to learn how to use them.

There are some few cases when GNU make is not worthwhile or appropriate: in MELT I nearly gave up using it (by calling some autogen generated shell script from it) because it is a bootstrapped language where a set of C++ files is generating itself from a set of MELT files, so you have a multiple to multiple quasi-circular dependency relation. Probably using a GUILE extension could have helped a lot. But such nightmare situations are rare.

PS: I answered as a Linux user; don't know what applies -or not- to Windows which I never use. See also these hints about C or C++ programming on Linux.

PS2: Paul Evans' answer is relevant: don't write your own Makefile, copy some existing one to suit your needs.

Solution 2:

If you are asking for a good tutorial then I think this one is good! You can totally follow it. I learned the make file by it.

Solution 3:

The fundamental concept for success when starting to roll your own makefile's is don't! Always grab a similar, simple, working makefile as a template and alter it to your own build. Only after getting this working, you may look at ways to improve it, make it more generic, etc through diligent reading and study. Then one day may come in the far, far future where you can actually write a makefile from scratch. But don't be disappointed if that day never comes.