≡ Menu

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

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

(or)

$ 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 
main.o:main.c 
	cc -c main.c 
getaccno.o:getaccno.c 
	cc -c getaccno.c 
getname.o:getname.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
main.o:main.c
	cc -c main.c
getaccno.o:getaccno.c
	cc -c getaccno.c
getname.o:getname.c
	cc -c getname.c

clean:
	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
main.o:
getaccno.o:
getname.o:
clean:
	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."
main.o:
getaccno.o:
getname.o:
clean:
	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.

Add your comment

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

Comments on this entry are closed.

  • JimG August 19, 2010, 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.

  • Anurag Rana August 19, 2010, 7:22 am

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

    thanxs

  • null August 19, 2010, 7:45 am

    thank yoo. nice article

  • Ron August 19, 2010, 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#.

  • shllpa June 7, 2011, 1:54 am

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

  • null July 10, 2011, 6:20 am

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

  • Ravi August 29, 2011, 3:51 am

    Very nice article and helpful for beginners.

  • Krishna November 9, 2011, 5:32 am

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

  • soummo February 17, 2012, 8:09 am

    thanks, now i can begin with make 🙂

  • Aiyaz Ahmad March 15, 2012, 7:34 am

    thanks, your article is really useful for beginners.

  • jegan October 2, 2012, 1:54 am

    Good article

  • Rohit October 9, 2012, 1:34 am

    Very Nice & Useful Artical.
    Thanks.

  • keerthana October 30, 2012, 8:35 pm

    Very Good Article, Useful to students 🙂

  • Luis November 16, 2012, 8:10 pm

    Thank you! 🙂

  • Anonymous December 18, 2012, 1:10 am

    nice article , thanku

  • karthik January 5, 2013, 2:53 am

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

  • Sk Hasanujjaman April 18, 2013, 5:05 am

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

  • bells May 5, 2013, 12:27 am

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

  • G Leela sankar May 21, 2013, 7:47 am

    Thank you.. very nice article for beginners

  • kamal babu August 6, 2013, 8:44 pm

    Very usefull tutorial.

  • sumitha September 8, 2014, 12:36 am

    Superb

  • Nitesh January 4, 2016, 12:41 am

    Thank You! Appreciate your efforts! 🙂

  • Ashish Patil March 11, 2016, 10:30 pm

    Thank you so much.. superb tutorial.