6

I have been programming in c/c++ for a while now, and I have never once used a makefile. I know that it is supposed to be useful when you are dealing with a large project, but I have always been able to compile, build and execute my program using only

gcc main.c -o run

and if I am working with an external library (gtk+, for example) I make a simple bash script that looks like:

#!/bin/bash
echo compiling....
gcc main.c `pkg-config --cflags --libs gtk+-3.0` -o run

So what I'm asking is do I need to learn how to make a makefile?

  • 2
    You should take the habit to compile with gcc -Wall -Wextra -g. Then use the gdb debugger. Once you have no bugs, ask the compiler to optimize with -O – Basile Starynkevitch Feb 18 '15 at 8:48
  • You can always use a general-purpose high-level language (Python, Haskell, etc) instead of using an archaic special-purpose language (Makefile). prog21.dadgum.com/49.html – Thomas Eding Feb 25 '15 at 0:16
19

First, a Makefile for make is really useful when you build a program from several translation units (i.e. several *.c or *.cc files which are #include-ing some other header files) which are linked together (it is not very useful for a single source file tiny program). It organizes the various compilation steps of the translation units (and avoid running useless compilations again). See also this answer to a related question.

During the debugging phase, compile with all warnings and debug info (e.g. gcc -Wall -Wextra -g for C code compiled by GCC...) and learn how to use your debugger, e.g. GDB and memory leak detectors like valgrind.... Be scared of undefined behavior. With a recent GCC 5 compiler (at end of 2015), you may also want to use (occasionally) various -fsanitize= debugging options. Have some good testing procedures. For production and benchmarking, ask for compiler optimizations (e.g. add -march=native -O2 to your GCC compiler flags). For C++11 code, replace gcc with g++ -std=c++11; in your GNU Makefile, use CC & CFLAGS variables for C and CXX & CXXFLAGS for C++.

As soon as you are writing some not-tiny program in C or C++ (e.g. more than ten thousand lines of source code), you'll want to organize it in several translation units (at least to avoiding very long build times while working on it, and preferably to group together related code or features). Notice that with C++ the usual included header files are themselves quite big, so having tiny translation units slows the overall build process.

The size, organization, name, and purpose of a translation unit (i.e. of a foo.c or bar.cc file) is a matter of habits and conventional. Some people prefer having many tiny files (of a few dozen lines). I like having source files of several thousand lines. The recent version of GCC compiler, and the recent Linux kernel have dozens of human-written C or C++ source files bigger than ten thousand lines. Both are quite large software (many millions of source lines)

Then, you could build such a program using some other builder (like omake or scons, etc...), or even using a shell script (BTW, the GNU make distribution contains a shell script to build it on systems without any make yet!).

But yes, I believe you should learn GNU make (and you may even want to take advantage of recent GNU make features, e.g. Guile scriptability). Here is an example of Makefile, and another one.

Notice that for historical reasons the tab character is significant for make, so you need a specific mode in your editor.

In many cases, e.g. for configuration reasons, the Makefile is generated (e.g. with autoconf or cmake).

You should look into the source code of several free software programs (e.g. GNU make itself! See also sourceforge, github, etc... to find some) and try building them. That would teach you a lot.

So you don't need make (or some other builder) yet, just because your programs are very tiny. As soon as they will grow, you'll need some building process. Notice that large programs (a web browser, an optimizing compiler, an OS kernel) have often many millions lines of source code organized in at least hundreds of translation units, and often have some generated C/C++ code (by some script in awk, python, guile, etc..., or a specialized program itself coded in C++, or an external generator like ANTLR or gperf) for application-specific metaprogramming or aspect-oriented programming purposes.

PS. Some other programming languages (Ocaml, Haskell, Go, SML, ...) know about modules and have very different builders.

  • 4
    I do have several translation units of about 10Klines. But it is a matter of opinion and habits. I strongly dislike Java because it almost forces to have a lot of small source files (only a few hundred lines each). – Basile Starynkevitch Feb 18 '15 at 6:40
  • Rather than being so vague as to say "translation units with x lines," you should consider saying "translation units should represent a logical unit of functionality - related functions and classes that encompass a feature." Translation units should be as big as they need to be and no larger. Putting a number on it is misleading. – greyfade Feb 18 '15 at 7:04
  • 1
    I agree, but that is also subjective and matter of taste and of opinion. And many software have a misc.c or utilities.cc file grouping unrelated functions – Basile Starynkevitch Feb 18 '15 at 7:05
  • 3
    Does the GCC compiler counts as "real world of software programming" (for me, yes!)? It has several dozen of translation units of more than ten thousand lines. – Basile Starynkevitch Feb 19 '15 at 5:38
  • 2
    The Linux 3.19 kernel also has two dozens of *.c files of more than ten thousand lines. And it also looks like real world software programming. – Basile Starynkevitch Feb 19 '15 at 5:46
4

If you use a modern IDE(*) you will probably never have to look at a makefile in your life, even though the IDE generally will generate one for you on the fly.

Makefiles were a needed skill when I started out 30+ years ago. I rarely see them nowadays (and, if you do need one, there are makefile generators).

In short, don't learn a skill until you need it, or can anticipate needing it. Use the timer saved by not learning makefile to learn something else which will make you a better developer.


(*) and if you are not, you are missing out on a ton of helpful features, like code completion (often with pop up documentation of the completions), code navigation, integrated debugger, integrated unit test, GUI designers, refactoring, et al

  • 1
    I don't know much free software on Linux which requires an IDE to be compiled. All the major free software I have compiled at least once (Qt, GCC, Linux kernel, KDE, Gtk, Gnome, ...) use some builder; none of them require an IDE. And many of them (GCC; kernel) would be very painful to build with an IDE... – Basile Starynkevitch Feb 18 '15 at 18:30
  • 2
    That is a very good point, but free s/w has different requirements (and the world is bigger than free software on Linux). It needs to be buildable by everyone, so you can"t expect/force them to have, for instance, Eclipse installed. But for non-FOSS projects, once (please don't take this wrongly) would have ot be a foll not to use an IDE. I have been a professional freelance s/w developer for 35 years now, with 20+ companies, in 15+ countries, on three continents, and it has been 20+ years since I worked a project where we did not use some form of IDE. – Mawg Feb 19 '15 at 6:49
  • YMMV, of course, but, as the OP sounds like he is at the learning stage, an IDE is highly recommended. Your point, however, is valid for FOSS (but I would argue against it being widely valid, for personal or business projects). – Mawg Feb 19 '15 at 6:51
  • At the learning stage I would not recommend an IDE to automate build and deployment. Their are fine for editing, but new developers need to understand how their code is converted to something executable, and how it runs. For C/C++, that means understanding src => object => executable. – kevin cline Nov 21 '15 at 21:21
3

Do you have a specific need for make?

Tools like make are all about automation - being able to repeat a process flawlessly, time after time, as efficiently as possible. Check out this thread on github regarding a JavaScript development framework and the potential choice of using make as the build tool:

https://github.com/ericelliott/cloverfield/issues/2#issuecomment-68798159

Whatever tool you choose, you should use it because you have a particular purpose in mind, not because you "should be doing it". You'll see in the github thread that the tooling discussion centers on identifying and meeting specific criteria that the developers want in a task runner.

Other answers in the thread suggest reasons to use make with C programming. Do those benefits sound like things you need?

If you choose to use make, I agree with SHiNKiROU, learn make yourself before you use tools to build Makefiles. I learned a little bit of make during the github discussion, and it was very enlightening.

2

Checkout the section on make in The Art of Unix Programming. It explains the motivation behind make and why we have tools that generate Makefiles.

To summarize, the creator of make had a time when he wasted time debugging a working program because he forgot to manually recompile an object code. Make is an automated tool that determines what files need to be recompiled based on timestamps and the dependencies between files. Make is crucial for multi-file projects. You need to learn how to write Makefile in order to declare the dependencies between the files. I recommend you to write medium-sized, manageable Makefiles before learning how to use tools that generate Makefiles.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.