<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Joey Armstrong&#039;s blog</title>
	<atom:link href="http://blog.mozilla.org/adirondackfirefly/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.mozilla.org/adirondackfirefly</link>
	<description>Blogging at mozilla</description>
	<lastBuildDate>Thu, 12 Apr 2012 21:10:36 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>makefiles</title>
		<link>http://blog.mozilla.org/adirondackfirefly/2012/04/12/makefiles/</link>
		<comments>http://blog.mozilla.org/adirondackfirefly/2012/04/12/makefiles/#comments</comments>
		<pubDate>Thu, 12 Apr 2012 21:10:36 +0000</pubDate>
		<dc:creator>adirondackfirefly</dc:creator>
				<category><![CDATA[makefiles]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/adirondackfirefly/?p=318</guid>
		<description><![CDATA[Threadsafe mkdir made easy]]></description>
				<content:encoded><![CDATA[<p><a href="http://adirondackfirefly.wordpress.com/2012/04/12/makefiles-howto-threadsafe-mkdir/">Threadsafe mkdir made easy</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/adirondackfirefly/2012/04/12/makefiles/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>An interesting view outside this morning</title>
		<link>http://blog.mozilla.org/adirondackfirefly/2012/03/15/an-interesting-view-outside-this-morning/</link>
		<comments>http://blog.mozilla.org/adirondackfirefly/2012/03/15/an-interesting-view-outside-this-morning/#comments</comments>
		<pubDate>Thu, 15 Mar 2012 13:42:07 +0000</pubDate>
		<dc:creator>adirondackfirefly</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/adirondackfirefly/?p=296</guid>
		<description><![CDATA[A double rainbow: photo #1, photo #2.]]></description>
				<content:encoded><![CDATA[<p>A double <a href="http://en.wikipedia.org/wiki/Rainbow" title="rainbow">rainbow</a>: <a href="http://people.mozilla.org/~jarmstrong/photos/double_rainbow.jpg">photo #1</a>, <a href="http://people.mozilla.org/~jarmstrong/photos/rainbow_pic2.jpg">photo #2</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/adirondackfirefly/2012/03/15/an-interesting-view-outside-this-morning/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>makefile landmines</title>
		<link>http://blog.mozilla.org/adirondackfirefly/2012/03/06/makefile-landmines/</link>
		<comments>http://blog.mozilla.org/adirondackfirefly/2012/03/06/makefile-landmines/#comments</comments>
		<pubDate>Tue, 06 Mar 2012 15:55:03 +0000</pubDate>
		<dc:creator>adirondackfirefly</dc:creator>
				<category><![CDATA[makefiles]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/adirondackfirefly/?p=221</guid>
		<description><![CDATA[Makefile landmines: avoiding limb loss [ps] ignore a similar makefile post I made yesterday. Somehow draft+update implied publish and the original content was not yet ready to see the light of day. When writing makefiles there are a few logic &#8230; <a href="http://blog.mozilla.org/adirondackfirefly/2012/03/06/makefile-landmines/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<h2>Makefile landmines: avoiding limb loss</h2>
<p><font size=-1>[ps] ignore a similar makefile post I made yesterday.  Somehow draft+update implied publish and the original content was not yet ready to see the light of day.</font></p>
<p>When writing makefiles there are a few logic bombs to try and avoid as they can mask failure conditions.  When command exit status is ignored or overlooked the site can become a source for random failures or manifest in downstream testing.</p>
<p>A few problem sources to mention are:</p>
<ol>
<li>Not returning, propagating, testing for or ignoring shell exit status.
<li>Use of line continuation to join multi-line commands within a makefile.
<li>Prefixing commands with a hyphen &#8216;-&#8217; to ignore errors.
</ol>
<p>A simple makefile (gotcha.mk) is attached below that will illustrate problem space for items #1 and #2 using the true &#038; false shell commands.  True will succeed with a shell exit status of zero (0==$?).  False will fail with a non-zero exit status:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">%</span> <span style="color: #c20cb9; font-weight: bold;">gmake</span> <span style="color: #660033;">-f</span> gotcha.mk show
makefile target is: show
     <span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>true: <span style="color: #007800;">$?</span>=<span style="color: #000000;">0</span>
    <span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>false: <span style="color: #007800;">$?</span>=<span style="color: #000000;">1</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">%</span> <span style="color: #c20cb9; font-weight: bold;">gmake</span> <span style="color: #660033;">-f</span> gotcha.mk pass
makefile target is: pass
<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">true</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">%</span> <span style="color: #c20cb9; font-weight: bold;">gmake</span> <span style="color: #660033;">-f</span> gotcha.mk fail
makefile target is: fail
<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">false</span>
gmake: <span style="color: #000000; font-weight: bold;">***</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>fail<span style="color: #7a0874; font-weight: bold;">&#93;</span> Error <span style="color: #000000;">1</span></pre></td></tr></table></div>

<h3>Line continuation: why they can be a problem</h3>
<p>Line continuation is an efficiency that is often used to avoid the overhead of having to spawn a new command shell for each command mentioned in a target rule.  Most of the time line continuation will function as expected but when exit status is lost or over-written, success is returned allowing make to return a false-positive.</p>
<p>An easy way to create this condition is by wrappering the logic in an if block.  Commands can merrily fail in bulk within the block but final exit status will be set by the shell if/test condition &#8212; which always succeeds.</p>
<p>This can be illustrated by the makefile target &#8216;<strong>bad</strong>&#8216;.  Run the true command, then false and if all is well the target should fail on the false call.  Guess what, we have opened a logic hole for bugs to quietly sneak in through:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">%</span> <span style="color: #c20cb9; font-weight: bold;">gmake</span> <span style="color: #660033;">-f</span> gotcha.mk bad
makefile target is: bad
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #000000; font-weight: bold;">!</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">'/non/existent/file'</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span> \
            <span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">true</span>; \
            <span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">false</span>; \
            <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;ASSERT: should not reach this point&quot;</span>; \
        <span style="color: #000000; font-weight: bold;">fi</span>
ASSERT: should not reach this point</pre></td></tr></table></div>

<p>There are a few workarounds for this problem space.  One of the easiest is use of the shell &#8216;-e&#8217; set/command line arg.  When enabled a shell will exit immediately with non-zero status whenever a command fails.</p>
<p>Uncomment this line in the gotcha.mk and the command will fail as expected:<br />
<code>&nbsp;&nbsp;&nbsp;&nbsp;SHELL := $(SHELL) -e</code></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">%</span> <span style="color: #c20cb9; font-weight: bold;">gmake</span> <span style="color: #660033;">-f</span> gotcha.mk bad
makefile target is: bad
   <span style="color: #7a0874; font-weight: bold;">&#91;</span>snip<span style="color: #7a0874; font-weight: bold;">&#93;</span>
gmake: <span style="color: #000000; font-weight: bold;">***</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>bad<span style="color: #7a0874; font-weight: bold;">&#93;</span> Error <span style="color: #000000;">1</span></pre></td></tr></table></div>

<p>The -e option or a morale equivalent is supported by bourne, bash, dash, ksh or whatever other shells people may prefer to use.</p>
<h3>suggestions: line continuation alternatives</h3>
<ul>
<li>At a minimum for readability consider using GNU make&#8217;s <code>.ONESHELL:<code> directive in place of large line continuation blocks:
<p>http://www.gnu.org/software/make/manual/html_node/One-Shell.html</p>
<li>Avoid line continuation wherever possible.  Make is very good at control flow and processing but not so much as a scripting language.  Blocks that span more than ~5 commands or are encapsulated within an if block would be ripe for breaking up into several distinct makefile goals {better yet general targets in a makefile library} or moving the entire block into a shell script that will be invoked by the target.
<li>shell/set -e flags should be enabled everywhere to improve error detection along with options to detect uninitialized variable usage.  Functionality is already enabled by in a few places with use of the <code>$(EXIT_ON_ERROR)</code> make macro defined in config/config.mk.  Listing <code>$(EXIT_ON_ERROR)</code> as the first item of a target rule will be expanded by make into $(SHELL) -e @command_text enabling fail on all command failure handling:
<p>config/config.mk</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>50
</pre></td><td class="code"><pre class="make" style="font-family:monospace;">EXIT_ON_ERROR <span style="color: #004400;">=</span> set <span style="color: #004400;">-</span>e<span style="color: #004400;">;</span> <span style="color: #339900; font-style: italic;"># Shell loops continue past errors without this.</span></pre></td></tr></table></div>

<p>config/rules.mk</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>226
227
228
229
230
</pre></td><td class="code"><pre class="make" style="font-family:monospace;">check<span style="color: #004400;">::</span>
  <span style="color: #004400;">@$</span><span style="color: #004400;">&#40;</span><span style="color: #000088;">EXIT_ON_ERROR</span><span style="color: #004400;">&#41;</span> \
    for f in <span style="color: #004400;">$</span><span style="color: #004400;">&#40;</span><span style="color: #0000CC; font-weight: bold;">subst</span> <span style="color: #004400;">.</span>cpp<span style="color: #004400;">,$</span><span style="color: #004400;">&#40;</span><span style="color: #000088;">BIN_SUFFIX</span><span style="color: #004400;">&#41;</span><span style="color: #004400;">,$</span><span style="color: #004400;">&#40;</span><span style="color: #000088;">CPP_UNIT_TESTS</span><span style="color: #004400;">&#41;</span><span style="color: #004400;">&#41;</span><span style="color: #004400;">;</span> do \
      XPCOM_DEBUG_BREAK<span style="color: #004400;">=</span>stack<span style="color: #004400;">-</span>and<span style="color: #004400;">-</span>abort <span style="color: #004400;">$</span><span style="color: #004400;">&#40;</span><span style="color: #000088;">RUN_TEST_PROGRAM</span><span style="color: #004400;">&#41;</span> <span style="color: #004400;">$</span><span style="color: #004400;">&#40;</span><span style="color: #000088;">DIST</span><span style="color: #004400;">&#41;</span><span style="color: #004400;">/</span>bin<span style="color: #004400;">/</span><span style="color: #000088; font-weight: bold;">$$</span>f<span style="color: #004400;">;</span> \
    done</pre></td></tr></table></div>

<p>Make judicious use of sh -e functionality but do not blindly trust that the option has been enabled for a given makefile target.  There will not always be a visual cue that the flag is active. In this case if the EXIT_ON_ERROR macro were inadvertently cleared or commented out a subset of error detection would be lost.  Best option initially is to manually verify the failure condition then write a negative unit test to back up the assertion long term.</p>
<ul>
<li>One trivial way to validate logic blocks like these is leverage the <a href="https://wiki.mozilla.org/ReleaseEngineering/TryServer" title="try server" target="_blank">try&nbsp;server</a> and modify the makefile to perform a negative test.  Simply inline a call to <code>'<b>exit ###</b>'</code> as the last statement in a block.  Submit makefile edits that are guaranteed to fail then verify all platforms reported the failure everywhere: in logfiles, email and tbpl web status.

<div class="wp_syntax"><table><tr><td class="code"><pre class="make" style="font-family:monospace;">all<span style="color: #004400;">:</span>
    if <span style="color: #004400;">&#91;</span> <span style="color: #CC2200;">1</span> <span style="color: #004400;">-</span>eq <span style="color: #CC2200;">1</span> <span style="color: #004400;">&#93;</span><span style="color: #004400;">;</span> then\
    <span style="color: #004400;">/</span>bin<span style="color: #004400;">/</span>ps \
    <span style="color: #004400;">&amp;&amp;</span> <span style="color: #004400;">/</span>bin<span style="color: #004400;">/</span>who \
    <span style="color: #004400;">&amp;&amp;</span> echo <span style="color: #CC2200;">&quot;********************************&quot;</span>\
    <span style="color: #004400;">&amp;&amp;</span> echo <span style="color: #CC2200;">&quot;Failure forced&quot;</span>\
    <span style="color: #004400;">&amp;&amp;</span> echo <span style="color: #CC2200;">&quot;********************************&quot;</span>\
    <span style="color: #004400;">&amp;&amp;</span> exit <span style="color: #CC2200;">99</span>\
    fi
<span style="color: #004400;">&lt;/</span>code<span style="color: #004400;">&gt;</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">%</span> <span style="color: #800000;">${EDITOR}</span> makefile.in
<span style="color: #000000; font-weight: bold;">%</span> hg qnew patch.try
<span style="color: #000000; font-weight: bold;">%</span> hg qref <span style="color: #660033;">--message</span> <span style="color: #ff0000;">&quot;try: -b do -e -p all -u all -t none&quot;</span>
<span style="color: #000000; font-weight: bold;">%</span> hg push <span style="color: #660033;">-f</span> try</pre></td></tr></table></div>

<p>If all goes well failure email will soon be on it's way.  If the makefile fails with status 99 the negative test succeded.  Be careful of errors reported early by ps or who, status could still be ignored by logic later on.  ($?==99) is the only exit status that should be used to assert the negative test passed:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">gmake: <span style="color: #000000; font-weight: bold;">***</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>all<span style="color: #7a0874; font-weight: bold;">&#93;</span> Error <span style="color: #000000;">99</span></pre></td></tr></table></div>

<p>Negative testing can be as important as positive testing and will sanity check two important items.  First that the exit/error status was properly detected and make was able to generate and record an error in the logs.  Second, the failure status was able to propagate through the try server and was reported accurately by the web interface and through status email.</p>
<p>If either condition is not met a bug should be opened so the logic can be modified to prevent any future failure conditions from silently sneaking into the tree.  If negative tests are not able to force a failure conditions valid errors that occur while building/processing will not either.</p>
<li>The configure script would also be a place to perform similar -e tests.<br />
     Often when commands cannot be found or failures occur the configure script<br />
     is able to run to completion but underlying failures are lost in the<br />
     shuffle.</p>
<li> Lastly a plug for testing.  If you will be expending effort to test makefile logic go the extra setup and write a unit test and add a 'check:' target to automate the activity.  Even if the test is a trivial smoke test initially it can be expanded later.  Start with these three conditions, if any fail something has gone horribly wrong and may needlessly waste queue time and build resources:
<ul>
<li>positive test: target does not exist initially, generate and verify.
<li>negative test: target cannot be created and test fails.
<li>nop test: target exists, minimal overhead should be imposed.  If a target performs work when up to date think of how much time is being wasted by the sum of all targets with this behavior.
     </ul>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">%</span> <span style="color: #c20cb9; font-weight: bold;">gmake</span> <span style="color: #660033;">-f</span> gotcha.mk check
makefile target is: check
Running positive <span style="color: #7a0874; font-weight: bold;">test</span>
OK
Running negative <span style="color: #7a0874; font-weight: bold;">test</span>
OK
Running negative <span style="color: #7a0874; font-weight: bold;">test</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>failure forced<span style="color: #7a0874; font-weight: bold;">&#93;</span>
gmake: <span style="color: #000000; font-weight: bold;">***</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>check<span style="color: #7a0874; font-weight: bold;">&#93;</span> Error <span style="color: #000000;">1</span></pre></td></tr></table></div>

</ul>
<h3><a href="http://www.gnu.org/software/make/manual/make.html#Errors">Ignoring errors</a>: hyphen prefix for commands</h3>
<p>AKA I do not care what type of explosion occurs on this line, ignore status and always return success.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="make" style="font-family:monospace;">all<span style="color: #004400;">:</span>
    <span style="color: #004400;">@</span>echo <span style="color: #CC2200;">&quot;Inhibit target rule errors&quot;</span>
    <span style="color: #004400;">-/</span>bin<span style="color: #004400;">/</span>false</pre></td></tr></table></div>

<p>There are a few legitimate places where this option can be used.</p>
<ul>
<li>File deletion on a system that does not support rm -f.
<li>Shell/OS command bug that will force returning non-zero status for
</ul>
<p>command that should succeed (~transient problems).</p>
<p>Aside from cases like these, use of a hyphen in general makefile logic to ignore a set of failure conditions will have an ugly side effect of also ignoring an entire set of unrelated problems.  In the filesystem and OS area, that a target should be aware of and fail on.</p>
<p>Ignoring conditions like say a file being conditionally non-existent when a target is processed because the file will be generated by the target is one example.  Hmmm, this might also be an instance of trying to work around a line continuation problem, testing for file existence and subsequent loss of command exit status within the if block.</p>
<p>In place of using hyphens to code around a set of conditions remove them outright and use an external shell script to do the right thing.  Handle conditions, test for existence and return an overall shell exit status from the actions.  If anything fails always return non-zero.</p>
<h4>Samples:</h4>
<p>Here is a sampling of makefile code from the tree with problems mentioned above.  Not trying to pick on anything specific, just what can be found with a bit of poking around.</p>
<ul>
<li>
<a href="http://hg.mozilla.org/mozilla-central/file/64c582d2b02c/toolkit/locales/l10n.mk toolkit/locales/l10n.mk" title="toolkit/locales/l10n.mk" target="_blank">toolkit/locales/l10n.mk</a><br />
** -cp -r $(JARLOG_DIR)/en-US/*.jar.log $(JARLOG_DIR_AB_CD)<br />
** -$(PERL) -pi.old -e "s/en-US/$(AB_CD)/g" $(JARLOG_DIR_AB_CD)/*.jar.log<br />
** A few conditions these commands will succeed on:<br />
*** Source files do not exist.  When file existence is not mandatory $(if ) conditions and extra target rules can conditionally copy when needed.  As could an external shell script that could bundle several statements and eventually be tested.<br />
*** Destination directory does not exist or filesystem is full.<br />
*** Source file is not readable.<br />
*** Destination file exists but is not writable.<br />
*** $(JARLOG_DIR_AB_CD) does not exist and we attempt to copy files into the directory.</p>
<li>
<a href="http://hg.mozilla.org/mozilla-central/file/64c582d2b02c/js/src/ctypes/libffi/Makefile.in" title="js/src/ctypes/libffi/Makefile.in" target="_blank">js/src/ctypes/libffi/Makefile.in</a><br />
** -rm -f src/alpha/ffi.$(OBJEXT)<br />
*** -rm is implied by the $(RM) macro: <code>RM = rm -f</code><br />
*** Written as: $(RM) src/alpha/ffi.$(OBJEXT)<br />
** -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)<br />
** -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)<br />
*** Avoid spawning extra shells<br />
*** $(RM) will not fail when the macros are empty<br />
*** Written as: $(RM) $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)</p>
<li>
<a href="http://hg.mozilla.org/mozilla-central/file/64c582d2b02c/config/rules.mk" title="config/rules.mk">config/rules.mk</a><br />
* clean clobber realclobber clobber_all:: $(SUBMAKEFILES)<br />
* -$(RM) $(ALL_TRASH)<br />
* -$(RM) -r $(ALL_TRASH_DIRS)<br />
** -$(RM) is redundant of $(RM) unless RM != /bin/rm -f
</ul>
<h2>Sample makefile: gotcha.mk</h2>

<div class="wp_syntax"><table><tr><td class="code"><pre class="make" style="font-family:monospace;"><span style="color: #339900; font-style: italic;"># -*- makefile -*-</span>
<span style="color: #339900; font-style: italic;">###############################################</span>
<span style="color: #339900; font-style: italic;">## Intent: makefile landmine examples</span>
<span style="color: #339900; font-style: italic;">###############################################</span>
&nbsp;
<span style="color: #666622; font-weight: bold;">ifneq</span> <span style="color: #004400;">&#40;</span><span style="color: #004400;">$</span><span style="color: #004400;">&#40;</span><span style="color: #000088;">null</span><span style="color: #004400;">&#41;</span><span style="color: #004400;">,$</span><span style="color: #004400;">&#40;</span><span style="color: #000088;">MAKECMDGOALS</span><span style="color: #004400;">&#41;</span><span style="color: #004400;">&#41;</span>
  <span style="color: #004400;">$</span><span style="color: #004400;">&#40;</span><span style="color: #666622; font-weight: bold;">info</span> makefile target is<span style="color: #004400;">:</span> <span style="color: #004400;">$</span><span style="color: #004400;">&#40;</span><span style="color: #000088;">MAKECMDGOALS</span><span style="color: #004400;">&#41;</span><span style="color: #004400;">&#41;</span>
<span style="color: #666622; font-weight: bold;">endif</span>
&nbsp;
SHELL <span style="color: #004400;">:=</span> <span style="color: #004400;">$</span><span style="color: #004400;">&#40;</span><span style="color: #000088;">SHELL</span><span style="color: #004400;">&#41;</span> <span style="color: #004400;">-</span>e
&nbsp;
all<span style="color: #004400;">:</span> pass fail bad
&nbsp;
pass<span style="color: #004400;">:</span>
        <span style="color: #004400;">/</span>bin<span style="color: #004400;">/</span>true
&nbsp;
fail<span style="color: #004400;">:</span>
        <span style="color: #004400;">/</span>bin<span style="color: #004400;">/</span>false
&nbsp;
bad<span style="color: #004400;">:</span>
        if <span style="color: #004400;">&#91;</span> <span style="color: #004400;">!</span> <span style="color: #004400;">-</span>e <span style="color: #CC2200;">'/non/existent/file'</span> <span style="color: #004400;">&#93;</span><span style="color: #004400;">;</span> then \
            <span style="color: #004400;">/</span>bin<span style="color: #004400;">/</span>true<span style="color: #004400;">;</span> \
            <span style="color: #004400;">/</span>bin<span style="color: #004400;">/</span>false<span style="color: #004400;">;</span> \
            echo <span style="color: #CC2200;">&quot;ASSERT: target $@: should not reach this point&quot;</span><span style="color: #004400;">;</span> \
        fi
&nbsp;
check<span style="color: #004400;">:</span>
        <span style="color: #004400;">@</span>echo <span style="color: #CC2200;">&quot;Running positive test&quot;</span>
        <span style="color: #004400;">@/</span>bin<span style="color: #004400;">/</span>true <span style="color: #004400;">&amp;&amp;</span> echo <span style="color: #CC2200;">&quot;OK&quot;</span> <span style="color: #004400;">||</span> exit <span style="color: #CC2200;">1</span>
        <span style="color: #004400;">@</span>echo <span style="color: #CC2200;">&quot;Running negative test&quot;</span>
        <span style="color: #004400;">@!</span> <span style="color: #004400;">/</span>bin<span style="color: #004400;">/</span>false <span style="color: #004400;">&amp;&amp;</span> echo <span style="color: #CC2200;">&quot;OK&quot;</span> <span style="color: #004400;">||</span> exit <span style="color: #CC2200;">1</span>
        <span style="color: #004400;">@</span>echo <span style="color: #CC2200;">&quot;Running negative test [failure forced]&quot;</span>
        <span style="color: #004400;">@/</span>bin<span style="color: #004400;">/</span>false <span style="color: #004400;">&amp;&amp;</span> echo <span style="color: #CC2200;">&quot;OK&quot;</span> <span style="color: #004400;">||</span> exit <span style="color: #CC2200;">1</span>
&nbsp;
show<span style="color: #004400;">:</span>
        <span style="color: #004400;">@</span>if <span style="color: #004400;">&#91;</span> <span style="color: #CC2200;">1</span> <span style="color: #004400;">&#93;</span><span style="color: #004400;">;</span> then\
            <span style="color: #004400;">/</span>bin<span style="color: #004400;">/</span>true<span style="color: #004400;">;</span>  echo <span style="color: #CC2200;">&quot;     /bin/true: <span style="color: #000099; font-weight: bold;">\$</span>$?=$$?&quot;</span><span style="color: #004400;">;</span> \
            <span style="color: #004400;">/</span>bin<span style="color: #004400;">/</span>false<span style="color: #004400;">;</span> echo <span style="color: #CC2200;">&quot;    /bin/false: <span style="color: #000099; font-weight: bold;">\$</span>$?=$$?&quot;</span><span style="color: #004400;">;</span> \
        fi</pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/adirondackfirefly/2012/03/06/makefile-landmines/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Build system tools: make-makefile, file generation</title>
		<link>http://blog.mozilla.org/adirondackfirefly/2012/02/17/build-system-tools-make-makefile-file-generation-2/</link>
		<comments>http://blog.mozilla.org/adirondackfirefly/2012/02/17/build-system-tools-make-makefile-file-generation-2/#comments</comments>
		<pubDate>Fri, 17 Feb 2012 18:29:35 +0000</pubDate>
		<dc:creator></dc:creator>
				<category><![CDATA[build tools]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/adirondackfirefly/?p=30</guid>
		<description><![CDATA[This post will be article #2 in a series about the build-config tool make-makefile. The series is being written to formally document current tool functionality and provide a base for future topics related to the container makefile project. Container structure, &#8230; <a href="http://blog.mozilla.org/adirondackfirefly/2012/02/17/build-system-tools-make-makefile-file-generation-2/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>This post will be article #2 in a series about the build-config tool make-makefile.<br />
The series is being written to formally document current tool functionality and<br />
provide a base for future topics related to the container makefile project.<br />
Container structure, functionality and example usage.</p>
<h3>Series posts</h3>
<ul>
<li><a href="http://blog.mozilla.org/adirondackfirefly/2011/12/15/build-system-tools-make-makefile">#2: A cookbook for makefile generation</a></li>
<li><a href="http://blog.mozilla.org/adirondackfirefly/2011/12/15/build-system-tools-make-makefile">#1: intro</a></li>
</ul>
<p>When makefile generation is needed the tool will perform a few steps.</p>
<ol>
<li>gmake -f client.mk is invoked. During traversal if gmake detects one<br />
of two conditions the tool will be invoked to generate a Makefile:<br />
&nbsp;&nbsp;&nbsp;&nbsp;o $(obj)/Makefile does not exist.<br />
&nbsp;&nbsp;&nbsp;&nbsp;o $(src)/Makefile.in is newer than $(obj)/Makefile.</li>
<li>Target rules used to invoke mm live in config/rules.mk near line 1342 and 1347<br />
&nbsp;&nbsp;&nbsp;&nbsp;o 1342 Makefile: Makefile.in<br />
&nbsp;&nbsp;&nbsp;&nbsp;o 1343 @$(PERL) $(AUTOCONF_TOOLS)/make-makefile -t $(topsrcdir) -d $(DEPTH)</li>
<li>make-makefile will be passed -d and -t command line arguments:<br />
&nbsp;&nbsp;&nbsp;&nbsp;o -t path to root of a development sandbox ~$(TOPSRCDIR)<br />
&nbsp;&nbsp;&nbsp;&nbsp;o -d relative path &#8211;depth from file to hierarchy root directory.<br />
Makefile: $(MOZ_OBJDIR), Makefile.in: $( TOPSRCDIR)</li>
<li>When invoked make-makefile is aware of the directory hierarchy and will expect cwd for the shell to be $(MOZ_OBJDIR) or a subdir of it [1]. config/rules.mk logic will place make-makefile in the target directory for each makefile to be generated [2].</li>
<li>Step 1 &#8211; obtain values for depth, topsrcdir and objdir.
<p>Values will be:<br />
&nbsp;&nbsp;&nbsp;&nbsp;o used to construct directory and file paths.<br />
&nbsp;&nbsp;&nbsp;&nbsp;o perform text substitution within Makefile.in templates.</p>
<p>Values can be:<br />
&nbsp;&nbsp;&nbsp;&nbsp;o explicitly passed on the command line.<br />
&nbsp;&nbsp;&nbsp;&nbsp;o determined from the filesystem based on arguments and/or cwd.<br />
&nbsp;&nbsp;&nbsp;&nbsp;o extracted from file arguments.</p>
<p>$depth will be set by:<br />
&nbsp;&nbsp;&nbsp;&nbsp;o Explicitly using the -d command line argument.<br />
&nbsp;&nbsp;&nbsp;&nbsp;o Assignment of DEPTH=../.. specified within an individual Makefile.<br />
&nbsp;&nbsp;&nbsp;&nbsp;o Assignment of DEPTH=../.. within any other files passed on the command line<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(is this behavior a bug or feature?).<br />
&nbsp;&nbsp;&nbsp;&nbsp;o Assignment of DEPTH=../.. contained within a parent directory Makefile [3], [4].</li>
<li>Step 2 &#8211; Using cwd and arguments, derive paths to the source template<br />
Makefile.in and generated target file Makefile.</li>
<li>Step 3 &#8211; Slurp the source template Makefile.in. Perform value substitutions<br />
on tokens embedded within the template of the form @token@.</p>
<pre><code>
browser/branding/official/Makefile.in
=====================================
DEPTH = ../../..
topsrcdir = @topsrcdir@
srcdir = @srcdir@
VPATH = @srcdir@
</code></pre>
<p>Some directory/file paths are derived internally by the tool for quick substitution. For any @${unknown}@ tokens make-makefile will delegate expansion with a call to system(&#8220;./config.status&#8221;) [5] to obtain values, create directories and who knows what else. Shell overhead will be imposed by this step so avoid unnecessary tokens when possible. When only a handful of tokens are in play one optimization to check on is if mm could derive values for the tokens and avoid overhead from calling the config.status script [6].</li>
<li>Step 4 &#8211; update or preserve generated Makefile timestamps. If obj/Makefile does not exist create it. If the file exists compare generated content against the original and only update when modified.</li>
</ol>
<h4>footnotes</h4>
<table>
<tr>
<td>[1]</td>
<td>The requirement of cwd==$(MOZ_OBJDIR)/ can be removed with use of the &#8211;enhanced flag. This option and other new flags will be covered in a future post.</td>
<tr>
<td>[2]</td>
<td>Enhancement: a response file could be used to support bulk makefile processing and directory creation (by config.status) saving some shell overhead. Bulk processing might also reduce the number of times config.status must be invoked independently.</td>
<tr>
<td>[3]</td>
<td>Potential bug. DEPTH= searches within multiple files could set $depth incorrectly when it is not explicitly set within a makefile. One ex would be passing browser/&#8230;/Makefile and js/src/&#8230;/Makefile as command line arguments. Though this error condition exists it is not likely to be triggered as files are processed individually.
  </td>
<tr>
<td>[4]</td>
<td>Potential bug: checking ../Makefile for &#8216;DEPTH=&#8217; will fail for makefiles invoked from a parent directory several layers above cwd.</td>
<tr>
<td>[5]</td>
<td>Enhancement &#8211; modify make-makefile to parse and extract fully expanded values from config* to avoid invoking ./config.status for a subset of substitution tokens.</td>
<tr>
<td>[6]</td>
<td>make-makefile will issue a warning when the ./config.status script will be launched<br />
WARNING: token SET_MAKE not defined<br />
line 2, src: [.....]/js/src/ctypes/libffi/Makefile.in
</td>
</table>
<h2>resources</h2>
<p>Tool source</p>
<ul>
<li><a href="http://hg.mozilla.org/mozilla-central/file/78fde7e54d92/build/autoconf/make-makefile">build/autoconf/make-makefile</a></li>
<li><a href="http://hg.mozilla.org/mozilla-central/file/78fde7e54d92/build/autoconf/makemakefile.pm">build/autoconf/make-makefile.pm</a></li>
<li><a href="http://hg.mozilla.org/mozilla-central/file/78fde7e54d92/build/autoconf/make-makefile.excl">build/autoconf/make-makefile.excl</a></li>
</ul>
<p>Unit tests</p>
<ul>
<li><a href="http://hg.mozilla.org/mozilla-central/file/78fde7e54d92/build/autoconf/test/Makefile.in">build/autoconf/test/Makefile.in</a><br />
glob *.tp{l,m} scripts and launch as standalone unit tests.</li>
<li><a href="http://hg.mozilla.org/mozilla-central/file/78fde7e54d92/build/autoconf/test/make-makefile.tpl">build/autoconf/test/make-makefile.tpl</a></li>
<li><a href="http://hg.mozilla.org/mozilla-central/file/78fde7e54d92/build/autoconf/test/makemakefile.tpm">build/autoconf/test/makemakefile.tpm</a></li>
</ul>
<p>makefiles</p>
<ul>
<li><a href="http://hg.mozilla.org/mozilla-central/file/78fde7e54d92/config/rules.mk">config/rules.mk</a>  <a href="http://hg.mozilla.org/mozilla-central/file/78fde7e54d92/config/rules.mk#l1336">[target rule]</a>
</li>
</ul>
<h2>Pending enhancements</h2>
<ul>
<li>Expand test coverage for make-makefile
<li>Add Response file support.
<li>Rewrite unit tests in python.
<li>Porting make-makefile from perl to python.
<li>minimize shell overhead from config.status use
</ul>
<h2>Future Blog Topics</h2>
<ul>
<li>make-makefile args and enhancements to generalize logic and support container builds.
<li>Container makefiles: scripts &#038; config
<ul>
<li>containermake.py
<li>template files
<li>non-invasive makefile edits to support container builds
  </ul>
<li>Container makefiles: bulk file processing
<ul>
<li>Makefile.in => Makefile
<li>*.idl => .h, .xpt, and deps .xpt.pp
<li>makefile targets: export, tools, libs, test, *
<li>thread mutex from target modifiers and extra container dependencies
</ul>
<li>Makefiles and library logic
<ul>
<li>threadsafe mkdir library function</li>
<li>config/rules.mk modularity &#8211; isolating logic based on bulk build types</li>
<li>thread mutex from target modifiers and container dependencies</li>
</ul>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/adirondackfirefly/2012/02/17/build-system-tools-make-makefile-file-generation-2/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Build system tools: make-makefile</title>
		<link>http://blog.mozilla.org/adirondackfirefly/2011/12/15/build-system-tools-make-makefile/</link>
		<comments>http://blog.mozilla.org/adirondackfirefly/2011/12/15/build-system-tools-make-makefile/#comments</comments>
		<pubDate>Thu, 15 Dec 2011 15:51:24 +0000</pubDate>
		<dc:creator></dc:creator>
				<category><![CDATA[build tools]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/adirondackfirefly/?p=18</guid>
		<description><![CDATA[Build system tools: make-makefile The build process consists of several steps, one of which is the dynamic generation of makefiles &#8211; the creation of recipes that control how and when elements of firefox and friends are generated.  The tool currently &#8230; <a href="http://blog.mozilla.org/adirondackfirefly/2011/12/15/build-system-tools-make-makefile/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p><em>Build system tools: make-makefile</em></p>
<p>The build process consists of several steps, one of which is the dynamic generation of makefiles &#8211; the creation of recipes that control how and when elements of firefox and friends are generated.  The tool currently used for generation is make-makefile, a utility written way back in the days of Netscape (circa 1999).  Intent for this post and a few more that will follow will be to document the tool and usage.</p>
<p><em>Program and config</em><br />
* build/autoconf/make-makefile<br />
* build/autoconf/makemakefile.pm<br />
* build/autoconf/make-makefile.excl</p>
<p>make-makefile will be automatically invoked while building whenever a Makefile does not exist beneath the object directory or a template (Makefile.in) is newer than a previously generated Makefile.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/adirondackfirefly/2011/12/15/build-system-tools-make-makefile/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>NYC &#8211; The City that Never Sleeps? Not so much.</title>
		<link>http://blog.mozilla.org/adirondackfirefly/2011/08/05/nyc-the-city-that-never-sleeps-not-so-much/</link>
		<comments>http://blog.mozilla.org/adirondackfirefly/2011/08/05/nyc-the-city-that-never-sleeps-not-so-much/#comments</comments>
		<pubDate>Fri, 05 Aug 2011 17:15:14 +0000</pubDate>
		<dc:creator></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/adirondackfirefly/?p=6</guid>
		<description><![CDATA[On Friday, July 29, 2011, after completing my first work week with the rest of the Release Engineering team in Toronto I left for the airport around 3pm to catch a flight home to Albany, NY. The week went well &#8230; <a href="http://blog.mozilla.org/adirondackfirefly/2011/08/05/nyc-the-city-that-never-sleeps-not-so-much/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>On Friday, July 29, 2011, after completing my first work week with the rest of the Release Engineering team in Toronto I left for the airport around 3pm to catch a flight home to Albany, NY. The week went well and everyone had a great time, visited plenty of good restaurants and pubs along with a trip to the new office (under construction). Little did I know what adventure lay ahead on the trip back home. Here is the abridged version of the chain of events.</p>
<ul>
<li>My Air Canada flight from Toronto to La Guardia was scheduled to depart @ 7:15pm EDT. Upon arrival at the airport the ticket agent mentioned that the flight had been delayed. My connection from NYC to Albany would be missed, but figured the flight could be straightened out on the ground in LaGuardia.</li>
<li>Sent a text to my wife Lisa to let her know what was going on and she told me heavy thunder storms were in the forecast, moving out around 10-11pm.</li>
<li>Not long before we were supposed to board the plane, the flight was delayed a 2<sup>nd</sup> time to 9:00pm EDT</li>
<li>A 3<sup>rd</sup> gate change delayed departure until 9:40pm EDT.</li>
<li>Finally boarding, the flight was supposed to leave at 9:40pm, but we are still sitting on the runway at 9:48. We spent another 20-30 minutes taxiing and waiting for overhead traffic to clear but at least we are on the plane!</li>
<li>Oh, did I forget to mention one kid played basketball in the waiting area for 2hrs. Dribbiling, lay-ups on glass by the check in desk. What a special treat for everyone in the waiting area&#8230;</li>
<li>Landed at La Guardia around 11pm on Friday night to find out that the US Air flight @ 9:29pm was the <strong>ONLY</strong> flight available and was clearly missed. The earliest flight out to Albany would be sometime on Sunday.</li>
</ul>
<p>Yes things were not looking good. Called Lisa again to let her know what was going on.</p>
<ul>
<li>Began calling car rental companies from the airport. Lovely, these multiple choice answers can be used for all of them:</li>
</ul>
<ol type="a">
<li>Business is closed after 10pm</li>
<li>All vehicles have been rented</li>
<li>Vendor will not rent vehicles one-way, must be picked up and dropped off at LaGuardia.</li>
</ol>
<ul>
<li>So, onto hotels, maybe I could rest for the night and try to pick up an early rental return. Well Deja-vu:</li>
</ul>
<ol type="a">
<li>No Vacancy – on a Friday in NYC, go figure&#8230;</li>
<li>No shuttle service available between the hotel &amp; airport</li>
<li>No answer at the main desk or through central reservations</li>
</ol>
<ul>
<li>Called Lisa back with an update, with her having never driven in NYC let alone La Guardia and the fact that it was getting late with a ~3.5 hour drive looming overhead. Having her drive down for a pickup did not seem like a good idea.</li>
<li>In the meantime, Lisa was trying to find alternate transportation. She checked the Amtrak schedule but both early morning trains on Saturday were sold out. Also friends we know in NYC were out of town so the streak of bad luck continued.</li>
<li>Lisa found the Metro-North Railroad (commuter train) schedule online and suggested I take a cab to Grand Central Station and try to catch a train to Poughkeepsie NY. The drive would be less than 2 hours from home and she could pick me up. We thought worst case scenario, at Grand Central Station I would have a place to stay until the next train, so that was the plan.</li>
<li>My cabbie made really good time from the airport, even with some construction delays. Figures, arrival time at Grand Central was not long after the 1:50am train for Poughkeepsie left the station so I was stuck waiting around until 6:20am.</li>
</ul>
<p>Yes 11 hours and counting.</p>
<ul>
<li>Well hello there Murphy how have you been? Last train departs Grand Central at 2am and police begin sweeping vagrants out into the street shortly afterward. FYI, the station closes from 2am to 5:30am daily. Two young teenage girls and a boy were in the same predicament but luckily an officer made arrangements for them to remain in the dispatch office rather than having to fend for themselves.</li>
<li>So at 2:00am I joined the ranks of NYC&#8217;s homeless. With my knapsack and suitcase in tow started walking the streets of Midtown Manhattan. I can easily say that nothing heightens your awareness like having “tourist”, “mobility impaired” and “come rob me” stenciled in neon on your person while walking around the city.</li>
<li>Must have walked at least 40 blocks around Park Ave. Lugging a knapsack loaded with books and a laptop around for 3+ hours is loads of fun, I highly recommend it especially when you are bored with nothing to do and tired.</li>
<li>Looked for a 24/7 coffee shop nearby but there was nothing open.</li>
<li>It was really hot and muggy that night (mid 70s), while roaming the streets, kept texting Lisa so she would know I was still breathing.</li>
</ul>
<p>Depressing, saw at least 20 homeless people sleeping on street grates, benches, building steps and in alleyways. Ages ranged from teenagers to the elderly. Some people were so contorted from being slumped over on a hard bench with relaxed muscles there should have been damage from snapping or dislocation. Not sure how two people were even able to breathe given the position they were in. I did see one very odd group of “nappers”. They appeared to be clean/fairly well dressed with a few pieces of luggage, wondered if they also had the pleasure of being booted from Grand Central.</p>
<ul>
<li>Around 4:45am managed to find a local grocery store open and was able to get something to drink but didn’t want to hang around. If this is the city that never sleeps I am not convinced!</li>
<li>At 5am the entertainment arrived, bars were closing and it was time for the severely inebriated to meander home. Good thing most of the travelers were couples, leaning into each other and staggering provided enough forward momentum w/o drifting out in to the street or light fixtures very often. All in all this was probably the most amusing point of the night.</li>
<li>After completing my walking tour of NYC, shuffled back to Grand Central in time to board the 6:20am train bound for Poughkeepsie.  Lisa sent a message that she was on her way to pick me up.</li>
</ul>
<p>It is a little over a 90 minute drive from home but near her parents so she knew the area. Neither one of us were able to get any sleep the night before and were running on pure adrenaline.</p>
<ul>
<li>My train rolled into the Poughkeepsie train station at about 8:30am and Lisa was waiting for me on the platform. We were both tired but we hopped back into the car , made a quick stop for breakfast at a drive through and headed home.</li>
<li>We got home about 10:40am and crashed at about 11am; don&#8217;t think we were conscious again until 6:30pm.</li>
</ul>
<p>So there you have it, 20 hours of non-stop excitement after an awesome work week in Toronto. In the grand scheme of things this is small potatoes but I thought everyone would appreciate a good laugh; Murphy’s Law certainly took over. This concludes my little NYC adventure. I wonder what my next trip has in store… Can’t wait!</p>
<p>Until next time.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/adirondackfirefly/2011/08/05/nyc-the-city-that-never-sleeps-not-so-much/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Hello from the Adirondack Mts</title>
		<link>http://blog.mozilla.org/adirondackfirefly/2011/07/01/hello-world/</link>
		<comments>http://blog.mozilla.org/adirondackfirefly/2011/07/01/hello-world/#comments</comments>
		<pubDate>Fri, 01 Jul 2011 17:30:20 +0000</pubDate>
		<dc:creator></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.mozilla.org/adirondackfirefly/?p=1</guid>
		<description><![CDATA[Welcome to my inaugural blog post! I’ve read plenty of blogs but never saw myself actually writing one, so this is uncharted territory for me.  It sort of feels like it did last Saturday while helping my father back his &#8230; <a href="http://blog.mozilla.org/adirondackfirefly/2011/07/01/hello-world/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Welcome to my inaugural blog post! I’ve read plenty of blogs but never saw myself actually writing one, so this is uncharted territory for me.  It sort of feels like it did last Saturday while helping my father back his boat into Chateaugay Lake, I ran out dock while directing him and plunged into the lake, clothes, Droid and all!</p>
<p>I figured I’d stop in and day “Hi” before I run off for 10 days for our annual camping trip in the Adirondack Mountains. We plan these trips a year in advance and hope Mother Nature is kind to us; the weather in the Adirondacks can be unpredictable. Breaking down camp in the pouring rain may be a fun challenge for some but doing it in a torrential downpour is something I could live without doing again for a very long time.</p>
<p>As John stated in his blog post, I am wading through <strong>TONS</strong> of “stuff” to familiarize myself with Mozilla’s Makefiles. Thank you John for the Welcome BTW and thanks to those who have been patient and answered my questions so far.</p>
<p><a href="http://oduinn.com/blog/2011/06/06/welcome-joey-armstrong-to-release-engineering/">http://oduinn.com/blog/2011/06/06/welcome-joey-armstrong-to-release-engineering/</a></p>
<p>Photos from the trip will be forthcoming, until next time!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mozilla.org/adirondackfirefly/2011/07/01/hello-world/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
