📄 linux tutorial-5.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0066)http://www.cs.ncl.ac.uk/modules/2003-04/csc842/LinuxTut/linux5.htm -->
<HTML><HEAD><TITLE>Home</TITLE>
<META http-equiv=Content-Type content="text/html; charset=windows-1252">
<META content="MSHTML 6.00.2800.1226" name=GENERATOR>
<META content=FrontPage.Editor.Document name=ProgId></HEAD>
<BODY>
<TABLE width=600 border=0>
<TBODY>
<TR>
<TD width=19></TD>
<TD width=567>
<P align=center><I><B><A
href="http://www.cs.ncl.ac.uk/modules/2003-04/csc842/LinuxTut/index.htm">Home</A>
- <A
href="http://www.cs.ncl.ac.uk/modules/2003-04/csc842/LinuxTut/linux1.htm">(1)
Shells</A> - <A
href="http://www.cs.ncl.ac.uk/modules/2003-04/csc842/LinuxTut/linux2.htm">(2)
Files & Directories</A> - <A
href="http://www.cs.ncl.ac.uk/modules/2003-04/csc842/LinuxTut/linux3.htm">(3)
Processes</A> - <A
href="http://www.cs.ncl.ac.uk/modules/2003-04/csc842/LinuxTut/linux4.htm">(4)Shell
scripting</A> - <A
href="http://www.cs.ncl.ac.uk/modules/2003-04/csc842/LinuxTut/linux5.htm">(5)Makefiles</A></B></I></P></TD></TR>
<TR>
<TD width=19></TD>
<TD width=567><FONT face="Times New Roman" size=5>Linux Tutorial - User's
view (5)</FONT>
<P><FONT face="Times New Roman">Subject Summary</FONT></P>
<OL>
<LI><FONT face="Times New Roman">How to produce a simple Makefile with
comments</FONT>
<LI><FONT face="Times New Roman">Providing quicker solutions with macros
and inference</FONT> </LI></OL>
<P><FONT face="Times New Roman" size=5><B><I>Makefiles</I></B></FONT></P>
<P>The <B>make</B> mechanism allows you place all the commands associated
to compiling and linking files (when developing programs written in a
higher level language) in a single file that is treated in a similar
fashion as a script file (<I>see Linux Tutorial - User's view (4) for
information on scripting</I>). This saves a lot of time as there may be
many commands to compile even the most simplest programs.</P>
<P><FONT size=4>1. Running your own make files
(<B>Makefiles</B>)</FONT></P>
<P>Create your Makefile using a text editor and saving it as
"<B>Makefile</B>". Ensure that your Makefile is in the same directory as
your source code (not required, but easier for beginner). Then, in the
directory where the Makefile is located simply type:</P>
<UL type=circle>
<LI><B>make</B> </LI></UL>
<P><FONT size=4>2. Comments</FONT></P>
<P>If a <B># </B>(hash) appears at the front of some text in your Makefile
then the parser will assume this to be a comment and ignore the text
directly following <B>#</B>. Some sample comments: notice how you need the
<B>#</B> at the beginning of each comment:</P>
<UL type=circle>
<LI><B># This a comment</B>
<LI><B># 'So is this</B>
<LI><B># and this</B> </LI></UL>
<P>You usually put the author and date of writing in the comments that
appear at the start of the Makefile.</P>
<P><FONT size=4>3. Rules</FONT></P>
<P>A rule indicates how and when to make a file. Consider the following
extract from a Makefile:</P>
<UL type=circle>
<LI><PRE><B>hello.o : hello.cc </B></PRE>
<LI><PRE><B> @echo Compiling hello.cc</B></PRE>
<LI><PRE><B> g++ -c hello.cc</B></PRE></LI></UL>
<P>The above rule is associated to deriving the file "<B>hello.o</B>".
"<B>hello.o</B>" is simply the compiled version of "<B>hello.cc</B>". The
compiler is <B>g++</B> and the <B>-c</B> indicates that we desire compiled
code only (not linked). Remember, a compiled piece of code will not run
until it has been passed through the linker. An interesting observation
with regard to this rule is that an <B>echo</B> command is been used to
tell the user what is happening, always a good idea as there may be many
rules and you can let the user know what rule the <B>Makefile</B> has
reached during its execution.</P>
<P>You can run rules directly by running your <B>Makefile</B> from the
command line followed by the item you wish to make:</P>
<UL type=circle>
<LI><B>make hello.o</B> </LI></UL>
<P><FONT size=4>4. Dependency</FONT></P>
<P>The lines in <B>Makefiles</B> that have <B>:</B> (colon) on them
indicate the dependencies involved in satisfying a rule. Consider this
rule from a Makefile:</P>
<UL type=circle>
<LI><PRE><B>meeting</B><B> : hello.o bye.o </B></PRE>
<LI><PRE><B> @echo Linking </B><B>to produce meeting</B></PRE>
<LI><PRE><B> g++ -o meeting hello.o bye.o</B></PRE></LI></UL>
<P>The <B>-o</B> indicates that we are now linking (we need object files
only to link). Notice that <B>meeting</B> is dependent on two object files
(<B>hello.o</B> and <B>bye.o</B>).</P>
<P><FONT size=4>5. Macros</FONT></P>
<P>Macros are used to reduce the amount of repetition exhibited within a
Makefile. Consider the following:</P>
<UL type=circle>
<LI><PRE><B>meeting</B><B> : hello.o bye.o </B></PRE>
<LI><PRE><B> @echo Linking </B><B>to produce meeting</B></PRE>
<LI><PRE><B> g++ -o meeting hello.o bye.o</B></PRE></LI></UL>
<P>We see that "<B>hello.o bye.o</B>" is repeated twice. If this
<B>Makefile</B> was of substantial size then there may be longer strings
repeated much more frequently. A macro uses the <B>=</B> (equals) sign and
associates a string to a shorter representation. For example, we may write
the following:</P>
<UL type=circle>
<LI><PRE><B>OBJS = hello.o bye.o</B></PRE>
<LI><PRE><B>meeting</B><B> : $(OBJS) </B></PRE>
<LI><PRE><B> @echo Linking </B><B>to produce meeting</B></PRE>
<LI><PRE><B> g++ -o meeting </B><B>$(OBJS)</B></PRE></LI></UL>
<P>We can see how the "<B>hello.o bye.o</B>" string is replaced by a
shorter, easier to repeat string. Another way of thinking about macros is
as strings. However, the appropriate term is macro as they are parsed as
translated, which could represent more than just data in its meaning.</P>
<P><FONT size=4>6. Inference</FONT></P>
<P>Inference rules generalize the build process so you don't have to give
an explicit rule for each target. For example, instead of requiring a rule
for each source file compilation, an inference rule may be used. Consider
the following:</P>
<UL type=circle>
<LI><PRE><B>OBJS = hello.o bye.o</B></PRE>
<LI><PRE><B>hello.o : hello.cc </B></PRE>
<LI><PRE><B> @echo Compiling hello.cc</B></PRE>
<LI><PRE><B> g++ -c hello.cc</B></PRE>
<LI><PRE><B>bye</B><B>.o : bye.cc </B></PRE>
<LI><PRE><B> @echo Compiling bye.cc</B></PRE>
<LI><PRE><B> g++ -c bye.cc</B></PRE>
<LI><PRE><B>meeting</B><B> : $(OBJS) </B></PRE>
<LI><PRE><B> @echo Linking </B><B>to produce meeting</B></PRE>
<LI><PRE><B> g++ -o meeting </B><B>$(OBJS)</B></PRE></LI></UL>
<P>We can see that compiling "<B>hello.o</B>" is very similar to compiling
"<B>bye.o</B>". This provides an ideal opportunity to use an inference
rule:</P>
<UL type=circle>
<LI><PRE><B>OBJS = hello.o bye.o</B></PRE>
<LI><PRE><B>%</B><B>.o : %.cc </B></PRE>
<LI><PRE><B> @echo Compiling</B></PRE>
<LI><PRE><B> g++ -c $.cc</B></PRE>
<LI><PRE><B>meeting</B><B> : $(OBJS) </B></PRE>
<LI><PRE><B> @echo Linking </B><B>to produce meeting</B></PRE>
<LI><PRE><B> g++ -o meeting </B><B>$(OBJS)</B></PRE></LI></UL>
<P>By using the <B>%</B> (percent) sign we indicate that if a rule does
not exist for compiling a file that ends in <B>.cc</B> then use this rule.
The <B>$.cc</B> says use the prerequisite (the <B>.cc</B> to the left of
the colon) as the file to compile.</P>
<P><FONT size=4>7. Cleaning up</FONT></P>
<P>Sometimes you want to simply delete all the object files. It is common
practice to use "<B>clean</B>" to specify such a rule:</P>
<UL type=circle>
<LI><B>RM = rm</B>
<LI><B>clean::</B>
<LI><B>
$(RM) *.o core</B>
<LI><B>
$(RM) meeting</B> </LI></UL>
<P>Notice how we are using macros and we are removing the executable and
any wasteful cores that are the result of a crashed process.</P>
<P><BR></P>
<P> </P>
<P> </P>
<P><BR><BR></P>
<P> </P>
<P> </P>
<P> </P></TD></TR>
<TR>
<TD width=19></TD>
<TD width=567></TD></TR></TBODY></TABLE></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -