tag:blogger.com,1999:blog-81926427773751462182024-02-20T12:13:32.271-05:00The Blog of FernleafFernleaf is my blog handle. My name is Keith Smith. I have been a computer programming for almost 40 years. My blog will be about computer science mainly, specializing in embedded systems. I will sometimes venture into other topics like math and astronomy, as these are my hobbies. I hope you find the posts worth your time. Oh, yes, I have a fern garden.Unknownnoreply@blogger.comBlogger19125tag:blogger.com,1999:blog-8192642777375146218.post-61850622574004957582019-09-11T20:27:00.000-04:002019-09-11T20:27:32.987-04:00Yet Another Make Tutorial - VIIYet another chapter in the Yet Another Make Tutorial.<br />
<br />
[ <a href="http://fernleaf07.blogspot.com/2015/07/yet-another-make-tutorial.html" target="_blank">I</a>, <a href="http://fernleaf07.blogspot.com/2015/07/yet-another-makefile-tutorial-part-ii.html" target="_blank">II</a>, and <a href="http://fernleaf07.blogspot.com/2015/08/yet-another-make-tutorial-iii.html" target="_blank">III</a>, <a href="http://fernleaf07.blogspot.com/2015/08/yet-another-makefile-tutorial-iv.html" target="_blank">IV</a>, <a href="http://fernleaf07.blogspot.com/2015/08/yet-another-make-file-tutorial-v.html" target="_blank">V</a>, <a href="http://fernleaf07.blogspot.com/2015/08/yet-another-make-file-tutorial-vi.html" target="_blank">VI</a>. Make files are found <a href="https://bitbucket.org/FernLeaf_07/makefiletutorial" target="_blank">here</a>.]<br />
<br />
The previous post showed the framework for creating a production program and its unit tests using a library.<br />
<br />
The unit test and production program were both built together. The production program could be dependent on the unit test. If the unit test doesn't run, then why build the production program.<br />
<br />
Let's run the unit test after its built.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"># makefile<span style="color: red;">18</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">LIB := lib</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">UNITEST := unitest</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">TARGET := target</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">MYLIBRARY := mylibrary</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">.PHONY: all clean</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">all: <strike><span style="color: red;">build_unitest </span></strike>build_target</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">clean:</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> $(MAKE) -C $(TARGET) -f makefile<span style="color: red;">18</span>target clean</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> $(MAKE) -C $(UNITEST) -f makefile<span style="color: red;">18</span>unitest clean</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> $(MAKE) -C $(LIB) -f makefile<span style="color: red;">18</span>lib clean<span style="color: red;"> LIBRARY=$(MYLIBRARY)</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span>
<span style="font-size: x-small;"><span style="font-family: "courier new" , "courier" , monospace;">build_target: </span><span style="font-family: "courier new" , "courier" , monospace;"><span style="color: red;">build_unitest</span></span><span style="font-family: "courier new" , "courier" , monospace;"> </span></span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> $(MAKE) -C $(TARGET) -f makefile<span style="color: red;">18</span>target LIBRARY=$(MYLIBRARY) LIBDIR=$(LIB) <span style="color: red;">LIB_INC_DIR=../lib/inc</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">build_unitest: build_lib</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> $(MAKE) -C $(UNITEST) -f makefile<span style="color: red;">18</span>unitest LIBRARY=$(MYLIBRARY) LIBDIR=$(LIB) <span style="color: red;">LIB_INC_DIR=../lib/inc</span></span><br />
<span style="color: red; font-family: "courier new" , "courier" , monospace; font-size: x-small;"> chmod +755 ./$(UNITEST)/target/unittest</span><br />
<span style="color: red; font-family: "courier new" , "courier" , monospace; font-size: x-small;"> ./$(UNITEST)/target/unittest</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">build_lib:</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> $(MAKE) -C $(LIB) -f makefile<span style="color: red;">18</span>lib LIBRARY=$(MYLIBRARY)</span><br />
<div>
<br /></div>
<div>
Updates are 1) <span style="font-family: "courier new" , "courier" , monospace;">build_unittest</span> is now a dependency of <span style="font-family: "courier new" , "courier" , monospace;">build_target</span>, 2) the unit test is run after building, 3) to clean the library, the name of the library must be supplied, and 4) must supply path to lib include files for unit test and target.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">makefile15a</span> is used as the base for the makefiles <span style="font-family: "courier new" , "courier" , monospace;">makefile18lib</span>, <span style="font-family: "courier new" , "courier" , monospace;">makefile18unitest</span>, <span style="font-family: "courier new" , "courier" , monospace;">make18target</span>.<br />
<h3>
Library Makefile</h3>
<div>
Add LIB_NAME to make file</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"># LIBRARY is a passed variable</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">LIB_NAME := lib$(LIBRARY).a</span></div>
</div>
<div>
<br /></div>
<div>
Change command for $(TARGET) to make libary</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">$(TARGET) : $(OBJS_C) $(OBJS_CXX)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><span style="white-space: pre;"> </span>ar rvf $(TARGET_DIR)/$(LIB_NAME) $(OBJS_C) $(OBJS_CXX)</span></div>
</div>
<div>
<br /></div>
<h3>
Unitest Makefile</h3>
<div>
<div>
Add LIB_NAME to make file.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"># Input variables: LIBRARY, LIBDIR, LIB_INC_DIR</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">LIB_NAME := lib$(LIBRARY).a</span></div>
</div>
<div>
<br /></div>
<div>
Change dependency and command for $(TARGET) to make unit test.</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">$(TARGET): $(OBJS_C) $(OBJS_CXX) $(LIBDIR)/$(LIB_NAME)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><span style="white-space: pre;"> </span>$(CXX) $^ -o $@ -L$(LIBDIR) -l$(LIBRARY)</span></div>
</div>
<div>
<br /></div>
<h3>
Target Makefile</h3>
Same changes are make to target makefile as was make to unit test makefile.<br />
<br />
<h3>
Unit Test Main</h3>
</div>
<div>
Add a source file, <span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">unittest.cpp</span>, to the unit test <span style="font-family: "courier new" , "courier" , monospace;">src</span> directory to build a unit test program and test that the unit test program runs and fails.<br />
<br />
If a command <span style="font-family: "courier new" , "courier" , monospace;">make</span> runs returns an error code >0, then <span style="font-family: "courier new" , "courier" , monospace;">make</span> stops.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">//! \file unittest.cpp</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">#include <iostream></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">int main(void)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">{</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> std::cout << "Unit test failed" << std::endl;</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> return 1;</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">}</span></div>
<div>
<br />
Now there is a 'main()' to build a unit test.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzBy04IhIcYVAP_-jkUtgvH0cV9u1yfk6xX2d5WJE3eWGpaGSE2OkPL6HbJNWVC-LZ5S9x6YlBfWqHM6O_Mxc304Q_sid_7oHOVkMRWj3-hywoJs5LsN7IhgfInWKugNvEM9o2WOsZDrA/s1600/makefile18.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="341" data-original-width="1101" height="198" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzBy04IhIcYVAP_-jkUtgvH0cV9u1yfk6xX2d5WJE3eWGpaGSE2OkPL6HbJNWVC-LZ5S9x6YlBfWqHM6O_Mxc304Q_sid_7oHOVkMRWj3-hywoJs5LsN7IhgfInWKugNvEM9o2WOsZDrA/s640/makefile18.png" width="640" /></a></div>
<br />
The unit test reports failure.<br />
<br />
Update the unit test to succeed.<br />
<br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;">//! \file unittest.cpp</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">#include <iostream></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">int main(void)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">{</span></div>
<div>
</div>
<span style="font-family: "courier new" , "courier" , monospace;"> std::cout << "Unit test success" << std::endl;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> return 0;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: inherit;">With the unit test passing, the target program is built.</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgS_aHTpAAROm6OK3xyKxzPJHW0QkfV14jQmd3sliA-MMgBHmh5CcSg7BNRYLKsiieEPi1Bmw9TN8mzbNu1dlCizD9Pdg2_ssroMGIKObviSy_GEBt7xIO6qUscpEw_62CTFNeX2RIUdRw/s1600/makefile18a.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="233" data-original-width="1081" height="136" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgS_aHTpAAROm6OK3xyKxzPJHW0QkfV14jQmd3sliA-MMgBHmh5CcSg7BNRYLKsiieEPi1Bmw9TN8mzbNu1dlCizD9Pdg2_ssroMGIKObviSy_GEBt7xIO6qUscpEw_62CTFNeX2RIUdRw/s640/makefile18a.png" width="640" /></a></div>
<br />
This ends the tutorial. You should now have a good framework to build a program and unit test using a set of makefiles that do not need to be modified as the project progresses.<br />
<br />
Fin.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br /></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8192642777375146218.post-71662017145190720912018-09-30T08:06:00.000-04:002018-09-30T08:06:56.723-04:00Driving in New ZealandMy wife and I recently traveled to New Zealand. It had been a bucket list place to visit. We had a great time visiting the Coromandel Peninsula and greater Rotorua on the North Island.<br />
<br />
<div>
New Zealand is a country where you drive on the left. Nothing new here. The national speed limit is 100 kph, unless otherwise posted, which is a lot, mainly for towns, but also during construction.<br />
<br />
The unusual driving item are the rural one lane bridges. A sign as you approach indicates which travel direction has the right-of-way. Sometimes it is a challenge to see to the end of the bridge to see if anyone is coming. Didn't meet anyone on the middle of a bridge, but I'm sure it happens.<br />
<br />
Details from New Zealand government are <a href="https://www.nzta.govt.nz/resources/roadcode/about-driving/giving-way-on-one-lane-bridges/">here</a>.<br />
<br />
When using a navigation system in New Zealand the estimated travel time requires adjustment, especially on rural roads and unsealed roads. [Unsealed road means dirt roads where I come from.] As stated, the national speed limit is 100 kph. If the distance to travel is 50 kilometers, the navigation system will report a time of 30 minutes. Not!<br />
<br />
The rural roads in New Zealand can be twisty and hilly. The speed at turns can drop to 55 kph, then 45 kph, even 25 kph. Even if the navigation system knows the speed and distance of turns, it assumes you can go 100 kph between them. This is not possible. Add 25-50% to the estimated time and "She'll be right."</div>
<div>
<br /></div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8192642777375146218.post-13124247292073275262018-07-19T19:55:00.001-04:002021-05-24T21:14:44.812-04:00Primes and Sines<h2>
Primes and Sines</h2>
<div>
Prime numbers are a fascinating set of numbers. A prime is a number divisible by only one and itself. 11 is prime. 6 is not prime.<br />
<br />
Primes are a subset of the counting numbers, 1, 2, 3, 4,... Prime numbers are never negative. The first few primes are 2,3,5,7,11.<br />
<br />
1 is not considered a prime. 2 is sometimes not considered a prime. Math papers on primes might start 'Consider the set of primes starting at 3...'.<br />
<br />
When a number is not prime it has a list of prime factors. This is part of the <a href="https://brilliant.org/wiki/fundamental-theorem-of-arithmetic/">Fundamental Theorem of Arthimetic</a>. The non-prime number is created by multiplying all the prime factors together. A prime factor may repeat. 18 has 2, 3, and 3 as prime factors (2*3*3=18).<br />
<br />
Any even number is a multiple of 2. All primes numbers are odd, except 2. This is why 2 is sometimes left off the list of primes numbers.<br />
<br />
<br />
To determine if a number, N, is prime, a simple sequence of steps can be followed.<br />
<br />
1 - Find the list of all primes less than the square root of the number N.<br />
<br />
2 - For each prime, p[i], in the list of primes, N/p[i].<br />
2a - If there is no remainder from the division of any p[i], then N is not prime.<br />
<br />
Given 21, the square root of 21 is 4. The list of prime numbers less than or equal to 4 is 2 and 3. 21/2 = 10, with 1 remainder. 21/3 = 7, with no remainder. 21 is not prime.<br />
<br />
To create a list of primes, one follows a sequence called a prime number sieve.<br />
<br />
First select a maximum number to be examined, say 1000.<br />
<br />
2 is given as a prime (or ignored).<br />
<br />
Create a list of 1000 numbers, mark all numbers as prime.<br />
<br />
Starting with 3, add 3 to 3. In the list, at 6, mark 6 as not prime. Continue adding 3 to obtain the next multiple of 3 marking that entry in the list as not prime until the maximum number is reached, 1000.<br />
<br />
Repeat for all odd numbers.<br />
<br />
Examine each odd number in the list. Those entries still marked prime is the list of prime numbers less than 1000.<br />
<br />
This is prime number sieve is very easy to write in computer code. There are various methods of optimizing the method. One such method is found in <a href="https://gmplib.org/">GMP</a>. The GMP prime number sieve finds all the primes in the first ten million digits is much less than one second (running on a recent laptop).<br />
<br />
The basic process is 1) create a list, assume a numbers are prime, 2) mark those numbers not prime, 3) examine the resulting list looking for prime numbers.<br />
<br />
<h2>
Sines</h2>
<div>
A sine wave is a periodic wave. It repeats as much as desired.</div>
<div>
<br /></div>
<div>
y = sin(x) <b>[1]</b></div>
<div>
<br /></div>
<div>
generates a periodic wave, starting at 0,0, with four points being (π/2, 1), (π, 0), (3π/2, -1) and (2π, 0). The sine wave cross y=0 at π intervals.</div>
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGqhABhK1K7CYC5i6RqqkDAlsjiF65YhSs1OTC9njytEsKmXKUuNFGU52Bx6iIarsFlctmYEJLkkXLXsWIyff-KLe6nxlt2oW2Ub5gfLlOGsznylDzQjDTvLrk5ex1GSy4KPblo6Ymdfg/s1600/desmos-graph+%25281%2529.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="800" data-original-width="800" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGqhABhK1K7CYC5i6RqqkDAlsjiF65YhSs1OTC9njytEsKmXKUuNFGU52Bx6iIarsFlctmYEJLkkXLXsWIyff-KLe6nxlt2oW2Ub5gfLlOGsznylDzQjDTvLrk5ex1GSy4KPblo6Ymdfg/s320/desmos-graph+%25281%2529.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">y = sin(x)</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div>
<br /></div>
<div>
If the equation is changed to</div>
<div>
<br /></div>
<div>
y = sin(π/2 * x) <b>[2]</b></div>
<div>
<br /></div>
<div>
Equation <b>[2],</b> starting at 0,0 has the following four points (1,1), (2,0), (3,-1), (4,0).</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI1cv2DDQHT2PeAkpTNV4Z8uJKqz0QC_kxc96OlGa8n0ySS3EKfAOfqtU3O3K5ZHfQlpwNSI01EBJJxWZBfPl0b1T-lrlhWqJw9m547-hOPvacxTsBcqD79HxfLFnEvlWvIb8RrlMm9R8/s1600/desmos-graph+%25282%2529.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="800" data-original-width="800" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI1cv2DDQHT2PeAkpTNV4Z8uJKqz0QC_kxc96OlGa8n0ySS3EKfAOfqtU3O3K5ZHfQlpwNSI01EBJJxWZBfPl0b1T-lrlhWqJw9m547-hOPvacxTsBcqD79HxfLFnEvlWvIb8RrlMm9R8/s320/desmos-graph+%25282%2529.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">y = sin(π/2 * x)</td></tr>
</tbody></table>
<br />
For equation <b>[2] </b>the value of y is 0 at every multiple of 2. Equation <b>[2] </b>can be viewed as marking all those numbers that are multiples of 2 and thus not prime.<br />
<br />
y = sin(π/3 * x) <b>[3]</b><br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1zCi4mvtT7ZkhaRPvMVL_cBp3uqiHcQ-9Tvl4QkvYt3siMVEWEXQOy3jhnO88XWKO93P2yPX3LbSoP51m1VV02Hp4Xwtl1GlwZ3yiZ4dVIMSTzLhgrVqbt87OEPUgsacSjy6-Uj2rD-w/s1600/desmos-graph+%25283%2529.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="800" data-original-width="800" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1zCi4mvtT7ZkhaRPvMVL_cBp3uqiHcQ-9Tvl4QkvYt3siMVEWEXQOy3jhnO88XWKO93P2yPX3LbSoP51m1VV02Hp4Xwtl1GlwZ3yiZ4dVIMSTzLhgrVqbt87OEPUgsacSjy6-Uj2rD-w/s320/desmos-graph+%25283%2529.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">y = sin(π/3 * x)</td></tr>
</tbody></table>
For equation <b>[3] </b>the value of y is 0 at every multiple of 3. Again all those numbers that are multiples of three have y=0 and visually mark the number as not prime.<br />
<br />
Now if equations <b>[2] </b>and <b>[3] </b>are shown together.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhF0jZIg3g8GT6AoJlZERc25IR8SrObVoCjuMBYwxetduHdz4oR5ZMq4KPKMyLVkar0Sp52gdnhaXNPBbK_TXUAQrTz1G10AG9cCw4e6dt6xrJLm8k60ENMu9jYjcVtI6ECgOllAoCjR28/s1600/desmos-graph+%25285%2529.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="800" data-original-width="800" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhF0jZIg3g8GT6AoJlZERc25IR8SrObVoCjuMBYwxetduHdz4oR5ZMq4KPKMyLVkar0Sp52gdnhaXNPBbK_TXUAQrTz1G10AG9cCw4e6dt6xrJLm8k60ENMu9jYjcVtI6ECgOllAoCjR28/s320/desmos-graph+%25285%2529.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">y = sin(π/2 * x) and y = sin(π/3 * x)</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
Any odd number not crossed by equation <b>[2]</b> or <b>[3] </b>is prime. 5, 7, and 11 are the next 3 prime numbers.<br />
<br />
Any point where y=0 for either equation <b>[2] </b>or <b>[3]</b> represents a number that is not prime.<br />
<br />
This is true for all primes up to 24. Why 24?<br />
<br />
Any odd number less than 24 has at least 2 or 3 as a prime factor. 25 is the first number without 2 or 3 as prime number, 5 * 5.<br />
<br />
The list of prime numbers after 3 and before 24 is 5, 7, 11, 13, 17, 19, and 23. Using just 2 prime numbers we find an additional 7 prime numbers.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVnozdWLwRjVpDj0-jw3qEg5e-hmOWPd71nq3DJrxByjYfO1gIqX2K_Sjy7mKIhqLCPtAkrmAZ1ROzFZYZFDP-wc9apCpSDw8g49OLh4kDNer7BY2J2k_s3s5xd9pYnGUxQ1H5RNJV378/s1600/desmos-graph+%25286%2529.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="800" data-original-width="800" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVnozdWLwRjVpDj0-jw3qEg5e-hmOWPd71nq3DJrxByjYfO1gIqX2K_Sjy7mKIhqLCPtAkrmAZ1ROzFZYZFDP-wc9apCpSDw8g49OLh4kDNer7BY2J2k_s3s5xd9pYnGUxQ1H5RNJV378/s320/desmos-graph+%25286%2529.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">y = sin(π/2 * x) and y = sin(π/3 * x)</td></tr>
</tbody></table>
<br />
If we add a new equation<br />
<br />
y = sin(π/5 * x) <b>[4]</b></div>
<div>
<b><br /></b></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbcx3gVNRyqYaTzAJ23HZg1umFcQNEyRbUosSHx_Zk3IWc9DJz06SbXK7ycsn4vureoa9IIt6QHP3_dL7yheO5g4QoUp5czKugtJgEr3nXbxkxjhb-G8-tenechEnc7WchRa5kxB0jjjQ/s1600/desmos-graph+%25287%2529.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="800" data-original-width="800" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbcx3gVNRyqYaTzAJ23HZg1umFcQNEyRbUosSHx_Zk3IWc9DJz06SbXK7ycsn4vureoa9IIt6QHP3_dL7yheO5g4QoUp5czKugtJgEr3nXbxkxjhb-G8-tenechEnc7WchRa5kxB0jjjQ/s320/desmos-graph+%25287%2529.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">y = sin(π/2 * x), y = sin(π/3 * x), and y = sin(π/5 * x)</td></tr>
</tbody></table>
<div>
<b><br /></b></div>
<div>
It is a bit more difficult to see those numbers that are prime. 29, 31, 37, etc. are prime.</div>
<div>
<br /></div>
<div>
This is a graphical representation of the prime number sieve.</div>
<div>
<br /></div>
<div>
Take the absolute value of <b>[2]</b>.</div>
<div>
<br /></div>
<div>
y = | sin(π/2 * x) | <b>[5]</b></div>
<div>
<b><br /></b></div>
<div>
<br /></div>
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiV9CHavo5nrHXtXFq3V5Vyn85-myLg-ry9GEhWKS3PeP45SLVEWuEuTnR9Sl2767RMzPY9RNPfw5rnO-vUuHbSGwvTblbe9RGt8W2ZSQ8PhctOKr8ZoHRvPy5RD0aF5xPkEZTwnuTGgE4/s1600/desmos-graph+%25288%2529.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="800" data-original-width="800" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiV9CHavo5nrHXtXFq3V5Vyn85-myLg-ry9GEhWKS3PeP45SLVEWuEuTnR9Sl2767RMzPY9RNPfw5rnO-vUuHbSGwvTblbe9RGt8W2ZSQ8PhctOKr8ZoHRvPy5RD0aF5xPkEZTwnuTGgE4/s320/desmos-graph+%25288%2529.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">y = | sin(π/2 * x) | </td></tr>
</tbody></table>
<div>
<br /></div>
<div>
Repeat this process for equations <b>[3] </b>and <b>[4].</b></div>
<div>
<b><br /></b></div>
<div>
<div>
y = | sin(π/3 * x) | <b>[6]</b></div>
</div>
<div>
<div>
y = | sin(π/4 * x) | <b>[7]</b></div>
</div>
<div>
<b><br /></b></div>
<div>
Combine [5], [6], and [7].</div>
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWEkTNQgMbLd1Lp5xFFPOnueV9fp37GkgxyrQiyY8aQOphLYx3y2Oze6LOOhyphenhyphenWirF2F3rXuMxG7m6gkeBuXji9xHyLUtrXBz1l9xEr5DIj2MKdc42By2FO59_BF26PML_S3eD3K_Gqx4k/s1600/desmos-graph+%25289%2529.png" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="800" data-original-width="800" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWEkTNQgMbLd1Lp5xFFPOnueV9fp37GkgxyrQiyY8aQOphLYx3y2Oze6LOOhyphenhyphenWirF2F3rXuMxG7m6gkeBuXji9xHyLUtrXBz1l9xEr5DIj2MKdc42By2FO59_BF26PML_S3eD3K_Gqx4k/s320/desmos-graph+%25289%2529.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">y = | sin(π/2 * x) | , y = | sin(π/3 * x) | , and y = | sin(π/5 * x) | </td></tr>
</tbody></table>
<div><br /></div><div>
The numbers that are prime are now much easier to identify. The prime numbers are where the three equations lack a y=0 point.</div>
<div>
<br /></div>
<div>
Using <b>[5]</b>, <b>[6]</b>, and <b>[7]</b> will find the prime numbers up to 48, as 49 is 7*7. The first number without 2, 3, or 5 as a factor. The remaining primes are 7,11,13,17,19,23,29,31,37,41,43,47. With just 3 primes 12 additional primes are found.<br />
<br />
This visualization of the prime number sieve uncovered an algorithm that seems more pleasing that the standard prime number sieve, at least to this author.<br />
<br />
<br />
<h2>
Modulo</h2>
<div>
The sine graphs are visual, but not practical. The curves are continuous. Only the values at odd numbers need to be calculated, but trigonometric functions are expensive to calculate.<br />
<br /></div>
<div>
It is only required to know if the sine curve is zero or not zero at the point N.</div>
<div>
<br /></div>
<div>
A way of determining if a number is prime is to use the same prime number list, but use modulo arithmetic instead of sines.</div>
<div>
<br /></div>
<div>
Modulo arithmetic was shown above for the number 21.</div>
<div>
<br /></div>
<div>
If a number, N, has a prime sine curve, p, passing through it (y=0) then the modulo of N of p is zero stating that N is not prime.</div>
<div>
<br /></div>
<div>
Given a list of primes, whose largest prime is P, for all odd numbers N from P+2 to (P+2)(P+2)-1, perform modulo arithmetic on N using the list of primes. If all modulo results are non-zero, the number is prime. Testing N can stop when one modulo result is zero.</div>
<div>
<br /></div>
The graphs above were created using Desmos. The link to the Desmos page with the graphs is <a href="https://www.desmos.com/calculator/ccicp29mjj">here</a>.<br />
<br />
Modulo code is found on <a href="https://github.com/FernOfGitHub/PrimeSines">GitHub</a>.</div>
<div>
<br /></div>
<div>
<br /></div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8192642777375146218.post-43030762770090738662018-04-28T15:50:00.002-04:002018-04-28T15:50:46.600-04:00Software, Insurance, and Underwriter's Laboratory<div class="gmail_default" style="color: #222222; font-family: tahoma, sans-serif; font-size: small;">
Jack Ganssle wrote this article entitled 'Fire Code for Software'.</div>
<div class="gmail_default" style="color: #222222; font-family: tahoma, sans-serif; font-size: small;">
<br /></div>
<div class="gmail_default">
<span style="color: #222222; font-family: tahoma, sans-serif; font-size: x-small;">http://www.ganssle.com/articles/FireCode.htm</span></div>
<div class="gmail_default">
<span style="color: #222222; font-family: tahoma, sans-serif; font-size: x-small;"><br /></span></div>
<div class="gmail_default" style="color: #222222; font-family: tahoma, sans-serif; font-size: small;">
"Fire code for Software?" is essentially saying why hasn't the software industry developed an Underwriter's Laboratory or an Insurance Institute for Highway Safety for software?</div>
<div class="gmail_default" style="color: #222222; font-family: tahoma, sans-serif; font-size: small;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: tahoma, sans-serif; font-size: small;">
Both UL and IIHS are products of the insurance companies desire to improve human safety, lower claims, and manage insurance costs. UL has been around since 1894. Software has only be around for 50 or so years and only in the last 20 or so years has software been 'mainstream'.</div>
<div class="gmail_default" style="color: #222222; font-family: tahoma, sans-serif; font-size: small;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: tahoma, sans-serif; font-size: small;">
Currently software is not insured. Problems with software are resolved after the fact, usually by litigation.</div>
<div class="gmail_default" style="color: #222222; font-family: tahoma, sans-serif; font-size: small;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: tahoma, sans-serif; font-size: small;">
Regulators, such as the FDA, monitor software for medical devices. The NTSB can audit software when a 'recall' event occurs involving vehicle (car, train, plane) software. Several companies have gone bankrupt because of software mistakes that killed people, Therac-25, for example.</div>
<div class="gmail_default" style="color: #222222; font-family: tahoma, sans-serif; font-size: small;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: tahoma, sans-serif; font-size: small;">
Self-driving cars may push the issue of software testing for insurance reasons.</div>
<div class="gmail_default" style="color: #222222; font-family: tahoma, sans-serif; font-size: small;">
<br /></div>
<div class="gmail_default" style="color: #222222; font-family: tahoma, sans-serif; font-size: small;">
When the cost of software mistakes are born by someone other than the software builder and the customer, this is insurance, and the insurance companies will protect their interests.</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8192642777375146218.post-38599302734695877852018-01-26T19:23:00.000-05:002018-07-20T20:23:16.839-04:00Speculations of an Autonomous Vehicle WorldAutonomous vehicles are just around the corner. Tesla has semi-autonomous vehicles for sale today. Waymo, Google, and Uber are all working on fully autonomous vehicles. Delphi, a supplier of auto parts, is selling the sensors necessary for autonomous vehicles to know about their environment.<br />
<br />
What will happen to society, jobs, work, travel, and the environment as the autonomous vehicle becomes the norm? This is a speculation on a new world with autonomous vehicles.<br />
<br />
In the beginning of the autonomous vehicle world only those early adopters will experience a new life style. Sitting in an autonomous vehicle will be like being in an airplane on the ground. The passenger doesn't care where the vehicle is going, just the vehicle gets to the destination safely and on time.<br />
<br />
The world will not have 100% autonomous vehicles soon. It will start slow and build. As it builds, changes will occur in transportation, jobs, and leisure.<br />
<br />
The first adoption of autonomous vehicles will be where the most savings of money and labor can be realized. There will also be adoption by those that can afford new technology, but that will be as a status symbol, a toy. The initial commercial impact will be in long haul trucks, street sweepers, garbage trucks, snowplows, delivery vehicles, pizza delivery, and package delivery.<br />
<br />
Already long haul trucks have been driven coast to coast autonomously. [ref] Volvo is advertising a self driving garbage truck. Self driving street sweeper is a direct spin off. Snowplows may be more difficult given the size of the blade and parked cars, but on limited access highways a distinct possibility. Pizza delivery can be by drone, but can also be done by small, go cart like vehicles. Punch in a code to unlock door when vehicle arrives. UPS is looking at deploying autonomous carts from a vehicle to deliver more than one package at a time in a limited area. The UPS truck could drive itself to the deployment location.<br />
<br />
Those that drive trucks, short haul and long haul, delivery trucks, garbage trucks, street sweepers, snow plows, or other municipal vehicles will be the first to feel the job stress from autonomous vehicles. Drivers of taxis and buses will be affected as well.<br />
<br />
Cities and towns will definitely do a cost analysis of employing autonomous vehicles to reduce costs. When current vehicles have reached their useful life, autonomous vehicles will be available for purchase. Unions will push back. It may take decades to change the union contracts or wait for existing employees to retire. Removing the toll booth operators around NYC was technically feasible when the first FastPass was installed. It wasn't until 2017 that all human operator toll booths were removed.<br />
<br />
When an autonomous delivery vehicle arrives with goods for a customer, does the customer unload the vehicle? Does the vehicle unload itself? Is there still a person with the delivery vehicle to unload the goods?<br />
<br />
Vacation travel will change. RVs will now be a living room on wheels. One will get to a destination in half the time. The vehicle drives 24 hours a day. Fueling a vehicle will need some thought. A robot gas station perhaps? How will humans tell the autonomous vehicle to pull over for a bathroom break or stop for lunch? Yes, RVs and buses have toilets, but not sedans.<br />
<br />
How many less cars will on the road? Will there be less congestion? Will autonomous vehicles drive better resulting in less rush hour delays?<br />
<br />
Who will benefit? Fleet owners of autonomous vehicles, body shops that customize interiors, software programmers, advanced auto mechanics, and training schools.<br />
<br />
Who will lose? Truck drivers, taxi cab drivers, delivery drivers, public works employees, parking lot owners, parking lot attendees, automobile assembly line workers, car dealerships, auto mechanics, the Teamsters Union. Municipalities will have less revenue because there will be less cars to tax, less parking, so less parking meter fees. The parking meter fees represent a significant percentage of some cities revenues. A <a href="http://www.businessinsider.com/massachusetts-law-proposal-tax-self-driving-car-per-mile-2017-3">law was proposed in Massachusetts</a> that will tax autonomous vehicles for 'cruising' around without parking. The law essentially taxes the vehicle at different rates, with passengers, without passengers, etc. This is an attempt to recapture the lost taxes from less cars.<br />
<br />
Ford, GM, and others are looking into subscription service for vehicles, not ownership. Cadillacs are already offers normal cars on a subscription basis. Subscription service is going to be required by the auto manufacturers to make up for lost revenue as the number of cars required drops, by some estimates as much as 75%. [ref].<br />
<br />
Everyone will pay a monthly fee to be able to 'hail' an autonomous vehicle. What sort of premium services will be available? Will there be 'congestion' pricing, 'time of day' pricing?<br />
<br />
Enter into your 'hail a ride' app how far you want to walk from your home, how far to want to walk to work, when you want to leave and arrive at your destination. A vehicle shows up as requested. It may have no passengers, it may be a van pool, it may be a bus. It all depends on your choices and level of service.<br />
<br />
Will there be a bus as we know it? Buses run on fixed routes at fixed times to be predictable. It is used, mainly, by those that don't have vehicles today. Buses won't have to run on fixed routes, if they are autonomous. There may be fixed pick up and drop off points, but the buses don't have to follow a fixed route to get to each point. Either a kiosk or a phone app will be used to say which destination you want to go to and from which location you want to be picked up. Routes will be created dynamically based on the real time demand. Less total buses will be needed and can run 24 hours a day.<br />
<br />
The displacement of workers due to work sent overseas took decades and affected mainly manufacturing. Autonomous vehicles will affect the entire transportation infrastructure and all the people that work in it and will be rolled out in less than a decade.<br />
<br />
Houses will be built without garages. Housing density go up as off street parking will not be required. What other planning and zoning changes will occur? Will there be a surge in customization of vehicles? Boutique fleet owners will provide unusual, exotic rides for special occasions. The living room sofa ride will now be a reality. Will traveling in luxury take on a new meaning? A TV, Internet, lounger, mini-bar, microwave, refrigerator are all items that can be found in a vehicle today. What will be found in the luxury autonomous car of tomorrow? Multiple day rides in an autonomous vehicles will include a bed. Autonomous vehicles may be fueled or charged while they roll, just like midair refueling of military aircraft. Definitely a time saver.<br />
<br />
Will there be an entire generation that doesn't know how to drive? The department of motor vehicles will have less cars to register. You will go to DMV to get a state identification card, not a driver's license.<br />
<br />
The autonomous vehicle will be a boon to those who are blind and handicapped, or those who cannot drive for some reason. The mobility of seniors will greatly increase.<br />
<br />
The challenges today for autonomous vehicles is snow obscures visibility, snow covers the painted lines. Heavy rain and glare are also an issue. Northern climate residents may see a slower roll out of the autonomous vehicle.<br />
<br />
The autonomous vehicle will be assisted by other vehicles and by road side devices to help with navigation. Auto manufactures are designing the communication and devices for a smart highway. The smart highway will help to define the autonomous experience. States may have to do a better job with road line painting for the autonomous vehicle fleet. What happens after a road is paved? There are no lines on the road immediately after paving. Will line painting be autonomous too?<br />
<br />
What about computer hacking? Vehicles have already been shown to be hackable. Will a terrorist be able to cause death and mayhem on the road?<br />
<br />
What about the classic car owners? How will older cars fit into the world of autonomous vehicles? Will they have to be fitted with special sensors?<br />
<br />
The decrease in the number of cars will free up resources for other purposes. Commodity prices will fall as demand for iron and copper to build cars go down. Yes, there will be less cars on the road, but will there be more or less miles traveled? Ride sharing would decrease traveled miles, but those that didn't drive will be more mobile. Does oil demand go down or up?<br />
<br />
How will criminals use autonomous vehicles?<br />
<br />
The Chinese character for crisis, 危機, combines glyphs from danger, 危險, and opportunity, 機會. The world of autonomous vehicles will be different than today, danger for those supporting the non-autonomous world and opportunity for those that embrace the autonomous world. Will there be room for everyone?<br />
<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8192642777375146218.post-47740835609058618142016-09-03T16:08:00.000-04:002016-09-08T19:20:46.090-04:00Loss of the Night SkyThis is not my usual computer geek blog, this blog is on the theme of<br />
<br />
<b><span style="font-family: "verdana" , sans-serif;">"It should be dark at night"</span></b><br />
<br />
<h2>
Earth at Night </h2>
<br />
NASA has published <a href="http://eoimages.gsfc.nasa.gov/images/imagerecords/55000/55167/earth_lights_lrg.jpg">this famous picture</a> of what the dark side of the Earth looks like from space. This picture shows hot bright the cities of the world are at night, and how much of the developed world is lit up 24/7. (A really large version of this map, 10MB, is <a href="http://a/">here</a>. [biggest, 40MB, <a href="http://eoimages.gsfc.nasa.gov/images/imagerecords/55000/55167/land_lights_16384.tif">here</a>.]<br />
<br />
How many features can you see of the Earth without sun light? Find the Nile River, the Hawaiian Islands, the border between N and S Korea.<br />
<br />
A lot of places 'left the lights on'.<br />
<br />
<h2>
Light Pollution</h2>
All of these lights cause light pollution, light that obscures the night sky.<br />
<br />
Here is an <a href="http://www.lightpollutionmap.info/">interactive map of world light pollution</a>. Light pollution has been put on a color scale. Red is like Times Square, NYC. Black is <a href="http://www.redbull.com/us/en/adventure/stories/1331715076623/point-nemo-most-remote-on-earth">Point Nemo</a>. Where do you live? Orange, Yellow, maybe Green. [<a href="http://advances.sciencemag.org/content/2/6/e1600377.full">Map from Falchi et. al.</a>]<br />
<br />
[<a href="http://mappingignorance.org/2016/09/05/to-know-the-dark/">Good background</a>, nice tweet, good references for mapping light pollution on the ground.]<br />
<br />
Years ago a scale was developed for the <a href="https://en.wikipedia.org/wiki/Apparent_magnitude">apparent magnitude</a> of stars in the night sky. The scale is logarithmic (read the link for all the maths :) ). The edge of human seeing is 6.5 on this scale. Just over <a href="http://www.skyandtelescope.com/astronomy-resources/how-many-stars-night-sky-09172014/">9000</a> stars can be seen by the human eye if the sky is dark enough (article has a lot more detail on the exact count and where this count is valid).<br />
<br />
Add light pollution to obscure the dim stars, and the number of stars you could see at 4th magnitude drops to only HUNDREDs.<br />
Here's a great set of charts showing how the constellation <a href="http://www.globeatnight.org/magcharts/cygnus">Cynus the Swan</a> changes from 0 magnitude to 6 magnitude viewing.<br />
<br />
Excellent <a href="http://www.aceshooting.com/post/150072561415/light-pollution-vs-dark-skies-in-astrophotography">demonstration of the difference of two areas</a> with different night pollution. <br />
<h2>
Milky Way</h2>
Have you ever seen the Milky Way, horizon to horizon? Seeing it makes you understand why the Ancient Greeks called it gala, 'milk'.<br />
<br />
All ancient civilizations have stories on how the Milky Way was created or what it represents. In the modern world, with our night skies, that connection is lost.<br />
<br />
<h2>
Citizen Science, Apps, No Telescope Needed</h2>
There is a great mobile phone app <a href="https://play.google.com/store/apps/details?id=com.cosalux.welovestars&hl=en">"Loss of the Night"</a> (iTunes <a href="https://itunes.apple.com/us/app/loss-of-the-night/id928440562?mt=8">here</a>). You become a citizen scientist. The program guides you through locating dimmer and dimmer stars until it determines how dark is your sky. It takes 15 or so 'sightings' to get enough data for a reasonably accurate measurement. The authors have a <a href="http://lossofthenight.blogspot.com/">blog</a>, shows the results, good stuff. They are developing a map of how the night sky is changing, literally from the ground up. See <a href="http://lossofthenight.blogspot.com/2015/03/the-globe-at-night-revisit-project-2015.html">this</a> for more details.<br />
<br />
Another, more manual, citizen science project that has been running longer than 'Loss of the Night' is <a href="http://www.globeatnight.org/">Globe at Night</a>. Simple 5 step directions <a href="http://www.globeatnight.org/5-steps.php">here</a>.<br />
<br />
<h2>
Dark Sky Reserves and Parks</h2>
The <a href="http://darksky.org/">International Dark Sky Association</a> has started declaring areas a <a href="http://darksky.org/idsp/reserves/">Dark Sky Reserve</a>. It is a rigorous process to get an area designated such a site. Only 11 such sites are listed.<br />
<br />
A lower designation is a <a href="http://darksky.org/idsp/parks/">Dark Sky Park</a>. The US has many of these, associated with its National Park system.<br />
<br />
Finally, a <a href="http://darksky.org/idsp/sanctuaries/">Dark Sky Sanctuary</a> is like a Dark Sky Reserve, but remote, with limited access.<br />
<br />
It is a fact of modern times, one must create a park to see the night sky as it was ONLY 100 or so years ago, just outside living memory.<br />
<br />
<h2>
Man Made Lights and Lighting Science</h2>
The culprit in the loss of the night sky is the electric light. IDSA does have an excellent page on <a href="http://darksky.org/lighting/">outdoor lighting</a> and what communities can do to "bring back the night".<br />
<br />
One result of light pollution is the brightening of the night sky, <a href="http://www.lrc.rpi.edu/programs/nlpip/lightinganswers/lightpollution/skyGlow.asp">Sky Glow</a>.<br />
<br />
Another excellent website on lighting is <a href="http://www.lrc.rpi.edu/">The Lighting Institute</a> at <a href="http://www.rpi.edu/">Rensselaer Polytechnic Institute</a> The Lighting Institute conducts a <a href="http://www.lrc.rpi.edu/education/outreachEducation/OutdoorInstitute.asp">two day course</a> on outdoor lighting, and much more. A great resource for municipal public works departments, planning and zoning committees, as well as departments of transportation at the state level (Yes, USA centric terminology).<br />
<br />
<h2>
Look Up, Measure Your Night Sky, Report It, Get Involved </h2>
<br />
Lots of links in this article. Lots of people to talk to.<br />
<br />
Learn about outdoor lighting.<br />
<br />
Learn where you can educate local government officials on what is a loss of a NATURAL RESOURCE, the night sky. They can control lighting issues with local zoning.<br />
<br />
Many US states are passing laws regarding the lighting of highways and roads, state buildings, etc.<br />
<br />
Bring the Milky Way back, for good!<br />
<br />
<br />
<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8192642777375146218.post-78293440079842267642016-07-08T18:46:00.000-04:002018-10-25T07:50:46.312-04:00Software ArchaeologyThis blog is to discuss what a software engineer, me, has to do when there has been years of neglect to a program.<br />
<br />
I work in the embedded systems space, so this blog will talk about embedded programs, not Windows, not Unix, but embedded programs. Some written exclusively in assembly, some in C. Most with no threads or other OS assistance.<br />
<br />
Definitions: Software Archaeology - The investigation, research, documentation, and rewriting to gain meaningful understanding of long ago abandoned or neglected software programs.<br />
<br />
What causes a program to be abandoned or neglected? Why is archaeology required in the first place?<br />
<br />
The programs I have worked with were written in the early '90s. Software standard practices are better than back then. I will say that many projects today are better than back then, but there are many that are still built the same way it was done 20 years ago.<br />
<br />
Software consultant, Joe, talking to friend consultant John.<br />
<br />
"Joe - How's the new assignment going?" ask John. "Oh, they're writing legacy code" replied Joe.<br />
<br />
When software is written it combines 1) the author's domain knowledge, and 2) the author's understanding of the underlying hardware.<br />
<br />
The software is constrained by how well the underlying hardware can accomplish the task to be completed. The software is also constrained by the author's knowledge of the domain problem that is the source of information for the task. The author then brings their personality, experience, drive, and insight to the writing of software.<br />
<br />
Software is the art and science of translating human goals into a language where a computer can perform the task expounded in the goal.<br />
<br />
What do I find when I read code from another era? I find the remnants of enough of the domain and programming language knowledge to do the job, but no more.<br />
<br />
I took a computer languages course in 1976. I was introduced to Algol, PL/1, Snobol, and APL. I do not use any of these languages today. I don't know who does. I learned and used FORTRAN in other courses, which is still widely used in numerical computing applications. C was just starting to be used in research labs.<br />
<br />
If I had to resurrect a program from that era, I would have to learn, to a certain extent, the actual computer language, its syntax and nuance, to understand how the program functioned.<br />
<br />
Sometimes, the need for the source code is not necessary. Sometimes all that is required is a complete definition of the inputs and outputs of the program. This is probably a simple program, but if you know that a certain list of numbers goes into a program and a set of operations is performed on that list and a new new set of numbers is created, then any programming language that handles the inputs and outputs could be used to satisfy the task of converting the input to the output.<br />
<br />
The constraint on recovering an old program is that the inputs and outputs are still in place. They cannot be changed. What is missing is the exact definition of the inputs and outputs. The program knows what those inputs and outputs are. But the complete definition is in the code.<br />
<br />
Unfortunately, the program can't expound on its nuances or give background on what the author was thinking. Comments help, when they are present.<br />
<br />
The techniques of re-factoring are those that will provide the most insight with the best chance of documenting the inputs and outputs.<br />
<br />
The other difficulty with working with old programs are the tools. With each generation of processors, comes a new generation of tools.<br />
<br />
In the '90s the method by which one debugged an embedded program was very primitive or very sophisticated, but not much in between. The primitive method was to output RS-232 messages to display the current state of the code. Each output would reveal the changing state. Analysis would then determine what might be wrong. The very sophisticated, and thus very expensive method, was to use an In-Circuit Emulator or ICE.<br />
<br />
Memory was expensive in the '90s. Embedded processors did not have cache. Programs ran from Read Only Memory, which may have been PROMs, EPROMs or Flash. The processor would have break point capability, but only if the memory location could be changed to an 'illegal instruction' to cause a jump to the interrupt handler that would provide the debugging support. This only worked if the program was running in RAM. Inserting an illegal instruction into ROM is impossible. This is the same mechanism used today for software breakpoints. Hardware breakpoints were nowhere to be seen.<br />
<br />
The ICE provided a way for a host processor, a PC, to have RAM memory substitute for ROM memory as well as take over the clock operations of the processor, allowing the user to watch the processor step through each instruction in as much detail as desired.<br />
<br />
Breakpoints are essential.<br />
<br />
RS-232 output disturbs the timing of the program and use up precious memory. The ICE was an emulator and thus provided the debugging functions without the rewriting of code and using any additional memory.<br />
<br />
If the program was neglected, then the tools have been neglected. The ICE unit may no longer power on, if it can be found at all.<br />
<br />
The history of how the author came to writing the code is lost. The author learned, most likely by trial and error, the nuances of the language and the hardware. This history is not documented.<br />
<br />
All in all a puzzle.<br />
<br />
That's another good definition of software archaeology, the study of puzzles created by time and neglect.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8192642777375146218.post-88837100233676233712015-09-08T19:27:00.001-04:002018-07-20T21:48:41.185-04:00Number of Processors, Linux, and Make[Much of this post is from here,<a href="http://www.binarytides.com/linux-cpu-information/"> <span style="color: blue; font-family: "courier new" , "courier" , monospace; font-size: x-small;">http://www.binarytides.com/linux-cpu-information/</span></a>]<br />
<span style="color: blue; font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span>
For those who use Windows, there is an environment variable that comes pre-loaded, NUMBER_OF_PROCESSORS.<br />
<br />
This variable contains the number of processors that a program might want to know to allow for parallel operations.<br />
<br />
But in this day and age, the number of actual processors and the number reported may differ by a factor of two. The technology that allows this is called <a href="https://en.wikipedia.org/wiki/Hyper-threading">hyperthreading</a>. Hyperthreading has been around for more than ten years.<br />
<br />
A CPU chip may have two physical cores, but with hyperthreading, the operating system is presented with four processors.<br />
<br />
Under Windows, <span style="font-size: x-small;">NUMBER_OF_PROCESSORS</span> is the hyperthreading number.<br />
<br />
Under Linux, we can run a set of commands and get both.<br />
<br />
<div>
<div>
<span style="color: blue; font-family: "courier new" , "courier" , monospace; font-size: x-small;"># Get the number of actual processors, not hyperthreaded processors</span><br />
<span style="color: blue; font-family: "courier new" , "courier" , monospace; font-size: x-small;">NUMBEROFPROCESSORS=`cat /proc/cpuinfo | grep 'core id' | wc -l`</span><br />
<span style="color: blue; font-family: "courier new" , "courier" , monospace; font-size: x-small;">echo "Number of Processors="$NUMBEROFPROCESSORS</span><br />
<span style="color: blue; font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span>
<span style="color: blue; font-family: "courier new" , "courier" , monospace; font-size: x-small;"># Get the number of hyperthreaded processors</span><br />
<span style="color: blue; font-family: "courier new" , "courier" , monospace; font-size: x-small;">NUMBEROFHTTPROCESSORS=`cat /proc/cpuinfo | grep processor | wc -l`</span><br />
<span style="color: blue; font-family: "courier new" , "courier" , monospace; font-size: x-small;">echo "Number of Hyperthreaded Processors="$(($NUMBEROFHTTPROCESSORS-$NUMBEROFPROCESSORS))</span></div>
</div>
<div>
<br /></div>
<div style="-webkit-text-stroke-width: 0px; color: black; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
<div style="margin: 0px;">
<span style="font-family: inherit;">The environment variable </span><span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">NUMBEROFPROCESSORS</span><span style="font-family: inherit;"> is created by the output of the file </span><a href="http://www.binarytides.com/linux-check-processor/"><span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">/proc/cpuinfo</span></a><span style="font-family: inherit;"> being piped to </span><span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">grep</span><span style="font-family: inherit;">, which looks for the string </span><span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">processor</span><span style="font-family: inherit;"> or </span><span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">core id</span><span style="font-family: inherit;">. The result is then piped to </span><span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">wc</span><span style="font-family: inherit;"> which counts the number of lines </span><span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">grep</span><span style="font-family: inherit;"> found.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">My results are as follows. I'm running on an Intel(c) Core(tm)2 T9400. It does not support hyperthreading.</span></div>
<div style="margin: 0px;">
<span style="font-family: inherit;"><br /></span></div>
<div style="margin: 0px;">
<span style="background-color: black; color: white; font-family: "courier new" , "courier" , monospace;">Number of Processors=2</span><br />
<span style="background-color: black; color: white; font-family: "courier new" , "courier" , monospace;">Number of Hyperthreaded Processors=0</span><br />
<div>
<br /></div>
<span style="font-family: inherit;">We can use this information with the </span><span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">-j</span><span style="font-family: inherit;"> argument for </span><span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">make</span><span style="font-family: inherit;">.</span></div>
<div style="margin: 0px;">
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="color: blue; font-family: "courier new" , "courier" , monospace; font-size: x-small;"># Get the number of actual processors, not hyperthreaded processors</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">NUMBEROFPROCESSORS=</span><span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">`</span><span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">cat /proc/cpuinfo | grep processor | wc -l`</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">make -j$NUMBEROFPROCESSORS</span></div>
<div style="margin: 0px;">
<span style="font-family: inherit;"><br /></span></div>
<div style="margin: 0px;">
<span style="font-family: inherit;">Now </span><span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">make</span><span style="font-family: inherit;"> will use the number of processors (with hyperthreading). We don't have to change the make script each time we get more cores on our VM or laptop.</span></div>
<div style="margin: 0px;">
<span style="font-family: inherit;"><br /></span></div>
<div style="margin: 0px;">
<span style="font-family: inherit;">It is mentioned (can't find the URL) that </span><span style="font-family: "courier new" , "courier" , monospace;">-j</span><span style="font-family: inherit;"> has no effect when running under MS-DOS. Don't know if this has changed. The version of Windows is not mentioned. </span><span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">nmake</span><span style="font-family: inherit;">, supplied with Visual Studio, is said to be available for multi-core (parallel) operation. <a href="http://stackoverflow.com/questions/601970/how-do-i-utilise-all-the-cores-for-nmake">StackOverflow discussion here</a>.</span></div>
<div style="margin: 0px;">
<br />
<div>
Using -j, in general, assumes that the build is not a highly dependent build. Lots of leaves in the build tree.</div>
<div>
<br /></div>
More details on cpuinfo can be found <a href="http://www.binarytides.com/linux-cpu-information/">here</a>.<br />
<br />
Nice discussion on the why's and wherefore's of processors, physical ids, and cores <a href="http://www.linuxforums.org/forum/red-hat-fedora-linux/155256-3-ways-tell-if-ht-enabled-without-going-through-bios-problems.html">here</a>.<br />
<h3>
Busy - Sluggish</h3>
Now that you have enabled <span style="font-family: "courier new" , "courier" , monospace;">make</span> to use all the available processors, be prepared for your system to get sluggish.<br />
<br />
On a build machine you want to build fast. On a development machine you want to do something else, but you just told <span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">make</span> to use all the available CPUs. Ctrl-C might not even be effective, for a while.<br />
<br />
Your mileage may vary. Forewarned is forearmed.<br />
<h3>
Number of Processors + 1</h3>
<div>
There are many discussions that state the value for the make argument -j should be the number of processors +1, even +2. The idea is that make (and compiling) is an I/O intensive activity. While waiting for one compile to finish, another can be prepared.</div>
<div>
<br /></div>
<div>
At this <a href="https://blogs.gentoo.org/ago/2013/01/14/makeopts-jcore-1-is-not-the-best-optimization/">URL</a>, Agostino Sarubbo, has shown that one should use the number of processors and no more.<br />
<br />
The reason for this would be a subject of a separate blog. Exercise for the reader. :)</div>
<div>
<h2>
References</h2>
</div>
<div>
All the in-line links listed in one place.</div>
<div>
<br /></div>
<div>
<a href="https://en.wikipedia.org/wiki/Hyper-threading">https://en.wikipedia.org/wiki/Hyper-threading</a></div>
<div>
<br /></div>
<div>
<a href="http://www.binarytides.com/linux-check-processor/">http://www.binarytides.com/linux-check-processor/</a></div>
<div>
<br /></div>
<div>
<a href="http://stackoverflow.com/questions/601970/how-do-i-utilise-all-the-cores-for-nmake">http://stackoverflow.com/questions/601970/how-do-i-utilise-all-the-cores-for-nmake</a></div>
<div>
<br /></div>
<div>
<a href="http://www.linuxforums.org/forum/red-hat-fedora-linux/155256-3-ways-tell-if-ht-enabled-without-going-through-bios-problems.html">http://www.linuxforums.org/forum/red-hat-fedora-linux/155256-3-ways-tell-if-ht-enabled-without-going-through-bios-problems.html</a></div>
<div>
<br /></div>
<div>
<a href="https://blogs.gentoo.org/ago/2013/01/14/makeopts-jcore-1-is-not-the-best-optimization/">https://blogs.gentoo.org/ago/2013/01/14/makeopts-jcore-1-is-not-the-best-optimization/</a></div>
<div>
<br /></div>
</div>
</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8192642777375146218.post-77153386350346229222015-08-27T21:43:00.000-04:002015-08-28T20:04:52.922-04:00IAR, Vybrid, Low Power Timer, and Getting Started ExampleThis is a short blog on a tiny issue I found working with the FreeScale Vybrid Tower evaluation board with the IAR IDE 'Getting Started' example.<br />
<br />
The Getting Started example has two interrupts, one for a periodic timer using the Lower Power Timer (0) and a hardware interrupt for a button, SW1.<br />
<br />
There are two IRQs, one for the timer, and one for the button.<br />
<br />
The button IRQ outputs the number of times the button has been pushed each time the button is pushed. The timer IRQ blinks a blue LED, off for 1/2 second and on for 1/2 second.<br />
<br />
I decided to tweak the example. I want to report the value of the timer counter when the button is pushed. I should see a value from 0 to 500, as the periodic timer is set to 1kHz.<br />
<br />
I used the existing IAR symbols, <span style="font-family: Courier New, Courier, monospace;">LPTMR0->CNR</span>, to read the timer counter.<br />
<br />
Each time I pushed the button the value for CNR was 0.<br />
<br />
The Low Power Timer documentation in the <a href="http://cache.freescale.com/files/32bit/doc/ref_manual/VYBRIDRM.pdf" target="_blank">FreeScale Vybrid reference manual</a>, pg. 1910-1913.<br />
<br />
On page 1913, 41.4.5 LPTMR Counter, it states<br />
<br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><i>The CNR cannot be initialized, but can be read at any time. On each read of the CNR,
software must first write to the CNR with any value. This will synchronize and register
the current value of the CNR into a temporary register. The contents of the temporary
register are returned on each read of the CNR.</i></span><br />
<br />
Thus one must first write to CNR, then read. The write does not change CNR, it just enables the timer counter to be latched into the CNR register when read.<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">LPTMR0->CNR = 1;</span><br />
<span style="font-family: Courier New, Courier, monospace;">printf("Timer: %d\n:, LPTMR0->CNR);</span><br />
<br />
Unfortunately, the first line of code gives a compiler error. The error states that CNR cannot be modified.<br />
<br />
The structure defined in the Getting Started example for the Vybrid tower that defines the LPTMR registers (<span style="font-family: Courier New, Courier, monospace;"><span style="background-color: white; color: #222222; font-size: 12.8000001907349px;">MVF50GS10MK50</span>.h</span>), CSR, PSR, CMR and CNR. The registers CSR, PSR, and CMR are defined <span style="font-family: Courier New, Courier, monospace;">_IO uint32_t</span>. <span style="font-family: Courier New, Courier, monospace;">_IO</span> means read/write.<br />
<br />
CNR is defined <span style="font-family: Courier New, Courier, monospace;">_I uint32_t</span> as read only. Wrong.<br />
<br />
The CNR definition must be changed to <span style="font-family: Courier New, Courier, monospace;">_IO uint32_t</span> in order to read CNR.<br />
<span style="font-family: Courier New, Courier, monospace;"><span style="background-color: white; color: #222222; font-size: 12.8000001907349px;"><br /></span></span>
<span style="font-family: Courier New, Courier, monospace;"><span style="background-color: white; color: #222222; font-size: 12.8000001907349px;">/** LPTMR - Register Layout Typedef */</span><br style="background-color: white; color: #222222; font-size: 12.8000001907349px;" /><span style="background-color: white; color: #222222; font-size: 12.8000001907349px;">typedef struct {</span><br style="background-color: white; color: #222222; font-size: 12.8000001907349px;" /><span style="background-color: white; color: #222222; font-size: 12.8000001907349px;"> __IO uint32_t CSR; /**< Low Power</span><br style="background-color: white; color: #222222; font-size: 12.8000001907349px;" /><span style="background-color: white; color: #222222; font-size: 12.8000001907349px;">Timer Control Status Register, offset: 0x0 */</span><br style="background-color: white; color: #222222; font-size: 12.8000001907349px;" /><span style="background-color: white; color: #222222; font-size: 12.8000001907349px;"> __IO uint32_t PSR; /**< Low Power</span><br style="background-color: white; color: #222222; font-size: 12.8000001907349px;" /><span style="background-color: white; color: #222222; font-size: 12.8000001907349px;">Timer Prescale Register, offset: 0x4 */</span><br style="background-color: white; color: #222222; font-size: 12.8000001907349px;" /><span style="background-color: white; color: #222222; font-size: 12.8000001907349px;"> __IO uint32_t CMR; /**< Low Power</span><br style="background-color: white; color: #222222; font-size: 12.8000001907349px;" /><span style="background-color: white; color: #222222; font-size: 12.8000001907349px;">Timer Compare Register, offset: 0x8 */</span><br style="background-color: white; color: #222222; font-size: 12.8000001907349px;" /><span style="background-color: white; color: #222222; font-size: 12.8000001907349px;"> </span><span style="background-color: white; font-size: 12.8000001907349px;"><span style="color: red;">__IO uint32_t CNR; </span></span><span style="background-color: white; color: #222222; font-size: 12.8000001907349px;"> /* </span></span><span style="background-color: white; color: red; font-family: 'Courier New', Courier, monospace; font-size: 12.8000001907349px;">__I uint32_t *</span><span style="font-family: Courier New, Courier, monospace;"><span style="background-color: white; font-size: 12.8000001907349px;"><span style="color: red;">/</span></span><span style="background-color: white; color: #222222; font-size: 12.8000001907349px;"> /**< Low Power</span><br style="background-color: white; color: #222222; font-size: 12.8000001907349px;" /><span style="background-color: white; color: #222222; font-size: 12.8000001907349px;">Timer Counter Register, offset: 0xC */</span><br style="background-color: white; color: #222222; font-size: 12.8000001907349px;" /><span style="background-color: white; color: #222222; font-size: 12.8000001907349px;">} LPTMR_Type;</span></span><br />
<div class="yj6qo ajU" style="background-color: white; color: #222222; cursor: pointer; font-size: 12.8000001907349px; outline: none; padding: 10px 0px; width: 22px;">
</div>
<br />
<br />
Oops.<br />
<br />
As I said, a tiny issue.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8192642777375146218.post-11848242327157327732015-08-20T22:03:00.000-04:002019-09-11T20:27:22.441-04:00Yet Another Make Tutorial - VILast post we created a framework to build a library, a unit test program, and a production program. Let's make a few changes to introduce the building of a library.<br />
<br />
[This is a continuation of posts <a href="http://fernleaf07.blogspot.com/2015/07/yet-another-make-tutorial.html" target="_blank">I</a>, <a href="http://fernleaf07.blogspot.com/2015/07/yet-another-makefile-tutorial-part-ii.html" target="_blank">II</a>, and <a href="http://fernleaf07.blogspot.com/2015/08/yet-another-make-tutorial-iii.html" target="_blank">III</a>, <a href="http://fernleaf07.blogspot.com/2015/08/yet-another-makefile-tutorial-iv.html" target="_blank">IV</a>, and <a href="http://fernleaf07.blogspot.com/2015/08/yet-another-make-file-tutorial-v.html" target="_blank">V</a>. Make files are found <a href="https://bitbucket.org/FernLeaf_07/makefiletutorial" target="_blank">here</a>.]<br />
<br />
<span style="font-family: inherit;">Building a library requires a different program than </span><span style="font-family: "courier new" , "courier" , monospace;">clang</span><span style="font-family: inherit;">, </span><span style="font-family: "courier new" , "courier" , monospace;">clang++</span><span style="font-family: inherit;">, </span><span style="font-family: "courier new" , "courier" , monospace;">gcc</span><span style="font-family: inherit;">, or </span><span style="font-family: "courier new" , "courier" , monospace;">g++</span><span style="font-family: inherit;">. The program is called </span><span style="font-family: "courier new" , "courier" , monospace;">ar</span><span style="font-family: inherit;">, for archive.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">The standard arguments are:</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">ar rvf <libraryname>.a <object files></span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Note: </span><span style="font-family: "courier new" , "courier" , monospace;">gcc (clang)</span><span style="font-family: inherit;"> requires, when using the </span><span style="font-family: "courier new" , "courier" , monospace;">-l</span><span style="font-family: inherit;"> switch to build a program, that the library name starts with the three letters </span><span style="font-family: "courier new" , "courier" , monospace;">lib</span><span style="font-family: inherit;">, and the three letters </span><span style="font-family: "courier new" , "courier" , monospace;">lib</span><span style="font-family: inherit;"> are not supplied with the </span><span style="font-family: "courier new" , "courier" , monospace;">-l</span><span style="font-family: inherit;"> switch. The </span><span style="font-family: "courier new" , "courier" , monospace;">.a</span><span style="font-family: inherit;"> extension is also assumed.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">For example:</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"># Create libmylibrary.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">ar rvf libmylibrary.a iseven.o isnumber.o</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">#Use libmylibrary.a with gcc</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">gcc -o aprogram -lmylibrary</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">The </span><span style="font-family: "courier new" , "courier" , monospace;">ar</span><span style="font-family: inherit;"> program will be used for our </span><span style="font-family: "courier new" , "courier" , monospace;">$(TARGET): $(OBJS_C) $(OBJS_CXX) </span><span style="font-family: inherit;">command in our make file in the </span><span style="font-family: "courier new" , "courier" , monospace;">lib</span><span style="font-family: inherit;"> directory.</span><br />
<br />
<span style="font-family: inherit;">The </span><span style="font-family: "courier new" , "courier" , monospace;">$(TARGET): $(OBJS_C) $(OBJS_CXX)</span><span style="font-family: inherit;"> command in the </span><span style="font-family: "courier new" , "courier" , monospace;">target</span><span style="font-family: inherit;"> and </span><span style="font-family: "courier new" , "courier" , monospace;">unitest</span><span style="font-family: inherit;"> directories will have have </span><span style="font-family: "courier new" , "courier" , monospace;">-lmylibrary</span><span style="font-family: inherit;"> added.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">In addition, </span><span style="font-family: "courier new" , "courier" , monospace;">gcc</span><span style="font-family: inherit;"> (or </span><span style="font-family: "courier new" , "courier" , monospace;">clang</span><span style="font-family: inherit;">) needs to know the path to the library. That is supplied with the </span><span style="font-family: "courier new" , "courier" , monospace;">-L</span><span style="font-family: inherit;"> switch (uppercase L). </span><span style="font-family: "courier new" , "courier" , monospace;">-L../lib/target</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Duplicating two hard coded library names is not good coding practice.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">In addition, the dependency list has to have the library added.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">$(TARGET): $(OBJS_C) $(OBJS_CXX) ../lib/target/libmylibrary.a</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: inherit;">Now there are three hard coded locations for the library.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Let's solve this problem using make variables.</span><br />
<span style="font-family: inherit;"><br /></span>
One variable can hold the <span style="font-family: "courier new" , "courier" , monospace;">-L</span> path and one variable can hold the <span style="font-family: "courier new" , "courier" , monospace;">-l</span> library name.<br />
<br />
But we have a problem, if the variables are defined in the <span style="font-family: "courier new" , "courier" , monospace;">lib</span> directory make file, the variables are not seen by the <span style="font-family: "courier new" , "courier" , monospace;">unitest</span> and <span style="font-family: "courier new" , "courier" , monospace;">target</span> make files as the <span style="font-family: "courier new" , "courier" , monospace;">lib</span> make file is a child of the parent make file. Variables don't flow up from the child make files.<br />
<br />
If we define parts of the -L variable and the -l variable in the parent, pass them as variables to the child make file. We only change to the parent make file is the name of the library.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"># makefile17</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">LIB := lib</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">UNITEST := unitest</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">TARGET := target</span><br />
<span style="color: red; font-family: "courier new" , "courier" , monospace; font-size: x-small;">MYLIBRARY := mylibrary</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">.PHONY: all clean</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">all: build_unitest build_target</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">clean:</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> $(MAKE) -C $(TARGET) -f makefile17target clean</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> $(MAKE) -C $(UNITEST) -f makefile17unitest clean</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> $(MAKE) -C $(LIB) -f makefile17lib clean</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">build_target: build_lib </span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> $(MAKE) -C $(TARGET) -f makefile17target <span style="color: red;">LIBRARY=$(MYLIBRARY) LIBDIR=$(LIB)</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">build_unitest: build_lib</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> $(MAKE) -C $(UNITEST) -f makefile17unitest <span style="color: red;">LIBRARY=$(MYLIBRARY) LIBDIR=$(LIB)</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">build_lib:</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> $(MAKE) -C $(LIB) -f makefile17lib <span style="color: red;">LIBRARY=$(MYLIBRARY)</span></span><br />
<div>
<br /></div>
<br />
We've added the variable <span style="font-family: "courier new" , "courier" , monospace;">MYLIBRARY</span><span style="font-family: inherit;">. </span>We have added arguments to the make commands.<br />
<br />
The argument of the form<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><name>=<string></span><br />
<br />
defines <span style="font-family: "courier new" , "courier" , monospace;"><name></span> as a variable with the contents of <span style="font-family: "courier new" , "courier" , monospace;"><string></span>. <span style="font-family: "courier new" , "courier" , monospace;"><name></span> is a variable that is then available when make is run.<br />
<br />
For the build_lib target, <span style="font-family: "courier new" , "courier" , monospace;">makefile17lib</span> will have LIBRARY defined as <span style="font-family: "courier new" , "courier" , monospace;">mylibrary</span>.<br />
<br />
We will have a convention in directory names. The directory under <span style="font-family: "courier new" , "courier" , monospace;">lib</span> where <span style="font-family: "courier new" , "courier" , monospace;">libmylibrary.a</span> will be built is <span style="font-family: "courier new" , "courier" , monospace;">target</span>. Yes, it is hard coded. A variable could be created, LIB_DIR_TARGET, but <span style="font-family: "courier new" , "courier" , monospace;">target</span> will be fine for this tutorial.<br />
<br />
Below are the other Make16 make files updated to use the new arguments. [Not complete makexx17 files]<br />
<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"># Makefile17lib</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"># Build the library</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">LIB_NAME := lib$(LIBRARY).a</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">TARGET_DIR := target</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">all: $(TARGET_DIR)/$(LIB_NAME)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">$(TARGET_DIR)/$(LIB_NAME) :</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>mkdir -p $(TARGET_DIR)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>cd $(TARGET_DIR)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>touch $(TARGET_DIR)/$(LIB_NAME)</span><br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"># makefile17unitest</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">LIB_NAME := lib$(LIBRARY).a</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">all: unitest</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">unitest: ../$(LIBDIR)/target/$(LIB_NAME)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>echo Build unitest</span></div>
</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"># makefile17target</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"># Build the target program</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">LIB_NAME := lib$(LIBRARY).a</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">all: aprogram</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">aprogram: ../$(LIBDIR)/target/$(LIB_NAME)</span></div>
</div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>echo Build target</span></div>
</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
The make files still don't do much, but the framework is coming into shape. We parameterized the library name.</div>
<div>
<br /></div>
<div>
Next post is to add some code. Add the make file commands from makefile15 to build a library, a unit test, and a program.<br />
<br />
Next blog <a href="http://fernleaf07.blogspot.com/2015/08/yet-another-makefile-tutorial-vii.html" target="_blank">VII</a>.</div>
<div>
<br /></div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8192642777375146218.post-25635489826687904152015-08-15T14:29:00.000-04:002019-09-02T13:09:50.417-04:00Yet Another Make File Tutorial - VThe past four tutorials, <a href="http://fernleaf07.blogspot.com/2015/07/yet-another-make-tutorial.html" target="_blank">I</a>, <a href="http://fernleaf07.blogspot.com/2015/07/yet-another-makefile-tutorial-part-ii.html" target="_blank">II</a>, and <a href="http://fernleaf07.blogspot.com/2015/08/yet-another-make-tutorial-iii.html" target="_blank">III</a>, and <a href="http://fernleaf07.blogspot.com/2015/08/yet-another-makefile-tutorial-iv.html" target="_blank">IV</a> have created a good make file for a sub-directory of sources and kept the build directories clean and neat, as well as configure make to run a bit faster.<br />
<br />
[Again the source for these tutorials is found <a href="https://bitbucket.org/FernLeaf_07/makefiletutorial" target="_blank">here</a>.]<br />
<br />
Note: These make files are NOT POSIX compliant.<br />
<br />
These next tutorial(s) will build a production quality set of make files that handle libraries, unit tests, and the production program. There will be more discussion about compilers, linkers, unit tests, libraries as well as make files. Using make files also solves the requirement of having one button builds for build tools such a Jenkins. These next tutorials will set up a framework for production and unit test programs.<br />
<br />
Unit tests are the sanity checkers for programmers. They make you feel good because they prove that you haven't messed up with your last set of changes. But building unit tests and that program you want to ship for $$s with the same code takes some planning.<br />
<br />
A unit test program has a <span style="font-family: "courier new" , "courier" , monospace;">main()</span>. Your program has a <span style="font-family: "courier new" , "courier" , monospace;">main()</span>. You can't have two <span style="font-family: "courier new" , "courier" , monospace;">main()</span><span style="font-family: inherit;"> functions</span> in the same program.<br />
<br />
Solution: A library or libraries for your code that isn't <span style="font-family: "courier new" , "courier" , monospace;">main()</span><span style="font-family: inherit;">. E</span>ach library gets a directory. Each unit test gets a directory, and the production program gets a directory. Thus three directories, <span style="font-family: "courier new" , "courier" , monospace;">lib</span>, <span style="font-family: "courier new" , "courier" , monospace;">unitest</span>, and <span style="font-family: "courier new" , "courier" , monospace;">target</span>.<br />
<br />
Each directory will need a make file. A master make file is required to 'run' each of the other make files.<br />
<br />
This tutorial will introduce new make syntax and features.<br />
<br />
Our first make file is not a make file that compiles code. It calls other make files. Some of the more experienced readers will see we are starting down the path to make file recursion, where make calls make.<br />
<br />
There is an article detailing this topic <a href="http://aegis.sourceforge.net/auug97.pdf" target="_blank">here</a>. The argument is to create a single make file instead of series of recursively called make files.<br />
<br />
Let's start.<br />
<br />
The new directory <span style="font-family: "courier new" , "courier" , monospace;">Make16</span> is where we start.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"># makefile16</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">LIB := lib</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">UNITEST := unitest</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">TARGET := target</span><br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">all: build_unitest build_target</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>$(MAKE) -C $(TARGET) -f makefile16target clean</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>$(MAKE) -C $(UNITEST) -f makefile16unitest clean</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>$(MAKE) -C $(LIB) -f makefile16lib clean</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">build_target: build_lib </span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>$(MAKE) -C $(TARGET) -f makefile16target</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">build_unitest: build_lib</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>$(MAKE) -C $(UNITEST) -f makefile16unitest</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">build_lib:</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>$(MAKE) -C $(LIB) -f makefile16lib </span><br />
<div>
<br /></div>
<span style="font-family: inherit;">[Links for more details <a href="http://stackoverflow.com/questions/3494999/subdirectories-and-makefiles" target="_blank">here</a>.]</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">The </span><span style="font-family: "courier new" , "courier" , monospace;">-C</span><span style="font-family: inherit;"> switch changes the working directory to the next argument. When using -C the option -w is automatically turned on. The -w option outputs </span><span style="font-family: "courier new" , "courier" , monospace;">Entering <directory></span><span style="font-family: inherit;"> and </span><span style="font-family: "courier new" , "courier" , monospace;">Leaving <directory></span><span style="font-family: inherit;">. This helps with debugging.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">The </span><span style="font-family: "courier new" , "courier" , monospace;">$(MAKE)</span><span style="font-family: inherit;"> variable is a special variable of the Gnu Make. As has been said before, this tutorial is NOT writing POSIX make files.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">The make files for </span><span style="font-family: "courier new" , "courier" , monospace;">lib</span><span style="font-family: inherit;">, </span><span style="font-family: "courier new" , "courier" , monospace;">unitest</span><span style="font-family: inherit;">, and </span><span style="font-family: "courier new" , "courier" , monospace;">target</span><span style="font-family: inherit;"> are below. These are just shells. The make files have no source code. </span><span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;"> still outputs its messages. There are no errors and the framework is shown correct.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"># Makefile16lib</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"># Build the library</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">all: alibrary</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<br />
<span style="font-family: "courier new" , "courier" , monospace;">alibrary:</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">================</span><br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"># makefile16unitest</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">all: unitest</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">unitest:</span></div>
</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">===============</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"># makefile16target</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"># Build the target program</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">all: aprogram</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">aprogram:</span></div>
</div>
<div>
<br /></div>
<div>
<br /></div>
<span style="font-family: inherit;">To run enter</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">make -f makefile16</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">or</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">make -f makefile16 clean</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<span style="font-family: inherit;">If you don't want all of the </span><span style="font-family: "courier new" , "courier" , monospace;">Entering</span><span style="font-family: inherit;"> and </span><span style="font-family: "courier new" , "courier" , monospace;">Leaving</span><span style="font-family: inherit;"> messages, add the </span><span style="font-family: "courier new" , "courier" , monospace;">-s</span><span style="font-family: inherit;"> switch.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">make -s -f </span><span style="font-family: "courier new" , "courier" , monospace;">makefile16</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: inherit;">No output appears.</span><br />
<br />
Next blog we'll add more details about the library. <a href="http://fernleaf07.blogspot.com/2015/08/yet-another-makefile-tutorial-vi.html" target="_blank">VI</a>.<br />
<br />
<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8192642777375146218.post-31613654173741102182015-08-13T19:45:00.003-04:002015-09-05T22:08:34.876-04:00Yet Another Makefile Tutorial - IVThe three previous tutorials on make files, <a href="http://fernleaf07.blogspot.com/2015/07/yet-another-make-tutorial.html" target="_blank">I</a>, <a href="http://fernleaf07.blogspot.com/2015/07/yet-another-makefile-tutorial-part-ii.html" target="_blank">II</a>, and <a href="http://fernleaf07.blogspot.com/2015/08/yet-another-make-tutorial-iii.html" target="_blank">III</a>, discussed the contents of a make file.<br />
<div>
<br /></div>
<div>
This tutorial will discuss the program <span style="font-family: Courier New, Courier, monospace;">make</span> itself, some switches, and internals to help with performance.</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">make</span> has a lot of built in defaults. The defaults can allow one to create a quick make file. No dependencies have to be created. The simple dependency patterns are already defined. For example.</div>
<div>
<br /></div>
<div>
A directory containing *.c files.</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">$(SRC_LIST) := $(wildcard *.c)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">$(OBJ_LIST) := <span style="background-color: #fff9ee; color: #222222; line-height: 21.5599994659424px;">$(</span>SRC_LIST<span style="background-color: #fff9ee; color: #222222; line-height: 21.5599994659424px;">:.c=.o)</span></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">aprogram : $(OBJ_LIST)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> </span><span style="background-color: #fff9ee; color: #222222; line-height: 21.5599994659424px;"><span style="font-family: Courier New, Courier, monospace;">gcc $^ -o $@</span></span></div>
<div>
<br /></div>
<div>
That's it. <span style="font-family: Courier New, Courier, monospace;">make</span> has default dependencies for <span style="font-family: Courier New, Courier, monospace;">%o:%c</span> and <span style="font-family: Courier New, Courier, monospace;">gcc</span>.</div>
<div>
<br /></div>
<div>
<span style="font-family: 'Courier New', Courier, monospace;">make --help</span></div>
<div>
<br /></div>
<div>
will show all the arguments supported by <span style="font-family: Courier New, Courier, monospace;">make</span>.</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">-d</span> Print a lot of debugging information.</div>
<div>
<br /></div>
<div>
The debugging referred to is about patterns and rules. It is not about variables. [You have to use $(info ...) for variables as discussed in <a href="http://fernleaf07.blogspot.com/2015/07/yet-another-makefile-tutorial-part-ii.html" target="_blank">II</a>.]</div>
<div>
<br /></div>
<div>
Create an empty make file and debug it.</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">touch makefile</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">make -d</span></div>
<div>
<br /></div>
<div>
A partial output from <span style="font-family: Courier New, Courier, monospace;">make</span> is below.</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GNU Make 3.82</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Built for x86_64-redhat-linux-gnu</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Copyright (C) 2010 Free Software Foundation, Inc.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">This is free software: you are free to change and redistribute it.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">There is NO WARRANTY, to the extent permitted by law.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Reading makefiles...</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Reading makefile `makefile'...</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Updating makefiles....</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Considering target file `makefile'.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Looking for an implicit rule for `makefile'.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Trying pattern rule with stem `makefile'.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Trying implicit prerequisite `makefile.o'.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Trying pattern rule with stem `makefile'.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Trying implicit prerequisite `makefile.c'.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Trying pattern rule with stem `makefile'.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Trying implicit prerequisite `makefile.cc'.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Trying pattern rule with stem `makefile'.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Trying implicit prerequisite `makefile.C'.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Trying pattern rule with stem `makefile'.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">. . . . . . . .</span></div>
</div>
<div>
<br /></div>
<div>
Examining the complete listing the following file extensions are found.</div>
<div>
<br /></div>
<div>
c, cc, C, o, cpp, p, f, F, m, r, s, S, mod, sh, v, y, l, and w.</div>
<div>
<br /></div>
<div>
There are many more implicit patterns and rules than one needs for a simple set of C or C++ files.</div>
<div>
<br /></div>
<div>
Processing all the implicit patterns does slowdown <span style="font-family: Courier New, Courier, monospace;">make</span>.</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">-r --no-builtin-rules</span> Disable built-in implicit rules.</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">make -d -r</span></div>
<div>
<br /></div>
<div>
The entire debug output is below.</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GNU Make 3.82</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Built for x86_64-redhat-linux-gnu</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Copyright (C) 2010 Free Software Foundation, Inc.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">This is free software: you are free to change and redistribute it.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">There is NO WARRANTY, to the extent permitted by law.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Reading makefiles...</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Reading makefile `makefile'...</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Updating makefiles....</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Considering target file `makefile'.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Looking for an implicit rule for `makefile'.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> No implicit rule found for `makefile'.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> Finished prerequisites of target file `makefile'.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"> No need to remake target `makefile'.</span></div>
</div>
<div>
<br /></div>
<div>
Let's go back to the <span style="font-family: Courier New, Courier, monospace;">Make15</span> directory and use <span style="font-family: Courier New, Courier, monospace;">-d</span> and <span style="font-family: Courier New, Courier, monospace;">-r</span>.</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">make -d -f makefile15</span></div>
<div>
<br /></div>
<div>
2689 lines of output for 4 files!</div>
<div>
<br /></div>
<div>
Now</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">make -d -r -f makefile15</span></div>
<div>
<br /></div>
<div>
Only 152 lines of output.</div>
<div>
<br /></div>
<div>
For a project with just 4 files, the difference between using <span style="font-family: Courier New, Courier, monospace;">-r</span> and not using it is probably isn't noticeable, but with a large project using only one or two patterns, <span style="font-family: Courier New, Courier, monospace;">-r</span> can save time.</div>
<div>
<br /></div>
<div>
There is a pseudo target that has a similar feature as <span style="font-family: Courier New, Courier, monospace;">-r</span>, <span style="font-family: Courier New, Courier, monospace;">.SUFFIXES:</span></div>
<div>
<br /></div>
<div>
Create a make file with just <span style="font-family: Georgia, Times New Roman, serif;">.SUFFIXES:</span></div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">echo .SUFFIXES: > makefile</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">makefile -d</span></div>
<div>
<br /></div>
<div>
Similar short output, but not as short as <span style="font-family: Courier New, Courier, monospace;">-r</span>.</div>
<div>
<br /></div>
<div>
Two methods of saving time with make, <span style="font-family: Courier New, Courier, monospace;">-r</span> or <span style="font-family: Courier New, Courier, monospace;">.SUFFIXES:</span></div>
<div>
<br /></div>
<div>
Saving time is what <span style="font-family: Courier New, Courier, monospace;">make</span> is all about.</div>
<div>
<br /></div>
<div>
A page discussing many of the implicit rules.</div>
<div>
https://www.gnu.org/software/make/manual/html_node/Catalogue-of-Rules.html<br />
<br />
Next post on make files is here, <a href="http://fernleaf07.blogspot.com/2015/08/yet-another-make-file-tutorial-v.html" target="_blank">V</a>.<br />
<br />
-----------------------------------</div>
<div>
<br /></div>
<div>
P.S. Is there a way to find out ALL the implicit rules and patterns?</div>
<div>
<br /></div>
<div>
Try</div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">make-p</span></div>
<div>
<br /></div>
<div>
http://stackoverflow.com/questions/16842930/why-does-gnu-make-define-implicit-pattern-and-implicit-suffix-rules</div>
<div>
<br /></div>
<div>
More details on .SUFFIXES:</div>
<div>
<br /></div>
<div>
https://www.gnu.org/software/make/manual/html_node/Suffix-Rules.html</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8192642777375146218.post-33219488639425976152015-08-11T22:43:00.001-04:002019-09-02T13:05:00.263-04:00Yet Another Make Tutorial - IIIIn the first <a href="http://fernleaf07.blogspot.com/2015/07/yet-another-make-tutorial.html" target="_blank">Yet Another Make Tutorial</a> a simple make file, <span style="font-family: "courier new" , "courier" , monospace;">makefile10a</span>, was created to handle the organization of a parent directory, a source directory and an include directory. <a href="http://fernleaf07.blogspot.com/2015/07/yet-another-makefile-tutorial-part-ii.html" target="_blank">Yet Another Make Tutorial - II</a> updated <span style="font-family: "courier new" , "courier" , monospace;">makefile10a</span> to include sub-directories in the source directory, <span style="font-family: "courier new" , "courier" , monospace;">makefile13</span><span style="font-family: inherit;">, and</span> <span style="font-family: "courier new" , "courier" , monospace;">makefile14</span>.<br />
<br />
All files are found in a BitBucket archive <a href="https://bitbucket.org/FernLeaf_07/makefiletutorial" target="_blank">here</a>.<br />
<br />
Both make files 13 and 14 dealt with only one source file extension <span style="font-family: "courier new" , "courier" , monospace;">*.c</span> and only one compiler <span style="font-family: "courier new" , "courier" , monospace;">gcc</span>.<br />
<br />
Here we are going to expand to add C++ source files and <span style="font-family: "courier new" , "courier" , monospace;">clang</span>.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">clang</span> is the up and coming compiler that is replacing <span style="font-family: "courier new" , "courier" , monospace;">gcc</span><span style="font-family: inherit;">, part of the LLVM project.</span><span style="font-family: "courier new" , "courier" , monospace;"> clang.llvm.org.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: inherit;">Pre-built images are available for Windows and Linux.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">In </span><span style="font-family: "courier new" , "courier" , monospace;">makefile13</span><span style="font-family: inherit;">, the source files were selected by the statement</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">SRC_LIST := $(shell find $(SRC_DIR) -name "*.c" -type f)</span><br />
<div>
<br /></div>
<div>
<span style="font-family: inherit;">If we want to use this make file for both C and C++ files changes need to be made.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">Typically the compiler options used for building C files are not the same as those used for C++ files, in fact </span><span style="font-family: "courier new" , "courier" , monospace;">gcc</span><span style="font-family: inherit;"> is used for C files and linkage, where </span><span style="font-family: "courier new" , "courier" , monospace;">g++</span><span style="font-family: inherit;"> is used for C++ files.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">We will need a second set of variables to handle C++ files.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">We will also create a set of mixed source files, </span><span style="font-family: "courier new" , "courier" , monospace;">main.cpp</span><span style="font-family: inherit;">, </span><span style="font-family: "courier new" , "courier" , monospace;">suba.cpp</span><span style="font-family: inherit;">, </span><span style="font-family: "courier new" , "courier" , monospace;">subc.c</span><span style="font-family: inherit;">, and </span><span style="font-family: "courier new" , "courier" , monospace;">subd.c</span><span style="font-family: inherit;">.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">These new files are found in the folder </span><span style="font-family: "courier new" , "courier" , monospace;">Make15</span><span style="font-family: inherit;"> of the BitBucket <a href="https://bitbucket.org/FernLeaf_07/makefiletutorial" target="_blank">repository</a>.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">Something that has been missing from the tutorials is the standard variable names used for the compiler, CC and CXX.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">Let's add the CC variable, used to define the C compiler and CXX to define the C++ compiler. The default for make is </span><span style="font-family: "courier new" , "courier" , monospace;">cc</span><span style="font-family: inherit;"> for the C compiler and </span><span style="font-family: "courier new" , "courier" , monospace;">g++</span><span style="font-family: inherit;"> for the C++ compiler. We will define both just to be clear.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">CC = gcc</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">CXX = g++</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">Now add the new set of variables for the C++ source files and objects. The C and C++ source files will be mixed together in the same source tree.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">SRC_LIST_CXX := $(shell find $(SRC_DIR) -name "*.cpp" -type f)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">SRC_DIR_LIST_CXX := $(patsubst %/,%,$(sort $(dir $(SRC_LIST_CXX))))</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">OBJS_CXX := $(patsubst %.cpp,$(OBJ_DIR)/%.o,$(notdir $(SRC_LIST_CXX)))</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">DEPS_CXX := $(OBJS_CXX:.o=.d)</span></div>
<div style="font-family: inherit;">
<br /></div>
</div>
<div>
<span style="font-family: inherit;">Remember to tell make where to find the </span><span style="font-family: "georgia" , "times new roman" , serif;">*.cpp</span><span style="font-family: inherit;"> files via </span><span style="font-family: "courier new" , "courier" , monospace;">vpath</span><span style="font-family: inherit;">.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">vpath %.cpp $(SRC_DIR_LIST_CPP)</span></div>
<div style="font-family: inherit;">
<br /></div>
</div>
<div style="font-family: inherit;">
<br /></div>
<div>
<span style="font-family: inherit;">These updates result in </span><span style="font-family: "courier new" , "courier" , monospace;">makefile15</span><span style="font-family: inherit;">.</span></div>
<div style="font-family: inherit;">
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">#makefile<span style="color: red;">15</span></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">SRC_DIR := src</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">OBJ_DIR := obj</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">INC_DIR := inc</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">SRC_LIST_C := $(shell find $(SRC_DIR) -name "*.c" -type f)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">SRC_DIR_LIST_C := $(patsubst %/,%,$(sort $(dir $(SRC_LIST_C))))</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">OBJS_C := $(patsubst %.c,$(OBJ_DIR)/%.o,$(notdir $(SRC_LIST_C)))</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">DEPS_C := $(OBJS_C:.o=.d)</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace; font-size: x-small;">SRC_LIST_CXX := $(shell find $(SRC_DIR) -name "*.cpp" -type f)</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace; font-size: x-small;">SRC_DIR_LIST_CXX := $(patsubst %/,%,$(sort $(dir $(SRC_LIST_CXX))))</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace; font-size: x-small;">OBJS_CXX := $(patsubst %.cpp,$(OBJ_DIR)/%.o,$(notdir $(SRC_LIST_CXX)))</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace; font-size: x-small;">DEPS_CXX := $(OBJS_CXX:.o=.d)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">TARGET_DIR := target</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">TARGET := $(TARGET_DIR)/aprogram</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">vpath %.c $(SRC_DIR_LIST_C)</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace; font-size: x-small;">vpath %.cpp $(SRC_DIR_LIST_CXX)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">.PHONY: all clean</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace; font-size: x-small;">CC = gcc</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace; font-size: x-small;">CXX = g++</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">all: $(TARGET)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">clean:</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(OBJ_DIR)/*.o $(OBJ_DIR)/*.d</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(TARGET)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rmdir $(OBJ_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rmdir $(TARGET_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">$(TARGET): $(OBJS_C) <span style="color: red;">$(OBJS_CXX)</span></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc <span style="color: red;">-lstdc++ </span>$^ -o $@</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">$(OBJ_DIR)/%.o: %.c</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>$(CC) -c -MMD -I $(INC_DIR) $< -o $@</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace; font-size: x-small;">$(OBJ_DIR)/%.o: %.cpp</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>$(CXX) -c -MMD -I $(INC_DIR) $< -o $@</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">REQUIRED_DIRS := $(OBJ_DIR) $(TARGET_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">_MKDIRS := $(shell for d in $(REQUIRED_DIRS); \</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> do \</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> mkdir -p $$d; \</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"> done)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">-include $(DEPS_C)</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace; font-size: x-small;">-include $(DEPS_CXX)</span></div>
<div style="font-family: inherit;">
<br /></div>
</div>
<div>
<span style="font-family: inherit;">Let's review each of the updates.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">The new C++ variables have been discussed above.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">The new </span><span style="font-family: "courier new" , "courier" , monospace;">vpath</span><span style="font-family: inherit;"> statement has been discussed above.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">The new </span><span style="font-family: "courier new" , "courier" , monospace;">CC</span><span style="font-family: inherit;"> and </span><span style="font-family: "courier new" , "courier" , monospace;">CXX</span><span style="font-family: inherit;"> variables have been discussed above.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;">$(TARGET): $(OBJS_C) <span style="color: red;">$(OBJS_CXX)</span></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc $^ -o $@</span></div>
</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: inherit;">The linkage statement adds </span><span style="font-family: "courier new" , "courier" , monospace;">$(OBJS_CXX)</span><span style="font-family: inherit;">. This makes </span><span style="font-family: "courier new" , "courier" , monospace;">$(TARGET)</span><span style="font-family: inherit;"> dependent on the C++ object files as well as the C object files.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace; font-size: x-small;">$(OBJ_DIR)/%.o: %.cpp</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace; font-size: x-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>$(CXX) -c -MMD -I $(INC_DIR) $< -o $@</span></div>
</div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: inherit;">The new dependent statement builds the C++ object files from the C++ sources, specifically </span><span style="font-family: "courier new" , "courier" , monospace;">*.cpp</span><span style="font-family: inherit;"> extensions.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="color: red; font-family: "courier new", courier, monospace; font-size: x-small;">-include $(DEPS_CXX)</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: inherit;">Finally, the second </span><span style="font-family: "courier new" , "courier" , monospace;">-include</span><span style="font-family: inherit;"> statement to add the </span><span style="font-family: "courier new" , "courier" , monospace;">*.d</span><span style="font-family: inherit;"> dependencies for C++ files.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">[Note: To update to use </span><span style="font-family: "courier new" , "courier" , monospace;">*.cc</span><span style="font-family: inherit;"> or </span><span style="font-family: "courier new" , "courier" , monospace;">*.cxx</span><span style="font-family: inherit;"> extensions one can changes the 'find' statement for </span><span style="font-family: "courier new" , "courier" , monospace;">SRC_LIST_CXX</span><span style="font-family: inherit;"> and the <span style="font-family: inherit;">OBJ_DIR</span> dependency.</span><span style="font-family: inherit;">]</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">If more than one extension is used, two sets of code mixed together, one can add an additional </span><span style="font-family: "courier new" , "courier" , monospace;">-name</span><span style="font-family: inherit;"> argument using the </span><span style="font-family: "courier new" , "courier" , monospace;">-o</span><span style="font-family: inherit;">, the or operator.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace; font-size: x-small;">SRC_LIST_CXX := $(shell find $(SRC_DIR)</span><span style="color: red; font-family: "courier new" , "courier" , monospace; font-size: x-small;">-type f</span><span style="color: red; font-family: "courier new" , "courier" , monospace; font-size: x-small;"> -name "*.cpp" -o -name "*.cc" )</span></div>
</div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span></div>
<div>
<span style="font-family: inherit;">However, just adding </span><span style="font-family: "courier new" , "courier" , monospace;">-o -name "*.cc"</span><span style="font-family: inherit;"> is not all that is required to handle multiple extensions. Another post will go into the details. Note that a new pattern, another vpath, and the OBJS need updating.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Now lets change to use </span><span style="font-family: "courier new" , "courier" , monospace;">clang</span><span style="font-family: inherit;">. Simple. Update </span><span style="font-family: "courier new" , "courier" , monospace;">CC</span><span style="font-family: inherit;"> and </span><span style="font-family: "courier new" , "courier" , monospace;">CXX</span><span style="font-family: inherit;">.</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;">CC = clang</span></div>
<div>
</div>
<br />
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;">CXX = clang++</span></div>
</div>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Both C and C++ files are handled by </span><span style="font-family: "courier new" , "courier" , monospace;">clang</span><span style="font-family: inherit;">.</span><br />
<span style="font-family: inherit;"><br /></span><span style="font-family: inherit;">Another step forward to more make know how.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Next blog on make performance, <a href="http://fernleaf07.blogspot.com/2015/08/yet-another-makefile-tutorial-iv.html" target="_blank">IV</a>.</span><br />
<span style="font-family: inherit;"><br /></span></div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8192642777375146218.post-84494969901727974822015-07-27T19:55:00.002-04:002018-03-05T18:27:31.240-05:00Using GDB with a target processor that does not have hardware breakpoints.--This is an expansion of a previous blog <a href="http://fernleaf07.blogspot.com/2013/08/augment-gdb-with-convenience-variables.html" target="_blank">GDB and Symbol Tables</a>.--<br />
<br />
GNU Debugger, GDB is one of the most popular debuggers today.<br />
<br />
It has a lot of features. One of those features that doesn't have a lot discussion are the convenience variables and user-defined commands.<br />
<br />
I work with firmware. GDB can be used with processors that are not the host processor where you write and compile your code. However, additional GDB commands must be used to provide this feature.<br />
<br />
I found a very good use for both of these neglected features when working on firmware on legacy (old) hardware.<br />
<br />
<h2>
Motorla 68000</h2>
Microprocessors today support hardware breakpoints. The microprocessor provides these breakpoints as part of its structure, no additional support or tools required, JTAG enabled and all that rot.<br />
<br />
But what happens when you have to work with legacy devices. The Motorola 68000 series microprocessor is such an example.<br />
<br />
When the M68K was first introduced, the tool to use was an ICE, In-Circuit Emulator. A large connector, the same as the CPU, was inserted into the circuit board instead of the M68K, and an M68K was placed on top of this connector. The ICE device then controlled ALL the pins of the M68K. The ICE also had RAM that mirrored the memory space on the circuit board. In essence, a complete clone.<br />
<br />
ICEs were expensive. One could still use an ICE today, if you can find one, and it is still working. :)<br />
<br />
A simpler method was developed for the M68K, and later families of Motorola processors (today Freescale), BDM, Background Debug Mode.<br />
<br />
BDM is a serial bus dedicated to debugging supported by a simple header.<br />
<br />
Using BDM, one can read and write registers, read and write RAM, read from ROM and reflash programs, but it has very limited instruction debugging. This makes debugging complex programs difficult. BDM was a predecessor to JTAG.<br />
<br />
Enter the convenience variables and user-defined commands.<br />
<br />
<h2>
GDB Server</h2>
To use GDB with any target hardware, one needs a GDB server to translate the GDB commands to those supported by the target hardware, along with sending the commands over a wire from the host to the target and back.<br />
<br />
This is done in two ways, one is with a software GDB server, and one is with a hardware GDB server. With a software GDB server, a GDB server program is run on the host and it talks to the target via dedicated hardware. With a hardware GDB server, there is a hardware device that communicates with host, via Ethernet or RS-232 and has a built-in GDB server as well as its own set of commands. No software running on the host.<br />
<br />
With either choice, you must inform GDB where the GDB server is located.<br />
<h2>
.GDBINIT</h2>
<span style="font-family: "courier new" , "courier" , monospace;">.gdbinit</span> is the default file that GDB reads before it starts debugging your program. If the file doesn't exist, GDB doesn't complain about the missing file, but GDB won't talk to the hardware where you want to debug your program.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">.gdbinit</span> is a file that establishes the environment you want GDB to use with the target. You specify the DDR memory register values. You specify valid memory address ranges. You specify chip selects, etc. Anything that needs to be specified to be able to read and write to registers and memory of the target hardware.<br />
<br />
Your program does all this, but GDB needs to talk to the hardware before your program starts.<br />
<br />
In addition to configuring the remote target hardware, GDB needs to know where the hardware is.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">target remote 192.168.0.10</span><br />
<br />
This would be a typical command line added to <span style="font-family: "courier new" , "courier" , monospace;">.gdbinit</span><span style="font-family: inherit;">, one of the first lines of the file.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">One does not have use the file name </span><span style="font-family: "courier new" , "courier" , monospace;">.gdbinit</span><span style="font-family: inherit;">. The command switch </span><span style="font-family: "courier new" , "courier" , monospace;">-x <filename></span><span style="font-family: inherit;"> can be used to specify a file other than </span><span style="font-family: "courier new" , "courier" , monospace;">.gdbinit</span><span style="font-family: inherit;">. On Linux systems, </span><span style="font-family: "courier new" , "courier" , monospace;">.gdbinit</span><span style="font-family: inherit;"> will be a hidden file. On Windows systems it is sometimes difficult to create a file with a period. [Notepad++ helps with this.]</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<h2>
Abatron BDI2000</h2>
Abatron, of Switzerland, produced a device, BDI2000, that supports the Motorola BDM and the CPU32 family of Motorola processors.<br />
<br />
The Abatron BDI2000 is an example of a hardware GDB server.<br />
<br />
<a href="http://www.abatron.ch/fileadmin/user_upload/products/pdf/ManGDBCF-2000C.pdf" rel="nofollow">Abatron BDI2000 User's Manual</a><br />
<br />
[BTW, this device is no longer manufactured. Abatron has announced in 2015 that they will be closing their doors. There are several listings on eBay. ]<br />
<br />
The BDI2000 supports two native M68000 commands, <span style="font-family: "courier new" , "courier" , monospace;">ti</span> and <span style="font-family: "courier new" , "courier" , monospace;">tc</span>.<br />
<br />
<span style="font-family: inherit;">The </span><span style="font-family: "courier new" , "courier" , monospace;">ti</span> command steps to the next machine instruction.<br />
<br />
<span style="font-family: inherit;">The </span><span style="font-family: "courier new" , "courier" , monospace;">tc</span> command runs until there is a change in the flow of instructions. Essentially stop when there is a jump instruction.<br />
<br />
The BDI2000 does not disassemble machine instructions. We use GDB to perform this task.<br />
<br />
The Motorola 68332 starts at location 0. The first 32-bit value is top of the stack. The second 32-bit value is the address of the first instruction.<br />
<br />
Upon 'reset' using the BDI2000, the 68332 program counter is at location 0x4.<br />
<div>
<br /></div>
How does one debug code written for this hardware?<br />
<br />
How does one use GDB with such hardware?<br />
<br />
You say "Can't you just use software breakpoints?". Yes, if the program is running out of RAM. If the program runs out of flash or EEProm, software breakpoints are not possible. A software break point requires the modification of the break location to replace the desired instruction with a BREAK interrupt instruction. Flash does not allow this substitution.<br />
<br />
An alternative is to substitute a RAM chip for the Flash chip and download the program with each power on.<br />
<br />
But let's say we don't want to change the hardware. We need to test and debug it the way it is.<br />
<br />
Today with C/C++ compilers debugging in assembly is only for the most hard core programmers or difficult hardware bugs.<br />
<br />
<h2>
Convenience Variables and User-Defined Commands</h2>
Using convenience variables and user-defined commands, we are going to create break point commands, break on memory change, and other commands.<br />
<br />
The GDB command that allows access to the native BDI2000 commands is <span style="font-family: "courier new" , "courier" , monospace;">monitor</span> or <span style="font-family: "courier new" , "courier" , monospace;">mon</span> for short.<br />
<br />
To list the M68K registers, enter<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"> mon rd</span><br />
<br />
GDB has the equivalent<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">info reg</span><br />
<br />
But <span style="font-family: "courier new" , "courier" , monospace;">mon rd</span> has a very compact presentation. GDB presents each register on a separate line.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">mon reset</span> will perform a soft reset of the CPU.<br />
<br />
The BDI2000 converts the GDB command <span style="font-family: "courier new" , "courier" , monospace;">si</span> into <span style="font-family: "courier new" , "courier" , monospace;">ti</span> and the <span style="font-family: "courier new" , "courier" , monospace;">ni</span> into <span style="font-family: "courier new" , "courier" , monospace;">ti</span>. The normal <span style="font-family: "courier new" , "courier" , monospace;">n</span> and <span style="font-family: "georgia" , "times new roman" , serif;">s</span> commands do not work as they expect native hardware breakpoints or software breakpoints.<br />
<br />
We will simulate <span style="font-family: "courier new" , "courier" , monospace;">s</span> and <span style="font-family: "courier new" , "courier" , monospace;">n</span> with user-defined commands. The user-defined commands are added to <span style="font-family: "courier new" , "courier" , monospace;">.gdbinit</span>.<br />
<br />
<h2>
User-Define Commands</h2>
<div>
The format of a user-defined command is</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">define </span><command></div>
<div>
<body of command></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">end</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">document </span><command></div>
<div>
<documentation></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">end</span></div>
<div>
<br /></div>
The documentation written with the command is echoed when you type the GDB command <span style="font-family: "courier new" , "courier" , monospace;">help <command>.</span><br />
All the user-defined commands are listed with the GDB command <span style="font-family: "courier new" , "courier" , monospace;">help user-defined.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<br />
<h2>
<span style="font-family: inherit;">Convenience Variables</span></h2>
<div>
<span style="font-family: inherit;">A convenience variable is defined as</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">set <variable> = <expression></span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<h2>
<span style="font-family: inherit;">Reset, Read, Info</span></h2>
<div>
Let's define three user-defined commands, <span style="font-family: "courier new" , "courier" , monospace;">mreset</span>, <span style="font-family: "courier new" , "courier" , monospace;">mrd</span>, and <span style="font-family: "courier new" , "courier" , monospace;">minfo</span>.</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">define mreset</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">mon reset</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">flushregs</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">end</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">document mreset</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">Send the BDI2000 command 'reset'</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">'flushregs' is required as GDB does not</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">know what 'mon reset' did to the target</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">end</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">define mrd</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">mon rd</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">end</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">document mrd</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">Send the BDI2000 command 'rd'. Reads better than 'info reg'</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">end</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">define minfo</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">mon info</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">end</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">document minfo</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">Send the BDI2000 command 'info'</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">end</span></div>
</div>
<div>
<br /></div>
<span style="font-family: "courier new" , "courier" , monospace;">mreset</span><span style="font-family: inherit;"> is a short cut for the two commands </span><span style="font-family: "courier new" , "courier" , monospace;">mon reset</span><span style="font-family: inherit;"> and </span><span style="font-family: "courier new" , "courier" , monospace;">flushregs</span><span style="font-family: inherit;">.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">User-defined commands are very useful to define repetitive commands.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">mrd</span><span style="font-family: inherit;"> is a repetitive command to use BDI2000 to output registers instead of GDB, as the output is more compact.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">minfo</span><span style="font-family: inherit;"> is again another short cut command.</span><br />
<br />
A more useful command is <span style="font-family: "courier new" , "courier" , monospace;">beefcore</span>.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">define beefcore</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> mon mm 0xe00000 0xdeadbeef 0x10000</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> mon mm 0xe10000 0xdeadbeef 0x10000</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> mon mm 0xe20000 0xdeadbeef 0x10000</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> mon mm 0xe30000 0xdeadbeef 0x10000</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> mon mm 0xe40000 0xdeadbeef 0x10000</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> mon mm 0xe50000 0xdeadbeef 0x10000</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> mon mm 0xe60000 0xdeadbeef 0x10000</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> mon mm 0xe70000 0xdeadbeef 0x10000</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">document beefcore</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">Fill RAM (0xe00000), 1MB, with 0xdeadbeef</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">end</span><br />
<div>
<br /></div>
Fills RAM with the same data, <span style="font-family: "courier new" , "courier" , monospace;">0xdeadbeef</span>.<br />
<br />
Now that we done the easy commands, let's build more complicated ones.<br />
<br />
<h2>
dxi</h2>
First let's make a short cut <span style="font-family: "courier new" , "courier" , monospace;">dxi</span>.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"># dxi</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"># dxi <count></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"># dxi <count> <startaddress></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">define dxi</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">if $argc == 2</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> x /$arg0i $arg1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">if $argc == 1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> x /$arg0i $pc</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">if $argc == 0</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> x /20i $pc</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">document dxi</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">Output $arg0 instructions from current PC</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">If $arg0 is not supplied, output 20 instructions</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">end</span><br />
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">#</span> starts a comment in <span style="font-family: "courier new" , "courier" , monospace;">.gdbinit</span>.</div>
<div>
<br /></div>
<div>
The user-defined command supports <span style="font-family: "courier new" , "courier" , monospace;">if/then/else</span> and <span style="font-family: "courier new" , "courier" , monospace;">while</span> constructs.</div>
<div>
<br /></div>
<div>
Just like a function, arguments can be passed to a user-defined command. <span style="font-family: "courier new" , "courier" , monospace;">$argc</span> is the variable with the number of arguments. Each argument is <span style="font-family: "courier new" , "courier" , monospace;">$arg</span>x where x is the argument number starting with zero.</div>
<div>
<br /></div>
<div>
The command <span style="font-family: "courier new" , "courier" , monospace;">dxi</span> has three forms,</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">dxi</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">dxi <number></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">dxi <number> <address></span></div>
<br />
<span style="font-family: "courier new" , "courier" , monospace;">$pc</span> is the built-in GDB variable for the current program counter.<br />
<br />
With no arguments, <span style="font-family: "courier new" , "courier" , monospace;">dni</span> executes the GDB command <span style="font-family: "courier new" , "courier" , monospace;">x /20i $pc</span><span style="font-family: inherit;">. Output 20 assembly instructions starting at the program counter.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">dxi <number></span><span style="font-family: inherit;"> changes the 20 to </span><span style="font-family: "courier new" , "courier" , monospace;"><number></span><span style="font-family: inherit;">. Notice this is a string substitution. </span><span style="font-family: "courier new" , "courier" , monospace;"><number></span><span style="font-family: inherit;"> is not a number in the 'int' sense. It is a string that GDB interprets as a number.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Finally, </span><span style="font-family: "courier new" , "courier" , monospace;">dxi <number> <address></span><span style="font-family: inherit;"> outputs </span><span style="font-family: "courier new" , "courier" , monospace;"><number></span><span style="font-family: inherit;"> of assembly instructions starting at </span><span style="font-family: "courier new" , "courier" , monospace;"><address></span><span style="font-family: inherit;">.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">dxi</span> is a short cut command, but with some variability.<br />
<br />
<h2>
BMEM - Break on Change of Contents of An Address</h2>
Below are three command <span style="font-family: "courier new" , "courier" , monospace;">bmemc</span>, <span style="font-family: "courier new" , "courier" , monospace;">bmems</span>, and <span style="font-family: "courier new" , "courier" , monospace;">bmeml</span>. <span style="font-family: "courier new" , "courier" , monospace;">bmemloop</span> is used by all three other commands. This shows GDB user-defined commands support subroutines.<br />
<br />
Each command executes an <span style="font-family: "courier new" , "courier" , monospace;">si</span> command until the value at the specified address changes a specified number of times.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">bmemc</span> examines 8-bit values, <span style="font-family: "courier new" , "courier" , monospace;">bmems</span> examines 16-bit values, and <span style="font-family: "courier new" , "courier" , monospace;">bmeml</span> examines 32-bit values.<br />
<br />
The logic of each command is the same.<br />
<br />
Now the specific syntax of user-defined commands that is not well documented is shown.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">#bmemloop ptr count</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">#internal function, called by bmemc, bmemw, and bmeml</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">define bmemloop</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> if $argc == 2</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> set $loop = $arg1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> set $bmemlooprd = *($arg0)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> set $bmemlooporg = *($arg0)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> while ($loop > 0)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> while ($bmemlooprd==$bmemlooporg)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> si</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> set $bmemlooprd=*($arg0)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> set $loop = $loop - 1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> if $loop == 0</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> loop_break</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> set $bmemlooporg = *($arg0)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">document bmemloop</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">First argument specified address to watch</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">Second argument specifies number of times to loop</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> for each change of the specified address</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">bmemloop 10000 5 - Loop until address 10000 changes 5 times</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">end</span><br />
<div>
<br /></div>
<span style="font-family: "courier new" , "courier" , monospace;">define bmemc</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> if $argc>=1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> disable disp 1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> set $bmemcx=(char*)($arg0)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> set $bmemccount = 1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> if $argc == 2</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> set $bmemccount = $arg1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> bmemloop $bmemcx $bmemccount</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> enable disp 1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">document bmemc</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">bmemc runs until the byte at the address specified changes</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">end</span><br />
<div>
<br /></div>
<span style="font-family: "courier new" , "courier" , monospace;">define bmemw</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> if $argc>=1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> disable disp 1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> set $bmemwx=(short*)($arg0)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> set $bmemwcount = 1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> if $argc == 2</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> set $bmemwcount = $arg1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> bmemloop $bmemwx $bmemwcount</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> enable disp 1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">document bmemw</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">bmemw runs until the short (16-bit) at the address specified changes</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">end</span><br />
<div>
<br /></div>
<span style="font-family: "courier new" , "courier" , monospace;">define bmeml</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> if $argc>=1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> disable disp 1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> set $bmemlx=(long*)($arg0)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> set $bmemlcount = 1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> if $argc == 2</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> set $bmemlcount = $arg1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> bmemloop $bmemlx $bmemlcount</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> enable disp 1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">document bmeml</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">bmeml runs until the long (32-bit) at the address specified changes</span><br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;">end</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
Let's discuss some of the syntax.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">set $bmemcx=(char*)($arg0)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">set $bmemwx=(short*)($arg0)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">set $bmemlx=(long*)($arg0)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: inherit;">These three lines each declare a </span>convenience<span style="font-family: inherit;"> variable. Start with a dollar sign and create a name, start with a letter. The syntax that is not obvious is that the address specified as the first argument, </span><span style="font-family: "courier new" , "courier" , monospace;">arg0</span><span style="font-family: inherit;">, of the command has to be casted to the appropriate type, a pointer of a specific width.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">The syntax is the same as that of C.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">The three convenience variables are now pointers.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">We can pass the pointer to </span><span style="font-family: "courier new" , "courier" , monospace;">bmemloop</span><span style="font-family: inherit;">, a subroutine, along with an optional count.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">The </span><span style="font-family: "courier new" , "courier" , monospace;">enable</span><span style="font-family: inherit;"> and </span><span style="font-family: "courier new" , "courier" , monospace;">disable</span><span style="font-family: inherit;"> commands are used to </span>suppress<span style="font-family: inherit;"> GDB output while the</span><span style="font-family: "courier new" , "courier" , monospace;"> bmemloop</span><span style="font-family: inherit;"> is running. The </span><span style="font-family: "courier new" , "courier" , monospace;">si</span><span style="font-family: inherit;"> command outputs data each time it is executed.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">To compare the value of two addresses we need pointers. </span><span style="font-family: "courier new" , "courier" , monospace;">bmemloop</span><span style="font-family: inherit;"> creates two </span>convenience<span style="font-family: inherit;"> variables, </span><span style="font-family: "courier new" , "courier" , monospace;">bmemlooporg</span><span style="font-family: inherit;">, the original value pointed to by </span><span style="font-family: "courier new" , "courier" , monospace;">arg0</span><span style="font-family: inherit;"> and </span><span style="font-family: "courier new" , "courier" , monospace;">bmemlooprd</span><span style="font-family: inherit;">, the value pointed to by </span><span style="font-family: "courier new" , "courier" , monospace;">arg0</span><span style="font-family: inherit;"> after each </span><span style="font-family: "courier new" , "courier" , monospace;">si</span><span style="font-family: inherit;"> command.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">bmemw 20000</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
This command will execute the <span style="font-family: "courier new" , "courier" , monospace;">si</span> command until the 16-bit value at <span style="font-family: "courier new" , "courier" , monospace;">20000</span> changes.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">bmemc 0x30000 10</span></div>
<div>
<br /></div>
<div>
This command will execute the <span style="font-family: "courier new" , "courier" , monospace;">si</span> command until the 8-bit value at 0x<span style="font-family: "courier new" , "courier" , monospace;">30000</span> changes 10 times.</div>
<div>
<br /></div>
<div>
Note that the address is hexadecimal. The cast to a pointer understands hexadecimal notation.</div>
<div>
<br /></div>
<h2>
Performance</h2>
<div>
The commands <span style="font-family: "courier new" , "courier" , monospace;">bmemc</span>, <span style="font-family: "courier new" , "courier" , monospace;">bmemw</span>, and <span style="font-family: "courier new" , "courier" , monospace;">bmeml</span> work, but they are slow. We are using the GDB interpreter to do something, that is today, done by hardware, but it does work.</div>
<div>
<br /></div>
<h2>
Break on an Address - brk</h2>
<div>
Now let's create a break point user-defined command, <span style="font-family: "courier new" , "courier" , monospace;">brk</span>.</div>
<div>
<br /></div>
<div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"># brk</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"># brk <dest_address></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"># brk <dest_address> <count></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"># brk <dest_address> <count> <offset></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">define brk</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> if $argc >= 1</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> disable disp 1</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> set $brkcount = 1</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> if $argc >=2</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> set $brkcount = $arg1</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> end</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> set $targ = (long)($arg0)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> if $argc == 3</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> set $targ = $targ + $arg2</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> end</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> set $brkx = (unsigned char *)($targ)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> print $brkx</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> if $brkcount > 0</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> set $loop = 0</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> while $brkx == $pc</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> si</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> end</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> while ($loop < $brkcount)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> while ($brkx != $pc)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> si</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> end</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> set $loop = $loop +1</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> if $loop == $brkcount</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> loop_break</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> end</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> si</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> end</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> else</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> print "Loop count cannot be negative"</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> end</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> enable disp 1</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> end</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> if $argc == 0</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> si</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> end</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">end</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">document brk</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">brk <dest_address> [count offset]</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">Send 'si' commands until <dest_address> reached</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">If count specified, send 'si' commands until <dest_address> is reached <count> times.</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">If offset specified, add <offset> to <dest_address> to make break address.</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> When using <offset>, must specify count.</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> brk $ReadSwitches 1 0x20 - break at $ReadSwitches+0x20 once.</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">end</span></div>
</div>
</div>
<div>
<br /></div>
<div>
The user-define command <span style="font-family: "courier new" , "courier" , monospace;">brk</span> accepts one to three arguments. The first argument, mandatory, is the address we want to break on. The second optional argument is how many times we want to break before stopping. The third optional argument is an offset to add to the address to specify the break point address.</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">while ($brkx != $pc)</span></div>
</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: inherit;">Execute </span><span style="font-family: "courier new" , "courier" , monospace;">si</span><span style="font-family: inherit;"> commands until the program counter is the same as the specified address.</span></div>
<div>
<br /></div>
<div>
Again the enable and disable commands are used.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">brk</span> is no speed demon, but it works.</div>
<div>
<br /></div>
<div>
The use of convenience variables and user-defined commands creates GDB commands that emulate break point commands.<br />
<br />
See this <a href="https://bitbucket.org/FernLeaf_07/gdbscripts">bitbucket repository</a> for all of the user-defined commands in one file.</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8192642777375146218.post-55043691207523599602015-07-20T10:39:00.000-04:002019-09-02T12:58:25.764-04:00Yet Another Makefile Tutorial - Part IIThis blog continues where '<a href="http://fernleaf07.blogspot.com/2015/07/yet-another-make-tutorial.html" target="_blank">Yet Another Makefile Tutorial</a>' left off. Remember sources are found at <a href="https://bitbucket.org/FernLeaf_07/makefiletutorial" target="_blank">https://bitbucket.org/FernLeaf_07/makefiletutorial</a>.<br />
<br />
NOTE: The make files in the tutorial are NOT POSIX compliant.<br />
<div>
<br /></div>
<div>
We have a general purpose make file, <span style="font-family: "courier new" , "courier" , monospace;">makefile10a</span>. The source is put in the source directory <span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR</span>. Object files are built in <span style="font-family: "courier new" , "courier" , monospace;">OBJ_DIR,</span> and the program is built in <span style="font-family: "courier new" , "courier" , monospace;">TARGET</span>. Includes files are found in <span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR</span>.</div>
<div>
<br /></div>
<div>
For a project with one flat directory of source, m<span style="font-family: "courier new" , "courier" , monospace;">akefile10a</span> does its job.</div>
<div>
<br /></div>
<div>
What about projects where there are sub-directories to <span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR</span>?</div>
<div>
<br /></div>
<div>
The problem with <span style="font-family: "courier new" , "courier" , monospace;">makefile10a</span> is that it uses the make function <span style="font-family: "courier new" , "courier" , monospace;">wildcard</span> to find the source files in <span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR</span>. <span style="font-family: "courier new" , "courier" , monospace;">wildcard</span> does not recursively descend <span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR</span> looking for files. We need another function to perform the recursive search.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">make</span> does not have such a function, but we can use external commands. The external command to use is <span style="font-family: "courier new" , "courier" , monospace;">find</span>.</div>
<div>
<br />
<div>
BTW, <span style="font-family: "courier new" , "courier" , monospace;">vpath</span> does not perform a recursive search for files. This is not a problem, yet.</div>
</div>
<h3>
find</h3>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">find</span> is a very complicated program. We are going to use a relatively simple form.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">SRC_LIST := $(shell </span><span style="font-family: "courier new" , "courier" , monospace;">find $(SRC_DIR) -name "*.c" -type f)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">find</span><span style="font-family: inherit;"> is started by </span><span style="font-family: "courier new" , "courier" , monospace;">shell</span><span style="font-family: inherit;">. </span><span style="font-family: "courier new" , "courier" , monospace;">find</span> is told to start the search for <span style="font-family: "courier new" , "courier" , monospace;">*.c</span> files in the <span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR</span>. <span style="font-family: "courier new" , "courier" , monospace;">find</span> recursively searches for files. <span style="font-family: "courier new" , "courier" , monospace;">-type f</span> makes sure that <span style="font-family: "courier new" , "courier" , monospace;">find</span> only retrieves files and not directories. It is rare that a directory could end in <span style="font-family: "courier new" , "courier" , monospace;">*.c</span>, but <span style="font-family: "courier new" , "courier" , monospace;">-type f</span> makes sure that directory is not included.</div>
<div>
<br /></div>
<div>
We update <span style="font-family: "courier new" , "courier" , monospace;">makefile10a</span> to use <span style="font-family: "courier new" , "courier" , monospace;">find</span>.</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">#makefile<span style="color: red;">11</span></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR := src</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">OBJ_DIR := obj</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace;">SRC_LIST := $(shell find $(SRC_DIR) -name "*.c" -type f)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">OBJS := $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC_LIST))</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">DEPS := $(OBJS:.o=.d)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">TARGET_DIR := target</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">TARGET := $(TARGET_DIR)/aprogram</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">vpath %.c $(SRC_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">all: $(TARGET)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(OBJ_DIR)/*.o $(OBJ_DIR)/*.d</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(TARGET)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rmdir $(OBJ_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rmdir $(TARGET_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(TARGET): $(OBJS)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc $^ -o $@</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(OBJ_DIR)/%.o: %.c</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c -MMD $< -o $@</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">REQUIRED_DIRS := $(OBJ_DIR) $(TARGET_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">_MKDIRS := $(shell for d in $(REQUIRED_DIRS); \</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> do \</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> mkdir -p $$d; \</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> done)</span></div>
</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">-include $(DEPS)</span></div>
<h4>
Debugging Make Files</h4>
<div>
The debugging of make files is difficult. <span style="font-family: "courier new" , "courier" , monospace;">make</span> does have a <span style="font-family: "courier new" , "courier" , monospace;">-d</span> switch which is used for showing how <span style="font-family: "courier new" , "courier" , monospace;">make</span> searches for targets and dependencies.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">make</span> does not have a switch to output its variables. The function <span style="font-family: "courier new" , "courier" , monospace;">info</span> that will output trace messages while <span style="font-family: "courier new" , "courier" , monospace;">make</span> is running.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(info message)</span></div>
<div>
<br /></div>
<div>
We can use any string or variable to create <span style="font-family: "courier new" , "courier" , monospace;">message</span>.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(info SRC_LIST=$(SRC_LIST))</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(info OBJS=$(OBJS))</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(info DEPS=$(DEPS))</span></div>
<div>
<br /></div>
<div>
The function <span style="font-family: "courier new" , "courier" , monospace;">error</span> can be substituted for the function <span style="font-family: "courier new" , "courier" , monospace;">info</span>. When the function <span style="font-family: "courier new" , "courier" , monospace;">error</span> is encountered, the message is output and <span style="font-family: "courier new" , "courier" , monospace;">make</span> stops. <span style="font-family: "courier new" , "courier" , monospace;">warning</span> is also available, but not needed for this debugging tutorial.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(error STOP HERE!)</span></div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">makefile11a</span> is updated to use <span style="font-family: "courier new" , "courier" , monospace;">info</span>.</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">#makefile<span style="color: red;">11a</span></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR := src</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">OBJ_DIR := obj</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">SRC_LIST := $(shell find $(SRC_DIR) -name "*.c" -type f)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">OBJS := $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC_LIST))</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">DEPS := $(OBJS:.o=.d)</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace;">$(info SRC_LIST=$(SRC_LIST))</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace;">$(info OBJS=$(OBJS))</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace;">$(info DEPS=$(DEPS))</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">TARGET_DIR := target</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">TARGET := $(TARGET_DIR)/aprogram</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">vpath %.c $(SRC_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">all: $(TARGET)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(OBJ_DIR)/*.o $(OBJ_DIR)/*.d</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(TARGET)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rmdir $(OBJ_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rmdir $(TARGET_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(TARGET): $(OBJS)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc $^ -o $@</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(OBJ_DIR)/%.o: %.c</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c -MMD $< -o $@</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">REQUIRED_DIRS := $(OBJ_DIR) $(TARGET_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">_MKDIRS := $(shell for d in $(REQUIRED_DIRS); \</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> do \</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> mkdir -p $$d; \</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> done)</span></div>
</div>
<div>
<br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;">-include $(DEPS)</span></div>
</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSfvic3RM1H4F_Pbncb2R_JDhSevs8hSVDVHfOiEo3Nry2m5lItEGzZAGhPqlvyEA9CvJqaJxhwpympmLdwqr5-Mdfde5_vH-fTwObBrt4I6XZxnWqdFMng8BYKh5O2sCSRQxJCh_JRl8/s1600/makefile11a.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="204" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSfvic3RM1H4F_Pbncb2R_JDhSevs8hSVDVHfOiEo3Nry2m5lItEGzZAGhPqlvyEA9CvJqaJxhwpympmLdwqr5-Mdfde5_vH-fTwObBrt4I6XZxnWqdFMng8BYKh5O2sCSRQxJCh_JRl8/s640/makefile11a.gif" width="640" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<h3>
Sub-Directories</h3>
<div>
We update our example by putting <span style="font-family: "courier new" , "courier" , monospace;">suba.c, subb.c,</span><span style="font-family: inherit;"> and </span><span style="font-family: "courier new" , "courier" , monospace;">subc.c</span> files in the sub-directory <span style="font-family: "courier new" , "courier" , monospace;">sub</span>. We also move all the include files to their own directory <span style="font-family: "courier new" , "courier" , monospace;">INC_DIR</span>.</div>
<div>
<br /></div>
<div>
See updates in <span style="font-family: "courier new" , "courier" , monospace;">makefile12</span>.</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">#makefile<span style="color: red;">12 - does not work</span></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR := src</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">OBJ_DIR := obj</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace;">INC_DIR := inc</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">SRC_LIST := $(shell find $(SRC_DIR) -name "*.c" -type f)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">OBJS := $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC_LIST))</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">DEPS := $(OBJS:.o=.d)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">TARGET_DIR := target</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">TARGET := $(TARGET_DIR)/aprogram</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">vpath %.c $(SRC_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">all: $(TARGET)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(OBJ_DIR)/*.o $(OBJ_DIR)/*.d</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(TARGET)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rmdir $(OBJ_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rmdir $(TARGET_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(TARGET): $(OBJS)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc $^ -o $@</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(OBJ_DIR)/%.o: %.c</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c -MMD <span style="color: red;">-I $(INC_DIR)</span> $< -o $@</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">REQUIRED_DIRS := $(OBJ_DIR) $(TARGET_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">_MKDIRS := $(shell for d in $(REQUIRED_DIRS); \</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> do \</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> mkdir -p $$d; \</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> done)</span></div>
</div>
<div>
<br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;">-include $(DEPS)</span></div>
</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<br /></div>
<div>
Unfortunately, <span style="font-family: "courier new" , "courier" , monospace;">makefile12</span> do not work.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCkYnVNuW1UmxvYQzT-JnwBnrJ151q1ZbaljrJ3sUlPSGr40cknwwhXMs-_HK86kUqB5mYKbOmb6_NHI0xOdsg9l0hG_B-2inRS0sP5-_otCcDIJPm9DChH1H0QmAjJT1kWN7RALmn4aI/s1600/makefile12.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="94" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCkYnVNuW1UmxvYQzT-JnwBnrJ151q1ZbaljrJ3sUlPSGr40cknwwhXMs-_HK86kUqB5mYKbOmb6_NHI0xOdsg9l0hG_B-2inRS0sP5-_otCcDIJPm9DChH1H0QmAjJT1kWN7RALmn4aI/s640/makefile12.gif" width="640" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
The problem is the old problem of directories do not exist that <span style="font-family: "courier new" , "courier" , monospace;">gcc</span> expects to exist. In this case, the directory <span style="font-family: "courier new" , "courier" , monospace;">obj/sub</span> does not exist.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">find</span> found all the source files, complete with sub-directory names, but there are no sub-directories in <span style="font-family: "courier new" , "courier" , monospace;">obj</span> to match those in <span style="font-family: "courier new" , "courier" , monospace;">src</span>.<br />
<br />
How to solve this problem?</div>
<div>
<br /></div>
<div>
There are two possible solutions. First, find all the sub-directories in the <span style="font-family: "courier new" , "courier" , monospace;">SRC_LIST</span> of files and create the corresponding sub-directories in <span style="font-family: "courier new" , "courier" , monospace;">OBJ_DIR</span>, or remove all the sub-directory names from the file names in <span style="font-family: "courier new" , "courier" , monospace;">OBJS</span>.</div>
<div>
<br /></div>
<div>
The first solution creates a mirror image of sub-directories in <span style="font-family: "courier new" , "courier" , monospace;">OBJ_DIR</span> found in <span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR</span>.</div>
<div>
<br /></div>
<div>
The second solution will create a flat listing of object files in <span style="font-family: "courier new" , "courier" , monospace;">OBJ_DIR</span>. No necessarily a bad solution.</div>
<div>
<br /></div>
<div>
Both solutions are acceptable. Both solutions shows using additional features of <span style="font-family: "courier new" , "courier" , monospace;">make</span>.</div>
<h4>
Sub-Directories Under OBJ_DIR</h4>
<div>
First solution involves using the make functions <span style="font-family: "courier new" , "courier" , monospace;">patsubst</span>, <span style="font-family: "courier new" , "courier" , monospace;">sort</span><span style="font-family: inherit;">,</span> and <span style="font-family: "courier new" , "courier" , monospace;">dir</span>. We saw <span style="font-family: "courier new" , "courier" , monospace;">patsubst</span> in the previous tutorial. <span style="font-family: "courier new" , "courier" , monospace;">sort</span> and <span style="font-family: "courier new" , "courier" , monospace;">dir</span> are new.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">dir</span> is a function that extracts the directory portion of a filename.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">sort</span> is a function that sorts a list and removes duplicates.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">patsubst</span> is the pattern substitution function.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR_LIST := $(patsubst %/,%,$(sort $(dir $(SRC_LIST))))</span></div>
<div>
<br /></div>
<div>
Let's explain the command from the inside out.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(dir $(SRC_LIST))</span></div>
<div>
<br /></div>
<div>
This changes SRC_LIST from this</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">src/main.c src/suba/suba.c src/subb/subb.c src/subc/subc.c</span> </div>
<div>
<br /></div>
<div>
to this.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">src/ src/sub/ src/sub/ src/sub/</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: inherit;">There is one entry for each *.c file. We have the same sub-directory three times, in this example. If there were 50 files in a sub-directory, that sub-directory would appear 50 times.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">sort is used to remove the duplicates. We really don't care about the sorting feature, we really just want the duplicates removed.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(sort $(dir $(SRC_LIST)))</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">changes the </span><span style="font-family: "courier new" , "courier" , monospace;">SRC_LIST</span><span style="font-family: inherit;"> into this.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">src/ src/sub/</span></div>
<div>
<br /></div>
<div>
Now we have a list of the sub directories.</div>
<div>
<br /></div>
<div>
Remove the trailing slash from the directory names. We will see why later.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(patsubst %/,%,$(sort $(dir $(SRC_LIST))))</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: inherit;">Finally, the list of directories where we find source files.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">src src/sub</span></div>
<div>
<br /></div>
<div>
Change <span style="font-family: "courier new" , "courier" , monospace;">src</span> to <span style="font-family: "courier new" , "courier" , monospace;">obj</span> and we have the list directories for object files.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">OBJ_DIR_LIST := $(patsubst $(SRC_DIR)%,$(OBJ_DIR)%,$(SRC_DIR_LIST))</span></div>
<div>
<br /></div>
<div>
Change how we create <span style="font-family: "courier new" , "courier" , monospace;">REQUIRED_DIRS</span> and we are done.</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">REQUIRED_DIRS := $(</span><span style="font-family: "courier new" , "courier" , monospace;">OBJ_DIR_LIST</span><span style="font-family: "courier new" , "courier" , monospace;">) $(TARGET_DIR)</span></div>
</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">makefile13</span><span style="font-family: inherit;"> shows all the updates for the first solution.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">#makefile<span style="color: red;">13</span></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR := src</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">OBJ_DIR := obj</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">INC_DIR := inc</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">SRC_LIST := $(shell find $(SRC_DIR) -name "*.c" -type f)</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace;">SRC_DIR_LIST := $(patsubst %/,%,$(sort $(dir $(SRC_LIST))))</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace;">OBJ_DIR_LIST := $(patsubst $(SRC_DIR)%,$(OBJ_DIR)%,$(SRC_DIR_LIST))</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">OBJS := $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC_LIST))</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">DEPS := $(OBJS:.o=.d)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">TARGET_DIR := target</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">TARGET := $(TARGET_DIR)/aprogram</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">vpath %.c $(SRC_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">all: $(TARGET)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(OBJ_DIR)/*.o $(OBJ_DIR)/*.d</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(TARGET)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rmdir $(OBJ_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rmdir $(TARGET_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(TARGET): $(OBJS)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc $^ -o $@</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(OBJ_DIR)/%.o: %.c</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c -MMD -I $(INC_DIR) $< -o $@</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">REQUIRED_DIRS := <span style="color: red;">$(OBJ_DIR_LIST)</span> $(TARGET_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">_MKDIRS := $(shell for d in $(REQUIRED_DIRS); \</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> do \</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> mkdir -p $$d; \</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> done)</span></div>
<div style="font-family: inherit;">
<br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;">-include $(DEPS)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
</div>
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhk9C8obzMDrSW7QwMQlrBPA88P6o8BlyvVuaD4iYBsz_fXp1Y6m-7wPaABxxzb6Q6YJOB8Rrsi86F7FPccPueR4A900IgwSDdEWP7zAEjOMNkHdh1Yp18LyqZIXapoiVGhW1B1yR-k2Yc/s1600/makefile13a.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="84" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhk9C8obzMDrSW7QwMQlrBPA88P6o8BlyvVuaD4iYBsz_fXp1Y6m-7wPaABxxzb6Q6YJOB8Rrsi86F7FPccPueR4A900IgwSDdEWP7zAEjOMNkHdh1Yp18LyqZIXapoiVGhW1B1yR-k2Yc/s640/makefile13a.gif" width="640" /></a></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: inherit;">We solved the directory problem for the first solution. We now have a mirror image of sub-directories in the </span><span style="font-family: "courier new" , "courier" , monospace;">OBJ_DIR</span><span style="font-family: inherit;"> as is found in </span><span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR</span><span style="font-family: inherit;">.</span></div>
<div>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Let's check the </span><span style="font-family: "courier new" , "courier" , monospace;">clean</span><span style="font-family: inherit;"> command.</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuGhyOvRtn_mtqoUuxRiEKQhRmjXYWvDvWG9S5RaKl_pnP-LKnwhDBV9fV6el-yHs6R2DZuO4em3OO3kBbSAg0uyToiT_0QwoETklJW9imxlH7scxd5_HC-NKhbdzI9TgRMjdCiBEoVpg/s1600/makefile13a_1.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="57" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuGhyOvRtn_mtqoUuxRiEKQhRmjXYWvDvWG9S5RaKl_pnP-LKnwhDBV9fV6el-yHs6R2DZuO4em3OO3kBbSAg0uyToiT_0QwoETklJW9imxlH7scxd5_HC-NKhbdzI9TgRMjdCiBEoVpg/s400/makefile13a_1.gif" width="400" /></a></div>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">The </span><span style="font-family: "courier new" , "courier" , monospace;">rm</span><span style="font-family: inherit;"> command does not remove directories recursively. We have a sub-directory under </span><span style="font-family: "courier new" , "courier" , monospace;">obj</span><span style="font-family: inherit;">, </span><span style="font-family: "courier new" , "courier" , monospace;">sub</span><span style="font-family: inherit;">. The </span><span style="font-family: "courier new" , "courier" , monospace;">sub</span><span style="font-family: inherit;"> directory has to be removed before we can remove </span><span style="font-family: "courier new" , "courier" , monospace;">obj</span><span style="font-family: inherit;">.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">rm</span><span style="font-family: inherit;"> has a switch to recursively delete directories recursively</span><br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">@rm -rf $(OBJ_DIR)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">@rm -rf $(TARGET_DIR)</span><br />
<span style="font-family: "courier new" , "courier" , monospace; font-size: x-small;"><br /></span>
<span style="font-family: inherit;">Updating </span><span style="font-family: "courier new" , "courier" , monospace;">makefile13</span><span style="font-family: inherit;"> the final make file is this.</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;">#makefile13</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR := src</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">OBJ_DIR := obj</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">INC_DIR := inc</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">SRC_LIST := $(shell find $(SRC_DIR) -name "*.c" -type f)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR_LIST := $(patsubst %/,%,$(sort $(dir $(SRC_LIST))))</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">OBJ_DIR_LIST := $(patsubst $(SRC_DIR)%,$(OBJ_DIR)%,$(SRC_DIR_LIST))</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">OBJS := $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC_LIST))</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">DEPS := $(OBJS:.o=.d)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">TARGET_DIR := target</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">TARGET := $(TARGET_DIR)/aprogram</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">vpath %.c $(SRC_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">all: $(TARGET)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(OBJ_DIR)/*.o $(OBJ_DIR)/*.d</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(TARGET)</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -rf $(OBJ_DIR)</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -rf $(TARGET_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(TARGET): $(OBJS)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc $^ -o $@</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(OBJ_DIR)/%.o: %.c</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c -MMD -I $(INC_DIR) $< -o $@</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">REQUIRED_DIRS := $(OBJ_DIR_LIST) $(TARGET_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">_MKDIRS := $(shell for d in $(REQUIRED_DIRS); \</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> do \</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> mkdir -p $$d; \</span></div>
<span style="font-family: "courier new" , "courier" , monospace;"> done)</span></div>
<div>
<br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;">-include $(DEPS)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<span style="font-family: "courier new" , "courier" , monospace;">makefile13</span> is the final make file. We have sources in <span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR </span><span style="font-family: inherit;">and its sub-directories.</span> We have include files in <span style="font-family: "courier new" , "courier" , monospace;">INC_DIR</span>. We generate object files in <span style="font-family: "courier new" , "courier" , monospace;">OBJ_DIR</span> and mirror image sub-directories of <span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR</span>, and the target is generated in <span style="font-family: "courier new" , "courier" , monospace;">TARGET_DIR</span>.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">clean</span> works correctly.<br />
<h4>
Sub-Directories - Second Solution, Flat OBJ_DIR</h4>
</div>
<div>
The second solution is to create a flat directory of object files.</div>
<div>
<br /></div>
<div>
We want the filenames from the <span style="font-family: "courier new" , "courier" , monospace;">SRC_LIST</span>, not the directories.</div>
<div>
<br /></div>
<div>
The make function <span style="font-family: "courier new" , "courier" , monospace;">notdir</span> extracts the filename, not the directory.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">OBJS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(notdir $(SRC_LIST)))</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: inherit;">We now have a list of files object files.</span><br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">obj/main.o obj/suba.o obj/subb.o obj/subc.o</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
Unfortunately changing <span style="font-family: "courier new" , "courier" , monospace;">OBJS</span> in makefile12 produces this error.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzymHLFPPPCo2S4YhgGznaoj3SDXArDVI0Gp4TNi570tBjDO6KAietcF4WybKgkiEOnCA0iDZ3o5qHV46TPKPzDLOuFr25UexsRLUaU5IdToSuS8LAqq_hAx48Jx1o2yMn_GyGtykH-Os/s1600/makefile14.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="57" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzymHLFPPPCo2S4YhgGznaoj3SDXArDVI0Gp4TNi570tBjDO6KAietcF4WybKgkiEOnCA0iDZ3o5qHV46TPKPzDLOuFr25UexsRLUaU5IdToSuS8LAqq_hAx48Jx1o2yMn_GyGtykH-Os/s640/makefile14.gif" width="640" /></a></div>
<br /></div>
<div>
<br />
<br />
<br />
<br />
The problem we have is that <span style="font-family: "courier new" , "courier" , monospace;">make</span> can't find <span style="font-family: "courier new" , "courier" , monospace;">suba.c</span>. It is in a sub-directory. The file name of the pattern is <span style="font-family: "courier new" , "courier" , monospace;">obj/suba.o</span>, not <span style="font-family: "courier new" , "courier" , monospace;">obj/sub/suba.o</span> which is changed to <span style="font-family: "courier new" , "courier" , monospace;">sub/suba.c</span>. With <span style="font-family: "courier new" , "courier" , monospace;">vpath</span> looking in <span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR</span>, the file <span style="font-family: "courier new" , "courier" , monospace;">suba.c</span> is found in <span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR/sub/suba.c.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: inherit;">We need to give </span><span style="font-family: "courier new" , "courier" , monospace;">vpath</span><span style="font-family: inherit;"> the list of source directories. Use </span><span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR_LIST</span><span style="font-family: inherit;"> from </span><span style="font-family: "courier new" , "courier" , monospace;">makefile13</span><span style="font-family: inherit;">.</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
</div>
<br />
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
<div style="margin: 0px;">
<span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR_LIST := $(patsubst %/,%,$(sort $(dir $(SRC_LIST))))</span></div>
</div>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">So update </span><span style="font-family: "courier new" , "courier" , monospace;">OBJS</span><span style="font-family: inherit;">, add </span><span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR_LIST</span><span style="font-family: inherit;"> to </span><span style="font-family: "courier new" , "courier" , monospace;">makefile12, update vpath,</span><span style="font-family: inherit;"> we get </span><span style="font-family: "courier new" , "courier" , monospace;">makefile14</span><span style="font-family: inherit;">.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">#makefile<span style="color: red;">14</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR := src</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">OBJ_DIR := obj</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">INC_DIR := inc</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">SRC_LIST := $(shell find $(SRC_DIR) -name "*.c" -type f)</span><br />
<span style="color: red; font-family: "courier new" , "courier" , monospace;">SRC_DIR_LIST := $(patsubst %/,%,$(sort $(dir $(SRC_LIST))))</span><br />
<span style="color: red; font-family: "courier new" , "courier" , monospace;">OBJS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(notdir $(SRC_LIST)))</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">DEPS := $(OBJS:.o=.d)</span><br />
<span style="color: red; font-family: "courier new" , "courier" , monospace;"><strike>$(info OBJS=$(OBJS))</strike></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">TARGET_DIR := target</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">TARGET := $(TARGET_DIR)/aprogram</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">vpath %.c <span style="color: red;">$(SRC_DIR_LIST)</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">all: $(TARGET)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(OBJ_DIR)/*.o $(OBJ_DIR)/*.d</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(TARGET)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rmdir $(OBJ_DIR)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rmdir $(TARGET_DIR)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">$(TARGET): $(OBJS)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc $^ -o $@</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">$(OBJ_DIR)/%.o: %.c</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c -MMD -I $(INC_DIR) $< -o $@</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">REQUIRED_DIRS := $(OBJ_DIR) $(TARGET_DIR)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">_MKDIRS := $(shell for d in $(REQUIRED_DIRS); \</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> do \</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> mkdir -p $$d; \</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> done)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<br />
<span style="font-family: "courier new" , "courier" , monospace;">-include $(DEPS)</span></div>
<div>
<br /></div>
<div>
This update works.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaFXnadamGXmR-Co5SGXwdgvW5TqBhLrTmegpHWLUmL74MQV43q3CfFWcr0qQ98473zUtxqXJaJ0yHJZyUAYH9DUSCYmR7Szst5ZGQq2vNdVyf6if-hwobkK4BF9cGa96bN7lasUdW7Ys/s1600/makefile14_1.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="51" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaFXnadamGXmR-Co5SGXwdgvW5TqBhLrTmegpHWLUmL74MQV43q3CfFWcr0qQ98473zUtxqXJaJ0yHJZyUAYH9DUSCYmR7Szst5ZGQq2vNdVyf6if-hwobkK4BF9cGa96bN7lasUdW7Ys/s400/makefile14_1.gif" width="400" /></a></div>
<br />
<br />
<br />
<br />
Update<span style="font-family: "courier new" , "courier" , monospace;"> makefile14</span> for <span style="font-family: "courier new" , "courier" , monospace;">clean </span>the same as <span style="font-family: "courier new" , "courier" , monospace;">makefile13</span>. The final result is this.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">#makefile14</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR := src</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">OBJ_DIR := obj</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">INC_DIR := inc</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">SRC_LIST := $(shell find $(SRC_DIR) -name "*.c" -type f)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR_LIST := $(patsubst %/,%,$(sort $(dir $(SRC_LIST))))</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">OBJS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(notdir $(SRC_LIST)))</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">DEPS := $(OBJS:.o=.d)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">TARGET_DIR := target</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">TARGET := $(TARGET_DIR)/aprogram</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">vpath %.c $(SRC_DIR_LIST)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">all: $(TARGET)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(OBJ_DIR)/*.o $(OBJ_DIR)/*.d</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(TARGET)</span><br />
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -rf $(OBJ_DIR)</span></div>
<span style="color: red; font-family: "courier new" , "courier" , monospace;">@rm -rf $(TARGET_DIR)</span><br />
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
<div style="margin: 0px;">
<span style="color: red; font-family: "courier new" , "courier" , monospace;"><br /></span></div>
</div>
<span style="font-family: "courier new" , "courier" , monospace;">$(TARGET): $(OBJS)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc $^ -o $@</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">$(OBJ_DIR)/%.o: %.c</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c -MMD -I $(INC_DIR) $< -o $@</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">REQUIRED_DIRS := $(OBJ_DIR) $(TARGET_DIR)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">_MKDIRS := $(shell for d in $(REQUIRED_DIRS); \</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> do \</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> mkdir -p $$d; \</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> done)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">-include $(DEPS)</span></div>
<div>
<br /></div>
<div>
The second solution is now complete.</div>
<div>
<br /></div>
<h2>
Summary</h2>
<div>
Fini.</div>
<div>
<br /></div>
<div>
We have two files, <span style="font-family: "courier new" , "courier" , monospace;">makefile13,</span> and <span style="font-family: "courier new" , "courier" , monospace;">makefile14,</span> that are general purpose make files for a project with sources in one directory, object files in another, and the target in a third directory.</div>
<div>
<br /></div>
<h2>
Future</h2>
<div>
The make files handle just one source type <span style="font-family: "courier new" , "courier" , monospace;">*.c</span>. What if you have <span style="font-family: "courier new" , "courier" , monospace;">*.cc</span>, or <span style="font-family: "courier new" , "courier" , monospace;">*.cxx</span> files? </div>
<div>
<br /></div>
<div>
If you just have <span style="font-family: "courier new" , "courier" , monospace;">*.cc</span> instead of <span style="font-family: "courier new" , "courier" , monospace;">*.c</span> or <span style="font-family: "courier new" , "courier" , monospace;">*.cxx</span> instead of <span style="font-family: "courier new" , "courier" , monospace;">*.c</span>, then simply change the <span style="font-family: "courier new" , "courier" , monospace;">find </span>command to use <span style="font-family: "courier new" , "courier" , monospace;">*.cc</span> or <span style="font-family: "courier new" , "courier" , monospace;">*.cxx</span>.</div>
<div>
<br /></div>
<div>
What if you have both <span style="font-family: "courier new" , "courier" , monospace;">*.c</span> and <span style="font-family: "courier new" , "courier" , monospace;">*.cxx</span>? Typically <span style="font-family: "courier new" , "courier" , monospace;">c</span> files are compiled differently than <span style="font-family: "courier new" , "courier" , monospace;">*.cxx</span> files. There are different switches supplied to <span style="font-family: "courier new" , "courier" , monospace;">gcc</span>.</div>
<div>
<br /></div>
<div>
The next part in this blog on make files will look at updating <span style="font-family: "courier new" , "courier" , monospace;">makefile13</span> to handle multiple file extensions, groups of files that need different compilation, and excluding source files from the build.<br />
<br />
See the next blog. <a href="http://fernleaf07.blogspot.com/2015/08/yet-another-make-tutorial-iii.html" target="_blank">Yet Another Make Tutorial III</a></div>
<div>
<br /></div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8192642777375146218.post-73854969332392714482015-07-19T09:35:00.000-04:002015-07-19T09:37:49.705-04:00True = False, Python 2.7This a quick blog on an anomaly in Python 2.7.<br />
<br />
At the >>> prompt, enter<br />
<br />
True = False<br />
<br />
True<br />
<br />
Now think about what you just did, for a second, or a minute.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivpCd4XaSgF2U5_cYoYoLtDQh-yuPkxf2NNyIhIpNKq6A50ra-tGWKErSJ7sZ-NjHN2DUYQHBD4YaR639QBvoSwl5IF2Dt5_pNDOoJF_dot89dhBjfoS7Tc584I1twbb1rLOmyJU8Wr7s/s1600/Python27_T_F.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="74" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivpCd4XaSgF2U5_cYoYoLtDQh-yuPkxf2NNyIhIpNKq6A50ra-tGWKErSJ7sZ-NjHN2DUYQHBD4YaR639QBvoSwl5IF2Dt5_pNDOoJF_dot89dhBjfoS7Tc584I1twbb1rLOmyJU8Wr7s/s640/Python27_T_F.gif" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
Now the question is how to correct it? [see below]<br />
<br />
This is an academic exercise. You would never really do this, right?<br />
<br />
<br />
Is Python 3 better?<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjw6Z1udrkQfDR7VNaPX6pryT0N94SCoJj4eHwrWgpBMOfA1FgXcipWVC-c8i9pKuaJeIh0Y6zRsyWGOKk6vp1FdMpviell1cqIDd-6MHSPMwwCo4qd5Z_W4XZyCTF70jGQdKL17Uv2yhc/s1600/python34_T_F.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="62" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjw6Z1udrkQfDR7VNaPX6pryT0N94SCoJj4eHwrWgpBMOfA1FgXcipWVC-c8i9pKuaJeIh0Y6zRsyWGOKk6vp1FdMpviell1cqIDd-6MHSPMwwCo4qd5Z_W4XZyCTF70jGQdKL17Uv2yhc/s640/python34_T_F.gif" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
Much more sensible, no?<br />
<br />
Use 3.+ where you can, n'est pas?<br />
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZTbrlqTHS4s-XOVIFtm4YitMN1AT2F4lwglYHbGBipCp0xmooeZBvrG0SO1XwNzjfzAoGJ-B-UGHTYAsWx0fMVTcA4gsWuQ7axzVmYIZk5ZY85MbYRNWzKCKK_ZdFZlu4HgSEgQKXHug/s1600/Python27_Fix_T_F.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZTbrlqTHS4s-XOVIFtm4YitMN1AT2F4lwglYHbGBipCp0xmooeZBvrG0SO1XwNzjfzAoGJ-B-UGHTYAsWx0fMVTcA4gsWuQ7axzVmYIZk5ZY85MbYRNWzKCKK_ZdFZlu4HgSEgQKXHug/s1600/Python27_Fix_T_F.gif" /></a><br />
<br />
<br />Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8192642777375146218.post-49019278833125057982015-07-15T21:11:00.000-04:002019-09-17T21:06:04.081-04:00Yet Another Make TutorialYAMT, an abbreviation that won't stick.<br />
<br />
This tutorial on <span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;"> </span>may be too little, too late, as other tools are replacing <span style="font-family: "courier new" , "courier" , monospace;">make</span>, Python, CMake, etc.<br />
<br />
But I will push on with this tutorial to create a fairly general purpose production make file.<br />
<div>
<br />
The reader is expected to have a bit of working knowledge of using <span style="font-family: "courier new" , "courier" , monospace;">gcc</span><span style="font-family: inherit;"> </span>from the command line, how to create an object file and how to link them together to form a program.</div>
<br />
<div>
</div>
At the end of this tutorial is a list of links where some of the features of <span style="font-family: "courier new" , "courier" , monospace;">make</span> I use were found, along with other references.<br />
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px;">
<div style="margin: 0px;">
<br />
All the files shown in the tutorial are found at this BitBucket site. <a href="https://bitbucket.org/FernLeaf_07/makefiletutorial" target="_blank">https://bitbucket.org/FernLeaf_07/makefiletutorial</a>.</div>
</div>
<br />
This is a seven part tutorial.<br />
<br />
Topics covered. gcc -mmd, make patterns, automatic variables, make variables, VPATH, patsubst, -include<br />
<h2>
Introduction</h2>
<div>
If you landed here not knowing much about <span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;">, this</span> very brief introduction to <span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;"> </span>will get us started. If you are versed in the world of <span style="font-family: "courier new" , "courier" , monospace;">make</span>, <span style="font-family: "courier new" , "courier" , monospace;">ctrl-f</span> to 'Advanced Make'. If you just want the punch line, <span style="font-family: "courier new" , "courier" , monospace;">ctrl-f</span> to 'makefile10a'.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;"> </span>is a program that builds things, usually programs. <span style="font-family: "courier new" , "courier" , monospace;">make</span> saves time. If the input file to <span style="font-family: "courier new" , "courier" , monospace;">make</span> is written properly, then just those files that need to be compiled since the last compilation will be compiled. The purpose of using <span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;"> </span>is to define how a program is built and to save time building a program after an update to the source.<br />
<br />
NOTE: The make files in this tutorial are NOT POSIX compliant.</div>
<div>
<br /></div>
<div>
<h3>
Target and Dependency</h3>
<div>
The fundamental concept of <span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;"> </span>is that files are targets and have dependencies.</div>
<div>
<br /></div>
</div>
<div>
If a file is a target and it doesn't exist or is older in terms of date time than its associated dependency files, then a command is executed to create a new version of the target file.</div>
<div>
<br /></div>
<div>
The syntax to define a target/dependency pair is</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">target : dependency ; command</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><tab>command</span></div>
<div>
<br /></div>
<div>
The target is first, starting in column 1, followed by a colon, followed by one or more dependencies.<br />
<br />
Each target/dependency/command is separated by at least one blank line.</div>
<div>
<br /></div>
<div>
The command to execute can follow the dependency list, separated by a semi-colon, or put on the next line. The common convention is to put the command on the next line.</div>
<div>
<br /></div>
<div>
If the command is put on the next line, then a tab character MUST BE THE ONLY CHARACTER before the command.</div>
<div>
<br /></div>
<div>
Again, if the command is on its own line, the tab character MUST BE THE ONLY CHARACTER before the command.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">make</span> does not output good error messages when the tab character is omitted or a space is used instead.</div>
<div>
<br /></div>
<div>
With whatever editor you use, display spaces and tabs so that you make sure you have the tab where it belongs.</div>
<div>
<br /></div>
<div>
NOTE: Make sure you use a TAB CHARACTER to start the command line of a target/dependency definition.</div>
<div>
<br /></div>
<div>
targets don't have to be files, but usually are.</div>
<div>
<br /></div>
<div>
dependencies don't have to be files, but usually are.</div>
<div>
<br /></div>
<div>
There can be more than one target, but this tutorial will not use that feature.<br />
<br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;"> </span>does not execute the commands in a make file sequentially. The make file defines target/dependency pairs. At least one target/dependency pair has to have associated with it a command, otherwise the make file will do nothing. When <span style="font-family: "courier new" , "courier" , monospace;">make</span> sees that the target is out of date with respect to its dependencies, the command or commands are executed. When these commands are executed has no relationship to its position in the file.</div>
<div>
<br /></div>
<div>
</div>
<span style="font-size: x-small;">Note: <span style="font-family: "courier new" , "courier" , monospace;">make</span> really doesn't like spaces in filenames. Many have asked 'the Internet' how to work around this problem. Any exercise for the reader or a future blog.</span></div>
<div>
<h4>
Make Command Line Syntax.</h4>
A bit of <span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;"> </span>command line syntax.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">make</span><br />
<br />
This command assumes there is a file name <span style="font-family: "courier new" , "courier" , monospace;">makefile</span><span style="font-family: inherit;"> </span>in the current directory and <span style="font-family: "courier new" , "courier" , monospace;">all</span><span style="font-family: inherit;"> </span>will be the default <span style="font-family: "courier new" , "courier" , monospace;">.PHONY</span> word. <span style="font-family: "courier new" , "courier" , monospace;">makefile.mak</span> can also be used. (<span style="font-family: "courier new" , "courier" , monospace;">all</span> and <span style="font-family: "courier new" , "courier" , monospace;">.PHONY</span> discussed soon.)<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">make all</span><br />
<br />
Same as the <span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;"> </span>command above.<br />
<br />
In this tutorial, each make file will get its own unique name.<br />
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">make -f makefile1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span><span style="font-family: inherit;">The </span><span style="font-family: "courier new" , "courier" , monospace;">-f</span><span style="font-family: inherit;"> argument informs </span><span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;"> <span style="font-family: inherit;">t</span>o use </span><span style="font-family: "courier new" , "courier" , monospace;">makefile1</span><span style="font-family: inherit;"> instead of </span><span style="font-family: "courier new" , "courier" , monospace;">makefile</span><span style="font-family: inherit;"> as the input file.</span><br />
<span style="font-family: inherit;"><br /></span><span style="font-family: inherit;">There is only one input file to </span><span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;">, at the command line.</span></div>
<h2>
Simple</h2>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">gcc main.c</span></div>
<div>
<br /></div>
<div>
This command causes <span style="font-family: "courier new" , "courier" , monospace;">gcc</span><span style="font-family: inherit;"> </span>to compile <span style="font-family: "courier new" , "courier" , monospace;">main.c</span> and create <span style="font-family: "courier new" , "courier" , monospace;">a.out</span> (or <span style="font-family: "courier new" , "courier" , monospace;">a.exe</span> for the Cygwin/MinGW crowd).</div>
<div>
<br /></div>
<div>
No need for <span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;"> </span>here. Just one file. No way to save time. Just the one file to compile.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">gcc main.c suba.c subb.c subc.c</span></div>
<div>
<br /></div>
<div>
This command will build another <span style="font-family: "courier new" , "courier" , monospace;">a.out</span> from the list of files. Now the need for <span style="font-family: "courier new" , "courier" , monospace;">make</span> and a make file begins.</div>
<div>
<br /></div>
<div>
If you change just <span style="font-family: "courier new" , "courier" , monospace;">suba.c</span>, then all the other files are built too. The same amount of time is used no matter how big or small the changes.</div>
<div>
<br /></div>
<div>
A shell script (or batch) can hold the complete command to save typing, but not time. Just <span style="font-family: "courier new" , "courier" , monospace;">./buildit.sh</span> (<span style="font-family: "courier new" , "courier" , monospace;">buildit.bat</span>).</div>
<div>
<br /></div>
<div>
But what if your project has dozens and dozens of files? Instead of taking mere moments to build, it will take an hour, even if all you added was one comment.</div>
<div>
<br /></div>
<div>
Let's break down the long <span style="font-family: "courier new" , "courier" , monospace;">gcc</span><span style="font-family: inherit;"> </span>command.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">gcc -c main.c</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">gcc -c suba.c</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">gcc -c subb.c</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">gcc -c subc.c</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">gcc main.o suba.o subb.o subc.o -o aprogram</span></div>
<div>
<br /></div>
<div>
<div>
Again, a shell script could be created to execute all 5 lines, but <span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;"> </span>can do better.</div>
<div>
</div>
<br />
The five commands above builds our program, <span style="font-family: "courier new" , "courier" , monospace;">aprogram</span>, one step at a time. This is the key to a make file. Break the build of your program into individual steps.</div>
<div>
<br /></div>
<div>
Here is the source files we will be using for this tutorial. The program is a scaffolding. It doesn't do anything. It is just code that has relationships to illustrate <span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;"> </span>and <span style="font-family: "courier new" , "courier" , monospace;">make</span>'s features.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">// main.c</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">#include "suba.h"</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">#include "subb.h"</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">#include "subc.h"</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">int main(void)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> suba();</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> subb();</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> subc();</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"> return 1;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">// suba.c</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">#include "suba.h"</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">void suba(void)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">// subb.c</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">#include "subb.h"</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">void subb(void)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">// subc.c</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">#include "subc.h"</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">void subc(void)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">{</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">// suba.h</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">void suba(void);</span><br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">// subb.h</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">void subb(void);</span><br />
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">// subc.h</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">void subc(void);</span><br />
<br /></div>
<div>
Here is the make file version of the above 5 commands.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"># makefile1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">all: aprogram</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f *.o</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f </span><span style="font-family: "courier new" , "courier" , monospace;">aprogram*</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">aprogram: main.o suba.o subb.o subc.o</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc $^ -o $@</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">main.o: main.c</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c $<</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">suba.o: suba.c</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c $<</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">subb.o: subb.c</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c $<</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">subc.o: subc.c</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c $<</span></div>
<div>
<br /></div>
<div>
Let's examine each line of the make file and get familiar with terminology and structure.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY</span> - This keyword tells <span style="font-family: "courier new" , "courier" , monospace;">make</span> where to start. Each of the words on the <span style="font-family: "courier new" , "courier" , monospace;">.PHONY</span> line are arguments to the make program to instruct <span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;"> </span>where to start.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY</span> keyword defines the top of a dependency tree.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">all</span> is a reserved <span style="font-family: "courier new" , "courier" , monospace;">.PHONY</span> word. If <span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;"> </span>is executed with no arguments, <span style="font-family: "courier new" , "courier" , monospace;">all</span><span style="font-family: inherit;"> </span>is the default <span style="font-family: "courier new" , "courier" , monospace;">.PHONY</span> word.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">clean</span><span style="font-family: inherit;"> </span>is a word, used by convention, to remove all files built by using the <span style="font-family: "courier new" , "courier" , monospace;">all</span><span style="font-family: inherit;"> </span>keyword.</div>
<div>
<br /></div>
<div>
Other keywords can be defined. No additional keywords will be defined in this tutorial.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">all: aprogram</span></div>
<div>
<br /></div>
<div>
This line defines our first target/dependency pair. <span style="font-family: "courier new" , "courier" , monospace;">all</span><span style="font-family: inherit;"> </span>is the target. <span style="font-family: "courier new" , "courier" , monospace;">aprogram</span> is the dependency. There is no command associated with this pair. The statement defines the dependency pair and the start of the dependency tree.<br />
<br />
We will skip <span style="font-family: "courier new" , "courier" , monospace;">clean</span> for now.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">aprogram: main.o suba.o subb.o subc.o</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><tab>gcc $^ -o $@</span></div>
<div>
<br /></div>
<div>
This is the first dependency pair with a target, a dependency list, and a command. (note the <span style="font-family: "courier new" , "courier" , monospace;"><tab></span> reminding you to use a tab character before the command.</div>
<div>
<br /></div>
<div>
The <span style="font-family: "courier new" , "courier" , monospace;">$^</span> and <span style="font-family: "courier new" , "courier" , monospace;">$@</span> are <span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;"> </span>automatic variables. <span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;"> </span>has several automatic variables. They define strings based on the targets and dependencies.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$^</span> is the list of dependencies, all of them.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$@</span> is the target.</div>
<div>
<br /></div>
<div>
Expanding the command we would get the following.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">gcc main.o suba.o subb.o subc.o -o aprogram</span></div>
<div>
<br /></div>
<div>
The automatic variables save typing, and later, we will see they are mandatory when using patterns to define dependency pairs.</div>
<div>
<br /></div>
<div>
We have defined <span style="font-family: "courier new" , "courier" , monospace;">all</span> as a target. We have defined <span style="font-family: "courier new" , "courier" , monospace;">aprogram</span><span style="font-family: inherit;"> </span>as its dependency. We have defined <span style="font-family: "courier new" , "courier" , monospace;">aprogram</span><span style="font-family: inherit;"> </span>as a target, the next level in the dependency tree. We have defined a list of object files as dependencies of <span style="font-family: "courier new" , "courier" , monospace;">aprogram</span>.</div>
<div>
<br /></div>
<div>
Now we define each object file as a target.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">main.o : main.c</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><tab>gcc -c $<</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">suba.o : suba.c</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><tab>gcc -c $<</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">subb.o : subb.c</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><tab>gcc -c $<</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">subc.o : subc.c</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><tab>gcc -c $<</span></div>
<div>
<br /></div>
<div>
Each object file has a dependency on a <span style="font-family: "courier new" , "courier" , monospace;">c</span> file. The command to create the target object file, compile the <span style="font-family: "courier new" , "courier" , monospace;">c</span> file is the same for each object and <span style="font-family: "courier new" , "courier" , monospace;">c</span> file pair.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$<</span> is the automatic variable that represents the first dependency. Initially it looks like we could also use <span style="font-family: "courier new" , "courier" , monospace;">$^</span>, as there is only one dependency, but later we will see it is better to use <span style="font-family: "courier new" , "courier" , monospace;">$<</span>.</div>
<div>
<br /></div>
<div>
The <span style="font-family: "courier new" , "courier" , monospace;">c</span> files do not need a dependency. They do not need to be created. They already exist.</div>
<div>
<br /></div>
<div>
Thus the dependency tree is complete.<br />
<br />
[<span style="font-family: "courier new" , "courier" , monospace;">make</span> does allow for dependency pattern, *.o : *.c. Thus all for lines of x.o : x.c are 'implied'. A large number of patterns are pre-defined. This topic discussed in later tutorials.]<br />
<br />
<h4>
clean</h4>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: inherit;">This is a target/dependency pair with no dependency. Thus the commands associated with it are always executed.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">@rm -f *.o</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">@rm -f </span><span style="font-family: "courier new" , "courier" , monospace;">aprogram*</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: inherit;">The command rm (remove files) remove all the object files. The </span><span style="font-family: "courier new" , "courier" , monospace;">-f</span><span style="font-family: inherit;"> switch says to not report an error if the file does not exist. The @ in front of </span><span style="font-family: "courier new" , "courier" , monospace;">rm</span><span style="font-family: inherit;"> suppresses any output from the program.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">The second line removes </span><span style="font-family: "courier new" , "courier" , monospace;">aprogram</span><span style="font-family: inherit;"> or </span><span style="font-family: "courier new" , "courier" , monospace;">aprogram.exe</span><span style="font-family: inherit;">, doesn't matter</span><span style="font-family: "courier new" , "courier" , monospace;">.</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">clean</span> removes all files created by <span style="font-family: "courier new" , "courier" , monospace;">all</span>.</div>
<div>
<br /></div>
<h4>
<span style="font-family: inherit;">Execute makefile1</span></h4>
</div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">make -f makefile1</span></div>
<div>
</div>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Running the above command we get the following output.</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4dOJ8aaZk8oZ_tBg6Q4BAWr7whxRuwZdvSeqCFPVPhQgTPsFAnc1Ky9TF34Ss-Maognfxo6ngn5hYFUwo4QRUh8XsL8l-1M9YL6-PjfpZsmLv5A70sPlgnbJHGkizxz8sg7E2cCBNCSE/s1600/makefile1a.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="82" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4dOJ8aaZk8oZ_tBg6Q4BAWr7whxRuwZdvSeqCFPVPhQgTPsFAnc1Ky9TF34Ss-Maognfxo6ngn5hYFUwo4QRUh8XsL8l-1M9YL6-PjfpZsmLv5A70sPlgnbJHGkizxz8sg7E2cCBNCSE/s320/makefile1a.gif" width="320" /></a></div>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span><br />
<span style="font-family: inherit;"><br /></span><span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span><br />
<span style="font-family: inherit;">We see that all four files are compiled and </span><span style="font-family: "courier new" , "courier" , monospace;">aprogram</span><span style="font-family: inherit;"> is built.</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">touch suba.c</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">make -f makefile1</span></div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiricwGWqeq6zPMT3fE_81dOuv3Gt7tfNxlaHCNU8c37PynTq7_LgHYABr0yqJXU8qO2AgN0WSAzKzIuxq7XOMiitUj67T3QJxLQLMBCOuIMXGGMRAtEyq7UZFGBeDEdJAS9LD8TJVPol8/s1600/makefile1b.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="81" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiricwGWqeq6zPMT3fE_81dOuv3Gt7tfNxlaHCNU8c37PynTq7_LgHYABr0yqJXU8qO2AgN0WSAzKzIuxq7XOMiitUj67T3QJxLQLMBCOuIMXGGMRAtEyq7UZFGBeDEdJAS9LD8TJVPol8/s320/makefile1b.gif" width="320" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
Now we see the power of <span style="font-family: "courier new" , "courier" , monospace;">make</span>. The <span style="font-family: "courier new" , "courier" , monospace;">touch</span><span style="font-family: inherit;"> </span>command updated the date time of <span style="font-family: "courier new" , "courier" , monospace;">suba.c</span>. <span style="font-family: "courier new" , "courier" , monospace;">suba.c</span> is now newer than its object file. <span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;"> </span>scans the target/dependencies and determines that the command associated with <span style="font-family: "courier new" , "courier" , monospace;">suba.o</span> needs to be executed. Since <span style="font-family: "courier new" , "courier" , monospace;">suba.o</span> is a dependency of <span style="font-family: "courier new" , "courier" , monospace;">aprogram</span>, the command for <span style="font-family: "courier new" , "courier" , monospace;">aprogram</span><span style="font-family: inherit;"> </span>is executed next.<br />
<br />
Only two commands are executed instead of five.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">make -f makefile1 clean</span><br />
<br />
This command specifies <span style="font-family: "courier new" , "courier" , monospace;">clean</span> as the top level dependency <span style="font-family: "courier new" , "courier" , monospace;">.PHONY</span> word.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgt8jh1FloU-IuJibpvyDmYSGv5NFzflTo21k8NVkknXzONsxg4VE5p0qmUUXftcSO8O3x69ejPoKU5rFrOmD7hmCAC1LPx1oWE2GyKP-NvxLVdOtObkCoxH8dWG-VKS58daOupDFQjakY/s1600/makefile1c.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="81" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgt8jh1FloU-IuJibpvyDmYSGv5NFzflTo21k8NVkknXzONsxg4VE5p0qmUUXftcSO8O3x69ejPoKU5rFrOmD7hmCAC1LPx1oWE2GyKP-NvxLVdOtObkCoxH8dWG-VKS58daOupDFQjakY/s400/makefile1c.gif" width="400" /></a></div>
<br />
<br /></div>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
</h3>
<h3>
Include Files</h3>
<div>
What about the include files?<br />
<br />
An observant reader will notice that the include files are not listed in <span style="font-family: "courier new" , "courier" , monospace;">makefile1</span>.<br />
<br />
Let's update that now.<br />
<br />
<span style="background-color: white; color: #6aa84f; font-family: "courier new" , "courier" , monospace;"># makefile2</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">all: aprogram</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f *.o</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f </span><span style="font-family: "courier new" , "courier" , monospace;">aprogram*</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">aprogram: main.o suba.o subb.o subc.o</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc $^ -o $@</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">main.o: main.c <span style="color: red;">suba.h subb.h subc.h</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c $<</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">suba.o: suba.c <span style="color: red;">suba.h</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c $<</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">subb.o: subb.c <span style="color: red;">subb.h</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c $<</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">subc.o: subc.c <span style="color: red;">subc.h</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c $<</span></div>
<div>
<br /></div>
<div>
<span style="font-size: x-small;">[Note: <span style="color: red;">Red </span>is used to show how the make files are updated from step to step in this tutorial.]</span><br />
<br /></div>
<div>
Each object file now has the corresponding include file as a dependency file.<br />
<br />
We now have more than one dependency for each object file, but we still want the command to compile just the c file. The automatic variable <span style="font-family: "courier new" , "courier" , monospace;">$<</span> still uses just the <span style="font-family: "courier new" , "courier" , monospace;">c</span> file, not the additional include files added (as long as the c file remains the first dependency).<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">touch suba.h</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">make -f makefile2</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEji_kvS6r98KOf4WdPS1pP1jJqTvnIKFIlh249GNKh9857DzQn-IsNyTaizSUDnuEdTBdlHxntBa0aUEs4FuUaZY2MP0PNPSA7OQnhnuLr36IkmyyJikkQJmKXEDFcQ5mdxQYg64rCiOFI/s1600/makefile2a.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="106" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEji_kvS6r98KOf4WdPS1pP1jJqTvnIKFIlh249GNKh9857DzQn-IsNyTaizSUDnuEdTBdlHxntBa0aUEs4FuUaZY2MP0PNPSA7OQnhnuLr36IkmyyJikkQJmKXEDFcQ5mdxQYg64rCiOFI/s320/makefile2a.gif" width="320" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
If <span style="font-family: "courier new" , "courier" , monospace;">suba.h</span> is changed, then both <span style="font-family: "courier new" , "courier" , monospace;">suba.o</span> and <span style="font-family: "courier new" , "courier" , monospace;">main.o</span> are rebuilt, thus <span style="font-family: "courier new" , "courier" , monospace;">aprogram</span><span style="font-family: inherit;"> </span>is rebuilt.<br />
<br />
Note that repeating the command, <span style="font-family: "courier new" , "courier" , monospace;">make</span> reports nothing to be done, a test the make file is correct.<br />
<br />
<h3>
Simple Summary</h3>
<div>
For really simple programs, I mean really simple programs, <span style="font-family: "courier new" , "courier" , monospace;">makefile2</span><span style="font-family: inherit;"> </span>provides a guide to creating useful make files.</div>
<div>
<br /></div>
<div>
But production quality programs are not this simple.</div>
<div>
<br /></div>
<div>
The problem with <span style="font-family: "courier new" , "courier" , monospace;">makefile2</span><span style="font-family: inherit;"> </span>is the file is brittle. If a new include file is created, or a new <span style="font-family: "courier new" , "courier" , monospace;">c</span> file is created or deleted, the dependency tree has to be updated, by hand. This is tedious and error prone.</div>
<div>
<br /></div>
<div>
The rest of the tutorial is how to create a make file that automates the building of the list of files to be compiled and linked.</div>
<h2>
Advanced Make</h2>
<h3>
Variables</h3>
Make is an interpretive programming language. Not a 'typical' programming language, but a programming language. (probably not Turing complete :) ).<br />
<br />
Just like all programming languages, <span style="font-family: "courier new" , "courier" , monospace;">make</span> has variables. We saw a few automatic variables above.<br />
<br />
Let's change <span style="font-family: "courier new" , "courier" , monospace;">makefile2</span> to use a variable or two.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"># makefile<span style="color: red;">3</span></span><br />
<span style="color: red; font-family: "courier new" , "courier" , monospace;">OBJS = main.o suba.o subb.o subc.o</span><br />
<span style="color: red; font-family: "courier new" , "courier" , monospace;">TARGET = aprogram</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">all: <span style="color: red;">$(TARGET)</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f *.o</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f <span style="color: red;">$(TARGET)</span>*</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="color: red; font-family: "courier new" , "courier" , monospace;">$(TARGET): $(OBJS)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc $^ -o $@</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">main.o: main.c suba.h subb.h subc.h</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c $<</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">suba.o: suba.c suba.h</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c $<</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">subb.o: subb.c subb.h</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c $<</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">subc.o: subc.c subc.h</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c $<</span></div>
<div>
<br />
<span style="font-family: inherit;">The string of object files is now a variable, </span><span style="font-family: "courier new" , "courier" , monospace;">OBJS</span><span style="font-family: inherit;">. The name of our program is now a variable, </span><span style="font-family: "courier new" , "courier" , monospace;">TARGET</span><span style="font-family: inherit;">.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">To use a variable name, the name is preceded by </span><span style="font-family: "courier new" , "courier" , monospace;">$(</span><span style="font-family: inherit;"> and followed by </span><span style="font-family: "courier new" , "courier" , monospace;">)</span><span style="font-family: inherit;">. The automatic variables were preceded with a </span><span style="font-family: "courier new" , "courier" , monospace;">$</span><span style="font-family: inherit;">. So any variable in </span><span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;"> is referenced by using a </span><span style="font-family: "courier new" , "courier" , monospace;">$</span><span style="font-family: inherit;">. An automatic variable is one of several letters. A user defined variable is surrounded with parentheses. Brackets </span><span style="font-family: "courier new" , "courier" , monospace;">{ }</span><span style="font-family: inherit;"> can be used in place of parentheses, but </span>parentheses<span style="font-family: inherit;"> are much more commonly used.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Variables will play a major role in the final production quality make file.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">makefile3</span><span style="font-family: inherit;"> is no less brittle than </span><span style="font-family: "courier new" , "courier" , monospace;">makefile2</span><span style="font-family: inherit;">.</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<h2>
<span style="font-family: inherit;">Patterns</span></h2>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;"> allows for patterns to be used in defining a target/dependency pair.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">%.o : %.c</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">The </span><span style="font-family: "courier new" , "courier" , monospace;">%.o</span><span style="font-family: inherit;"> pattern states any file that ends in a two characters </span><span style="font-family: "courier new" , "courier" , monospace;">.o</span><span style="font-family: inherit;"> is a target. The corresponding dependency file uses the same </span><span style="font-family: "courier new" , "courier" , monospace;">%</span><span style="font-family: inherit;"> string for the root name but changes the </span><span style="font-family: "courier new" , "courier" , monospace;">.o</span><span style="font-family: inherit;"> to </span><span style="font-family: "courier new" , "courier" , monospace;">.c</span><span style="font-family: inherit;">.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">Let's use the above pattern to change </span><span style="font-family: "courier new" , "courier" , monospace;">makefile3</span><span style="font-family: inherit;">.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"># makefile<span style="color: red;">4</span></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">OBJS = main.o suba.o subb.o subc.o</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">TARGET = aprogram</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">all: $(TARGET)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f *.o</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(TARGET)*</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(TARGET): $(OBJS)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc $^ -o $@</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace;">%.o: %.c</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c $<</span></div>
<div style="font-family: inherit;">
<br /></div>
</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">makefile4</span><span style="font-family: inherit;"> is a lot shorter than </span><span style="font-family: "courier new" , "courier" , monospace;">makefile3</span><span style="font-family: inherit;">. The automatic variable </span><span style="font-family: "courier new" , "courier" , monospace;">$<</span><span style="font-family: inherit;"> is required when using a pattern as the actual name of the dependency is not known until </span><span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;"> runs.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">A bit of automation has been added. If we add a new </span><span style="font-family: "courier new" , "courier" , monospace;">c</span><span style="font-family: inherit;"> file or delete a </span><span style="font-family: "courier new" , "courier" , monospace;">c</span><span style="font-family: inherit;"> file, we only have to add or remove from the corresponding object file in </span><span style="font-family: "courier new" , "courier" , monospace;">OBJS</span><span style="font-family: inherit;">.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Let's review how the dependency tree is built. </span><span style="font-family: "courier new" , "courier" , monospace;">all</span><span style="font-family: inherit;"> is dependent on </span><span style="font-family: "courier new" , "courier" , monospace;">$(TARGET)</span><span style="font-family: inherit;">. </span><span style="font-family: "courier new" , "courier" , monospace;">$(TARGET)</span><span style="font-family: inherit;"> is dependent on the list </span><span style="font-family: "courier new" , "courier" , monospace;">$(OBJS)</span><span style="font-family: inherit;">. The pattern dependency then generates the </span><span style="font-family: "courier new" , "courier" , monospace;">c</span><span style="font-family: inherit;"> file dependencies for each object file in the </span><span style="font-family: "courier new" , "courier" , monospace;">$(OBJS)</span><span style="font-family: inherit;"> list. The object file targets used by the pattern come from the make file. Remember the object files do not exist the first time.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">But we have lost the dependency relationship with the include files.</span></div>
<div>
<span style="font-family: inherit;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9MN71QxnoHZBQ0QBmXG1GOYuUe5CwxiclZky_KK6kayHM9BiB_bdzgLajDswWWUIFvL31hrSkXfe-3Bc6nzp2WECC2Cfr8-FnCBhrVWz_If7i3EIRu0ywtPn2h43CTVU7H_DRyKW5XF4/s1600/makefile4a.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="129" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9MN71QxnoHZBQ0QBmXG1GOYuUe5CwxiclZky_KK6kayHM9BiB_bdzgLajDswWWUIFvL31hrSkXfe-3Bc6nzp2WECC2Cfr8-FnCBhrVWz_If7i3EIRu0ywtPn2h43CTVU7H_DRyKW5XF4/s320/makefile4a.gif" width="320" /></a></div>
<span style="font-family: inherit;"><br /></span>
<br />
<h3>
<span style="font-family: inherit;"><br /></span></h3>
<h3>
<span style="font-family: inherit;"><br /></span></h3>
<h3>
<span style="font-family: inherit;"><br /></span></h3>
<span style="font-family: inherit;">Touching </span><span style="font-family: "courier new" , "courier" , monospace;">suba.h</span><span style="font-family: inherit;"> does not result in rebuilding </span><span style="font-family: "courier new" , "courier" , monospace;">suba.o</span><span style="font-family: inherit;"> and </span><span style="font-family: "courier new" , "courier" , monospace;">aprogram</span><span style="font-family: inherit;">.</span><br />
<h3>
<span style="font-family: inherit;">DEPS</span></h3>
</div>
<div>
<span style="font-family: inherit;">Let's do a quick and dirty remedy.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">#makefile<span style="color: red;">5</span></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">OBJS <span style="color: red;">:=</span> main.o suba.o subb.o subc.o</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace;">DEPS := suba.h subb.h subc.h</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">TARGET <span style="color: red;">:=</span> aprogram</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">all: $(TARGET)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f *.o</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(TARGET)*</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(TARGET): $(OBJS)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc $^ -o $@</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">%.o: %.c <span style="color: red;">$(DEPS)</span></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c $<</span></div>
<div style="font-family: inherit;">
<br /></div>
</div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">We created the variable </span><span style="font-family: "courier new" , "courier" , monospace;">DEPS</span><span style="font-family: inherit;"> to hold all the include files. We made this list a dependent on any object file. </span><span style="font-family: "courier new" , "courier" , monospace;">DEPS</span><span style="font-family: inherit;"> is a variable name, used by convention, for include files.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">This update works. However, if just an include file is changed, then all the objects and </span><span style="font-family: "courier new" , "courier" , monospace;">aprogram</span><span style="font-family: inherit;"> are rebuilt. </span><span style="font-family: "courier new" , "courier" , monospace;">aprogram</span><span style="font-family: inherit;"> is built properly, but </span><span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;"> builds more object files than is necessary.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvnsfuSmmu_hhyphenhyphenrr0IOoEJYubpgvTz71PeNm99PUIcG-TJeuP5bPL3JnbJe9QUBEeL-xZ8zoDtglfJnq_tt_XcpQrvf9gp9r6wJE25EZpfP-sdMZkbadMbo5NMw1KUhex8aaahKURo9do/s1600/makefile5a.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="167" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvnsfuSmmu_hhyphenhyphenrr0IOoEJYubpgvTz71PeNm99PUIcG-TJeuP5bPL3JnbJe9QUBEeL-xZ8zoDtglfJnq_tt_XcpQrvf9gp9r6wJE25EZpfP-sdMZkbadMbo5NMw1KUhex8aaahKURo9do/s320/makefile5a.gif" width="320" /></a></div>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span><span style="font-family: inherit;">We are back to an inefficient make file, but are now using variables to localize the files.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">We will come back and update the make file so that the minimum number of object files are built for just an include file change.</span></div>
<div>
<span style="font-family: inherit;"><br /></span>
<br />
<h4>
<span style="font-family: inherit;">Recursively Defined and Simply Defined Variables</span></h4>
Another subtle, but important change was made. Equal signs (<span style="font-family: "courier new" , "courier" , monospace;">=</span>) were changed to colon equal signs (<span style="font-family: "courier new" , "courier" , monospace;">:=</span>).<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">make</span> has two types of variables, recursively defined variables and simply defined variables. If the string being assigned to a variable can be determined without recursion, statically, then use the simply defined variable notation, colon equal (:=). It is faster than recursively defined variables.<br />
<br />
All variables in this tutorial are simply defined variables. It was difficult to find a good example of a recursively defined variable, and they are not needed here.</div>
<h2>
<span style="font-family: inherit;">Directories</span></h2>
<div>
<span style="font-family: inherit;">Another observant reader will notice that the object files and </span><span style="font-family: "courier new" , "courier" , monospace;">aprogram</span><span style="font-family: inherit;"> are being created in the same directory as the source files.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">This is considered poor form. It is messy. Production make files have the object files in one directory, the source in another directory, and the program in a third directory. A convention is followed where the object files and the program are put in the same directory. This tutorial will have the program and object files in separate directories.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">We move all the sources to a sub-directory named </span><span style="font-family: "courier new" , "courier" , monospace;">src</span><span style="font-family: inherit;">. The object files will be placed in the sub-directory </span><span style="font-family: "courier new" , "courier" , monospace;">obj</span><span style="font-family: inherit;">, and the program will be placed in the sub-directory </span><span style="font-family: "courier new" , "courier" , monospace;">target</span><span style="font-family: inherit;">.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">Several make tutorials talk about it being easiest to design a make file when the make file runs in the directory where the object files are to be built.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">Yes, this can be easier when building the make file. The make file is just like any other source file. It will be archived in source control. If it exists in a directory where all the other files are intermediate, temporary files, one can accidentally delete all the files in the </span><span style="font-family: "courier new" , "courier" , monospace;">obj</span><span style="font-family: inherit;"> directory, requiring the make file to be retrieved from the source control archive.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">The following make file is expected to be run in the parent directory of </span><span style="font-family: "courier new" , "courier" , monospace;">src</span><span style="font-family: inherit;">, </span><span style="font-family: "courier new" , "courier" , monospace;">obj</span><span style="font-family: inherit;">, and </span><span style="font-family: "courier new" , "courier" , monospace;">target</span><span style="font-family: inherit;">.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">Let's update the various filenames in the make file with the new directory names.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">#makefile<span style="color: red;">6 - doesn't work</span></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">OBJS := <span style="color: red;">obj/</span>main.o <span style="color: red;">obj/</span>suba.o <span style="color: red;">obj/</span>subb.o <span style="color: red;">obj/</span>subc.o</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">DEPS := <span style="color: red;">src/</span>suba.h <span style="color: red;">src/</span>subb.h <span style="color: red;">src/</span>subc.h</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">TARGET := <span style="color: red;">target/</span>aprogram</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">all: $(TARGET)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm –f obj/*.o</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm –f $(TARGET)*</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(TARGET): $(OBJS)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc $^ -o $@</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: red;">obj/</span>%.o: %.c $(DEPS)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc –c $<<span style="color: red;"> -o $@</span></span></div>
<div style="font-family: inherit;">
<br /></div>
</div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">The include files have the </span><span style="font-family: "courier new" , "courier" , monospace;">src</span><span style="font-family: inherit;"> directory pre-pended. The object files have the </span><span style="font-family: "courier new" , "courier" , monospace;">obj</span><span style="font-family: inherit;"> directory pre-pended. </span><span style="font-family: "courier new" , "courier" , monospace;">aprogram</span><span style="font-family: inherit;"> has </span><span style="font-family: "courier new" , "courier" , monospace;">target</span><span style="font-family: inherit;"> pre-pended.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">However, as the comment states, </span><span style="font-family: "courier new" , "courier" , monospace;">makefile6</span><span style="font-family: inherit;"> doesn't work.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjh8G83nk_SoitTygBSAfaaxMd9XBvwITdw7-cLyUNeraYbiKpA5r35_BcaNW5QYbr7LvkASo1l6pNuVkfGHt0C8gHvqjPZgZ5bDTghsyYotVhr6QFm2J9tatUwWctB5FFzxvrr6ruNaVw/s1600/makefile6a.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="92" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjh8G83nk_SoitTygBSAfaaxMd9XBvwITdw7-cLyUNeraYbiKpA5r35_BcaNW5QYbr7LvkASo1l6pNuVkfGHt0C8gHvqjPZgZ5bDTghsyYotVhr6QFm2J9tatUwWctB5FFzxvrr6ruNaVw/s640/makefile6a.gif" width="640" /></a></div>
<br /></div>
<div>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">There are two reasons </span><span style="font-family: "courier new" , "courier" , monospace;">makefile6</span><span style="font-family: inherit;"> does not work. A simple change will correct one problem.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Change</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: red;">obj/</span>%.o: %.c $(DEPS)</span></div>
<span style="font-family: "courier new" , "courier" , monospace;"><span style="white-space: pre;"> </span>gcc –c $< -o $@</span></div>
<div>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">to</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: red;">obj/</span>%.o: <span style="color: red;">src/</span>%.c $(DEPS)</span></div>
<span style="font-family: "courier new" , "courier" , monospace;"><span style="white-space: pre;"> </span>gcc –c $< -o $@</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">This change illustrates the literal nature of the make pattern.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">obj/%.o</span><span style="font-family: inherit;"> specifies any file in </span><span style="font-family: "courier new" , "courier" , monospace;">obj</span><span style="font-family: inherit;"> where the pattern (</span><span style="font-family: "courier new" , "courier" , monospace;">%</span><span style="font-family: inherit;">) is the root portion of the name.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">%.c</span><span style="font-family: inherit;"> then says take the found object root name and simply change </span><span style="font-family: "courier new" , "courier" , monospace;">.o</span><span style="font-family: inherit;"> to </span><span style="font-family: "courier new" , "courier" , monospace;">.c</span><span style="font-family: inherit;">.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">If we start with </span><span style="font-family: "courier new" , "courier" , monospace;">obj/main.o</span><span style="font-family: inherit;"> for a target. The dependency is then </span><span style="font-family: "courier new" , "courier" , monospace;">main.c</span><span style="font-family: inherit;">.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">gcc -c main.c -o obj/main.o</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: inherit;">The source files do not exist in the parent </span><span style="font-family: inherit;">directory, thus </span><span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;"> cannot find the dependency.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">With the update of </span><span style="font-family: "courier new" , "courier" , monospace;">src/%.c</span><span style="font-family: inherit;"> the command is now</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">gcc -c src/main.c -o obj/main.o</span><br />
<span style="font-family: inherit;"><br /></span>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOANFMX31t23iTlOuFL8qWhKfu-sms8Ph-PaxDtxe3TOkPwqH-HTwXCA5mrEzNDOspmxZl68QMTnHGUjdgJK49PDNic5W_uNwU5BMm0K3mi17T9ZJjgHdFfF387a55eoSfaaZfuSpstng/s1600/makefile6b.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="114" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOANFMX31t23iTlOuFL8qWhKfu-sms8Ph-PaxDtxe3TOkPwqH-HTwXCA5mrEzNDOspmxZl68QMTnHGUjdgJK49PDNic5W_uNwU5BMm0K3mi17T9ZJjgHdFfF387a55eoSfaaZfuSpstng/s640/makefile6b.gif" width="640" /></a><span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">There is still an error. This time from </span><span style="font-family: "courier new" , "courier" , monospace;">gcc</span><span style="font-family: inherit;">, not </span><span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;">. The error 'No such file or directory' is being reported because the </span><span style="font-family: "courier new" , "courier" , monospace;">obj</span><span style="font-family: inherit;"> directory does not exist, not that the file </span><span style="font-family: "courier new" , "courier" , monospace;">obj/main.o</span><span style="font-family: inherit;"> does not exist. A bit confusing, but par for make error messages.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">gcc</span><span style="font-family: inherit;"> expects the </span><span style="font-family: "courier new" , "courier" , monospace;">obj</span><span style="font-family: inherit;"> directory (and the </span><span style="font-family: "courier new" , "courier" , monospace;">target</span><span style="font-family: inherit;"> directory) to exist before it will write </span><span style="font-family: "courier new" , "courier" , monospace;">main.o</span><span style="font-family: inherit;"> into the o</span><span style="font-family: "courier new" , "courier" , monospace;">bj</span><span style="font-family: inherit;"> directory. </span><span style="font-family: "courier new" , "courier" , monospace;">gcc</span><span style="font-family: inherit;"> does not create directories if they are missing.</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<h3>
<span style="font-family: inherit;">VPATH and vpath</span></h3>
<div>
<span style="font-family: inherit;">We take a step back and solve the issue not finding the sources a different way than adding </span><span style="font-family: "courier new" , "courier" , monospace;">src/</span><span style="font-family: inherit;"> to the pattern.</span><br />
<span style="font-family: inherit;"><br /></span><span style="font-family: inherit;">Enter </span><span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;">'s </span><span style="font-family: "courier new" , "courier" , monospace;">vpath</span><span style="font-family: inherit;"> feature.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">make</span> contains a variable and a function to define a virtual path to look for dependencies.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">VPATH</span> is a reserved variable. It may contain a list of one or more directories to look for dependencies.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">vpath</span>, all lowercase, is a function that has two arguments, a pattern and a list of directories.</div>
<div>
<br /></div>
<div>
There is only one <span style="font-family: "courier new" , "courier" , monospace;">VPATH</span> variable. There may be as many <span style="font-family: "courier new" , "courier" , monospace;">vpath</span> pattern/directory pairs as you need.</div>
<div>
<br /></div>
<div>
Update <span style="font-family: "courier new" , "courier" , monospace;">makefile6</span> to use <span style="font-family: "courier new" , "courier" , monospace;">vpath</span>.</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">#makefile<span style="color: red;">7</span> - does not work</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">OBJS := obj/main.o obj/suba.o obj/subb.o obj/subc.o</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">DEPS := src/suba.h src/subb.h src/subc.h</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">TARGET := target/aprogram</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace;">vpath %.c src</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">all: $(TARGET)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f obj/*.o</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(TARGET)*</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(TARGET): $(OBJS)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc $^ -o $@</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">obj/%.o: %.c $(DEPS)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c $< -o $@</span></div>
</div>
<div>
<br /></div>
<div>
Now the command</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">gcc -c main.c -o obj/main.o</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: inherit;">is still generated, but </span><span style="font-family: "courier new" , "courier" , monospace;">vpath</span><span style="font-family: inherit;"> instructs </span><span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;"> to look in the </span><span style="font-family: "courier new" , "courier" , monospace;">src</span><span style="font-family: inherit;"> directory if a dependent file with a </span><span style="font-family: "courier new" , "courier" , monospace;">.c</span><span style="font-family: inherit;"> extension is not found by default.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">makefile7</span><span style="font-family: inherit;"> still does not work, We'll fix the missing directories next.</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvUPoPbjUqeHSLY5T6W7MrltVuMMRZp4pjIOiG5uXT-gaiAerjt1m6F7Fw5AAaVrqY6U4ZVojAmqIsNse07q-d-T44Xy0akygP32GnuXyTztB8fjfxfKCRUB1fb7gwb8YO5-nVRqBgPLE/s1600/makefile7a.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="113" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvUPoPbjUqeHSLY5T6W7MrltVuMMRZp4pjIOiG5uXT-gaiAerjt1m6F7Fw5AAaVrqY6U4ZVojAmqIsNse07q-d-T44Xy0akygP32GnuXyTztB8fjfxfKCRUB1fb7gwb8YO5-nVRqBgPLE/s640/makefile7a.gif" width="640" /></a></div>
<span style="font-family: inherit;"><br /></span></div>
<br />
<h3>
<span style="font-family: inherit;"><br /></span></h3>
<h3>
<span style="font-family: inherit;">Creating Missing Directories</span></h3>
<div>
The make file must define the directories that need to be created and create them prior to compiling the <span style="font-family: "courier new" , "courier" , monospace;">c</span> files.</div>
<div>
<br /></div>
<div>
There are two directories to create, <span style="font-family: "courier new" , "courier" , monospace;">obj</span> and <span style="font-family: "courier new" , "courier" , monospace;">target</span>. We need to have a command to create these directories, if they don't exist.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">mkdir</span> is the command to create a directory. <span style="font-family: "courier new" , "courier" , monospace;">mkdir</span><span style="font-family: inherit;"> is an external command. It is not built into </span><span style="font-family: "courier new" , "courier" , monospace;">make</span><span style="font-family: inherit;">, just like </span><span style="font-family: "courier new" , "courier" , monospace;">gcc</span><span style="font-family: inherit;">.</span></div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">mkdir -p <directory></span> will create <span style="font-family: "courier new" , "courier" , monospace;"><directory></span> if it does not exist and not report an error if it does.</div>
<div>
<br /></div>
<div>
There are two approaches to updating the make file to create the missing directories. Approach 1 is to add the missing directories to the dependency tree. Approach 2 is to use variables to create the directories.</div>
<div>
<br /></div>
<h4>
Missing Directory - Approach 1</h4>
<div>
<div style="direction: ltr; margin-bottom: 0pt; margin-left: 0in; margin-top: 3.84pt; text-indent: 0in; unicode-bidi: embed; word-break: normal;">
<span style="font-family: "courier new";">all: </span><span style="font-family: "courier new"; text-indent: 0in;">required_dirs </span><span style="font-family: "courier new"; text-indent: 0in;">$(TARGET)</span></div>
<div style="direction: ltr; margin-bottom: 0pt; margin-left: 0in; margin-top: 3.84pt; text-indent: 0in; unicode-bidi: embed; word-break: normal;">
<br /></div>
<div style="direction: ltr; margin-bottom: 0pt; margin-left: 0in; margin-top: 3.84pt; text-indent: 0in; unicode-bidi: embed; word-break: normal;">
<span style="font-family: "courier new";">required_dirs </span><span style="font-family: "courier new";">:
$(OBJ_DIR) $(TARGET_DIR</span><span style="font-family: "courier new";">)</span><br />
<span style="font-family: "courier new";"><br /></span></div>
<div style="direction: ltr; margin-bottom: 0pt; margin-left: 0in; margin-top: 3.84pt; text-indent: 0in; unicode-bidi: embed; word-break: normal;">
</div>
<div style="direction: ltr; margin-bottom: 0pt; margin-left: 0in; margin-top: 3.84pt; text-indent: 0in; unicode-bidi: embed; word-break: normal;">
<span style="font-family: "courier new";">$(OBJ_DIR) :</span></div>
<div style="direction: ltr; margin-bottom: 0pt; margin-left: 0in; margin-top: 3.84pt; text-indent: 0in; unicode-bidi: embed; word-break: normal;">
<span style="font-family: "courier new";"><tab>@</span><span style="font-family: "courier new";">mkdir</span><span style="font-family: "courier new";"> –p
$@</span></div>
<div style="direction: ltr; margin-bottom: 0pt; margin-left: 0in; margin-top: 3.84pt; text-indent: 0in; unicode-bidi: embed; word-break: normal;">
<span style="font-family: "courier new";"><br /></span></div>
<div style="direction: ltr; margin-bottom: 0pt; margin-left: 0in; margin-top: 3.84pt; text-indent: 0in; unicode-bidi: embed; word-break: normal;">
<span style="font-family: "courier new";">$(TARGET_DIR) :</span></div>
<span style="font-family: "courier new";"><tab></span><span style="font-family: "courier new"; text-indent: 0in;">@</span><span style="font-family: "courier new"; text-indent: 0in;">mkdir</span><span style="font-family: "courier new"; text-indent: 0in;"> –p
$@</span></div>
<br />
The new target, <span style="font-family: "courier new" , "courier" , monospace;">required_dirs</span> is added to the list of dependencies for <span style="font-family: "courier new" , "courier" , monospace;">all</span>. Each directory in turn has a target/command pair. Without a dependency the command, <span style="font-family: "courier new" , "courier" , monospace;">mkdir,</span> is always executed. If the directory does not exist, it is created.<br />
<h4>
Missing Directory - Approach 2</h4>
<br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;">REQUIRED_DIRS := $(OBJ_DIR) $(TARGET_DIR)</span></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">_MKDIRS := $(shell for d in $(REQUIRED_DIRS);<span class="Apple-tab-span" style="white-space: pre;"> </span>\</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>do<span class="Apple-tab-span" style="white-space: pre;"> </span>\</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>mkdir -p $$d;<span class="Apple-tab-span" style="white-space: pre;"> </span>\</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>done)</span></div>
</div>
<div>
<br /></div>
<br />
<div>
The variable <span style="font-family: "courier new" , "courier" , monospace;">REQUIRED_DIRS</span> is now a list of the required directories.</div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">_MKDIRS</span> is a variable that is assigned the result of the shell command.</div>
<div>
<br /></div>
<div>
make allows scripts to be run using the function <span style="font-family: "courier new" , "courier" , monospace;">shell</span>.</div>
<div>
Note that <span style="font-family: "courier new" , "courier" , monospace;">shell</span> is surrounded by <span style="font-family: "courier new" , "courier" , monospace;">$( )</span>. Essentially the return code of <span style="font-family: "courier new" , "courier" , monospace;">shell</span> is a variable.</div>
<div>
<br /></div>
<div>
The above shell script is a do loop that iterates over the list of directories, creates a shell variable <span style="font-family: "courier new" , "courier" , monospace;">d</span> and creates each directory if it does not exist. The <span style="font-family: "courier new" , "courier" , monospace;">$$</span> is so that <span style="font-family: "courier new" , "courier" , monospace;">d</span> is used as a shell variable, not a make file variable.<br />
<br />
Note: Tabs are not required here. This is a definition of variables, not a target/pair dependency.</div>
<div>
<br /></div>
<div>
Let's incorporate Approach 2 into <span style="font-family: "courier new" , "courier" , monospace;">makefile7</span>.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">#makefile<span style="color: red;">8</span></span><br />
<span style="color: red; font-family: "courier new" , "courier" , monospace;">OBJ_DIR := obj</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">OBJS := <span style="color: red;">$(OBJ_DIR)</span>/main.o <span style="color: red;">$(OBJ_DIR)</span>/suba.o <span style="color: red;">$(OBJ_DIR)</span>/subb.o <span style="color: red;">$(OBJ_DIR)</span>/subc.o</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">DEPS := src/suba.h src/subb.h src/subc.h</span><br />
<span style="color: red; font-family: "courier new" , "courier" , monospace;">TARGET_DIR := target</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">TARGET := <span style="color: red;">$(TARGET_DIR)</span>/aprogram</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">vpath %.c src</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">all: $(TARGET)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f <span style="color: red;">$(OBJ_DIR)</span>/*.o</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(TARGET)*</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">$(TARGET): $(OBJS)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc $^ -o $@</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: red;">$(OBJ_DIR)</span>/%.o: %.c $(DEPS)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c $< -o $@</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="color: red; font-family: "courier new" , "courier" , monospace;">REQUIRED_DIRS := $(OBJ_DIR) $(TARGET_DIR)</span><br />
<span style="color: red; font-family: "courier new" , "courier" , monospace;">_MKDIRS := $(shell for d in $(REQUIRED_DIRS);<span class="Apple-tab-span" style="white-space: pre;"> </span>\</span><br />
<span style="color: red; font-family: "courier new" , "courier" , monospace;"><span style="white-space: pre;">do \
mkdir -p $$d; \</span></span> <span class="Apple-tab-span" style="color: red; font-family: "courier new" , "courier" , monospace; white-space: pre;"> </span><span style="color: red; font-family: "courier new" , "courier" , monospace;">done)</span></div>
<div>
<br /></div>
<div>
Added the variables <span style="font-family: "courier new" , "courier" , monospace;">OBJ_DIR</span> and <span style="font-family: "courier new" , "courier" , monospace;">TARGET_DIR</span>. Updated <span style="font-family: "courier new" , "courier" , monospace;">OJBS</span> and <span style="font-family: "courier new" , "courier" , monospace;">TARGET</span> to use these new variables. Finally added the variables to run the shell script to create the missing directories, if needed.<br />
<br />
Success. The object files are created in the <span style="font-family: "courier new" , "courier" , monospace;">obj</span> directory. <span style="font-family: "courier new" , "courier" , monospace;">aprogram</span> is created in the <span style="font-family: "courier new" , "courier" , monospace;">target</span> directory and <span style="font-family: "courier new" , "courier" , monospace;">gcc</span> does not complain about directories missing.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyquT7p2VL067ipoyszcX6TZZg7d-JHDU5kqNv0P48a1dhkRyWDQBOnlVehuf6suDv52TPIYN2r4YmmIloXUEiYZ9hC4z956-o2BQTNNC6jp0knFJaECB3MHylhE-dedCQ3reavDYCpAc/s1600/makefile8a.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="131" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyquT7p2VL067ipoyszcX6TZZg7d-JHDU5kqNv0P48a1dhkRyWDQBOnlVehuf6suDv52TPIYN2r4YmmIloXUEiYZ9hC4z956-o2BQTNNC6jp0knFJaECB3MHylhE-dedCQ3reavDYCpAc/s640/makefile8a.gif" width="640" /></a></div>
<br />
<br />
<h3>
</h3>
<h3>
Wildcard</h3>
</div>
<div>
Now let's start to get some automation into the make file.</div>
<div>
<br /></div>
<div>
There is a make function, <span style="font-family: "courier new" , "courier" , monospace;">wildcard</span>, which will create a list of files from a pattern.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR := src</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(wildcard $(SRC_DIR)/*.c)</span></div>
<br />
This function looks for all <span style="font-family: "courier new" , "courier" , monospace;">c</span> files in the <span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR</span> directory and creates a space separated list of all the files found.<br />
<br />
Let's assign this list to the variable <span style="font-family: "courier new" , "courier" , monospace;">SRC_LIST</span>.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">SRC_LIST := $(wildcard $(SRC_DIR)/*.c)</span><br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">SRC_LIST</span> can be used to create the list of object files.<br />
<br />
Using the make function <span style="font-family: "courier new" , "courier" , monospace;">patsubt</span>, short for pattern substitution, we can create <span style="font-family: "courier new" , "courier" , monospace;">OBJS</span> from <span style="font-family: "courier new" , "courier" , monospace;">SRC_LIST</span>.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">OBJS := $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC_LIST))</span><br />
<br />
Automation. Whatever files are in <span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR</span>, the corresponding list of object files is created.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">#makefile<span style="color: red;">9</span></span><br />
<span style="color: red; font-family: "courier new" , "courier" , monospace;">SRC_DIR := src</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">OBJ_DIR := obj</span><br />
<span style="color: red; font-family: "courier new" , "courier" , monospace;">SRC_LIST := $(wildcard $(SRC_DIR)/*.c)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">OBJS := <span style="color: red;">$(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC_LIST))</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">DEPS := $(SRC_DIR)/suba.h $(SRC_DIR)/subb.h $(SRC_DIR)/subc.h</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">TARGET_DIR := target</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">TARGET := $(TARGET_DIR)/aprogram</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">vpath %.c <span style="color: red;">$(SRC_DIR)</span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">all: $(TARGET)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(OBJ_DIR)/*.o</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(TARGET)*</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">$(TARGET): $(OBJS)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc $^ -o $@</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">$(OBJ_DIR)/%.o: %.c $(DEPS)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c $< -o $@</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">REQUIRED_DIRS := $(OBJ_DIR) $(TARGET_DIR)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">_MKDIRS := $(shell for d in $(REQUIRED_DIRS);<span class="Apple-tab-span" style="white-space: pre;"> </span>\</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>do<span class="Apple-tab-span" style="white-space: pre;"> </span>\</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>mkdir -p $$d;<span class="Apple-tab-span" style="white-space: pre;"> </span>\</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>done)</span></div>
<div>
<br /></div>
<div>
Good make file. Simply add a new <span style="font-family: "courier new" , "courier" , monospace;">c</span> file or delete the file from <span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR</span> and the appropriate object file will be created and linked.</div>
<div>
<br /></div>
<div>
However, the include files are still not automated.</div>
<div>
<br /></div>
<div>
Let's finally solve this problem.</div>
<div>
<br /></div>
<h3>
Automated Include Files</h3>
<div>
There are three features that are required to automate the include files. One feature is from <span style="font-family: "courier new" , "courier" , monospace;">gcc</span> and two features are from <span style="font-family: "courier new" , "courier" , monospace;">make</span>.</div>
<div>
<br /></div>
<h4>
gcc -MMD switch</h4>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">gcc</span> has a command line switch <span style="font-family: "courier new" , "courier" , monospace;">-MMD</span>. It is specifically designed to assist in the creation of automated include file dependencies.<br />
<br />
<h4>
Note on User Header and System Header Files.</h4>
gcc -MMD scans c file for user header files, not system file headers.<br />
<br />
If you use <span style="font-family: "courier new" , "courier" , monospace;">#include "stdio.h"</span><span style="font-family: inherit;">, you need to use </span><span style="font-family: "courier new" , "courier" , monospace;">#include <stdio.h>. </span><span style="font-family: inherit;">If quotes are used, make will evenutyally look for stdio.h, which will not be in </span><span style="font-family: "courier new" , "courier" , monospace;">SRC </span><span style="font-family: inherit;">and the make file will fail with unable to find dependency.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;"> -- end note --</span></div>
<div>
<br /></div>
<div>
Using <span style="font-family: "courier new" , "courier" , monospace;">-MMD,</span> <span style="font-family: "courier new" , "courier" , monospace;">gcc</span> creates, in addition to the object file, an include dependency file, <span style="font-family: "courier new" , "courier" , monospace;">*.d</span> file, in the same directory as the object file.</div>
<div>
<br /></div>
<div>
The include dependency file is a make file with no commands. The target is the object file created. The dependencies are the include files used by the <span style="font-family: "courier new" , "courier" , monospace;">c</span> file compiled. The include file dependencies is the complete include calling tree. If include files are nested in include files, the nested files are in the dependency list.</div>
<div>
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWKrLfCv7vQhFiR3dkDKMWc9TgPgPJM_RxWAEiDLxoi4_LlKOxqkhm99NmLjb_ZgcjIhT6oSStkmgYCIhx-hv544ZwDQiZPtuAujvx05xhLSFeCzFsov5_ojdloSf6bKws9oaBZqdWw9k/s1600/makefile10a.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="51" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWKrLfCv7vQhFiR3dkDKMWc9TgPgPJM_RxWAEiDLxoi4_LlKOxqkhm99NmLjb_ZgcjIhT6oSStkmgYCIhx-hv544ZwDQiZPtuAujvx05xhLSFeCzFsov5_ojdloSf6bKws9oaBZqdWw9k/s640/makefile10a.gif" width="640" /></a></div>
<br /></div>
<div>
<br />
<br />
<br />
Next we need a list of these include dependency files.</div>
<div>
<br /></div>
<h4>
Short cut string replacement</h4>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">DEPS := $(OBJS:.o=.d)</span></div>
<div>
<br /></div>
<div>
The above assignment changes every <span style="font-family: "courier new" , "courier" , monospace;">.o</span> in OBJS to <span style="font-family: "courier new" , "courier" , monospace;">.d</span>. This is simpler, but not as flexible, as <span style="font-family: "courier new" , "courier" , monospace;">patsubst</span>.</div>
<div>
<br /></div>
<h4>
include function</h4>
<div>
Now that we have created the include dependency files and we have a list of these files, we need to put these files into the dependency tree.</div>
<div>
<br /></div>
<div>
The make function <span style="font-family: "courier new" , "courier" , monospace;">include</span> will perform this step.</div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">-include $(DEPS)</span></div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">include</span> causes the files listed to be included within the make file. As each include dependency file has a target and dependency pair, each pair now part of the dependency tree.</div>
<div>
<br /></div>
<div>
The target is the object file, which is already dependent on the <span style="font-family: "courier new" , "courier" , monospace;">c</span> file via the pattern. The object files are now also dependent on the include files associated with the <span style="font-family: "courier new" , "courier" , monospace;">c</span> file, as generated by <span style="font-family: "courier new" , "courier" , monospace;">gcc</span>.<br />
<br />
This shows that there may be more than one target/dependency pair that refers to the same target.</div>
<div>
<br /></div>
<div>
The minus sign in front of <span style="font-family: "courier new" , "courier" , monospace;">include</span> is important. If the include dependency file does not exist, include will not report an error. This will be true the first time make is run or after a clean.<br />
<br />
Notice that the order of dependencies is definitely not the order the dependencies are found in the file.</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">#makefile<span style="color: red;">10</span></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR := src</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">OBJ_DIR := obj</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">SRC_LIST := $(wildcard $(SRC_DIR)/*.c)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">OBJS := $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC_LIST))</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace;">DEPS := $(OBJS:.o=.d)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">TARGET_DIR := target</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">TARGET := $(TARGET_DIR)/aprogram</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">vpath %.c $(SRC_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">all: $(TARGET)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(OBJ_DIR)/*.o<span style="color: red;"> $(OBJ_DIR)/*.d</span></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(TARGET)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(TARGET): $(OBJS)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc $^ -o $@</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(OBJ_DIR)/%.o: %.c</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c <span style="color: red;">-MMD</span> $< -o $@</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">REQUIRED_DIRS := $(OBJ_DIR) $(TARGET_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">_MKDIRS := $(shell for d in $(REQUIRED_DIRS);<span class="Apple-tab-span" style="white-space: pre;"> </span>\</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>do<span class="Apple-tab-span" style="white-space: pre;"> </span>\</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>mkdir -p $$d;<span class="Apple-tab-span" style="white-space: pre;"> </span>\</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>done)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace;">-include $(DEPS)</span></div>
</div>
<div>
<br /></div>
<div>
Added <span style="font-family: "courier new" , "courier" , monospace;">-MMD</span> switch to <span style="font-family: "courier new" , "courier" , monospace;">gcc</span>. Updated the <span style="font-family: "courier new" , "courier" , monospace;">DEPS</span> variable and included all the include dependency files.</div>
<div>
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNzUyhfNcmdf-UwHOpHeDxv_r-W84Wn-H12L5OQHGIiv8_vJ3FTi-pk9Q79aYBy8fC6U_eKMB-qKVMjxTvUDm3PUaZGcwiyGBkk2BqkVaHybJoNpsXUkx_kbtzVrNwHS_IQ4bvvZhU-Mo/s1600/makefile10b.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="198" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNzUyhfNcmdf-UwHOpHeDxv_r-W84Wn-H12L5OQHGIiv8_vJ3FTi-pk9Q79aYBy8fC6U_eKMB-qKVMjxTvUDm3PUaZGcwiyGBkk2BqkVaHybJoNpsXUkx_kbtzVrNwHS_IQ4bvvZhU-Mo/s640/makefile10b.gif" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
The include file dependency problem is solved.<br />
<br />
There is one shortcoming with <span style="font-family: "courier new" , "courier" , monospace;">makefile10</span>. <span style="font-family: "courier new" , "courier" , monospace;">OBJ_DIR</span> and <span style="font-family: "courier new" , "courier" , monospace;">TARGET_DIR</span> are not deleted when <span style="font-family: "courier new" , "courier" , monospace;">clean</span> is run. We said <span style="font-family: "courier new" , "courier" , monospace;">clean</span> removes all files created by all. The directories are created by <span style="font-family: "courier new" , "courier" , monospace;">all</span>, but not removed by <span style="font-family: "courier new" , "courier" , monospace;">clean</span>.</div>
<div>
<br /></div>
<div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">#makefile<span style="color: red;">10a</span></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR := src</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">OBJ_DIR := obj</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">SRC_LIST := $(wildcard $(SRC_DIR)/*.c)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">OBJS := $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC_LIST))</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">DEPS := $(OBJS:.o=.d)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">TARGET_DIR := target</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">TARGET := $(TARGET_DIR)/aprogram</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">vpath %.c $(SRC_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">.PHONY: all clean</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">all: $(TARGET)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">clean:</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(OBJ_DIR)/*.o $(OBJ_DIR)/*.d</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>@rm -f $(TARGET)</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace;"> @rmdir $(OBJ_DIR)</span></div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace;"> @rmdir $(TARGET_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(TARGET): $(OBJS)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc $^ -o $@</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">$(OBJ_DIR)/%.o: %.c</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gcc -c -MMD $< -o $@</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">REQUIRED_DIRS := $(OBJ_DIR) $(TARGET_DIR)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">_MKDIRS := $(shell for d in $(REQUIRED_DIRS);<span class="Apple-tab-span" style="white-space: pre;"> </span>\</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>do<span class="Apple-tab-span" style="white-space: pre;"> </span>\</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>mkdir -p $$d;<span class="Apple-tab-span" style="white-space: pre;"> </span>\</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>done)</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">-include $(DEPS)</span></div>
</div>
</div>
<div>
<span style="color: red; font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
Fin. <span style="font-family: "courier new" , "courier" , monospace;">makefile10a</span> is completely automated. Give a list of source files in the <span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR</span> directory that will link, as object files, to create <span style="font-family: "courier new" , "courier" , monospace;">aprogram</span>, no changes to <span style="font-family: "courier new" , "courier" , monospace;">makefile10a</span> are required as new <span style="font-family: "courier new" , "courier" , monospace;">c</span> files or include files are added or deleted.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg82y0B_AmDidU49NKQrSLTbhl4KQ2_CBJ6c7QNgG75uApeCvegzZJ3Na_uBMJCnXR4IiizkfehSR0X2uT-rCBG4uW6gdAgY2rndKHp6bEvaTVUCZ0KmUEff08XZGPiML4FAdMwO6Y9Fl8/s1600/makefile10c.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="216" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg82y0B_AmDidU49NKQrSLTbhl4KQ2_CBJ6c7QNgG75uApeCvegzZJ3Na_uBMJCnXR4IiizkfehSR0X2uT-rCBG4uW6gdAgY2rndKHp6bEvaTVUCZ0KmUEff08XZGPiML4FAdMwO6Y9Fl8/s640/makefile10c.gif" width="640" /></a></div>
<br /></div>
<div>
<br /></div>
<div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<h4>
Include File Dependency Details</h4>
You may be wondering if the update for include files works for all circumstances. Let's discuss it in a bit more detail.</div>
<div>
<br /></div>
<div>
When the make file is run for the first time, there are no <span style="font-family: "courier new" , "courier" , monospace;">*.d</span> files, so the only dependent file for an object file is the <span style="font-family: "courier new" , "courier" , monospace;">c</span> file. Since the object file does not exist, the <span style="font-family: "courier new" , "courier" , monospace;">c</span> file is compiled.</div>
<div>
<br /></div>
<div>
The second running of the make file, the <span style="font-family: "courier new" , "courier" , monospace;">*.d</span> files exist and the include files are added to the dependencies of the object file. If an include file is changed, then the appropriate object file is created.</div>
<div>
<br /></div>
<div>
If an include is added or deleted, then some file, a <span style="font-family: "courier new" , "courier" , monospace;">c</span> file or another include file must have been changed. The appropriate object file is created.</div>
<div>
<br /></div>
<div>
Finally, what if a <span style="font-family: "courier new" , "courier" , monospace;">c</span> file is deleted, the corresponding object file is not deleted. No it is not, but the old object file is no longer a member of the list of object files, <span style="font-family: "courier new" , "courier" , monospace;">OBJS</span>, used to link <span style="font-family: "courier new" , "courier" , monospace;">aprogram</span>. An extra file exists in the <span style="font-family: "courier new" , "courier" , monospace;">OBJ_DIR</span> directory, but does not get used.<br />
<br />
The next time <span style="font-family: "courier new" , "courier" , monospace;">clean</span> is run the extra object files will be removed.</div>
<div>
<br /></div>
<div>
Again, <span style="font-family: "courier new" , "courier" , monospace;">makefile10a</span> is very good general purpose make file.</div>
<div>
<br /></div>
<div>
Change the target and you are ready to use <span style="font-family: "courier new" , "courier" , monospace;">makefile10a</span> for another program.</div>
<div>
<br /></div>
<div>
There are is, however, a limitation with <span style="font-family: "courier new" , "courier" , monospace;">makefile10a</span>. The sources must all be in <span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR</span>. There can be no sub-directories to <span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR</span> containing source. The problem is <span style="font-family: "courier new" , "courier" , monospace;">wildcard</span> does not recursively descend directories looking for files.</div>
<div>
<br /></div>
<div>
The next posting of this blog shows how to extend <span style="font-family: "courier new" , "courier" , monospace;">makefile10a</span> to use sub-directories of <span style="font-family: "courier new" , "courier" , monospace;">SRC_DIR</span>.<br />
<br />
Next post: <a href="http://fernleaf07.blogspot.com/2015/07/yet-another-makefile-tutorial-part-ii.html" target="_blank">Yet Another Make Tutorial II</a><br />
<br />
<h2>
References and Links</h2>
</div>
<div>
<div class="MsoNormal">
This is a listing of various URLs that discusses section of
this document and where the ideas came from.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
The foreach and macro - <a href="http://stackoverflow.com/questions/231229/how-to-generate-a-makefile-with-source-in-sub-directories-using-just-one-makefil">http://stackoverflow.com/questions/231229/how-to-generate-a-makefile-with-source-in-sub-directories-using-just-one-makefil</a>
<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
The overall design comes from here. <a href="http://stackoverflow.com/questions/231229/how-to-generate-a-makefile-with-source-in-sub-directories-using-just-one-makefil">http://stackoverflow.com/questions/231229/how-to-generate-a-makefile-with-source-in-sub-directories-using-just-one-makefil</a>
<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
The MMD section comes from here. <a href="http://stackoverflow.com/questions/11855386/using-g-with-mmd-in-makefile-to-automatically-generate-dependencies">http://stackoverflow.com/questions/11855386/using-g-with-mmd-in-makefile-to-automatically-generate-dependencies</a>
<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Note about putting –include at the end of the file comes
from here. <a href="http://www.microhowto.info/howto/automatically_generate_makefile_dependencies.html">http://www.microhowto.info/howto/automatically_generate_makefile_dependencies.html</a>
<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Automatic variables <a href="https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html">https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html</a>
<o:p></o:p></div>
</div>
<div>
<br /></div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8192642777375146218.post-24614463502939768582013-08-04T22:46:00.001-04:002013-08-05T17:22:19.886-04:00User's Guide to Fold.it Lua 2.0 APIThe site, <a href="http://fold.it/">http://fold.it</a>, is a site where you can 'fold for science'. Fold.it is a program, a client, that allows scientists and non-scientists to play a game of folding proteins.<br />
<br />
The problem of folding proteins is an inherently geometrically hard problem.<br />
<br />
People have been found to have intuitive ideas on what the shape of the protein should look like. The game Fold.it was created to allow people to express this intuition.<br />
<br />
The 3D shape of the protein is the most important property of a protein. The shape allows scientists to determine how the protein functions.<br />
<br />
So how is all this something for a computer science blog?<br />
<br />
Fold.It introduced a scripting language to allow repetitive folding tasks to be automated. There is a GUI scripting tool and a Lua scripting tool.<br />
<br />
The Lua language allowed with Fold.it is a subset of the official langue. <a href="http://www.lua.org/">http://www.lua.org/</a> with an additional API for folding and client functions.<br />
<br />
At Fold.it, a Lua script is called a 'recipe'.<br />
<br />
Below is a user's guide for the Fold.it Lua Version 2.0. There was a version 1.0. It has been deprecated. Old version 1.0 scripts can still be run, but one cannot create new 1.0 scripts or modify 1.0 scripts without upgrading to version 2.0 API.<br />
<br />
See the following two Lua recipes for the mapping of Lua 1.0 to Lua 2.0 functions. You will need to be running the Fold.it client in order to get a human readable version of the recipes.<br />
<a href="http://fold.it/portal/recipe/43867">http://fold.it/portal/recipe/43867</a><br />
<a href="http://fold.it/portal/recipe/31012">http://fold.it/portal/recipe/31012</a><br />
<br />
<span style="font-size: x-large;">Fold.it Lua 2.0 API</span><br />
<div>
<div>
Lua V2.0 is the fold.it 'programming' language. It is a subset of the Lua 5.0 language. <a href="http://lua.org/">http://lua.org</a> with an additional API.</div>
<div>
<br /></div>
<div>
The standard Lua 5.0 functions supported in Fold.it Lua V2.0 are found at <a href="http://foldit.wikia.com/wiki/Lua_Standard_Libraries">http://foldit.wikia.com/wiki/Lua_Standard_Libraries</a>.</div>
<div>
<br /></div>
<div>
The reader is expected to be familiar with how to run the Fold.it GUI client. Terminology here is the same as that found in the GUI.</div>
<div>
<br /></div>
<div>
The reader is also expected to have an understanding of programming and the syntax of Lua. If you are new to programming or Lua, please read here first, and elsewhere. <a href="http://foldit.wikia.com/wiki/Lua_Scripting">http://foldit.wikia.com/wiki/Lua_Scripting</a></div>
<div>
<br /></div>
<div>
Programming Note: One does not have the ability to use libraries, other than those in the Lua standard libraries, or refer other files in a Fold.it Lua V2.0 script. A Fold.it Lua script is one large file. Thus it is a good habit to keep a file that contains all the custom functions you have written and will need from script to script and simply paste them into the top of each new script you write.</div>
<div>
<br /></div>
<div>
<span style="font-size: large;">Short Example</span></div>
<div>
<br /></div>
<div>
When using the Fold.it client, one can hover over a segment and press <tab>.</div>
<div>
This brings up a note.</div>
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-LcilENceS-c/Uf7Exq0cR0I/AAAAAAAACtA/CTRZSYP9Of4/s1600/Fold-it-tab.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://3.bp.blogspot.com/-LcilENceS-c/Uf7Exq0cR0I/AAAAAAAACtA/CTRZSYP9Of4/s1600/Fold-it-tab.jpg" height="310" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Showing segment information for segment #15, Glycine<br />
The segment had been mutated as its original amino acide was Iosleucine</td></tr>
</tbody></table>
<div>
<br /></div>
<div>
This note has information about the protein at the segment hovered. It has the segment number and the amino acid of the segment. It has the segment score. It also has a list of additional values: clashing,</div>
<div>
pairwise (sometimes), packing, hiding, bonding, sidechain, and reference. This information can be obtained using Lua V2.0 objects and functions.</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">segmentindex = 15</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">current.GetSegmentEnergySubscore(segmentindex, "packing")</span></div>
<div>
<br /></div>
<div>
will return the packing value of <span style="font-family: Courier New, Courier, monospace;">segmentindex</span>. The image above shows a packing score of 34.2.</div>
<div>
<br /></div>
<div>
Segments are referred to by the term <span style="font-family: 'Courier New', Courier, monospace;">segmentindex</span>. This number runs from 1 to the number of segments in the protein.</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">structure.GetCount()</span>returns the number of segments in the protein.</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">structure.GetAminoAcid(segmentindex)</span>returns a single lowercase letter representing the amino acid for a particular segment index. The letter follows the standard as shown at this link <a href="http://en.wikipedia.org/wiki/Amino_acid">http://en.wikipedia.org/wiki/Amino_acid</a> and <a href="http://foldit.wikia.com/wiki/Lua_Script_Library">http://foldit.wikia.com/wiki/Lua_Script_Library</a></div>
<div>
<br /></div>
<div>
If there are ligands in the puzzle, then the ligand is given a secondary structure with the capital letter 'M, and it located at the last segment of the protein. One needs to decrease the segment count by one if a ligand exists.</div>
<div>
<br /></div>
<div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;">function filib.GetProteinSegCount()</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> segCount = structure.GetCount()</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> -- ligand is 'M' at the last segment of the protein</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> isLigand =(structure.GetSecondaryStructure(game.segCount))</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> if isLigand == 'M' then</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> segCount = segCount - 1</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> end</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> return segCount</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;">end</span></div>
</div>
<div>
<br /></div>
<div>
<span style="font-size: large;">Fold.it Lua V2 Objects</span></div>
<div>
<br /></div>
<div>
Fold.it Lua V2 uses objects to group functions. The list of objects are:</div>
<div>
<ul>
<li><span style="color: #cc0000; font-family: Times, Times New Roman, serif;"><a href="https://www.blogger.com/blogger.g?blogID=8192642777375146218#Score" rel="nofollow">absolutebest</a></span></li>
<li><span style="color: #cc0000;">band</span></li>
<li><span style="color: #cc0000;">behavior</span></li>
<li><span style="color: #cc0000;">contactmap</span></li>
<li><span style="color: #cc0000;"><a href="https://www.blogger.com/blogger.g?blogID=8192642777375146218#Score">creditbest</a></span></li>
<li><span style="color: #cc0000;"><a href="https://www.blogger.com/blogger.g?blogID=8192642777375146218#Score">current</a></span></li>
<li><span style="color: #cc0000;">dialog</span></li>
<li><span style="color: #cc0000;">freeze</span></li>
<li><span style="color: #cc0000;"><a href="https://www.blogger.com/blogger.g?blogID=8192642777375146218#Puzzle">puzzle</a></span></li>
<li><span style="color: #cc0000;"><a href="https://www.blogger.com/blogger.g?blogID=8192642777375146218#Score">recentbest</a></span></li>
<li><span style="color: #cc0000;"><a href="https://www.blogger.com/blogger.g?blogID=8192642777375146218#Recipe">recipe</a></span></li>
<li><span style="color: #cc0000;">rotamer</span></li>
<li><span style="color: #cc0000;">save</span></li>
<li><span style="color: #cc0000;"><a href="https://www.blogger.com/blogger.g?blogID=8192642777375146218#Scoreboard">scoreboard</a></span></li>
<li><span style="color: #cc0000;">selection</span></li>
<li><span style="color: #cc0000;">structure</span></li>
<li><span style="color: #cc0000;"><a href="https://www.blogger.com/blogger.g?blogID=8192642777375146218#User">user</a></span></li>
<li><span style="color: #cc0000;">ui</span></li>
</ul>
</div>
<div>
The objects and their functions fall into three broad categories,</div>
<div>
<ul>
<li>those functions that get information ("getters)</li>
<li>those functions that set information ("setters)</li>
<li>those functions that physically change the puzzle ("doers").</li>
</ul>
</div>
<div>
The objects that strictly retrieve information ("getters" only) are:</div>
<div>
<ul>
<li>the score objects</li>
<ul>
<li><span style="color: #cc0000;"><a href="https://www.blogger.com/blogger.g?blogID=8192642777375146218#Score">absolutebest</a></span></li>
<li><span style="color: #cc0000;"><a href="https://www.blogger.com/blogger.g?blogID=8192642777375146218#Score">creditbest</a></span></li>
<li><span style="color: #cc0000;"><a href="https://www.blogger.com/blogger.g?blogID=8192642777375146218#Score">current</a></span></li>
<li><span style="color: #cc0000;"><a href="https://www.blogger.com/blogger.g?blogID=8192642777375146218#Score">recentbest</a></span></li>
</ul>
<li><span style="color: #cc0000;">contactmap</span></li>
<li><span style="color: #cc0000;"><a href="https://www.blogger.com/blogger.g?blogID=8192642777375146218#User">user</a></span></li>
<li><span style="color: #cc0000;"><a cc0000="" color:="" href="https://www.blogger.com/blogger.g?blogID=8192642777375146218#Scoreboard>scoreboard</a></span></li><li><span style="></a><a href="https://www.blogger.com/blogger.g?blogID=8192642777375146218#Puzzle">puzzle</a></span></li>
</ul>
</div>
<div>
<span style="font-size: x-small;">Note: The 'puzzle' object has one function that does change the puzzle ("doer"), <span style="font-family: Courier New, Courier, monospace;">StartOver().</span></span></div>
<div>
<br /></div>
<div>
The objects that get and set information ("getters and setters") and are "doers" are:</div>
<div>
<ul>
<li><span style="color: #cc0000;">behavior</span></li>
<li><span style="color: #cc0000;">dialog</span></li>
<li><span style="color: #cc0000;"><a href="https://www.blogger.com/blogger.g?blogID=8192642777375146218#Recipe">recipe</a></span></li>
<li><span style="color: #cc0000;">save</span></li>
<li><span style="color: #cc0000;">structure</span></li>
<li><span style="color: #cc0000;">freeze</span></li>
<li><span style="color: #cc0000;">band</span></li>
</ul>
</div>
<div>
The <span style="color: #cc0000;">structure </span>and <span style="color: #cc0000;">rotamer </span>objects retrieve information of the protein and</div>
<div>
provide the functions to manipulate the protein directly.</div>
<div>
<br /></div>
<div>
The <span style="color: #cc0000;">contactmap </span>object is used during exploration puzzles.</div>
<div>
<br /></div>
<div>
<span style="font-size: x-small;"> [Don't know if the script can determine if the puzzle is an explorations puzzle?]</span></div>
<div>
<br /></div>
<div>
The <span style="color: #cc0000;">recipe </span>and <span style="color: #cc0000;">save</span> objects provide storage of information to measure progress and restore previous poses.</div>
<div>
The <span style="color: #cc0000;">behavior </span>object is the same as the Behavior/Clash Importance GUI feature.</div>
<div>
The <span style="color: #cc0000;">freeze </span>and <span style="color: #cc0000;">band </span>objects add additional items to the puzzle to help manipulate the protein, similar to the GUI freeze and band features.</div>
<div>
The <span style="color: #cc0000;">dialog </span>object helps the Lua V2.0 script writer communicate with the user. This is a new feature with version 2.0</div>
<div>
<br /></div>
<div>
<span style="font-size: large;">GUI Features and Lua functions</span></div>
<div>
<br /></div>
<div>
The Fold.it functions provide access to most, but not all of the same GUI features found in the client.</div>
<div>
<br /></div>
<div>
The GUI controls that are not available in Lua V2.0 are:</div>
<div>
<ul>
<li>The 'Undo' GUI feature is not available in the Lua V2.0. One cannot go back through the 'undo' list using Lua V2.0 scripts.</li>
<li>Tweak features are not available with Lua V2.0</li>
</ul>
</div>
<div>
As of 9Jul2013, a band cannot connect to an adjacent segment.</div>
<div>
See <a href="http://foldit-dev.cs.washington.edu/portal/node/987813">http://foldit-dev.cs.washington.edu/portal/node/987813</a></div>
<div>
<br /></div>
<div>
It will be noted when a Lua function is the same as a GUI control.</div>
<div>
<br /></div>
<div>
A comparison table of GUI and Lua features would be handy. I should add such a table later.</div>
<div>
<br /></div>
<div>
For the most current, but not detailed documentation of functions,</div>
<div>
open the recipe editor, click on New (ScriptV2.0), then click on the</div>
<div>
Help icon.</div>
<div>
<br /></div>
<div>
Also the following recipe lists Fold.it Lua functions, with a brief description. <a href="http://fold.it/portal/recipe/46122">http://fold.it/portal/recipe/46122</a> </div>
<div>
<br /></div>
<div>
<span style="font-size: large;">Print and Help()</span></div>
<div>
<br /></div>
<div>
There are two miscellaneous functions, <span style="font-family: Courier New, Courier, monospace;">print()</span><span style="font-family: inherit;"> and </span><span style="font-family: Courier New, Courier, monospace;">help()</span><span style="font-family: inherit;">.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">print() outputs to the recipe window.</span></div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">print()</span> uses the following syntax. Each argument is separated by a comma. The '+' (append) operator is not available as is found in standard Lua.</div>
<div>
<br /></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;">print(segmentscore," ",creditbest.GetScore())</span></div>
<div>
<br /></div>
<div>
Anytime print() is called, the string is shown on the recipe output window. It is also written to file. On Windows 7 the file is in <span style="font-family: Courier New, Courier, monospace;">C:\foldit\scriptlog.default.xml.</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: inherit;">When using tracks, the name of the track will be used for the file. If the name of the track was Wigglefast, then the log file would be </span><span style="font-family: 'Courier New', Courier, monospace;">C:\foldit\scriptlog.Wigglefast.xml.</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">help()</span> outputs a list of the API functions. No descriptions.</div>
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-HsDn-rMp-88/Uf7WejoOgAI/AAAAAAAACts/bSmb-jPn_MQ/s1600/recipewindow.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://4.bp.blogspot.com/-HsDn-rMp-88/Uf7WejoOgAI/AAAAAAAACts/bSmb-jPn_MQ/s1600/recipewindow.jpg" height="258" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Shows number output generated by print().<br />
Shows start of function output generated by help()</td></tr>
</tbody></table>
<div>
<br /></div>
<div>
<br /></div>
<div>
<span id="Score" style="font-size: large;">Puzzle Score</span></div>
<div>
<br /></div>
<div>
There are four objects that refer to the puzzle's score. They are 'getters' only.</div>
<div>
<ul>
<li><span style="color: #cc0000;">absolutebest</span></li>
<li><span style="color: #cc0000;">creditbest</span></li>
<li><span style="color: #cc0000;">current</span></li>
<li><span style="color: #cc0000;">recentbest</span></li>
</ul>
</div>
<div>
Each of these four objects have slightly different list of functions.</div>
<div>
The functions below are marked with AB, CR, CU, RE, or ALL. This shows</div>
<div>
which object supports that function.</div>
<div>
<br /></div>
<div>
The <span style="color: #cc0000;">absolutebest, </span><span style="color: #cc0000;">creditbest, </span>and <span style="color: #cc0000;">current </span>objects more or less stay in sync if one is on-line. They will be different if one is working on a puzzle off-line.</div>
<div>
<br /></div>
<div>
[Need to document what happens with these objects when one is off-line]</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">AreConditionsMet()</span> [ALL] - This is the same as at the top of the client window. Will always return <span style="font-family: Courier New, Courier, monospace;">true</span> when 'No bonuses or conditions' are show in the scoring window at the top of the client screen.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-vuwDtDaLTMg/Uf7JVeOv0vI/AAAAAAAACtQ/2oBHmyflSww/s1600/Conditions-Satisfied.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-vuwDtDaLTMg/Uf7JVeOv0vI/AAAAAAAACtQ/2oBHmyflSww/s1600/Conditions-Satisfied.jpg" height="95" width="320" /></a></div>
<div>
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-TDanIj4uqHg/Uf7KNi-7yqI/AAAAAAAACtc/1m5C70ZnNhQ/s1600/NoBonusesOrConditions.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://1.bp.blogspot.com/-TDanIj4uqHg/Uf7KNi-7yqI/AAAAAAAACtc/1m5C70ZnNhQ/s1600/NoBonusesOrConditions.jpg" height="80" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">This text 'No bonuses or conditions' always returns true.</td></tr>
</tbody></table>
<div>
<br /></div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GetEnergyScore()</span> [ALL] - This is the score shown in the score window at the top of the client.</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GetExplorationMultiplier()</span> [ALL] - Some puzzles have an exploration multiplier. This function returns that multiplier. If not an exploration puzzle, it returns 0.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GetScore()</span> [ALL] - This is the same as GetEnergyScore(). Not sure why there are two functions. Technically the energy score gets smaller as the protein is folded more towards its natural shape.</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GetSegmentEnergyScore(segmentindex) </span>[ALL] - Get the Rosetta energy score for <span style="font-family: Courier New, Courier, monospace;">segmentindex</span>. The sum of all segment scores will be 8000 points lower than the <span style="font-family: Courier New, Courier, monospace;">GetScore().</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> segscore = 0</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> for i=1,structure.GetCount(),1 do</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> segscore = segscore + creditbest.GetSegmentEnergyScore()</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> -- 8000 difference between scores.</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> print(segscore," ", creditbest.GetScore())</span></div>
</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GetSegmentEnergySubscore(segmentindex,part) </span>[ALL] - Get the energy score of a part of the segment. The <span style="font-family: Courier New, Courier, monospace;">part</span> argument may be one of the following strings.</div>
<div>
<ul>
<li>"clashing"</li>
<li>"packing"</li>
<li>"hiding"</li>
<li>"bonding"</li>
<li>"backbone"</li>
<li>"sidechain"</li>
<li>"reference"</li>
<li>"disulfides"</li>
<li>"density"</li>
</ul>
</div>
<div>
This is the same list as seen in the Note when the GUI feature <tab> key is pressed when hovering over a segment. See above.</div>
<div>
<br /></div>
<div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;">function filib.reportsegmentparts(segmentindex)</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> local parts =</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> {"clashing","pairwise","packing","bonding","hiding",</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> "sidechain","reference","disulfides","density"}</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> report = "segment#: "..segmentindex.." \n"</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> segment_total = 0</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> for i=1,#parts,1 do</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> partvalue = </span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> recentbest.GetSegmentEnergySubscore(segmentindex,parts[i])</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> report = report .. " "..parts[i]..": "..partvalue.." \n"</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> segment_total = segment_total + partvalue</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> end</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> print(report)</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;">end</span></div>
</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Restore() </span>[AB,CR,RE] - Load the best score of the appropriate object. Just like the GUI control.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Save()</span> [RE] - Save the current pose as the best for <span style="color: #cc0000;">recentbest </span>only. Just like the GUI control.</div>
<div>
<br /></div>
<div>
All of the scoring functions are 'read-only'. The values can only be read, not changed. That would be cheating. :) </div>
<div>
<br /></div>
<div>
<span style="color: #cc0000; font-size: large;"><a href="https://www.blogger.com/blogger.g?blogID=8192642777375146218" name="Puzzle">puzzle</a></span></div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">puzzle.GetDescription()</span> - Returns the text description of the puzzle as seen in the comment section of the Select Puzzle window. The text is one long string.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-MuzIeh4ieCQ/Uf7lNH8B0MI/AAAAAAAACt8/fuHAkyox70o/s1600/selectdescription.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-MuzIeh4ieCQ/Uf7lNH8B0MI/AAAAAAAACt8/fuHAkyox70o/s1600/selectdescription.jpg" height="133" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-9QI1-zV0-2w/Uf7lTUyHaMI/AAAAAAAACuE/erm5YK0MyQg/s1600/description.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-9QI1-zV0-2w/Uf7lTUyHaMI/AAAAAAAACuE/erm5YK0MyQg/s1600/description.jpg" height="93" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">puzzle.GetExpirationTime()</span> - Can compare to current time to find out how much time is left. This time is GMT. Below is the code to display the time left, as is shown at the top of the client in the score window.</div>
<div>
<br /></div>
<div>
<div>
<span style="background-color: white; color: #6aa84f; font-family: Courier New, Courier, monospace;">expire = puzzle.GetExpirationTime()</span></div>
<div>
<span style="background-color: white; color: #6aa84f; font-family: Courier New, Courier, monospace;">now = os.time()</span></div>
<div>
<span style="background-color: white; color: #6aa84f; font-family: Courier New, Courier, monospace;">timeleft = expire-now</span></div>
<div>
<span style="background-color: white; color: #6aa84f; font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="background-color: white; color: #6aa84f; font-family: Courier New, Courier, monospace;">print("Time left in seconds ",timeleft)</span></div>
<div>
<span style="background-color: white; color: #6aa84f; font-family: Courier New, Courier, monospace;">days = math.floor(timeleft/(60*60*24))</span></div>
<div>
<span style="background-color: white; color: #6aa84f; font-family: Courier New, Courier, monospace;">timeleft = timeleft - days*60*60*24</span></div>
<div>
<span style="background-color: white; color: #6aa84f; font-family: Courier New, Courier, monospace;">hours = math.floor(timeleft/(60*60))</span></div>
<div>
<span style="background-color: white; color: #6aa84f; font-family: Courier New, Courier, monospace;">timeleft = timeleft - hours*60*60</span></div>
<div>
<span style="background-color: white; color: #6aa84f; font-family: Courier New, Courier, monospace;">minutes = math.floor(timeleft/60)</span></div>
<div>
<span style="background-color: white; color: #6aa84f; font-family: Courier New, Courier, monospace;">timeleft = timeleft - minutes*60</span></div>
<div>
<span style="background-color: white; color: #6aa84f; font-family: Courier New, Courier, monospace;">seconds = timeleft </span></div>
<div>
<span style="background-color: white; color: #6aa84f; font-family: Courier New, Courier, monospace;"><br /></span></div>
<div>
<span style="background-color: white; color: #6aa84f; font-family: Courier New, Courier, monospace;">daystring = string.format("%2d",days)</span></div>
<div>
<span style="background-color: white; color: #6aa84f; font-family: Courier New, Courier, monospace;">hourstring = string.format("%2d",hours)</span></div>
<div>
<span style="background-color: white; color: #6aa84f; font-family: Courier New, Courier, monospace;">minutestring = string.format("%2d",minutes)</span></div>
<div>
<span style="background-color: white; color: #6aa84f; font-family: Courier New, Courier, monospace;">secondsstring = string.format("%2d",seconds)</span></div>
<div>
<span style="background-color: white; color: #6aa84f; font-family: Courier New, Courier, monospace;">timestring = "Time left on puzzle: "..daystring..</span></div>
<div>
<span style="background-color: white; color: #6aa84f; font-family: Courier New, Courier, monospace;"> " days "..hourstring..":"..minutestring..":"..secondsstring</span></div>
<div>
<span style="background-color: white; color: #6aa84f; font-family: Courier New, Courier, monospace;">print(timestring)</span></div>
</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">puzzle.GetName()</span> - A string is return holding the name of the puzzle.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">puzzle.GetPuzzleID()</span> - The ID of the puzzle is returned. Not certain how to use this.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">puzzle.StartOver()</span> - This is an action, not a read. It changes the puzzle. It resets the puzzle to the start pose.</div>
<div>
<br /></div>
<div>
<span style="color: #cc0000; font-size: large;"><a href="https://www.blogger.com/blogger.g?blogID=8192642777375146218" name="Scoreboard">scoreboard</a></span></div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">scoreboard.GetGroupRank()</span> - Can determine if recent recipe action has raised the ranking, or the ranking has fallen during the time the script was running. One's ranking can fall even if the score increased.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">scoreboard.GetGroupScore()</span> - Get group score. This is the best group score for this puzzle. Not necessarily the <span style="font-family: Courier New, Courier, monospace;">absolutebest.GetScore()</span> of the puzzle.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">scoreboard.GetRank(scoretype)</span> - Get rank of this puzzle.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">scoretype</span> is a number from 0 to 3.</div>
<div>
<ul>
<li>0 - SCORE_SOLOIST</li>
<li>1 -SCORE_EVOLVER</li>
<li>2 - SCORE_ALL_HANDS</li>
<li>3 - SCORE_NO_SCORE</li>
</ul>
[Note: as of 04Aug13, 2 and 3 return zero]</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">scoreboard.GetRank(scoreboard.GetType())</span></div>
<div>
Solo rank if puzzle is being run solo. Group rank if puzzle is being evolved.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">scoreboard.GetScore(scoretype)</span> - Get the score based on type. </div>
<div>
<span style="font-family: Courier New, Courier, monospace;">scoreboard.GetScoreType()</span> - Return the scoreboard type.</div>
<div>
Thus <span style="font-family: Courier New, Courier, monospace;">scoreboard.GetScore(scoreboard.GetScoreType())</span> returns</div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"> </span>the current score for active puzzle.</div>
<div>
<br /></div>
<div>
<span style="background-color: white; color: #cc0000; font-size: large;"><a href="https://www.blogger.com/blogger.g?blogID=8192642777375146218" name="User">user</a></span></div>
<div>
<br /></div>
<div>
The <span style="color: #cc0000;">user </span>object holds information about the user.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GetGroupID(), GetGroupName(), GetPlayerID(), GetPlayerName()</span>.</div>
<div>
Again read only functions. These values are changed at the <a href="http://fold.it/">http://fold.it</a> website, under the user's profile.</div>
<div>
<br /></div>
<div>
<span style="color: #cc0000; font-size: large;"><a href="https://www.blogger.com/blogger.g?blogID=8192642777375146218" name="Recipe">recipe</a></span></div>
<div>
<br /></div>
<div>
The <span style="color: #cc0000;">recipe</span> object is helpful to output information to the user as the script runs.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">CompareNumbers()</span> - Return true if two real numbers are the same to the precision Lua prints. This is a useful function to determine if there has been any change in the score.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GetRandomSeed()</span> - The value returned from this function can be input into the</div>
<div>
standard lua function <span style="font-family: Courier New, Courier, monospace;">math.randomseed()</span>.</div>
<div>
WARNING- Please read the following two links before generating random numbers.</div>
<div>
<a href="http://lua-users.org/wiki/MathLibraryTutorial">http://lua-users.org/wiki/MathLibraryTutorial</a></div>
<div>
<a href="http://fold.it/portal/node/992549">http://fold.it/portal/node/992549</a></div>
<div>
<br /></div>
<div>
To make sure random numbers are generated, add this code to the start of each script that requires random numbers. Seed the random number generator and ignore the first random number.</div>
<div>
</div>
<div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> math.randomseed( os.time() )</span></div>
<div>
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> math.random()</span></div>
<div>
<br /></div>
</div>
<div>
The three functions <span style="font-family: Courier New, Courier, monospace;">SectionStart()</span>, <span style="font-family: Courier New, Courier, monospace;">SectionEnd()</span>, and <span style="font-family: Courier New, Courier, monospace;">ReportStatus()</span> create three XML elements:</div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><Section name="startname"></span>, <span style="font-family: Courier New, Courier, monospace;"></SectionName></span>, and <span style="font-family: Courier New, Courier, monospace;"><SectionStatus ...></span>, respectively.</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">ReportStatus()</span> - Reports status to recipe output window and the recipe log file.</div>
<div>
Returns a lot of information.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">SectionStart(sectionname)</span> - Marks a section with a string name. </div>
<div>
<span style="font-family: Courier New, Courier, monospace;">SectionEnd()</span> - Returns the scoring difference between now and <span style="font-family: Courier New, Courier, monospace;">SectionStart()</span>. This does not disturb <span style="color: #cc0000;">recentbest,</span> <span style="color: #cc0000;">absolutebest,</span> <span style="color: #cc0000;">creditbest </span>values.</div>
<div>
<br /></div>
<div>
The output of <span style="font-family: Courier New, Courier, monospace;">SectionStart()</span>, <span style="font-family: Courier New, Courier, monospace;">SectionEnd()</span>, and <span style="font-family: Courier New, Courier, monospace;">ReportStatus()</span><span style="font-family: inherit;"> are written to the file </span><span style="font-family: Courier New, Courier, monospace;">script.default.xml</span><span style="font-family: inherit;">. This file is same file that the output of the print() function is recorded in. See </span><span style="font-family: Courier New, Courier, monospace;">print()</span><span style="font-family: inherit;"> function above.</span></div>
<div>
<br /></div>
<div>
<span style="color: #cc0000; font-size: large;">save</span></div>
<div>
<br /></div>
<div>
The <span style="color: #cc0000;">save </span>object is helpful to create snapshots of the protein. There are 100 slots allowed.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Quickload(n)</span> - Load snapshot in slot n.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Quicksave(n)</span> - Save snapshot into slot n.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">LoadSecondaryStructure()</span> - Restore secondary structure stored by <span style="font-family: Courier New, Courier, monospace;">SaveSecondaryStructure()</span>.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">SaveSecondaryStructure()</span> - This saves the secondary structure. <span style="font-family: Courier New, Courier, monospace;">structure.SetSecondaryStructure(...)</span>changes the secondary structure. Only one save slot for secondary structure.</div>
<div>
<br /></div>
<div>
<span style="color: #cc0000; font-size: large;">structure</span></div>
<div>
<br /></div>
<div>
The <span style="color: #cc0000;">structure</span> object, the <span style="color: #cc0000;">rotamer</span>, and the <span style="color: #cc0000;">contactmap</span> objects tells you about the protein.</div>
<div>
Now we're getting somewhere. :)</div>
<div>
The functions of the <span style="color: #cc0000;">structure </span>object that retrieve information about the protein ("getters") are:</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">CanMutate(segmentindex,aminoacid)</span> - Returns if a specific segment can be mutated to a specific amino acid. The <span style="font-family: 'Courier New', Courier, monospace;">aminoacid</span> value is one of the standard one letter representations for amino acids.See <a href="http://en.wikipedia.org/wiki/Amino_acid">http://en.wikipedia.org/wiki/Amino_acid</a></div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"> </span>As of 14Mar2013,</div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"> </span> Virtual residues will now return 'vrt'</div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"> </span> Sugars will now return 'unk'</div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"> </span> DNA will now return 'da' for "ADE", 'dc' for "CYT", 'dg' for "GUA", and 'dt' for "THY"</div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"> </span> RNA will now return 'ra' for "RAD", 'rc' for "RCY", 'rg' for "RGU", and 'ru' for "URA"</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GetAminoAcid(segmentindex)</span> - Returns the aminoacid letter or letters.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GetAtomCount(segmentindex)</span> - Returns the number of side chain atoms in a segment. For instance, glycine has no side chain atoms, so the count is zero.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GetCount()</span> - Get the number of segments in the protein. Almost all scripts use this function. This count is for the current count. The count can change in design puzzles.</div>
<div>
[don't know if the script can determine if the puzzle is a design puzzle]</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GetDistance(segmentindex1,segmentindex2)</span>- Get the distance between two segments. </div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GetNote(segmentindex)</span> - Gets the text notes of the segment.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GetSecondaryStructure(segmentindex)</span> - Returns E=sheet, H=helix, L=loop, M=molecule.</div>
<div>
Note: UPPER case letters for secondary structure, lowercase for amino acids.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">IsHydrophobic(segmentindex)</span> - Is the segment index hydrophobic or hydrophilic? True- the segment is hydrophobic.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">IsLocked(segmentindex)</span> - Is the segment index locked? In some puzzles, part of the segments are locked. This can allow the script to skip segments that can't be changed.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">IsMutable(segmentindex)</span>- Returns whether a segment is mutable.</div>
<div>
<br /></div>
<div>
Now for the <span style="color: #cc0000;">structure</span> object functions that set information about the protein ("setters")</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">SetAminoAcid(segmentindex, aminoacid)</span> - Change the segment index to the new aminoacid.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">SetAminoAcidSelected(aminoacid)</span> - Change all selected segments to the new aminoacid.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">SetNote(segmentindex,string)</span> - Place string into note section of segment.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">SetSecondaryStructure(segmentindex,secondarystructure)</span> - Change the segment index to the secondary structure, e=sheet, h=helix, l=loop, m=molecule. Letter can be uppercase or lowercase.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">SetSecondaryStructureSelected(secondarystructure)</span> - Change all selected segments to the secondary structure.</div>
<div>
<br /></div>
<div>
Lastly, the <span style="color: #cc0000;">structure</span> object functions that change the protein ("doers").</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">IdealizeSelected()</span> - Idealize the selected segments. The <span style="color: #cc0000;">selection</span> object is used to select the segments idealized.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">LocalWiggleAll(iterations,[backbone, sidechains])</span> - Does a local wiggle of all segments for <span style="font-family: Courier New, Courier, monospace;">iterations</span>. Can be set to wiggle on the backbone or the side chains for both. Note <span style="font-family: Courier New, Courier, monospace;">LocalWiggleAll()</span> is not the same as <span style="font-family: Courier New, Courier, monospace;">WiggleAll()</span>.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">LocalWiggleSelected(iterations,[backbone,sidechains])</span> - Does a local wiggle of the selected segments. Can be set to wiggle the backbone or the side chains for both.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">MutateSidechainsAll(iterations)</span> - The same as the GUI 'Mutate'.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">MutateSidechainsSelected(iterations)</span>- Mutate selected segments' side chains for <span style="font-family: Courier New, Courier, monospace;">iterations</span>. The <span style="color: #cc0000;">selection</span> object is used to select the segments mutated.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">RebuildSelected(iterations)</span> - Rebuild selected segments for iterations. The <span style="color: #cc0000;">selection</span> object is used to select the segments rebuilt. The GUI Rebuild automatically selects all the segments of the selected secondary structure.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">ShakeSidechainsAll(iterations)</span> - Same as GUI Shake.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">ShakeSidechainsSelected(iterations)</span>- Shakes the selected side chains.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">WiggleAll()</span>- Same as GUI Wiggle All.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">WiggleAllSelected()</span>- Wiggle All selected segments. The <span style="color: #cc0000;">selection</span> object is used select segments to wiggle.</div>
<div>
<br /></div>
<div>
<span style="color: #cc0000; font-size: large;">rotamer</span></div>
<div>
<br /></div>
<div>
The <span style="color: #cc0000;">rotamer </span>object has two functions, one "getter", one "setter".</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GetCount(index)</span> - This is the number of rotamers the sidechain at <span style="font-family: Courier New, Courier, monospace;">index </span>can snap to.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">SetRotamer(index, position)</span>- This sets the rotamer position for the given <span style="font-family: Courier New, Courier, monospace;">index</span>. Position can be from 1 to <span style="font-family: Courier New, Courier, monospace;">rotamer.GetCount().</span></div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"> </span></div>
<div>
<span style="color: #cc0000; font-size: large;">behavior</span></div>
<div>
<br /></div>
<div>
The <span style="color: #cc0000;">behavior</span> object modifies how shake and wiggle operate, "getters", and "setters".</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GetClashImportance()</span> - This gets the clash importance, or CI, a value from 0 to 1.0.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">SetClashImportance(ci)</span> - Set the CI to a value from 0 to 1.0.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GetBandStrengthMultiplier()</span> - Get the band strength multiplier.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">SetBandStrengthMultiplier(factor)</span> - Sets the band strength multiplier, 0.5 to 1.5, +/- 50%</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GetSlowFiltersDisabled()</span> - Get true if slow filters are disabled. See SetSlowFilterDisabled()</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">SetSlowFiltersDisabled()</span> - Same a GUI Behavior/Disable Slow Filters. If on, skips CPU intensive filters. Must be enabled to credit score. Disabling slow filters will make <span style="font-family: Courier New, Courier, monospace;">AreConditionsMet()</span> return false.</div>
<div>
<br /></div>
<div>
<span style="color: #cc0000; font-size: large;">contactmap</span></div>
<div>
<br /></div>
<div>
The <span style="color: #cc0000;">contactmap</span> object is only used for exploration puzzles, ("getter").</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">IsContact(index1,index2)</span> - Are two segments in contact (within a specified minimum)?</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GetHeat(index1,index2)</span> - Get the heat of two segments. This returns a value from 0 to 1.</div>
<div>
1 indicates all users have this pair of segments in contact.</div>
<div>
0 indicates no users have this pair of segments in contact.</div>
<div>
Between 0 and 1 is the percentage of users that have this pair of segments in contact.</div>
<div>
</div>
<div>
One would expect <span style="font-family: Courier New, Courier, monospace;">GetHeat(n,n+1)</span> to always return 1 for all segments of the protein.</div>
<div>
On a non-exploration puzzle <span style="font-family: Courier New, Courier, monospace;">IsContact(n,n+1)</span> returns false.</div>
<div>
<br /></div>
<div>
<span style="color: #cc0000; font-size: large;">selection </span></div>
<div>
<br /></div>
<div>
One of the features of a Lua V2.0 script is to be able to manipulate the protein one segment or more</div>
<div>
at a time. In the GUI client, one makes selections with the shift key down for freezing</div>
<div>
one segment and right-click to select an entirestructure. Lua V2.0 can be more detailed</div>
<div>
than the GUI.</div>
<div>
<br /></div>
<div>
The <span style="color: #cc0000;">selection </span>object provides the functions to select, and deselect segments for manipulation</div>
<div>
by the <span style="font-family: Courier New, Courier, monospace;">structure.xxxSelected()</span> functions.</div>
<div>
<br /></div>
<div>
The segments are selected using these functions.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Select(index)</span> - Select a segment index, just one.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">SelectAll()</span> - Select all the segments, 1 to<span style="font-family: Courier New, Courier, monospace;"> structure.GetCount()</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">SelectRange(index1,index2)</span> - Select from segment index1 to segment index2, inclusive.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Deselect(index)</span> - Deselect segment index.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">DeselectAll()</span> - Deselect all segments.</div>
<div>
<br /></div>
<div>
No. There is no <span style="font-family: Courier New, Courier, monospace;">DeselectRange(index1,index2)</span>.</div>
<div>
<br /></div>
<div>
The selected segments do not affect the <span style="font-family: Courier New, Courier, monospace;">structure.xxxAll()</span><span style="font-family: inherit;"> functions.</span></div>
<div>
Only the <span style="font-family: 'Courier New', Courier, monospace;">structure.xxxSelected()</span> functions act on the selected segments.</div>
<div>
There is only one set of selected segments.</div>
<div>
<br /></div>
<div>
One has to create storage in your Lua V2.0 script to hold more than one list</div>
<div>
of segments to be selected and call <span style="font-family: Courier New, Courier, monospace;">DeselectAll()</span> each time you want to use it.</div>
<div>
<br /></div>
<div>
<span style="color: #990000; font-size: large;">freeze</span></div>
<div>
<br /></div>
<div>
The <span style="color: #cc0000;">freeze </span>object modifies the properties of the protein. It is just like the GUI feature.</div>
<div>
A Lua V2.0 program must select a sub-structure to freeze the whole sub-structure.</div>
<div>
The GUI just requires a right-click followed by a freeze.</div>
<div>
The <span style="color: #cc0000;">freeze </span>functions are:</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Freeze(index,backbone,sidechain)</span> - The segment index is frozen. The backbone may be frozen. The sidechain may be frozen, or both. If neither are selected, nothing happens.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">FreezeAll()</span> - Freezes all segments, both backbone and sidechains.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">integer, integer GetCount()</span> - Get the count of the number of segments frozen. This is an unusual function, as it returns two values instead of one. The first value is the backbone frozen count. The second value is the sidechain frozen count.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">boolean, boolean IsFrozen(segment index)</span> - Is the backbone or sidechain of the segment index frozen?</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">UnfreezeAll()</span> - Unfreeze all backbones and sidechains.</div>
<div>
<br /></div>
<div>
<span style="color: #cc0000; font-size: large;">band</span></div>
<div>
<br /></div>
<div>
The <span style="color: #cc0000;">band </span>manipulates the bands. In the GUI, if one right-clicks on a band,</div>
<div>
one sees the list of options, enable/disable, set length, set strength, delete.</div>
<div>
These options are also available in the <span style="color: #cc0000;">band </span> object, and with more range</div>
<div>
to strength and length.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-58DwTSkcNlU/Uf8KjsFpC7I/AAAAAAAACuU/Et4TqGk7MFc/s1600/bandgui.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-58DwTSkcNlU/Uf8KjsFpC7I/AAAAAAAACuU/Et4TqGk7MFc/s1600/bandgui.jpg" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
Bands are numbered starting at 1. Each time a band is created a number is assigned.</div>
<div>
The function that created the band returns the band number of the new band.</div>
<div>
<br /></div>
<div>
The default length of a band is 3.5. The default strength of a band 1.0.</div>
<div>
Call <span style="font-family: Courier New, Courier, monospace;">SetGoalLength()</span> and <span style="font-family: Courier New, Courier, monospace;">SetStrength()</span> to change these values after creating a band.</div>
<div>
<br /></div>
<div>
When a band is created it is automatically enabled. Call <span style="font-family: Courier New, Courier, monospace;">Disable()</span> to disable band.</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Add(segmentOrigin, segmentXaxis, segmentYaxis, rho, phi, [atomindexorigin],[atomXaxis],[atomYaxis])</span></div>
<div>
This produces a band that ends in empty space. This is the only 3-D function in Lua V2.</div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"> </span>See <a href="http://foldit.wikia.com/wiki/Foldit_Lua_Function_band.Add">http://foldit.wikia.com/wiki/Foldit_Lua_Function_band.Add</a> for details.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">AddBetweenSegments(index1,index2,[atomindex1],[atomindex2])</span></div>
<div>
A band is drawn between the two segments or between the two atom indices</div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"> </span>of the two segments. The band length is <span style="font-family: Courier New, Courier, monospace;">structure.GetDistance(index1,index2)</span> or close there to.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">AddBetweenSegments(4,10,1,2)</span> will create a band between segments 4 atom index 1 and segment 10 atom index 2. The maximum value of atom index for segment 4 is <span style="font-family: Courier New, Courier, monospace;">structure.GetAtomCount(4)</span><span style="font-family: inherit;"> and for segment 10 is </span><span style="font-family: 'Courier New', Courier, monospace;">structure.GetAtomCount(10).</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">AddToBandEndpoint(segmentindex, bandindex,[atomindex])</span></div>
<div>
A band from segment index or atom index of segment index to the endpoint of <span style="font-family: Courier New, Courier, monospace;">bandindex </span>band. This only applies to bands created that end in empty space.</div>
<div>
<span class="Apple-tab-span" style="white-space: pre;"> </span>See <a href="http://foldit.wikia.com/wiki/Foldit_Lua_Function_band.AddToBandEndpoint">http://foldit.wikia.com/wiki/Foldit_Lua_Function_band.AddToBandEndpoint</a></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Delete(bandindex)</span> - Delete band index band.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">DeleteAll()</span> - Delete all bands. Same as GUI Remove All Bands.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Disable(bandindex)</span> - Disables band index band. Same as right-click on band, disable.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">DisableAll()</span> - Disable all bands.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Enable(bandindex)</span> - Enable band index band. Same as right-click on band, enable.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">EnableAll()</span> - Enable all the bands.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GetCount() </span>- Get the count of the number of bands.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GetGoalLength()</span> - This is the 'true' length of the band, at which length the band</div>
<div>
neither pushes or pulls. See SetGoalLength().</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GetLength(bandindex)</span> - Get the current length of the band.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GetStrength(bandindex)</span> - Get the strength of the band. See SetStrength()</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">IsEnabled(bandindex)</span> - Is the band enabled?</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">SetGoalLength(index,length)</span> - Set the 'true' length of the band. A value from 0 to 1000.</div>
<div>
If the band is less than this length, <span style="font-family: Courier New, Courier, monospace;">GetLength(index)</span> < <span style="font-family: Courier New, Courier, monospace;">GetGoalLength(index)</span>, then <span class="Apple-tab-span" style="white-space: pre;"> </span>the band pushes the endpoints apart. If <span style="font-family: Courier New, Courier, monospace;">GetLength(index)</span> > <span style="font-family: Courier New, Courier, monospace;">GetGoalLength(index)</span>, then the band pulls the endpoints inward.</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">SetStrength(bandindex,strength)</span> - Set the band strength. </div>
<div>
<br /></div>
<div>
<span style="color: #cc0000; font-size: large;">ui</span></div>
<div>
<br /></div>
<div>
The <span style="color: #cc0000;">ui</span> dialog allows the Lua V2.0 scripts to move the puzzle around on screen in a limited way.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">AlignGuide(segmentindex)</span> - This is the same as the GUI feature. Align the protein with</div>
<div>
the guide at the segment index.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">CenterViewport()</span> - This is the same as the GUI feature, HOME. Useful to make</div>
<div>
sure the user can see the protein after many iterations.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GetPlatform()</span> - Gets the 'OS' the client (script) is running on.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">win_x86</span> is one response.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">GetTrackName()</span> - Gets the track name. This gets the name of the current track.</div>
<div>
GUI allows user to create independent tracks. Since each track must be unique from puzzle to puzzle, some naming convention must be agreed to with the user so that the script doesn't have to change with each puzzle if the script is to use a particular track.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">puzzle.GetPuzzleName()</span> or <span style="font-family: Courier New, Courier, monospace;">puzzle.GetPuzzleID()</span> could provide a 'root' and then append standard suffixes for all puzzles. Without a <span style="font-family: Courier New, Courier, monospace;">GetTrackNameList()</span> or a <span style="font-family: Courier New, Courier, monospace;">SetTrackName()</span>, this function seems limited without a convention in track names.</div>
<div>
<br /></div>
<div>
<span style="color: #cc0000; font-size: large;">dialog</span></div>
<div>
<br /></div>
<div>
Finally, the <span style="color: #cc0000;">dialog </span>object. This is the most complicated Fold.it Lua V2.0 object.</div>
<div>
The functions are required to be called in a specific order.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">CreateDialog()</span> - Call this function first. It returns a lua table that is used</div>
<div>
with the rest of the 'dialog' functions.</div>
<div>
See <a href="http://foldit.wikia.com/wiki/Foldit_Lua_Function_dialog.Show">http://foldit.wikia.com/wiki/Foldit_Lua_Function_dialog.Show</a></div>
<div>
<br /></div>
<div>
One can add to the dialog window sliders, checkboxes, labels, and buttons.</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">AddLabel(string)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">AddCheckbox(string,[true,false])</span> - If 'true', box is checked by default</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">AddSlider(string,default,low,high,precision)</span> - A slider is presented that allows the user to select a number from 'low' to 'high' with a decimal precision of 'precision'. Use 0 for precision when working with integers. 'default' is the value shown at the start.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">AddButton(string,value)</span> - Each button needs to have its own unique value.</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">dialog.AddButton("OK",1)</span> <span style="font-family: Courier New, Courier, monospace;">dialog.AddButton("Cancel",0)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">CreateDialog(string)</span> - A dialog object is created that has labels, checkboxes, sliders and buttons added to it. <span style="font-family: Courier New, Courier, monospace;">dialog.show(dialog)</span> is used to display the dialog object created by <span style="font-family: Courier New, Courier, monospace;">dialog.CreateDialog(string)</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">Show(dialog)</span> - Here <span style="font-family: Courier New, Courier, monospace;">dialog.Show(dialog)</span> receives the variable of <span style="font-family: Courier New, Courier, monospace;">dialog.CreateDialog(string). </span>The return code of dialog.Show(dialog) will be the button selected.</div>
<div>
<br /></div>
<div>
The dialog window is a finite width and maximum height. It maybe necessary to program a 'Next' button to provide the user with another window of selections.</div>
<div>
<br />
<span style="font-size: large;">A Glimpse into the Future</span><br />
<br />
With a little investigating, one is able to find that there are several functions that are available to be called, but do not do anything.<br />
<br />
One can only speculate what the functions will do. Get and Set give some hint. <span style="font-family: Courier New, Courier, monospace;">structure.Tweakxxx()</span> is obvious. <span style="font-family: Courier New, Courier, monospace;">behavior.xxxAccuracy()</span> would seem to be a feature to make wiggle and shake run until the change in points is within a range and simply wait however many iterations it takes to get there.<br />
<br />
The following code will expose the functions of each of the major objects.<br />
<br />
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;">for key,value in pairs(object) do</span><br />
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;"> print("found member " .. key);</span><br />
<span style="color: #6aa84f; font-family: Courier New, Courier, monospace;">end</span><br />
<br />
where <span style="font-family: Courier New, Courier, monospace;">object</span> is one of the Fold.it Lua 2.0 objects, such as <span style="font-family: Courier New, Courier, monospace;">structure</span><span style="font-family: inherit;">, </span><span style="font-family: Courier New, Courier, monospace;">band</span><span style="font-family: inherit;">, or </span><span style="font-family: Courier New, Courier, monospace;">current</span>.<br />
<br />
These functions are:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">structure.TweakRotate(segmentindex,angle)</span> - Rotate segment by angle, angle in radians, -pi to +pi. Segment must be a sheet or helix.<br />
<span style="font-family: 'Courier New', Courier, monospace;">structure.</span><span style="font-family: Courier New, Courier, monospace;">TweakShift(segmentindex,shiftDirection)</span> - Shift segment index one way or other. Segment must be a sheet.<br />
<span style="font-family: Courier New, Courier, monospace;">structure.TweakStraighten(segmentindex)</span> - Straighten segment index. Segment must be a sheet.<br />
<div>
<div>
<span style="font-family: Courier New, Courier, monospace;">behavior.GetBuriedSideChainAccuracy()</span> - ??</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">behavior.SetBuriedSideChainAccuracy() </span>- range 0 to 1</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">behavior.GetExposedSideChainAccuracy()</span> - ??</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">behavior.SetExposedSideChainAccuracy() </span>- range 0 to 1</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">behavior.GetShakeAccuracy()</span> - Returns the shake accuracy</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">behavior.GetWiggleAccuracy()</span> - Returns the wiggle accuracy</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">behavior.SetShakeAccuracy() </span>- Sets the shake accuracy. range ?</div>
<div>
<span style="font-family: Courier New, Courier, monospace;">behavior.SetWiggleAccuracy() </span>- Sets the wiggle accuracy. range ?</div>
</div>
<div>
<br /></div>
<br /></div>
</div>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8192642777375146218.post-84531191079250030052013-08-03T05:03:00.000-04:002018-02-22T13:48:51.375-05:00Augment GDB with Convenience Variables and User-defined CommandsI have had the need over the past few months to work with GDB but without a symbol table.<br />
<br />
Searching the web one finds others, though a small minority, that have asked how to work with GDB when there is no symbol table available.<br />
<br />
I posted several questions to <a href="http://www.stackoverflow.com/">Stack Overflow</a> regarding GDB and not having a symbol table.<br />
<a href="http://stackoverflow.com/questions/17956799/it-is-possible-to-declare-a-gdb-convenience-variable-as-an-array">SO Question 17956799</a><br />
<a href="http://stackoverflow.com/questions/17492119/issue-with-gdb-jtag-and-cpu32">SO Question 17492119</a><br />
<a href="http://stackoverflow.com/questions/17956799/it-is-possible-to-declare-a-gdb-convenience-variable-as-an-array">SO Question 17956799</a><br />
<a href="http://stackoverflow.com/questions/17667590/how-do-i-write-a-gdb-function-to-make-a-comparison-to-the-program-counter">SO Question 17667590</a><br />
<br />
People have reported problems of not being able to set breakpoints. GDB reports<br />
<span style="font-family: "courier new" , "courier" , monospace;">'No symbol table loaded. Use "file" command'</span><br />
<br />
<a href="http://stackoverflow.com/questions/4698299/set-breakpoint-in-an-stripped-elf-executable">SO Question 4698299</a><br />
<br />
Some of these questions are from newbie programmers who didn't include debug symbols in their build, but others are those, like me, trying to work with legacy programs that are no longer compatible with the GDB tool chain.<br />
<br />
This is typical in reverse engineering of legacy code.<br />
<br />
This blog tells about how I made GDB useful when there is no symbol table available. My experience is in the embedded environment. I have small memory sizes, slow (relatively) speed processors, and only one process. I am also working with cross-tools and target hardware.<br />
<br />
Having used GDB before will help when reading what follows. I have added links to GDB commands mentioned in the text.<br />
<h1>
Symbol Map</h1>
First, one needs to have a symbol map.<br />
<br />
If one doesn't have a symbol map, well, you can start creating your own by giving your own names to hex addresses where <span style="font-family: "courier new" , "courier" , monospace;">call </span>or <span style="font-family: "courier new" , "courier" , monospace;">jsr </span>instructions are found in a dis-assembly listing, but having a symbol map is much better.<br />
<br />
What information does a symbol map have? Addresses with associated names.<br />
<br />
It is much better to refer to a memory address as <span style="font-family: "courier new" , "courier" , monospace;">main</span>, than <span style="font-family: "courier new" , "courier" , monospace;">0x243AD</span>. (Though over time you might start seeing <span style="font-family: "courier new" , "courier" , monospace;">main</span>, when you see<span style="font-family: "courier new" , "courier" , monospace;"> 0x243AD</span>, but why bother?)<br />
<br />
A symbol map, however, is not a symbol table, as far as GDB is concerned.<br />
<br />
I have not found any documentation on how to create a symbol table file without using a linker.<br />
<br />
One is able to create convenience variables in GDB that hold the addresses in the symbol map and give these addresses names that GDB can use. <a href="http://sourceware.org/gdb/onlinedocs/gdb/Convenience-Vars.html">GDB Convenience Variables</a><br />
<br />
From my symbol map, I have this record.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">_CheckCheckSum__6EepromFs code 000220D2 eeprom</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">Eeprom::CheckCheckSum(short)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: inherit;">I can create a GDB convenience variable.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">set $Eeprom_CheckCheckSum=(unsigned int*)0x220D2</span><br />
<div>
<br />
I can then say<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">x /40i $Eeprom_CheckCheckSum</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
The GDB e<span style="font-family: "courier new" , "courier" , monospace;">xamine</span><span style="font-family: inherit;"> (</span><span style="font-family: "courier new" , "courier" , monospace;">x</span><span style="font-family: inherit;"> for short)</span> command will disassemble the next 40 instructions starting at the address <span style="font-family: "courier new" , "courier" , monospace;">$Eeprom_CheckCheckSum</span>.<br />
<a href="http://ftp.gnu.org/old-gnu/Manuals/gdb-5.1.1/html_chapter/gdb_9.html#SEC56">GDB examine command</a></div>
<h1>
JTAG or BDM Device</h1>
<div>
If one has legacy code, it probably doesn't support GDB. To use GDB, one MUST have a GDB server, either in the target hardware or on a device connected to the target hardware.</div>
<div>
<br /></div>
<div>
Current JTAG or BDM (Motorola CPUs only) devices provide the GDB server.<br />
<br />
When using a JTAG device, the target of GDB is considered remote. GDB has a configuration command, <span style="font-family: "courier new" , "courier" , monospace;">target remote</span>. <a href="http://sourceware.org/gdb/onlinedocs/gdb/Connecting.html#Connecting">GDB target remote command</a></div>
<div>
<br /></div>
<div>
Once GDB can communicate with the JTAG device, then GDB has a command that allows one to send JTAG device-specific commands, <span style="font-family: "courier new" , "courier" , monospace;">monitor</span>.<br />
<br /></div>
<div>
Any command that you want to send to the JTAG device is sent via GDB by<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">monitor <JTAG command></span></div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">mon</span><span style="font-family: inherit;"> </span>is short for <span style="font-family: "courier new" , "courier" , monospace;">monitor</span>.</div>
<div>
<br />
Example, to reset the CPU via the Abatron BDI2000, one issues the GDB command<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">mon reset</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<a href="http://www.abatron.ch/fileadmin/user_upload/products/pdf/ManGDBCF-2000C.pdf">Abatron BDI200 User's Manual</a></div>
<h1>
GDB command file</h1>
<div>
When GDB is started, it looks for the file<span style="font-family: inherit;"> </span><span style="font-family: "courier new" , "courier" , monospace;">.gdbinit</span>. This file name can be overridden using the <span style="font-family: "courier new" , "courier" , monospace;">-x <filename></span> command line option. <a href="http://sourceware.org/gdb/onlinedocs/gdb/Startup.html">GDB Startup</a></div>
<div>
<br /></div>
<div>
This is the file where we place the <span style="font-family: "courier new" , "courier" , monospace;">target</span><span style="font-family: inherit;"> </span>command to communicate with the JTAG device or GDB server. Placing the <span style="font-family: "courier new" , "courier" , monospace;">target remote</span> command in <span style="font-family: "courier new" , "courier" , monospace;">.gdbinit</span> ensures the GDB session is communicating with the target. If there's a communication problem, we will know it right away.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"># Communicate with an Abatron BDI2000</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">target remote 192.168.0.10:2001</span></div>
<div>
<br /></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">.gdbinit</span> is also where we place the convenience variables we derived from the symbol map.</div>
<div>
<br /></div>
<div>
From my symbol map, I have this record.</div>
<div>
<br />
<span style="font-family: "courier new" , "courier" , monospace;">_CheckCheckSum__6EepromFs code 000220D2 eeprom</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">Eeprom::CheckCheckSum(short)</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: inherit;">I create the following convenience variable and put it in the </span><span style="font-family: "courier new" , "courier" , monospace;">.gdbinit</span><span style="font-family: inherit;"> file.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">set $</span><span style="font-family: "courier new" , "courier" , monospace;">Eeprom_CheckCheckSum</span><span style="font-family: "courier new" , "courier" , monospace;">=(unsigned int *)0x220D2</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<br />
<span style="font-family: inherit;">One can list the convenience variables with the GDB command</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">show conv</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<h2>
<span style="font-family: inherit;">GDB User-defined Command</span></h2>
</div>
<div>
<span style="font-family: inherit;">Along with convenience variables, GDB also allows one to define user-defined commands.</span></div>
<div>
<a href="http://sourceware.org/gdb/onlinedocs/gdb/Define.html">User-defined commands</a></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
User-defined commands are way to create automated functions for repetitive tasks or complicated debugging logic.<br />
<br />
They can also be used to create short cuts for JTAG device commands.<br />
<br />
Below are a few of Abatron BDI2000 JTAG commands and the GDB equivalent.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"># BDI2000 command 'reset'</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">define mreset</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> mon reset</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> flushregs</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">document mreset</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">Send the BDI2000 command 'reset'</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">'flushregs' is required as GDB does not</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">know what 'mon reset' did to the target</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;"># BDI2000 command 'mrd'-read registers</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">define mrd</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">mon rd</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">document mrd</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">Send the BDI2000 command 'rd'. More compact than 'info reg'</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">end</span></div>
<div>
<br /></div>
<div>
<span style="font-family: inherit;">In the </span><span style="font-family: "courier new" , "courier" , monospace;">document </span><span style="font-family: inherit;">section for the </span><span style="font-family: "courier new" , "courier" , monospace;">mreset </span><span style="font-family: inherit;">user-defined command is a key concept. If you use ANY </span><span style="font-family: "courier new" , "courier" , monospace;">monitor</span><span style="font-family: inherit;"> command that changes the registers of the target CPU, you MUST include the GDB </span><span style="font-family: "courier new" , "courier" , monospace;">flushregs </span><span style="font-family: inherit;">command at the end of the command.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">GDB does not know what </span><span style="font-family: "courier new" , "courier" , monospace;">monitor</span><span style="font-family: inherit;"> commands do to the CPU state, </span><span style="font-family: "courier new" , "courier" , monospace;">flushregs </span><span style="font-family: inherit;">is the GDB command to say to GDB 'The state of the registers has changed, your cache is no longer valid.'</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">The user-defined commands are also placed in </span><span style="font-family: "courier new" , "courier" , monospace;">.gdbinit</span><span style="font-family: inherit;">.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">show user [command name]</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: inherit;">The show user command lists the user-defined commands.</span><br />
<a href="http://sourceware.org/gdb/onlinedocs/gdb/Define.html">GDB show user command</a></div>
<div>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">So with the above user-functions and environment variables, one change enter at the GDB command prompt.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">mreset</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">mrd</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">x /40i $Eeprom_CheckCheckSum</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: inherit;">If the target hardware has hardware breakpoint support, I can also say</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">br $Eeprom_CheckCheckSum</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">continue</span><br />
<span style="font-family: inherit;"><br /></span>
When needing to disassemble instructions constantly, I created a user-command <span style="font-family: "courier new" , "courier" , monospace;">dxi</span>.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"># dxi</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"># dxi <count></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"># dxi <count> <startaddress></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">define dxi</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">if $argc == 2</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> x /$arg0i $arg1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">if $argc == 1</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> x /$arg0i $pc</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">if $argc == 0</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>x /20i $pc</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">end</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">document dni</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">Output $arg0 instructions from current PC</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">If $arg0 is not supplied, output 20 instructions</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">end</span></div>
<div>
<br /></div>
<div>
If one wants to capture the dis-assembly of the <span style="font-family: "courier new" , "courier" , monospace;">examine</span> command, one can create a pair of user-commands to turn on and turn off logging. The dis-assembly listing will be recorded in a log file.</div>
<div>
<br /></div>
<div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">#startlog</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">#startlog <file></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">define startlog</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> if $argc == 0</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> set logging off</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>set logging on</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> end</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> if $argc == 1</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> set logging off</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> set logging file $arg0</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> set logging on</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> end</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">end</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">document startlog</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"> Open 'gdb.txt' or $arg0 for GDB logging</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">end</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">define stoplog</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">set logging off</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">end</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">document stoplog</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">Turn off GDB logging</span></div>
<div>
<span style="font-family: "courier new" , "courier" , monospace;">end</span></div>
<div>
<br /></div>
</div>
<div>
Thus without a symbol table one can create a usable debugging environment.<br />
<br />
Hope you found this post worth reading.<br />
<br />
The next post discusses how to augment GDB when the target processor does not have <a href="https://fernleaf07.blogspot.com/2015/07/using-gdb-with-target-processor-that.html">hardware breakpoint support</a>.<br />
<span style="font-family: inherit;"><br /></span></div>
Unknownnoreply@blogger.com0