898-901.html

来自「linux-unix130.linux.and.unix.ebooks130 l」· HTML 代码 · 共 160 行

HTML
160
字号
<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=898-901//-->

<!--UNASSIGNED1//-->

<!--UNASSIGNED2//-->



<CENTER>

<TABLE BORDER>

<TR>

<TD><A HREF="893-898.html">Previous</A></TD>

<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>

<TD><A HREF="901-904.html">Next</A></TD>

</TR>

</TABLE>

</CENTER>

<P><BR></P>

<H4 ALIGN="LEFT"><A NAME="Heading4"></A><FONT COLOR="#000077">Basic makefile Format</FONT></H4>

<P>So, assuming that these files are in the same directory as the <TT>makefile</TT>, what do you have? The format of a <TT>makefile</TT>, such as the one you have made, is a series of entries. Your <TT>makefile</TT> has six entries: The first line of an entry is the dependency line, which lists the dependencies of the target denoted at the left of the colon; the second line is one or more command lines, which tells <TT>make</TT> what to do if the target is newer than its dependent (or dependents). An entry basically looks like this:</P>

<!-- CODE SNIP //-->

<PRE>

target: dependents

(TAB) command list

</PRE>

<!-- END CODE SNIP //-->

<P>The space to the left of the <TT>command list</TT> is actually a tab. This is part of the <TT>makefile</TT> syntax: Each command line must be indented using a tab. A dependency line can have a series of commands associated with it. <TT>make</TT> executes each command line as if the command had its own shell. Thus, the command</P>

<!-- CODE SNIP //-->

<PRE>

cd somewhere

mv *.c anotherwhere

</PRE>

<!-- END CODE SNIP //-->

<P>does not behave the way you may have intended. To remedy this kind of situation, use the following syntax whenever you need to specify more than one command:

</P>

<!-- CODE SNIP //-->

<PRE>

dependency line

command1;command2;command3;&#133;

</PRE>

<!-- END CODE SNIP //-->

<P>or

</P>

<!-- CODE SNIP //-->

<PRE>

dependency line

      command1; \

      command2; \

      command3;

</PRE>

<!-- END CODE SNIP //-->

<P>and so on. If you use a backslash to continue a line, it must be the last character before the end-of-line character.

</P>

<BLOCKQUOTE>

<P><FONT SIZE="-1"><HR><B>Tip:&nbsp;&nbsp;</B><BR>You can specify different kinds of dependencies for a target by placing the same target name on different dependency lines. Actually, <TT>make</TT> is even more powerful than described in this chapter, but unless you are working on very large projects with lots of interdependencies, you probably won&#146;t care about most of the subtleties <TT>make</TT> is capable of.<HR></FONT>

</BLOCKQUOTE>

<P>The first entry in our <TT>makefile</TT> is the key one for building our executable. It states that <TT>someonehappy</TT> is to be built if all the dependent object files and library files are present and if there are any newer files than the last version of <TT>someonehappy</TT>. Of course, if the executable is not present at all, <TT>make</TT> performs the compile command listed, but not right away. First, <TT>make</TT> checks to see which object files need to be recompiled in order to recompile <TT>someonehappy</TT>. This is a recursive operation, as <TT>make</TT> examines the dependencies of each target in the hierarchy, as defined in the <TT>makefile</TT>.</P>

<P>The last entry is a little goofy. It copies the header files <TT>yes.h</TT> and <TT>no.h</TT> (somehow related to <TT>maybe.h</TT>) to the home directories of the user named <TT>sue</TT> if they have been modified. This is somewhat conceivable if Sue is working on related programs that use these header files and need the most recent copies at all times. More importantly, it illustrates that <TT>make</TT> can be used to do more than compiling and linking and that <TT>make</TT> can execute several commands based on one dependency.</P>

<P>The <TT>fresh</TT> target is another example of a target being used to do more than just compiling. This target lacks any dependents, which is perfectly acceptable to the <TT>make</TT> program. As long as there is no file in the current directory named <TT>fresh</TT>, <TT>make</TT> executes the supplied command to remove all object files. This works because <TT>make</TT> treats any such entry as a target that must be updated.</P>

<P>So, if you enter the command</P>

<!-- CODE SNIP //-->

<PRE>

&#36; make someonehappy

</PRE>

<!-- END CODE SNIP //-->

<P><TT>make</TT> starts issuing the commands it finds in the <TT>makefile</TT> for each target that must be updated to achieve the final target. <TT>make</TT> echoes these commands to the user as it processes them. Simply entering</P>

<!-- CODE SNIP //-->

<PRE>

&#36; make

</PRE>

<!-- END CODE SNIP //-->

<P>also works in this case because <TT>make</TT> always processes the first entry it finds in the <TT>makefile</TT>. These commands are echoed to the screen, and the <TT>make</TT> process halts if the compiler finds an error in the code.</P>

<P>If all of <TT>someonehappy</TT>&#146;s dependencies are up-to-date, <TT>make</TT> does nothing except inform you of the following:</P>

<!-- CODE SNIP //-->

<PRE>

&#146;someonehappy&#146; is up to date

</PRE>

<!-- END CODE SNIP //-->

<P>You can actually supply the name (or names) of any valid target in your <TT>makefile</TT> on the command line for <TT>make</TT>. It performs updates in the order in which they appear on the command line, but still applies the dependency rules found in the <TT>makefile</TT>. If you supply the name of a fictional target (one that doesn&#146;t appear in your <TT>makefile</TT> and is not the name of a file in the current directory), <TT>make</TT> complains something like this:</P>

<!-- CODE SNIP //-->

<PRE>

&#36; make fiction

make: Don&#146;t know how to make fiction. Stop.

</PRE>

<!-- END CODE SNIP //-->

<H4 ALIGN="LEFT"><A NAME="Heading5"></A><FONT COLOR="#000077">Building Different Versions of Programs</FONT></H4>

<P>Suppose you want to have different versions of your <TT>someonehappy</TT> program that use most of the same code, but require slightly different interface routines. These routines are located in different C files (<TT>dothis.c</TT> and <TT>dothat.c</TT>), and they both use the code found in <TT>main.c</TT>. Instead of having separate <TT>makefile</TT>s for each version, you can simply add targets that do different compiles. Your <TT>makefile</TT> will look like the following one. (Note the first line that has been added. It is a comment about the <TT>makefile</TT> and is denoted by a <TT>#</TT> character followed by the comment text.)</P>

<!-- CODE //-->

<PRE>

# A makefile that creates two versions of the someonehappy program

someonehappy1: main.o dothis.o itquick.o /usr/happy/lib/likeatree.a

      cc -o someonehappy main.o dothis.o itquick.o/usr/happy/lib/

&#229;likeatree.a

someonehappy2: main.o dothat.o itquick.o /usr/happy/lib/likeatree.a

      cc -o someonehappy main.o dothat.o itquick.o/usr/happy/lib/

&#229;likeatree.a

main.o: main.c

      cc -c main.c

dothis.o: dothis.c

      cc -c dothis.c

dothat.o: dothat.c

      cc -c dothat.c

itquick.o: itquick.s

      as -o itquick.o itquick.s

fresh:

      rm *.o

maybe.h: yes.h no.h

      cp yes.h no.h /users/sue/

</PRE>

<!-- END CODE //-->

<P>Thus, your <TT>makefile</TT> is now equipped to build two variations of the same program. Issue the command</P>

<!-- CODE SNIP //-->

<PRE>

&#36; make someonhappy1

</PRE>

<!-- END CODE SNIP //-->

<P>to build the version using the interface routines found in <TT>dothis.c</TT>. Build your other program that uses the <TT>dothat.c</TT> interface routines with the following command:</P>

<!-- CODE SNIP //-->

<PRE>

&#36; make someonhappy2

</PRE>

<!-- END CODE SNIP //-->

<P><BR></P>

<CENTER>

<TABLE BORDER>

<TR>

<TD><A HREF="893-898.html">Previous</A></TD>

<TD><A HREF="../ewtoc.html">Table of Contents</A></TD>

<TD><A HREF="901-904.html">Next</A></TD>

</TR>

</TABLE>

</CENTER>





</td>
</tr>
</table>

<!-- begin footer information -->





</body></html>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?