Make

Make

1):The Makefile is often used not only to control the compilation of source code, but also to prepare manual pages and to install the application into a target directory.

2):The makefile is read by the make command, which determines the target file or files that are to be made and then compares the dates and times of the source files to decide which rules need to be invoked to construct the target.

3):The make program itself has several options. The three most commonly used are

-k, which tells make to keep going when an error is found, rather than stopping as soon as the first problem is detected. You can use this, for example, to find out in one go which source files fail to compile.

-n, which tells make to print out what it would have done without actually doing it.

-f which allows you to tell make which file to use as its makefile. If you don’t use this option, the standard version of make looks first for a file called makefile in the current directory. If that doesn’t exist, it looks for a file called Makefile. However if you are using GNU Make, which you probably are on Linux, that version of make looks for GNUmakefile first, before searching for makefile and then Makefile. By convention, many Linux programmers use Makefile; this allows the makefile to appear first in a directory listing of a directory filled with lowercase-named files.

4):To tell make to build a particular target, which is usually an executable file, you can pass the target name to make as a parameter. If you don’t, make will try to make the first target listed in the makefile.

5):Many programmers specify all as the first target in their makefile and then list the other targets as being dependencies

for all. This convention makes it clear which target the makefile should attempt to build by default when no target is specified. We suggest you stick to this convention.

6):If you want to make several files, you can use the phony target all.

7):All rules must be on lines that start with a tab; a space won’t do.Also, a space at the end of a line in the makefile may cause a make command to fail.

8):The make command has read your makefile, determined the minimum number of commands required to rebuild myapp, and carried them out in the correct order.

9):You define a macro in a makefile by writing MACRONAME=value, then accessing the value of MACRONAME by writing either $(MACRONAME) or ${MACRONAME}.Some versions of make may also accept $MACRONAME.You can set the value of a macro to blank (which expands to nothing) by leaving the rest of the line after the = blank

10):Another problem with Makefile1 is that it assumes the compiler is called gcc. On other UNIX systems, you might be using cc or c89. If you ever wanted to take your makefile to a different version of UNIX,or even if you obtained a different compiler to use on your existing system, you would have to change several lines of your makefile to make it work.

11):Macros are normally defined inside the makefile itself, but they can be specified by calling make with the macro definition, for example, make CC=c89. Command-line definitions like this override defines in the makefile. When used outside makefiles, macro definitions must be passed as a single argument, so either avoid spaces or use quotes like this:make “CC = c89 “

12):In fact, make has several special internal macros that you can use to make makefiles even more succinct. We list the more common ones in the following table; Each of these macros is only expanded just before it’s used, so the meaning of the macro may vary as the makefile progresses. In fact, these macros would be of very little use if they didn’t work this way.

$? List of prerequisites (files the target depends on) changed more recently than the current target

$@ Name of the current target

$< Name of the current prerequisite

$* Name of the current prerequisite, without any suffix

13):There are two other useful special characters you may see in a makefile, preceding a command:

- tells make to ignore any errors. For example, if you wanted to make a directory but wished to

ignore any errors, perhaps because the directory might already exist, you just precede mkdir

with a minus sign. You will see - in use a bit later in this chapter.

@ tells make not to print the command to standard output before executing it. This character is

handy if you want to use echo to display some instructions.

14):

clean:

-rm main.o 2.o 3.o The rules for making the target “clean” don’t specify clean as depending on anything; the rest of the line after clean: is blank. Thus the target is always consideredout of date, and its rule is always executed if clean is specified as a target

15):

install: myapp

@if [ -d $(INSTDIR) ];

then

cp myapp $(INSTDIR);

chmod a+x $(INSTDIR)/myapp;

chmod og-w $(INSTDIR)/myapp;

echo “Installed in $(INSTDIR)“;

else

echo “Sorry, $(INSTDIR) does not exist”;

fi

The rules for making install consist of some shell script commands. Because make invokes a shell for executing rules and uses a new shell for each rule, you must add backslashes so that all the script commands are on one logical line and are all passed together to a single invocation of the shell for execution.

If it was very important that subsequent commands executed only if the previous one had succeeded, you could have

written the commands joined by &&

@if [ -d $(INSTDIR) ];

then

cp myapp $(INSTDIR) &&

chmod a+x $(INSTDIR)/myapp &&

chmod og-w $(INSTDIR/myapp &&

echo “Installed in $(INSTDIR)“ ;

else

echo “Sorry, $(INSTDIR) does not exist” ; false ;

fi

16):In fact, make has a large number of built-in rules that can significantly simplify makefiles, particularly if you have many

source files.these built-in rules are referred to asinference rules. The default rules use macros, so by specifying some new values for the macros you can change the default behavior.You can ask make to print its built-in rules with the-p option.

17):The built-in rules that you’ve seen work by using suffixes (similar to Windows and MS-DOS filename extensions so that when it’s given a file with one ending, make knows which rule can be used to create a file with a different ending. The most common rule here is the one used to create a file ending in .o from a file ending in .c.

18):If the version of make being used with Linux at the time didn’t have a built-in rule for compiling .cpp files.So we needed to teach make a new rule for creating objects from files with the extension .cpp.The special dependency .cpp.o: tells make that the rules that follow are for translating from a file with a suffix of .cpp to a file with a suffix of .o.Notice that you tell make how to get only from a .cpp to a .o file; make already knows how to get from an object file to a binary executable file.

When you invoke make, it uses your new rule to get from bar.cpp to bar.o, then uses its built-in rules

to get from the .o to an executable file. The extra -xc++flag is to tell gcc that this is a C++ source file.

.SUFFIXES: .cpp

.cpp.o:

$(CC) -xc++ $(CFLAGS) -I$(INCLUDE) -c $<

%.cpp: %.o

$(CC) -xc++ $(CFLAGS) -I$(INCLUDE) -c $<

19):Libraries are files, conventionally with the extension .a(for archive), that contain a collection of object files.The makecommand has a special syntax for dealing with libraries that makes them very easy to manage The syntax islib(file.o) which means the object file file.o, as stored in the library lib.a. The make command has a built-in rule for managing libraries that is usually equivalent to something like this:

.c.a:

$(CC) -c $(CFLAGS) $<

$(AR) $(ARFLAGS) $@ $*.o

The macros $(AR) and $(ARFLAGS) normally default to the command arand the options rv, respectively. The rather terse syntax tells make that to get from a .c file to an .a library it must apply two rules:

❑ The first rule says that it must compile the source file and generate an object.

❑ The second rule says to use the ar command to revise the library, adding the new object file.

So, if you have a library fud, containing the file bas.o, in the first rule $< is replaced by bas.c. In the

second rule $@ is replaced by the library fud.a and $ is replaced by the name bas*

20):The main makefile in the higher-level directory then has a rule for making the library, which invokes the second makefile like this:a new shell is invoked for this, the program using the makefile doesn’t execute the cd. However, the shell invoked to carry out the rule to build the library is in a different directory. The brackets ensure that it’s all processed by a single shell

mylib.a:

(cd mylibdirectory;$(MAKE))

21):gcc -MM main.c 2.c 3.c

The gcccompiler simply scans the source files looking for includes and outputs the required depend-ency lines in a format ready for insertion into a makefile All you have to do is save the output into a temporary file and then insert it into the makefile for a perfect set of dependency rules.If you really feel confident about makefiles, you might try using the makedepend tool, which performs a function similar to the -MMoption but actually appends the dependencies at the end of the specified makefile.

4.5 Phony Targets

A phony target is one that is not really the name of a file; rather it is just a name for a

recipe to be executed when you make an explicit request. There are two reasons to use a

phony target: to avoid a conflict with a file of the same name, and to improve performance.

If you write a rule whose recipe will not create the target file, the recipe will be executed

every time the target comes up for remaking. Here is an example:

clean:

rm *.o temp

Because the rm command does not create a file named ‘clean’, probably no such file will

ever exist. Therefore, the rm command will be executed every time you say ‘make clean’.

The phony target will cease to work if anything ever does create a file named ‘clean’ in

this directory. Since it has no prerequisites, the file ‘clean’ would inevitably be considered

up to date, and its recipe would not be executed. To avoid this problem, you can explicitly

declare the target to be phony, using the special target .PHONY as follows:

.PHONY : clean

Once this is done, ‘make clean’ will run the recipe regardless of whether there is a file

named ‘clean’.

Since it knows that phony targets do not name actual files that could be remade from

other files, make skips the implicit rule search for phony targets This is why declaring a

target phony is good for performance, even if you are not worried about the actual file existing.

Thus, you first write the line that states that clean is a phony target, then you write the rule, like this:

.PHONY: clean

clean:

rm *.o temp

Another example of the usefulness of phony targets is in conjunction with recursive

invocations of make .In this case the makefile will often contain a variable which lists a number of subdirectories

to be built. One way to handle this is with one rule whose recipe is a shell loop over the

subdirectories, like this:

SUBDIRS = foo bar baz

subdirs:

for dir in $(SUBDIRS); do

$(MAKE) -C $$dir;

done

There are problems with this method, however. First, any error detected in a submake

is ignored by this rule, so it will continue to build the rest of the directories even when one

fails. This can be overcome by adding shell commands to note the error and exit, but then

it will do so even if make is invoked with the -k option, which is unfortunate. Second, and

perhaps more importantly, you cannot take advantage of make’s ability to build targets in

parallel ,since there is only one rule.

By declaring the subdirectories as phony targets (you must do this as the subdirectory

obviously always exists; otherwise it won’t be built) you can remove these problems:

SUBDIRS = foo bar baz

.PHONY: subdirs $(SUBDIRS)

subdirs: $(SUBDIRS)

$(SUBDIRS):

$(MAKE) -C $@

foo: baz

Here we’ve also declared that the ‘foo’ subdirectory cannot be built until after the ‘baz’

subdirectory is complete; this kind of relationship declaration is particularly important

when attempting parallel builds.

A phony target should not be a prerequisite of a real target file; if it is, its recipe will

be run every time make goes to update that file. As long as a phony target is never a

prerequisite of a real target, the phony target recipe will be executed only when the phony

target is a specified goal Phony targets can have prerequisites. When one directory contains multiple programs,

it is most convenient to describe all of the programs in one makefile ‘./Makefile’. Since

the target remade by default will be the first one in the makefile, it is common to make this

a phony target named ‘all’ and give it, as prerequisites, all the individual programs. For

example:

all : prog1 prog2 prog3

.PHONY : all

prog1 : prog1.o utils.o

cc -o prog1 prog1.o utils.o

prog2 : prog2.o

cc -o prog2 prog2.o

prog3 : prog3.o sort.o utils.o

cc -o prog3 prog3.o sort.o utils.o

Now you can say just ‘make’ to remake all three programs, or specify as arguments the ones

to remake (as in ‘make prog1 prog3’). Phoniness is not inherited: the prerequisites of a

phony target are not themselves phony, unless explicitly declared to be so.

When one phony target is a prerequisite of another, it serves as a subroutine of the other.

For example, here ‘make cleanall’ will delete the object files, the difference files, and the

file ‘program’:

.PHONY: cleanall cleanobj cleandiff

cleanall : cleanobj cleandiff

rm program

cleanobj :

rm *.o

cleandiff :

rm *.diff

Sample

1: a simple example

1 include http://www.cnblogs.com/http://www.cnblogs.com/build/Makefile.inc
 2 
 3 EXEC=mculink_d
 4 OBJS= main.o mculink.o mculink_protocol.o
 5 
 6 INCLUDE +=  -I../h -Ihttp://www.cnblogs.com/../export/interprocess -Ihttp://www.cnblogs.com/http://www.cnblogs.com/common/h
 7 LDLIBS+=-lpthread  -lipc_evt_api -L$(LIBDIR)
 8 
 9 all: $(EXEC)
10     cp -f mculink_d ../;
11 
12 $(EXEC): $(OBJS)
13     $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS) $(INCLUDES) $(LIBPATH)
14     cp -f $(EXEC) $(BINDIR)
15     rm -f *.o
16 
17 clean: 
18     $(RM) $(EXEC) *.o  
19 
20 %.o: %.cpp
21     $(CXX) -c -o $@ $< $(INCLUDE)

2:when a blank space appears after writer in the first line.It always reporting the below error:

Make

1 EXEC=writer
 2 OBJ=$(EXEC).o
 3 SRC=$(EXEC).c
 4 CFLAG = -lpthread
 5 
 6 all:$(EXEC)
 7     cp -f $(EXEC) ../
 8     rm -f *.o
 9 
10 $(EXEC):$(OBJ)
11     gcc -o $@ $(OBJ) $(CFLAG) 
12 
13 $(OBJ):$(SRC)
14     echo $(EXEC) $(OBJ) $(SRC)
15     gcc -c -o $@ $< 
16 
17 clean:
18     rm -f $(EXEC)

3.A sample to Make several target in the same directory.

Rember to make clean before make ,or it may fail.
MakeMakeSeveral Target

1  include /build/Makefile.inc
 2  
 3  INCLUDE += -I/common/h -I/export/interprocess
 4  LDLIBS += -lpthread -lipc_evt_api -L$(LIBDIR)
 5  
 6  EXEC1=public_xxx
 7  EXEC2=handle_xxx
 8  
 9  EXEC=$(EXEC1) $(EXEC2)
10  OBJ1=$(EXEC1).o
11  OBJ2=$(EXEC2).o
12  
13  .PHONY:all clean
14  
15  all:$(EXEC)
16          @cp -f $(EXEC) /;
17  
18  $(EXEC1):$(OBJ1)
19          $(CXX) -o $@ $(OBJ1) $(LDLIBS)
20  
21  $(EXEC2):$(OBJ2)
22          $(CXX) -o $@ $(OBJ2) $(LDLIBS)
23  
24  %.o:%.cpp
25          $(CXX) -c -o $@ $< $(INCLUDE)
26  
27  clean:
28          rm -f *.o $(EXEC)

原文链接: https://www.cnblogs.com/hshuzhao/archive/2013/03/14/2959605.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/80665

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 下午7:40
下一篇 2023年2月9日 下午7:40

相关推荐