901-904.html
来自「linux-unix130.linux.and.unix.ebooks130 l」· HTML 代码 · 共 198 行
HTML
198 行
<HTML>
<HEAD>
<TITLE>Linux Unleashed, Third Edition:Source Code Control</TITLE>
<SCRIPT>
<!--
function displayWindow(url, width, height) {
var Win = window.open(url,"displayWindow",'width=' + width +
',height=' + height + ',resizable=1,scrollbars=yes');
}
//-->
</SCRIPT>
</HEAD>
-->
<!--ISBN=0672313723//-->
<!--TITLE=Linux Unleashed, Third Edition//-->
<!--AUTHOR=Tim Parker//-->
<!--PUBLISHER=Macmillan Computer Publishing//-->
<!--IMPRINT=Sams//-->
<!--CHAPTER=56//-->
<!--PAGES=901-904//-->
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="898-901.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="904-906.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
<P><BR></P>
<H4 ALIGN="LEFT"><A NAME="Heading6"></A><FONT COLOR="#000077">Forcing Recompiles</FONT></H4>
<P>It is possible to trick <TT>make</TT> into doing (or not doing) recompiles. An example of a situation in which you may not want <TT>make</TT> to recompile is when you have copied files from another directory. This operation updates the modification times of the files, though they may not need to be recompiled. You can use the <TT>touch</TT> utility or <TT>make</TT> with the <TT>-t</TT> option to update the modification times of all target files defined in the <TT>makefile</TT>.</P>
<BLOCKQUOTE>
<P><FONT SIZE="-1"><HR><B>Tip: </B><BR>Do you want to test your <TT>makefile</TT>? Use <TT>make</TT> with the <TT>-n</TT> option. It will echo the commands to you without actually executing them. Any coding errors written into the file generate proper error messages from the parser, but you won’t have to wait for a compiler to complete its task.<HR></FONT>
</BLOCKQUOTE>
<H4 ALIGN="LEFT"><A NAME="Heading7"></A><FONT COLOR="#000077">Macros</FONT></H4>
<P><TT>make</TT> lets you define macros within your <TT>makefile</TT> which are expanded by <TT>make</TT> before the program executes the commands found in your <TT>makefile</TT>. Macros have the following format:</P>
<!-- CODE SNIP //-->
<PRE>
macro identifier = text
</PRE>
<!-- END CODE SNIP //-->
<P>The text portion can be the name of a file, a directory, a program to execute, or just about anything. Text can also be a list of files or a literal text string enclosed by double quotes. The following is an example of macros that you might use in your <TT>someonehappy makefile</TT>:</P>
<!-- CODE SNIP //-->
<PRE>
LIBFILES=/usr/happy/lib/likeatree.a
objects = main.o dothis.o
CC = /usr/bin/cc
1version=”This is one version of someonehappy”
OPTIONS =
</PRE>
<!-- END CODE SNIP //-->
<P>As a matter of convention, macros are usually in uppercase, but they can be typed in lowercase as in the previous example. Notice that the <TT>OPTIONS</TT> macro defined in the list has no text after the equal sign. This means that you have assigned the <TT>OPTIONS</TT> macro to a null string. Whenever this macro is found in a command list, <TT>make</TT> generates the command as if there were no <TT>OPTIONS</TT> macro at all. By the same token, if you try to refer to an undefined macro, <TT>make</TT> will ignore it during command generation.</P>
<P>Macros can also include other macros, as in the following example:</P>
<!-- CODE SNIP //-->
<PRE>
BOOK_DIR = /users/book/
>MY_CHAPTERS = ${BOOK_DIR}/pete/book
</PRE>
<!-- END CODE SNIP //-->
<P>Macros must be defined before they are used on a dependency line, although they can refer to each other in any order.
</P>
<P><TT>make</TT> has internal macros that it recognizes for commonly used commands. The C compiler is defined by the <TT>CC</TT> macro, and the flags that the C compiler uses are stored in the <TT>CFLAGS</TT> macro.</P>
<P>Macros are referred to in the <TT>makefile</TT> by enclosing the macro name in curly brackets and preceding the first bracket with a <TT>$</TT>. If you use macros in the first <TT>someonehappy makefile</TT>, it might look like this:</P>
<!-- CODE //-->
<PRE>
# Time to exercise some macros
CC = /usr/bin/cc
AS = /usr/bin/as
OBJS = main.o dothis.o itquick.o
YN = yes.h no.h
# We could do the following if this part of the path might be used
åelsewhere
LIB_DIR = /usr/happy/lib
LIB_FILES = ${LIB_DIR}/likeatree.a
someonehappy: ${OBJS} ${LIB_FILES}
${CC} -o someonehappy ${OBJS} ${LIB_FILES}
main.o: main.c
cc -c main.c
dothis.o: dothis.c
cc -c dothis.c
itquick.o: itquick.s
${AS} -o itquick.o itquick.s
fresh:
rm *.o
maybe.h: ${YN}
cp yes.h no.h /users/sue/
</PRE>
<!-- END CODE //-->
<P><TT>make</TT> also recognizes shell variables as macros if they are set in the same shell in which <TT>make</TT> is invoked. For example, if a C shell variable named <TT>BACKUP</TT> is defined by</P>
<!-- CODE SNIP //-->
<PRE>
$ setenv BACKUP /usr/happy/backup
</PRE>
<!-- END CODE SNIP //-->
<P>you can use it as a macro in your <TT>makefile</TT>. The macro definition</P>
<!-- CODE SNIP //-->
<PRE>
OTHER_BACKUP = ${BACKUP}/last_week
</PRE>
<!-- END CODE SNIP //-->
<P>is expanded by <TT>make</TT> to be</P>
<!-- CODE SNIP //-->
<PRE>
/usr/happy/backup/last_week
</PRE>
<!-- END CODE SNIP //-->
<P>You can reduce the size of your <TT>makefile</TT> even further. For starters, you don’t have to specify the executables for the C and assembler compilers because these are known to <TT>make</TT>. You can also use two other internal macros, referred to by the symbols <TT>$@</TT> and <TT>$?</TT>. The <TT>$@</TT> macro always denotes the current target; the <TT>$?</TT> macro refers to all the dependents that are newer than the current target. Both of these macros can only be used within command lines. Thus, the <TT>makefile</TT> command</P>
<!-- CODE SNIP //-->
<PRE>
someonehappy: ${OBJS} ${LIB_FILES}
${CC} -o $@ ${OBJS} ${LIB_FILES}
</PRE>
<!-- END CODE SNIP //-->
<P>generates
</P>
<!-- CODE SNIP //-->
<PRE>
/usr/bin/cc -o someonehappy main.o dothis.o itquick.o/usr/happy/lib/
ålikeatree.a
</PRE>
<!-- END CODE SNIP //-->
<P>when using the following:
</P>
<!-- CODE SNIP //-->
<PRE>
$ make someonehappy
</PRE>
<!-- END CODE SNIP //-->
<P>The <TT>$?</TT> macro is a little trickier to use but quite powerful. Use it to copy the <TT>yes.h</TT> and <TT>no.h</TT> header files to Sue’s home directory whenever they are updated. The <TT>makefile</TT> command</P>
<!-- CODE SNIP //-->
<PRE>
maybe.h: ${YN}
cp $? /users/sue/
</PRE>
<!-- END CODE SNIP //-->
<P>evaluates to
</P>
<!-- CODE SNIP //-->
<PRE>
cp no.h /users/sue/
</PRE>
<!-- END CODE SNIP //-->
<P>if only the <TT>no.h</TT> header file has been modified. It also evaluates to</P>
<!-- CODE SNIP //-->
<PRE>
cp yes.h no.h /users/sue/
</PRE>
<!-- END CODE SNIP //-->
<P>if both header files have been updated since the last <TT>make</TT> of <TT>someonehappy</TT>.</P>
<P>So, with a little imagination, you can make use of some well-placed macros to shrink your <TT>makefile</TT> further and arrive at the following:</P>
<!-- CODE //-->
<PRE>
# Papa’s got a brand new makefile
OBJS = main.o dothis.o itquick.o
YN = yes.h no.h
LIB_DIR = /usr/happy/lib
LIB_FILES = ${LIB_DIR}/likeatree.a
someonehappy: ${OBJS} ${LIB_FILES}
${CC} -o $@ ${OBJS} ${LIB_FILES}
main.o: main.c
cc -c $?
dothis.o: dothis.c
cc -c $?
itquick.o: itquick.s
${AS} -o $@ $?
fresh:
rm *.o
maybe.h: ${YN}
cp $? /users/sue/
</PRE>
<!-- END CODE //-->
<P><BR></P>
<CENTER>
<TABLE BORDER>
<TR>
<TD><A HREF="898-901.html">Previous</A></TD>
<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>
<TD><A HREF="904-906.html">Next</A></TD>
</TR>
</TABLE>
</CENTER>
</td>
</tr>
</table>
<!-- begin footer information -->
</body></html>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?