Can You Make It? Compile C Programs on Linux Using Make Command

by Balakrishnan Mariyappan on August 19, 2010

When you install any software from source, you typically execute commands like — “make”, “make install”, “make clean”, etc. Have you wondered what all these make commands are really making? Sure, we know that it is trying to compile and install the software. But, why make? What does it really do?

For compiling a single C program, cc command is very helpful. For compiling multiple C programs, Make utility is very helpful.

Also, C programmers and sysadmins will find it helpful to automate the compilation related tasks using make utility. In this article, let us review how to use make command.

1. Create the Makefile for a Simple Compilation

Let us assume that you have the sample C program file called helloworld.c. Using cc command, typically you would compile it as shown below.

$ cc -o helloworld helloworld.c

While you don’t need to use make for compiling single a program, the following example will give you an idea on how to use make. Create a makefile as shown below.

$ vim makefile
helloworld : helloworld.c
	cc -o helloworld helloworld.c

Execute make to create the helloworld executable as shown below.

$ make helloworld


$ make

Since makefile contains only one target “helloworld”, you can also call make command without any argument as shown above.”make”.

Please ensure that both makefile and the source code are present in the same directory, otherwise specify the respective path of source files in makefile.

By default, make command expects the make filename to be either Makefile or makefile. If the make filename is different than any of these two, you should specify that to the make command using -f option as shown below.

$ make -f sample.txt

For those who are new to C, read C Hello World Program article.

2. Create the Makefile to Compile More than One File

For the multiple file compilation, let us use three files — getname.c, getaccno.c and main.c.

Based on these three *.c files, let us create an executable called “getinto”.

Using the cc command, you would typically do the compilation as shown below.

$ cc -o getinfo main.c getname.c getaccno.c header.h

You can also compile the individual *.c files as shown below and finally create the “getinfo” executable as shown below.

$ cc -c getname.c
$ cc -c getaccno.c
$ cc -c main.c
$ cc -o getinfo main.o getname.o getaccno.o header.h

Using our friendly make utility, you can effectively do this as shown below.

$ vim makefile
getinfo:getname.o getaccno.o main.o header.h 
	cc -o getinfo getname.o getaccno.o main.o header.h 
	cc -c main.c 
	cc -c getaccno.c 
	cc -c getname.c 

Finally, execute the make command as shown below.

$ make getinfo 

Note: Everytime make command gets invoked, it checks and compiles only the file that are modified. This is huge for C programmers, where they typically have multiple C file, and compiling the whole project several times during development phase.

You can also use gdb to debug C programs.

3. Add Target for Cleanup Process

Inside the makefile (or Makefile), you can also add target to cleanup the object files, as shown below.

clean : 
	rm getname.o getaccno.o main.o

Now you can clean the object files from the current directory as shown below.

$ make clean

Note: Instead of specifying the individual *.o file in the rm command, you can also give rm *.o.

You can also create a C archive files (*.a) using ar command.

4. Variable Handling in Makefile

Inside makefile (or Makefile) you can use variables, which can be used throughout the makefile. An example usage is shown below, where $obj contains all the object file names.

$ vim makefile
obj= getname.o getaccno.o main.o
getinfo: $(obj) header.h
	cc -o getinfo getname.o getaccno.o main.o header.h
	cc -c main.c
	cc -c getaccno.c
	cc -c getname.c

	rm getinfo $(obj)

5. Simplifying the Makefile Further

Make utility implicitly invokes the cc -c command to generate .o files for the corresponding .c file. We really don’t need to specify the “cc -c” inside the makefile. So, we can rewrite the makefile to reflect this implicit rule as shown below.

$ vim makefile
obj= getname.o getaccno.o main.o
getinfo: $(obj) header.h
	cc -o getinfo getname.o getaccno.o main.o header.h
	rm getinfo $(obj)

6. Insert Debug Messages inside Makefile

When you are compiling a big project, you might want to displays some friendly message. Make utility can print messages to the standard output, which might help you to debug any potential issues in the make process. Use the @echo statement throughout your makefile as shown below to display custom messages.

$ vim makefile
obj= getname.o getaccno.o main.o
getinfo: $(obj) header.h
	cc -o getinfo getname.o getaccno.o main.o header.h	
	@echo "make complete."
	rm getinfo $(obj)
	@echo "getinfo, $(obj) files are removed."	

There you have it. Make is not a mystery anymore. If you liked this article, please bookmark it in delicious, or stumble it.

If you enjoyed this article, you might also like..

  1. 50 Linux Sysadmin Tutorials
  2. 50 Most Frequently Used Linux Commands (With Examples)
  3. Top 25 Best Linux Performance Monitoring and Debugging Tools
  4. Mommy, I found it! – 15 Practical Linux Find Command Examples
  5. Linux 101 Hacks 2nd Edition eBook Linux 101 Hacks Book

Bash 101 Hacks Book Sed and Awk 101 Hacks Book Nagios Core 3 Book Vim 101 Hacks Book

{ 21 comments… read them below or add one }

1 JimG August 19, 2010 at 6:26 am

Your first example will work without a makefile.

$ make helloworld

automatically does this:
cc helloworld.c -o helloworld

which gives the same results.

2 Anurag Rana August 19, 2010 at 7:22 am

Nice article….
now i m clear about make command and file…


3 null August 19, 2010 at 7:45 am

thank yoo. nice article

4 Ron August 19, 2010 at 10:51 am

good article. good work. thanks.
can you provide samples with ant to build, deploy, cruise control to build, run test cases, email when build fails run code coverage, assign versioning, and finally deploy versioned build to deploy/prod machine on success of builds, test case, coverage of say more than 90%. could be any open source language java, ruby or mono c#.

5 shllpa June 7, 2011 at 1:54 am

very nice article !!! thanks helped a lot ..

6 null July 10, 2011 at 6:20 am

Your use of examples really help me to understand the Make functionality

7 Ravi August 29, 2011 at 3:51 am

Very nice article and helpful for beginners.

8 Krishna November 9, 2011 at 5:32 am

Very useful article and as u said not any more mysterious in ‘Make’ utility

9 soummo February 17, 2012 at 8:09 am

thanks, now i can begin with make :)

10 Aiyaz Ahmad March 15, 2012 at 7:34 am

thanks, your article is really useful for beginners.

11 jegan October 2, 2012 at 1:54 am

Good article

12 Rohit October 9, 2012 at 1:34 am

Very Nice & Useful Artical.

13 keerthana October 30, 2012 at 8:35 pm

Very Good Article, Useful to students :)

14 Luis November 16, 2012 at 8:10 pm

Thank you! :)

15 Anonymous December 18, 2012 at 1:10 am

nice article , thanku

16 karthik January 5, 2013 at 2:53 am

thanks for the article….really awesome helped me a lot….good job

17 Sk Hasanujjaman April 18, 2013 at 5:05 am

Very nice tutorial. Thanks for explaining it clearly without complexity.

18 bells May 5, 2013 at 12:27 am

nice tutorial..thank you.
but i need “main.c getname.c getaccno.c header.h” source code? thanks.

19 G Leela sankar May 21, 2013 at 7:47 am

Thank you.. very nice article for beginners

20 kamal babu August 6, 2013 at 8:44 pm

Very usefull tutorial.

21 sumitha September 8, 2014 at 12:36 am


Leave a Comment

Previous post:

Next post: