How to write a makefile

xiaoxiao2021-03-06  57

How to write a makefile

Making makefilesmake is a program which is buy to compile programs, using lists of commists. It is essentially its OWN Programming Language. Here Are Two Tutorials on Making Makefiles, (from

and

Http://cs.gmu.edu/~tmaddox/cs211/sample_code/makefiles/make.html

How to write a makefile

IntroductionMake 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.

Important Adjuncts Are Lint (Source Coding for Obvious Errors) CTags (Locate Functions, etc. In Source Code) and mkdepend. These is Nice, And Good Programmers Use.

Important, And Related Tools, Are The Software Revision Systems Sccs (Source Cogn Control System) And RCS (Revision Control System - The Recommended Choice)

........................

Makefile naming

Make Is Going to Look for a File Called

Makefile, IF not Found Then A File Called

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 Anywhere ON A LINE AND CONTITIL 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 esample:

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 Aree Will Override The Defaults. You can set macros on the make command line:% make "cflags = -o" "ldflags = -s" Printenv

cc -oprintenv.c -s -o protetenv

Targets you make a particular target (eg. Make all), in none specified tell: Paper.dvi: $ (srcs)

$ (DITROFF) $ (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 Certain Special Macros PREDEfined.

$ @ is The name of the file to be my name. $? is The name of the change 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 is:

$ * the name of the service. $ * 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 Withnin RCS (Sometimes You'll Need To "Check Out" a Source File): SRCS = X.C Y.c Z.c

$ (Srcs):

Co $ @

To Manage Sources Stored Withnin SCCS (Sometimes You'll Need To "Get" a Source File: $ (srcs):

Sccs Get $ @ Alternativley, To Manage Sources Stored With 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 be a bit more fan you could use: obj = x.o y.o z.o

Ar = ar

LIB.A: $ (OBJ)

$ (Ar) rvu $ @ $ (bj)

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 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: HEOUWING 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 intending 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 Likey 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.make all - should compile everything so that you can do local testing before installing things make install -. should install things in the . right places But watch out that things are installed in the right place for your system 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

# T 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 $ @ $ (bjs)

# 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 doe wrong?

LINT: $ (srcs)

LINT $ (CFLAGS) $ (srcs)

# What Are the Source Dependencies

Depend: $ (srcs)

$ (Depend) $ (srcs) # to make a shar distance

Shar: Clean

$ (Shar) Readme Makefile Printenv.man $ (SRCS)> Shar

# clean out the dross

Clean:

-rm printenv * ~ * .o * .bak core tags shark

# 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 TOWORKIT 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 xc -.. Run cc on xc 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. Files out of .c (source file). .oc:

$ (Cc) $ (cflags) -c $

Alternative .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). The Usual Method for Handling this is to list the dependen - cies SeparationLy; 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

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 TAED 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.

HOW to create a makefile.

A requirement for this course is that all programs you submit for a grade must compile and run on osf1, which uses the Unix operating system. One component of this process is the make utility and its input data, the makefile.

Files are the standard unit of compilation in C , but it is rarely possible to put a complete program in one file. At a minimum, the standard libraries are separate. Even if the complete code for a program fits into one file, it may not ......................

A large program is divided into multiple source (* .cpp) and header (* .h) files. The header files contain the information that multiple source files share, such as class and struct definitions, while the source files contain functions and data definitions . in C, header files are #included in the source files. in C , source files for template function definitions may be included as well.When you build your program, the compiler takes source files that have changed and generates object (* .o ) files. The linker then collects those object files and the libraries you want incorporated and builds the executable file. In UNIX, the executable is called a.out by default. To run your program, you call a.out. The system that builds Your Program Needs to Know How Changes To Headers, Source Files, And Libraries Propagate. This is the documented in the makefile.

Here's A Sample Makefile:

Poly: polyterm.o poly_demo.o

G polyterm.o poly_demo.o -lm -o poly poly

POLYTERM.O: POLYTERM.CPP POLYTERM.H

G -wall -gstabs polyterm.cpp -c

Poly_Demo.o: polyterm.h poly_demo.cpp

G -wall -gstabs poly_demo.cpp -c

.. Let's unpack it The first line says that the executable file poly should be built if either of the object files have changed The second line is the instruction to the system for building poly - you can not see it, but the second line starts with a tab character. The -lm tells the compiler to link in the math library. The third line says that polyterm.o should be built if either polyterm.cpp or polyterm.h is changed. The '-Wall' in the fourth . line says that all errors are to be reported, and the -gstabs tells the compiler to build the debugging tables for gdb The -c indicates that only the object files (* .o) need be generated.Here's another sample makefile:

Result: a.O B.O C.0

G -o Result C.O A.O B.O

a.o: a.cpp a.h

G -wall -gstabs -c A.c

B.O: B.CPP B.H a.h

G -wall -gstabs -c B.c

C.O: C.C C.H B.H

G -wall -gstabs -c c.c

Notice That a Makefile Has The Form

Target: Depends

Actions

When You Type "make", make Updates a target by Enssuring That all the files

On Which IT Depends Exist and Are Up-to-Date.

IN a Makefile, Blank Lines Are Ignored, And Comment Lines Start with # # # #

Actions Begin with a Tab.

转载请注明原文地址:https://www.9cbs.com/read-118429.html

New Post(0)