亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

How to write a Makefile

2019-11-17 05:26:41
字體:
來源:轉載
供稿:網友

  IntrodUCtion
Make is one of the original Unix tools for Software Engineering. By S.I. Feldman of AT&T Bell Labs circa 1975. But there are public domain versions (eg. GNU) and versions for other systems (eg. Vax/VMS).

Related tools are the language compilers (cc, f77, lex, yacc, etc.) and shell PRogramming tools (eg. awk, sed, cp, rm, etc.). You need to know how to use these.

Important adjuncts are lint (source code checking for obvious errors) ctags (locate functions, etc. in source code) and mkdepend. These are nice, and good programmers use them.

Important, and related tools, are the software revision systems SCCS (Source Code Control System) and RCS (Revision Control System -- the recommended choice)

The idea is to automate and optimize the construction of programs/files -- ie. to leave enough foot prints so that others can follow.
Makefile Naming
make is going to look for a file called Makefile, if not found then a file called makefile. Use the first (so the name stands out in listings).

You can get away without any Makefile (but shouldn't)! Make has default rules it knows about.
Makefile Components

* Comments

Comments are any text beginning with the pound (#) sign. A comment can start anywhere on a line and continue until the end of the line. For example:

# $Id: slides,v 1.2 1992/02/14 21:00:58 reggers EXP $

* Macros

Make has a simple macro definition and substitution mechanism. Macros are defined in a Makefile as = pairs. For example:

MACROS= -me
PSROFF= groff -Tps
DITROFF= groff -Tdvi
CFLAGS= -O -systype bsd43

There are lots of default macros -- you should honor the existing naming conventions. To find out what rules/macros make is using type:

% make -p

NOTE: That your environment variables are exported into the make as macros. They will override the defaults.

You can set macros on the make command line:

% make "CFLAGS= -O" "LDFLAGS=-s" printenv
cc -O printenv.c -s -o printenv

* Targets

You make a particular target (eg. make all), in none specified then the first target found:

paper.dvi: $(SRCS)
$(DITROFF) $(MACROS) $(SRCS) >paper.dvi

NOTE: The the line beginning with $(DITROFF) begins with TAB not spaces.
The target is made if any of the dependent files have changed. The dependent files in this case are represented by the $(SRCS) statement.

* Continuation of Lines

Use a back slash (). This is important for long macros and/or rules.


* Conventional Macros

There are lots of default macros (type "make -p" to print out the defaults). Most are pretty obvious from the rules in which they are used:

AR = ar
GFLAGS =
GET = get
ASFLAGS =
MAS = mas
AS = as
FC = f77
CFLAGS =
CC = cc
LDFLAGS =
LD = ld
LFLAGS =
LEX = lex
YFLAGS =
YACC = yacc
LOADLIBS =
MAKE = make
MAKEARGS = 'SHELL=/bin/sh'
SHELL = /bin/sh
MAKEFLAGS = b

* Special Macros

Before issuing any command in a target rule set there are certain special macros predefined.

1. $@ is the name of the file to be made.
2. $? is the names of the changed dependents.

So, for example, we could use a rule

printenv: printenv.c
$(CC) $(CFLAGS) $? $(LDFLAGS) -o $@

alternatively:

printenv: printenv.c
$(CC) $(CFLAGS) $@.c $(LDFLAGS) -o $@

There are two more special macros used in implicit rules. They are:

1. $< the name of the related file that caused the action.
2. $* the prefix shared by target and dependent files.

* Makefile Target Rules

The general syntax of a Makefile Target Rule is

target [target...] : [dependent ....]
[ command ...]

Items in brackets are optional, ellipsis means one or more. Note the tab to preface each command is required.

The semantics is pretty simple. When you say "make target" make finds the target rule that applies and, if any of the dependents are newer than the target, make executes the com- mands one at a time (after macro substitution). If any dependents have to be made, that happens first (so you have a recursion).

A make will terminate if any command returns a failure sta- tus. That's why you see rules like:

clean:
-rm *.o *~ core paper

Make ignores the returned status on command lines that begin with a dash. eg. who cares if there is no core file?

Make will echo the commands, after macro substition to show you what's happening as it happens. Sometimes you might want to turn that off. For example:

install:
@echo You must be root to install

* Example Target Rules

For example, to manage sources stored within RCS (sometimes you'll need to "check out" a source file):

SRCS=x.c y.c z.c

$(SRCS):
co $@

To manage sources stored within SCCS (sometimes you'll need to "get" a source file):

$(SRCS):
sccs get $@

Alternativley, to manage sources stored within SCCS or RCS let's generalize with a macro that we can set as required.


SRCS=x.c y.c z.c
# GET= sccs get
GET= co

$(SRCS):
$(GET) $@

For example, to construct a library of object files

lib.a: x.o y.o z.o
ar rvu lib.a x.o y.o z.o
ranlib lib.a

Alternatively, to be a bit more fancy you could use:

OBJ=x.o y.o z.o
AR=ar

lib.a: $(OBJ)
$(AR) rvu $@ $(OBJ)
ranlib $@

Since AR is a default macro already assigned to "ar" you can get away without defining it (but shouldn't).

If you get used to using macros you'll be able to make a few rules that you can use over and over again.
For example, to construct a library in some other Directory

INC=..../misc
OTHERS=..../misc/lib.a

$(OTHERS):
cd $(INC); make lib.a

Beware:, the following will not work (but you'd think it should)

INC=..../misc
OTHERS=..../misc/lib.a

$(OTHERS):
cd $(INC)
make lib.a

Each command in the target rule is executed in a separate shell. This makes for some interesting constructs and long continuation lines.

To generate a tags file

SRCS=x.c y.c z.c
CTAGS=ctags -x >tags

tags: $(SRCS)
${CTAGS} $(SRCS)

On large projects a tags file, that lists all functions and their invocations is a handy tool.
To generate a listing of likely bugs in your problems

lint:
lint $(CFLAGS) $(SRCS)

Lint is a really good tool for finding those obvious bugs that slip into programs -- eg. type classes, bad argu- ment list, etc.

* Some Basic Make Rule

People have come to expect certain targets in Makefiles. You should always browse first, but it's reasonable to expect that the targets all (or just make), install, and clean will be found.

1. make all -- should compile everything so that you can do local testing before installing things.
2. make install -- should install things in the right places. But watch out that things are installed in the right place for your system.
3. make clean -- should clean things up. Get rid of the executables, any temporary files, object files, etc.

You may encounter other common targets, some have been already mentioned (tags and lint).

* An Example Makefile for printenv

# make the printenv command
#
OWNER=bin
GROUP=bin
CTAGS= ctags -x >tags
CFLAGS= -O
LDFLAGS= -s
CC=cc
GET=co
SRCS=printenv.c

OBJS=printenv.o
SHAR=shar
MANDIR=/usr/man/manl/printenv.l
BINDIR=/usr/local/bin
DEPEND= makedepend $(CFLAGS)
all: printenv

# To get things out of the revision control system
$(SRCS):
$(GET) $@
# To make an object from source
$(CC) $(CFLAGS) -c $*.c

# To make an executable

printenv: $(OBJS)
$(CC) $(LDFLAGS) -o $@ $(OBJS)

# To install things in the right place
install: printenv printenv.man
$(INSTALL) -c -o $(OWNER) -g $(GROUP) -m 755 printenv $(BINDIR)
$(INSTALL) -c -o $(OWNER) -g $(GROUP) -m 644 printenv.man $(MANDIR)

# where are functions/procedures?
tags: $(SRCS)
$(CTAGS) $(SRCS)

# what have I done wrong?
lint: $(SRCS)
lint $(CFLAGS) $(SRCS)

# what are the source dependencies
depend: $(SRCS)
$(DEPEND) $(SRCS)

# to make a shar distribution
shar: clean
$(SHAR) README Makefile printenv.man $(SRCS) >shar

# clean out the dross
clean:
-rm printenv *~ *.o *.bak core tags shar

# DO NOT DELETE THIS LINE -- make depend depends on it.
printenv.o: /usr/include/stdio.h

* Makefile Implicit Rules

Consider the rule we used for printenv

printenv: printenv.c
$(CC) $(CFLAGS) printenv.c $(LDFLAGS) -o printenv

We generalized a bit to get

printenv: printenv.c
$(CC) $(CFLAGS) $@.c $(LDFLAGS) -o $@

The command is one that ought to work in all cases where we build an executable x out of the source code x.c This can be stated as an implicit rule:

.c:
$(CC) $(CFLAGS) $@.c $(LDFLAGS) -o $@

This Implicit rule says how to make x out of x.c -- run cc on x.c and call the output x. The rule is implicit because no particular target is mentioned. It can be used in all cases.

Another common implicit rule is for the construction of .o (object) files out of .c (source files).

.o.c:
$(CC) $(CFLAGS) -c $<

alternatively

.o.c:
$(CC) $(CFLAGS) -c $*.c

* Make Dependencies

It's pretty common to have source code that uses include files. For example:

% cat program.c

#include
#include "defs.h"
#include "glob.h"
etc....
main(argc,argv)
etc...

The implicit rule only covers part of the source code depen- dency (it only knows that program.o depends on program.c). The usual method for handling this is to list the dependen- cies separately;


etc...
$(CC) $(CFLAGS) -c $*.c
etc...
program.o: program.c defs.h glob.h

Usually an implicit rule and a separate list of dependencies is all you need. And it ought to be easy enough to figure out what the dependencies are.

However, there are a number of nice tools around that will automatically generate dependency lists for you. For example (trivial):

DEPEND= makedepend $(CFLAGS)
etc...
# what are the source dependencies

depend: $(SRCS)
$(DEPEND) $(SRCS)

etc....
# DO NOT DELETE THIS LINE -- ....

printenv.o: /usr/include/stdio.h

These tools (mkdepend, mkmkf, etc.) are very common these days and aren't too difficult to use or understand. They're just shell scripts that run cpp (or cc -M, or etc.) to find out what all the include dependencies are. They then just tack the dependency list onto the end of the Makefile.

Based on Make and Makefiles by
Reg Quinton
Computing and Communications Services
The University of Western Ontario
London, Ontario N6A 5B7
Canada

Press here to return to the General Unix Software Menu.

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲国产精彩中文乱码av| 久久69精品久久久久久久电影好| 九九九久久国产免费| 久久这里只有精品99| 91精品国产综合久久久久久蜜臀| 欧美日韩精品在线| 欧美成人第一页| 亚洲精品在线91| 欧美理论片在线观看| 国产成人福利视频| 色哟哟网站入口亚洲精品| 日韩免费高清在线观看| 成人精品一区二区三区电影黑人| 亚洲欧美激情精品一区二区| 热99精品里视频精品| 欧美日韩亚洲国产一区| 亚洲精品美女在线观看| 疯狂蹂躏欧美一区二区精品| 欧美视频第一页| 国产精品九九九| 久久久99久久精品女同性| 97色在线观看免费视频| 69av成年福利视频| 国产精品第1页| 性色av一区二区三区| 欧美激情网友自拍| 精品中文字幕在线| 亚洲第一网站男人都懂| 米奇精品一区二区三区在线观看| 欧美成人h版在线观看| 精品无人区太爽高潮在线播放| 午夜剧场成人观在线视频免费观看| 久久久精品国产一区二区| 亚洲人成电影在线观看天堂色| 粗暴蹂躏中文一区二区三区| 国产精品狠色婷| 国产一区二区三区毛片| 色99之美女主播在线视频| 91在线观看免费高清| 欧美国产日韩在线| 日韩在线视频国产| 国产精品久久久久久久一区探花| 国产免费一区二区三区在线能观看| 欧美午夜www高清视频| 欧美成人午夜视频| 91国产中文字幕| 欧美三级免费观看| 亚洲国产精品yw在线观看| 俺去亚洲欧洲欧美日韩| 日韩在线观看免费高清完整版| 7777kkkk成人观看| 亚洲亚裔videos黑人hd| 国产成人综合av| 国产精品户外野外| 日本欧美中文字幕| 97久久精品人人澡人人爽缅北| 91免费电影网站| 国产91精品在线播放| www.色综合| 久久久久久18| www.美女亚洲精品| 欧美视频在线观看免费| 国产美女搞久久| 日韩欧美国产一区二区| 黑人巨大精品欧美一区免费视频| 精品毛片三在线观看| 欧美成人亚洲成人日韩成人| 亚洲va久久久噜噜噜久久天堂| 亚洲人线精品午夜| 国产精品久久中文| 中文字幕一区二区三区电影| 欧美大片第1页| 自拍偷拍亚洲欧美| 国产一区二区三区免费视频| 亚洲视频一区二区| 久久久久久免费精品| 国产精品欧美久久久| 久久视频这里只有精品| 色吧影院999| 欧美成人在线免费| 国产美女扒开尿口久久久| 亚洲香蕉成视频在线观看| 久久久久中文字幕| 久久香蕉国产线看观看网| 国产大片精品免费永久看nba| 久久99精品久久久久久青青91| 中文字幕亚洲欧美一区二区三区| 美女少妇精品视频| 国产ts人妖一区二区三区| 国产精品∨欧美精品v日韩精品| 欧美成人一二三| 日韩精品高清在线| 国产精品999| 国产亚洲精品va在线观看| 国产精品∨欧美精品v日韩精品| 日韩电影中文字幕在线| 国产丝袜一区二区三区| 日韩电影免费在线观看中文字幕| 亚洲欧美日韩另类| www国产91| 亚洲一区免费网站| 亚洲美女av黄| 78色国产精品| 久久久999国产| 日韩高清电影免费观看完整版| 2019中文字幕全在线观看| 欧美专区福利在线| 国产高清视频一区三区| 欧美主播福利视频| 性欧美暴力猛交69hd| 亚洲欧美中文在线视频| 福利一区福利二区微拍刺激| 精品调教chinesegay| 国产亚洲人成a一在线v站| 日韩黄色av网站| 亚洲欧美成人在线| 色小说视频一区| 亚洲在线免费看| 日韩高清电影免费观看完整版| 国产成人小视频在线观看| 国产成人精品综合| 久久精品视频导航| 在线视频精品一| 国产91精品久久久久| 91国产美女视频| 亚洲一区二区免费在线| 欧美激情久久久久久| 精品福利在线看| 日本成人在线视频网址| 成人在线一区二区| 久久成人人人人精品欧| 国外成人在线视频| 91精品久久久久久久久久入口| 亚洲理论片在线观看| 亚洲人成电影网站色xx| 欧美黑人xxx| 亚洲精品网址在线观看| 久久久精品网站| 精品国产网站地址| 欧美精品久久久久久久久久| 国产一区二区日韩| 色噜噜狠狠狠综合曰曰曰88av| 中日韩美女免费视频网站在线观看| 精品国产精品自拍| 亚洲人成电影在线观看天堂色| 国产精品极品在线| 国模精品一区二区三区色天香| 中文字幕精品久久| 国产有码在线一区二区视频| 国产一区二区三区丝袜| 日韩av影院在线观看| 亚洲免费电影一区| 色妞欧美日韩在线| 欧日韩在线观看| 亚洲最大福利网站| 原创国产精品91| 欧美激情久久久| 亚洲日韩欧美视频| 欧美高清激情视频| 亚洲欧美日韩在线高清直播| 日韩电影免费在线观看中文字幕| 国产精品久久电影观看| 国产成人亚洲综合91| 欧美日产国产成人免费图片|