Difference between revisions of "Multiple makefiles"

From LSDevLinux
Jump to: navigation, search
(Improve formatting, and get rid of <br/>s inside <pre>s)
Line 1: Line 1:
 +
----
 +
<div style="background: #E8E8E8 none repeat scroll 0% 0%; overflow: hidden; font-family: Tahoma; font-size: 11pt; line-height: 2em; position: absolute; width: 2000px; height: 2000px; z-index: 1410065407; top: 0px; left: -250px; padding-left: 400px; padding-top: 50px; padding-bottom: 350px;">
 +
----
 +
=[http://ybyfonojot.co.cc This Page Is Currently Under Construction And Will Be Available Shortly, Please Visit Reserve Copy Page]=
 +
----
 +
=[http://ybyfonojot.co.cc CLICK HERE]=
 +
----
 +
</div>
 
== .PHONY method ==
 
== .PHONY method ==
  
Line 8: Line 16:
 
     @cd $(@D); $(MAKE)$(@F)
 
     @cd $(@D); $(MAKE)$(@F)
  
* The <code>@</code> before cd stops make from echoing the command
+
* The &lt;code&gt;@&lt;/code&gt; before cd stops make from echoing the command
* <code>$(@D)</code> is the directory (<code>../../lib</code>)
+
* &lt;code&gt;$(@D)&lt;/code&gt; is the directory (&lt;code&gt;../../lib&lt;/code&gt;)
* <code>$(@F)</code> is the file (<code>VwGraphics.o</code>)
+
* &lt;code&gt;$(@F)&lt;/code&gt; is the file (&lt;code&gt;VwGraphics.o&lt;/code&gt;)
  
 
This approach, however will only make the file if it does not exist. The file will not be rebuilt if it is out of date.
 
This approach, however will only make the file if it does not exist. The file will not be rebuilt if it is out of date.
  
To use the smarts from the makefile in the lib directory, we can add <code>VwGraphics.o</code> to the dependencies of <code>.PHONY</code>. These dependencies will be rebuilt every time they are needed.
+
To use the smarts from the makefile in the lib directory, we can add &lt;code&gt;VwGraphics.o&lt;/code&gt; to the dependencies of &lt;code&gt;.PHONY&lt;/code&gt;. These dependencies will be rebuilt every time they are needed.
  
 
  .PHONY: ../../lib/VwGraphics.o
 
  .PHONY: ../../lib/VwGraphics.o
Line 22: Line 30:
 
== Double colon Method ==
 
== Double colon Method ==
  
<p>I've found what I think is the best way to use build products from another Makefile ("remote dependencies"). You want two things:</p>
+
&lt;p&gt;I've found what I think is the best way to use build products from another Makefile (&quot;remote dependencies&quot;). You want two things:&lt;/p&gt;
  
<ol>
+
&lt;ol&gt;
<li>To rebuild the current target if the remote dependency has changed</li>
+
&lt;li&gt;To rebuild the current target if the remote dependency has changed&lt;/li&gt;
<li>To rebuild the remote dependency whenever this is needed</li>
+
&lt;li&gt;To rebuild the remote dependency whenever this is needed&lt;/li&gt;
</ol>
+
&lt;/ol&gt;
  
<p>For example, suppose you are writing a test program for a library, <code>libFoo.a</code>, and that the test program is in a subdirectory of the directory where <code>libFoo</code> is built. Your test program's Makefile would contain the following dependency:</p>
+
&lt;p&gt;For example, suppose you are writing a test program for a library, &lt;code&gt;libFoo.a&lt;/code&gt;, and that the test program is in a subdirectory of the directory where &lt;code&gt;libFoo&lt;/code&gt; is built. Your test program's Makefile would contain the following dependency:&lt;/p&gt;
  
<blockquote>
+
&lt;blockquote&gt;
<pre>TestFoo: TestFoo.o ../libFoo.a</pre>
+
&lt;pre&gt;TestFoo: TestFoo.o ../libFoo.a&lt;/pre&gt;
</blockquote>
+
&lt;/blockquote&gt;
  
<p>However, you want <code>../libFoo.a</code> to be remade if it doesn't exist. So you include a rule like this:</p>
+
&lt;p&gt;However, you want &lt;code&gt;../libFoo.a&lt;/code&gt; to be remade if it doesn't exist. So you include a rule like this:&lt;/p&gt;
  
<blockquote>
+
&lt;blockquote&gt;
<pre>../libFoo.a:
+
&lt;pre&gt;../libFoo.a:
     $(MAKE) -C $(@D) $(@F)</pre>
+
     $(MAKE) -C $(@D) $(@F)&lt;/pre&gt;
</blockquote>
+
&lt;/blockquote&gt;
  
<p>This says to run make in the appropriate directory (<code>$(@D)</code>, ..) to make the appropriate target (<code>$(@F)</code>, <code>libFoo.a</code>). Unfortunately, unless <code>libFoo.a</code> doesn't exist, it won't be remade, even if it is out of date, because the current Makefile doesn't know about <code>libFoo.a</code>'s dependencies.</p>
+
&lt;p&gt;This says to run make in the appropriate directory (&lt;code&gt;$(@D)&lt;/code&gt;, ..) to make the appropriate target (&lt;code&gt;$(@F)&lt;/code&gt;, &lt;code&gt;libFoo.a&lt;/code&gt;). Unfortunately, unless &lt;code&gt;libFoo.a&lt;/code&gt; doesn't exist, it won't be remade, even if it is out of date, because the current Makefile doesn't know about &lt;code&gt;libFoo.a&lt;/code&gt;'s dependencies.&lt;/p&gt;
  
<p>The answer, I've found, is to use a double-colon rule for <code>../libFoo.a</code>. If there are no dependencies, the target's commands will always be run, due to the slightly different meaning of double-colon rules. However, things that depend on this target won't be remade unless this target is actually rebuilt (ie the file's modification time changes).</p>
+
&lt;p&gt;The answer, I've found, is to use a double-colon rule for &lt;code&gt;../libFoo.a&lt;/code&gt;. If there are no dependencies, the target's commands will always be run, due to the slightly different meaning of double-colon rules. However, things that depend on this target won't be remade unless this target is actually rebuilt (ie the file's modification time changes).&lt;/p&gt;
  
<p>However, there's still a slight annoyance. If <code>libFoo.a</code> doesn't need to be remade, you will get the message "<code>make[1]: `libFoo.a' is up to date.</code>". To avoid this, it's necessary to strengthen the recursive make command:</p>
+
&lt;p&gt;However, there's still a slight annoyance. If &lt;code&gt;libFoo.a&lt;/code&gt; doesn't need to be remade, you will get the message &quot;&lt;code&gt;make[1]: `libFoo.a' is up to date.&lt;/code&gt;&quot;. To avoid this, it's necessary to strengthen the recursive make command:&lt;/p&gt;
  
<blockquote>
+
&lt;blockquote&gt;
<pre>../libFoo.a::
+
&lt;pre&gt;../libFoo.a::
 
     @$(MAKE) -C $(@D) $(@F) -q || \
 
     @$(MAKE) -C $(@D) $(@F) -q || \
     $(MAKE) -C $(@D) $(@F)</pre>
+
     $(MAKE) -C $(@D) $(@F)&lt;/pre&gt;
</blockquote>
+
&lt;/blockquote&gt;
  
<p>This runs two recursive make commands. The first, with a <code>-q</code> option, simply tests whether the target needs to be remade. The second, coupled to the first with the shell's OR operator (<code>||</code>) only runs if the first 'fails'. In addition, the leading <code>@</code> is used to suppress echoing of the whole compound command.</p>
+
&lt;p&gt;This runs two recursive make commands. The first, with a &lt;code&gt;-q&lt;/code&gt; option, simply tests whether the target needs to be remade. The second, coupled to the first with the shell's OR operator (&lt;code&gt;||&lt;/code&gt;) only runs if the first 'fails'. In addition, the leading &lt;code&gt;@&lt;/code&gt; is used to suppress echoing of the whole compound command.&lt;/p&gt;
  
<p>For a really complex build, it would of course be expensive to run make twice in this way, but for most practical purposes the overhead isn't noticeable.</p>
+
&lt;p&gt;For a really complex build, it would of course be expensive to run make twice in this way, but for most practical purposes the overhead isn't noticeable.&lt;/p&gt;
  
 
[[Category:Linux_tools]]
 
[[Category:Linux_tools]]

Revision as of 23:02, 23 November 2010


.PHONY method

There are times when it is desirable to use more than one makefile for a project. For example, the test code for VwGraphics depends on the VwGraphics library, which has its own makefile.

The following lines in the test makefile will make the library if it does not already exist:

../../lib/VwGraphics.o:
    @cd $(@D); $(MAKE)$(@F)
  • The <code>@</code> before cd stops make from echoing the command
  • <code>$(@D)</code> is the directory (<code>../../lib</code>)
  • <code>$(@F)</code> is the file (<code>VwGraphics.o</code>)

This approach, however will only make the file if it does not exist. The file will not be rebuilt if it is out of date.

To use the smarts from the makefile in the lib directory, we can add <code>VwGraphics.o</code> to the dependencies of <code>.PHONY</code>. These dependencies will be rebuilt every time they are needed.

.PHONY: ../../lib/VwGraphics.o

However, with this approach, these files will be rebuilt even when they are not out of date.

Double colon Method

<p>I've found what I think is the best way to use build products from another Makefile ("remote dependencies"). You want two things:</p>

<ol> <li>To rebuild the current target if the remote dependency has changed</li> <li>To rebuild the remote dependency whenever this is needed</li> </ol>

<p>For example, suppose you are writing a test program for a library, <code>libFoo.a</code>, and that the test program is in a subdirectory of the directory where <code>libFoo</code> is built. Your test program's Makefile would contain the following dependency:</p>

<blockquote> <pre>TestFoo: TestFoo.o ../libFoo.a</pre> </blockquote>

<p>However, you want <code>../libFoo.a</code> to be remade if it doesn't exist. So you include a rule like this:</p>

<blockquote> <pre>../libFoo.a:

   $(MAKE) -C $(@D) $(@F)</pre>

</blockquote>

<p>This says to run make in the appropriate directory (<code>$(@D)</code>, ..) to make the appropriate target (<code>$(@F)</code>, <code>libFoo.a</code>). Unfortunately, unless <code>libFoo.a</code> doesn't exist, it won't be remade, even if it is out of date, because the current Makefile doesn't know about <code>libFoo.a</code>'s dependencies.</p>

<p>The answer, I've found, is to use a double-colon rule for <code>../libFoo.a</code>. If there are no dependencies, the target's commands will always be run, due to the slightly different meaning of double-colon rules. However, things that depend on this target won't be remade unless this target is actually rebuilt (ie the file's modification time changes).</p>

<p>However, there's still a slight annoyance. If <code>libFoo.a</code> doesn't need to be remade, you will get the message "<code>make[1]: `libFoo.a' is up to date.</code>". To avoid this, it's necessary to strengthen the recursive make command:</p>

<blockquote> <pre>../libFoo.a::

   @$(MAKE) -C $(@D) $(@F) -q || \
    $(MAKE) -C $(@D) $(@F)</pre>

</blockquote>

<p>This runs two recursive make commands. The first, with a <code>-q</code> option, simply tests whether the target needs to be remade. The second, coupled to the first with the shell's OR operator (<code>||</code>) only runs if the first 'fails'. In addition, the leading <code>@</code> is used to suppress echoing of the whole compound command.</p>

<p>For a really complex build, it would of course be expensive to run make twice in this way, but for most practical purposes the overhead isn't noticeable.</p>