Using make to Simplify the Build Process-C / C++-优质IT资源分享社区

  • UID1
  • 粉丝23
  • 关注4
  • 发帖数579
  • 社区居民
  • 忠实会员
  • 原创写手

  Using make to Simplify the Build Process

更多 发布于:2016-05-19 16:24

It isn't a big problem in this

case, but if you were dealing with a large development project and had hundreds

of source and header files to work on, it would be very time consuming to have

to rebuild them all every time you changed any one of them. The 'make' utility

is designed to resolve this issue by keeping up with what files were changed

when. It only recompiles the files that have been changed or have dependencies

that have been changed/recompiled. To use 'make' you must create a 'makefile'

for it to read the dependencies from. This file is most commonly called

'makefile' or 'Makefile', but can be anything you want, as long as you tell

'make' where it is (make will find a makefile named 'makefile' or 'Makefile' by

default). The syntax for the makefile isn't all that difficult, but as you

string more and more dependencies along and begin using some of the more

advanced features of the utility it can become fairly complex. If you are unable

to get your makefile to build your project correctly, there are some debugging

options available. For this and more info on make, read the man page, which

covers all of the command line arguments, but not the makefile syntax (check out for more info). Below is a simple makefile for miniwall:

miniwall : ui1.o hw3.o

gcc -o miniwall ui1.o hw3.o

ui1.o : ui1.c

gcc -c -w ui1.c

hw3.o : hw3.c

gcc -c -w hw3.c

This does precisely the same

thing as the few command line arguments to gcc shown above. By default, make

tries to build the first package listed in the makefile. In this case,

'miniwall'. Simply calling make in this directory will build miniwall. To tell

it to build a particular component of the makefile, you must specify the

specific target to build in the makefile (miniwall, ui1.o, or hw3.o in this


It is important to get the

syntax in the makefile exactly correct. The first line of each package is the

name of the file to build, then ':', and then the list of dependencies. Next,

there needs to be a carriage return to the next line. On the second line, you

must tab over once and enter the command line syntax for the command used to

build that file. Without a tab, it will not work. Whatever command is put on the

second line will be executed, even if it doesn't create the file. If more

commands than will fit on one line are needed, the line can be continued with

'\' rather than a carriage return.

Now, use the make command to

build the miniwall executable:

[nthomas@daisy hello]$ make

make: `miniwall' is up to


If you ran the gcc -c commands

to build the .o files and haven't edited the files since then, make won't see

any reason to rebuild them. To get make to rebuild miniwall, use the 'touch'

command to update the access time on those files:

[nthomas@daisy hello]$ touch

ui1.c hw3.c

[nthomas@daisy hello]$ make

gcc -c -w ui1.c

gcc -c -w hw3.c

gcc -o miniwall ui1.o hw3.o

When make went to build

miniwall, it saw that the sources for the two dependencies had been updated more

recently than their associated object files and rebuilt them. Once this was

done, it saw that the object files were newer than the latest copy of miniwall

and it decided to rebuild that as well. It is possible to 'trick' make into not

realizing it should rebuild by updating all of the files in question, so they

still appear to be matched up:

[nthomas@daisy hello]$ touch

ui1.c hw3.c miniwall ui1.o hw3.o

[nthomas@daisy hello]$ make

make: `miniwall' is up to


In a case like this, it would be

handy to have a 'make clean' option, where make would get rid of all of the old

object files and start fresh on the build. This is also useful when cleaning up

the build directory. Make does support such a function - it is done by adding

the following lines to the end of the makefile:

.PHONY : clean

clean :

rm *.o

You could just say:

clean :

rm *.o

but as previously discussed, the

name to the left of the colon is the name of the file that is checked for

dependencies. While no file named 'clean' will be created by the rm command,

what would happen if a file named clean already existed? Let's try it using a

modified makefile:

[nthomas@daisy hello]$ cp

makefile makefilebad

[nthomas@daisy hello]$ vi


Here the file is edited to drop

the 'PHONY' lines

[nthomas@daisy hello]$ make -f

makefilebad clean

rm *.o

This worked fine and deleted all

of the object files.

Now create a file named


[nthomas@daisy hello]$ touch


Remake the object and executable


[nthomas@daisy hello]$ make -f


gcc -c -w ui1.c

gcc -c -w hw3.c

gcc -o miniwall ui1.o hw3.o

Try to use the clean option:

[nthomas@daisy hello]$ make -f

makefilebad clean

make: `clean' is up to date.

Make sees that the file clean is

up-to-date (it has no dependencies). It doesn't execute the command associated

with it and fails to remove the object files.

To avoid this, we use the .PHONY

package name to tell make that there isn't a file to be associated with the

'clean' package name. Hence, it won't check and it won't matter if there is a

file named clean in the directory or not. Most clean statements also contain the

name of any targets that can be created by the makefile that don't have a .o

ending (in this case, 'miniwall'). The final line would read 'rm *.o miniwall'

and would delete the executable when clean was run. During development I often

don't add this command on the final executable.

As mentioned earlier, you can

include a remarkable amount of logic in a makefile and wind up with a very

robust and flexible way to build large scale projects. If you have a complex

development environment with many different compilation derivatives and large

numbers of source files, it is recommended you delve into make a little more by

checking out the gnu Web pages at If you want to see how complex

makefiles can become, check out the 400+ line makefile for the kernel in

/usr/src/linux/ (if you installed the kernel development packages).

[font=Tahoma  ]

优质IT资源分享社区为你提供此文。 [font=Tahoma  ][font=Tahoma  ]

本站有大量优质C、C++教程视频,资料等资源,包含C,C++基础教程,高级进阶教程等等,教程视频资源涵盖传智播客,极客学院,达内,北大青鸟,猎豹网校等等IT职业培训机构的培训教学视频,价值巨大。欢迎点击下方链接查看。 [font=Tahoma  ][font=Tahoma  ]




[PS:按 CTRL+D收藏本站网址~]