<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>plusHa &#187; Makefile</title>
	<atom:link href="http://plusha.com/tag/makefile/feed/" rel="self" type="application/rss+xml" />
	<link>http://plusha.com</link>
	<description>in the light</description>
	<lastBuildDate>Sat, 31 Dec 2011 01:57:59 +0000</lastBuildDate>
	<language>ko</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='plusha.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>plusHa &#187; Makefile</title>
		<link>http://plusha.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://plusha.com/osd.xml" title="plusHa" />
	<atom:link rel='hub' href='http://plusha.com/?pushpress=hub'/>
		<item>
		<title>Rakefile basic</title>
		<link>http://plusha.com/2008/05/20/rakefile-basic/</link>
		<comments>http://plusha.com/2008/05/20/rakefile-basic/#comments</comments>
		<pubDate>Tue, 20 May 2008 12:06:21 +0000</pubDate>
		<dc:creator>plusha</dc:creator>
				<category><![CDATA[Computer]]></category>
		<category><![CDATA[Makefile]]></category>
		<category><![CDATA[Rakefile]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://plusha.wordpress.com/?p=13</guid>
		<description><![CDATA[Rakefile은 Makefile과 비슷한 역할을 하는, Ruby script입니다. 따라서 Ruby라는 언어의 강력한 기능들을 그대로 가져다 쓸 수 있다는 장점이 있습니다. 단, Ruby를 알아야 제대로 사용할 수 있겠죠. Makefile을 make라는 명령어로 실행하듯이, Rakefile은 rake라는 명령어로 실행합니다. Rakefile 작성법을 Makefile 작성법과 비교하며 살펴보도록 하겠습니다. Makefile의 기본적인 작성법은 Target: Dependency list [Tab] Command 였죠. Rakefile도 유사합니다. 단, Ruby syntax를 [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=plusha.com&amp;blog=174108&amp;post=13&amp;subd=plusha&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Rakefile은 Makefile과 비슷한 역할을 하는, Ruby script입니다. 따라서 Ruby라는 언어의 강력한 기능들을 그대로 가져다 쓸 수 있다는 장점이 있습니다. 단, Ruby를 알아야 제대로 사용할 수 있겠죠. Makefile을 make라는 명령어로 실행하듯이, Rakefile은 rake라는 명령어로 실행합니다. Rakefile 작성법을 Makefile 작성법과 비교하며 살펴보도록 하겠습니다. Makefile의 기본적인 작성법은<br />
<code>Target: Dependency list<br />
[Tab] Command<br />
</code><br />
였죠. Rakefile도 유사합니다. 단, Ruby syntax를 사용하죠. 기본적인 작성법은 다음과 같습니다.<br />
<code>task :name = [:prereq1, :prereq2] do<br />
    Command<br />
end<br />
</code><br />
Makefile에서 Target에 해당하는 것이 Rakefile의 task입니다. 잘 살펴보면 task라는 함수명과 Hash, Block 두 개의 argument로 이루어진 구조라는 것을 알 수 있습니다. Hash의 key는 target이 되고 value는 prerequisites (dependency list)가 됩니다. Block은 실행해야 할 명령들로 이루어집니다. 특별히 compile하는 경우와 같이 파일을 작성하는 task의 경우에는<br />
<code>file "name" = ["prereq1", "prereq2"] do<br />
    Command<br />
end<br />
</code><br />
와 같이 file task를 사용합니다. Command 부분에서 &#8216;name&#8217; 또는 dependency list (prereq1, prereq2, &#8230; )를 사용하고 싶을 때는<br />
<code>file "name" = ["prereq1", "prereq2"] do |t|<br />
sh "f77 -o #{t.name} #{t.prerequisites.join(' ')}"<br />
end<br />
</code><br />
과 같이 사용하여 <code>f77 -o name prereq1 prereq2</code>와 같은 결과를 얻을 수도 있습니다.</p>
<p>그럼 <a href="http://plusha.com/2008/05/08/makefile-basic/">앞에서 만들었던 Makefile</a>과 같은 기능을 하는 Rakefile을 만들어 비교해 보겠습니다. 앞에서 만들었던 Makefile은 다음과 같고,</p>
<pre><tt><code><span style="color:#000000;">01:</span> <em><span style="color:#9a1900;"># target: dependency list</span></em>
<span style="color:#000000;">02:</span> <em><span style="color:#9a1900;"># [tab] command</span></em>
<span style="color:#000000;">03:</span> <span style="color:#009900;">F77=</span>gfortran
<span style="color:#000000;">04:</span>
<span style="color:#000000;">05:</span> <span style="color:#990000;">all:</span> main
<span style="color:#000000;">06:</span>
<span style="color:#000000;">07:</span> <span style="color:#990000;">main:</span> main.o sub1.o sub2.o
<span style="color:#000000;">08:</span>         <span style="color:#009900;">$(F77)</span> -O<span style="color:#993399;">2</span> -o main main.o sub1.o sub2.o
<span style="color:#000000;">09:</span> <span style="color:#990000;">main.o:</span> main.f
<span style="color:#000000;">10:</span>         <span style="color:#009900;">$(F77)</span> -O<span style="color:#993399;">2</span> -c main.f
<span style="color:#000000;">11:</span> <span style="color:#990000;">sub1.o:</span> sub1.f
<span style="color:#000000;">12:</span>         <span style="color:#009900;">$(F77)</span> -O<span style="color:#993399;">2</span> -c sub1.f
<span style="color:#000000;">13:</span> <span style="color:#990000;">sub2.o:</span> sub2.f
<span style="color:#000000;">14:</span>         <span style="color:#009900;">$(F77)</span> -O<span style="color:#993399;">2</span> -c sub2.f
<span style="color:#000000;">15:</span> <span style="color:#990000;">clean:</span>
<span style="color:#000000;">16:</span>         rm main main.o sub1.o sub2.o</code>
</tt></pre>
<p>이에 해당하는 Rakefile은 다음과 같습니다.</p>
<p><pre class="brush: ruby;">
f90='gfortran'

task :default =&gt; ['main.e']
file 'main.e' =&gt; ['main.o','sub1.o','sub2.o'] do |t|
    sh &quot;#{f90} -o #{t.name} main.o sub1.o sub2.o&quot;
end

file 'main.o' =&gt; ['main.f'] do
    sh &quot;#{f90} -c main.f&quot;
end
file 'sub1.o' =&gt; ['sub1.f'] do
    sh &quot;#{f90} -c sub1.f&quot;
end
file 'sub2.o' =&gt; ['sub2.f'] do
    sh &quot;#{f90} -c sub2.f&quot;
end

require 'rake/clean'
CLEAN.include('*.o')
CLOBBER.include('main.e')
</pre></p>
<p><code>task :default</code> 부분은 Makefile에서 all 이라는 target을 지정해서 사용했던 것과 같은 역할을 합니다. 단, Rakefile에서는 default task가 맨 처음에 나올 필요가 없습니다. 파일 내 아무데나 나와도 잘 인식합니다. 중간 부분은 Makefile과 매우 유사하므로 특별한 설명이 필요 없겠죠? 뒤에 있는 clean task는 rake에 이미 지정되어 있는 task입니다. 사용하기 위해서는 &#8216;rake/clean&#8217;을 불러옵니다. <code>rake clean</code>을 실행하면 CLEAN에 포함된 파일들을 지워주고 <code>rake clobber</code>를 실행하면 CLOBBER와 CLEAN에 지정된 파일들을 모두 지워줍니다. 위에서 볼 수 있는 것처럼, 최종 결과 파일만 CLOBBER에 포함시키고 중간에 생성되는 파일들은 CLEAN에 포함시키면 편리하게 사용할 수 있습니다.</p>
<p>Makefile에서는 확장자법칙을 이용해 편리하게 compile할 수 있었죠? Rakefile에도 같은 기능이 있습니다. 비교해볼까요?</p>
<pre><tt><code><span style="color:#000000;">01:</span> <em><span style="color:#9a1900;"># $^ : dependency list</span></em>
<span style="color:#000000;">02:</span> <em><span style="color:#9a1900;"># $@ : target</span></em>
<span style="color:#000000;">03:</span>
<span style="color:#000000;">04:</span> <span style="color:#009900;">F77=</span>ifort
<span style="color:#000000;">05:</span> <span style="color:#009900;">FFLAG=</span>-assume byterecl -O<span style="color:#993399;">2</span>
<span style="color:#000000;">06:</span> <span style="color:#009900;">TARGET=</span>main
<span style="color:#000000;">07:</span> <span style="color:#009900;">OBJECTS=</span>main.o sub1.o sub2.o
<span style="color:#000000;">08:</span>
<span style="color:#000000;">09:</span> <span style="color:#990000;">all:</span> <span style="color:#009900;">$(TARGET)</span>
<span style="color:#000000;">10:</span>
<span style="color:#000000;">11:</span> <span style="color:#009900;">$(TARGET)</span><span style="color:#990000;">:</span> <span style="color:#009900;">$(OBJECTS)</span>
<span style="color:#000000;">12:</span>         <span style="color:#009900;">$(F77)</span> -o <span style="color:#009900;">$@</span> <span style="color:#009900;">$^</span>
<span style="color:#000000;">13:</span>
<span style="color:#000000;">14:</span> <strong><span style="color:#000080;">.SUFFIXES:</span></strong> .o .f
<span style="color:#000000;">15:</span> <span style="color:#990000;">%</span>.o<span style="color:#990000;">:</span> <span style="color:#990000;">%</span>.f
<span style="color:#000000;">16:</span>         <span style="color:#009900;">$(F77)</span> <span style="color:#009900;">${FFLAG}</span> -c <span style="color:#009900;">$^</span>
<span style="color:#000000;">17:</span>
<span style="color:#000000;">18:</span> <span style="color:#990000;">clean:</span>
<span style="color:#000000;">19:</span>         rm <span style="color:#009900;">$(TARGET)</span> <span style="color:#009900;">$(OBJECTS)</span></code>
</tt></pre>
<p><pre class="brush: ruby;">
F90='ifort'
FFLAG='-assume byterecl -O2'
TARGET='main.e'
SRC=FileList['*.f']
OBJ=SRC.ext('o')

task :default =&gt; TARGET
file TARGET =&gt; OBJ do
    sh &quot;#{F90} -o #{TARGET} #{OBJ}&quot;
end
rule '.o' =&gt; '.f' do |t|
    sh &quot;#{F90} #{FFLAG} -c #{t.source}&quot;
end

require 'rake/clean'
CLEAN.include('*.o')
CLOBBER.include('main.e')
</pre></p>
<p>Rakefile에서는 rule이라는 함수가 Makefile의 확장자법칙과 같은 역할을 합니다. FileList 명령은 glob pattern (여기서는 &#8216;*.f&#8217;)을 받아들여서 해당하는 파일들의 목록을 만들어주고, FileList 객체의 ext method는 목록에 있는 파일들의 확장자를 원하는 확장자로 바꿔서 새로운 FileList를 만들어줍니다. 앞에서 dependency list를 불러올 때 <code>t.prerequisites.join(' ')</code>이라고 사용했었는데 여기서는 <code>t.source</code>라고 사용했습니다. 앞의 방법은 전체 dependency list를 문자열로 만들어주고(&#8216; &#8216;을 이용하여 각각을 합치죠), 뒤의 방법은 dependency list의 첫 번 째 항목만 문자열로 만들어줍니다. 위의 예에서는 dependency list에 &#8216;.o&#8217;에 해당하는 &#8216;.f&#8217; 파일 하나만 있으니까 <code>t.source</code>라고 사용해도 무관하겠죠?</p>
<p>Makefile에 없고 Rakefile에만 있는 기능 중 하나로, task에 설명을 달 수 있는 기능이 있습니다. task 또는 file task 바로 윗 줄에<br />
<code>desc "description"</code><br />
이라고 설명을 추가해주면 <code>rake -T</code>라고 실행했을 때 설명과 함께 task 목록을 보여줍니다. Rakefile을 직접 보지 않고도 안에 무슨 task가 있는지 확인할 수 있는 유용한 기능이죠^^</p>
<p>더 자세한 내용은 다음의 site들을 참고하세요.<br />
<a href="http://rake.rubyforge.org/">http://rake.rubyforge.org/</a><br />
<a href="http://docs.rubyrake.org/">http://docs.rubyrake.org/</a></p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/plusha.wordpress.com/13/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/plusha.wordpress.com/13/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/plusha.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/plusha.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/plusha.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/plusha.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/plusha.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/plusha.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/plusha.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/plusha.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/plusha.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/plusha.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/plusha.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/plusha.wordpress.com/13/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/plusha.wordpress.com/13/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/plusha.wordpress.com/13/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=plusha.com&amp;blog=174108&amp;post=13&amp;subd=plusha&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://plusha.com/2008/05/20/rakefile-basic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">plusha</media:title>
		</media:content>
	</item>
		<item>
		<title>Makefile basic</title>
		<link>http://plusha.com/2008/05/08/makefile-basic/</link>
		<comments>http://plusha.com/2008/05/08/makefile-basic/#comments</comments>
		<pubDate>Thu, 08 May 2008 12:57:35 +0000</pubDate>
		<dc:creator>plusha</dc:creator>
				<category><![CDATA[Computer]]></category>
		<category><![CDATA[Makefile]]></category>

		<guid isPermaLink="false">http://plusha.wordpress.com/?p=12</guid>
		<description><![CDATA[Makefile의 기초적인 사용법을 알아봅시다. 먼저, 다음과 같이 3개의 source 파일이 있을 때 컴파일하는 과정을 알아보겠습니다. 첫 번째 파일: main.f 1: implicit none 2: print *, 'main' 3: call sub1() 4: call sub2() 5: end 두 번째 파일: sub1.f 1: subroutine sub1() 2: print*, 'sub1' 3: end 세 번째 파일: sub2.f 1: subroutine sub2() 2: print*, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=plusha.com&amp;blog=174108&amp;post=12&amp;subd=plusha&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Makefile의 기초적인 사용법을 알아봅시다.</p>
<p>먼저, 다음과 같이 3개의 source 파일이 있을 때 컴파일하는 과정을 알아보겠습니다.</p>
<p>첫 번째 파일: main.f</p>
<pre><tt><code><span style="color:#000000;">1:</span>       <strong><span style="color:#0000ff;">implicit</span></strong> none
<span style="color:#000000;">2:</span>       <strong><span style="color:#0000ff;">print</span></strong> <em><span style="color:#9a1900;">*, 'main'</span></em>
<span style="color:#000000;">3:</span>       <strong><span style="color:#0000ff;">call</span></strong> <strong><span style="color:#000000;">sub1</span></strong><span style="color:#990000;">()</span>
<span style="color:#000000;">4:</span>       <strong><span style="color:#0000ff;">call</span></strong> <strong><span style="color:#000000;">sub2</span></strong><span style="color:#990000;">()</span>
<span style="color:#000000;">5:</span>       <strong><span style="color:#0000ff;">end</span></strong></code>
</tt></pre>
<p>두 번째 파일: sub1.f</p>
<pre><tt><code><span style="color:#000000;">1:</span>       <strong><span style="color:#0000ff;">subroutine</span></strong> <strong><span style="color:#000000;">sub1</span></strong><span style="color:#990000;">()</span>
<span style="color:#000000;">2:</span>       <strong><span style="color:#0000ff;">print</span></strong><em><span style="color:#9a1900;">*, 'sub1'</span></em>
<span style="color:#000000;">3:</span>       <strong><span style="color:#0000ff;">end</span></strong></code>
</tt></pre>
<p>세 번째 파일: sub2.f</p>
<pre><tt><code><span style="color:#000000;">1:</span>       <strong><span style="color:#0000ff;">subroutine</span></strong> <strong><span style="color:#000000;">sub2</span></strong><span style="color:#990000;">()</span>
<span style="color:#000000;">2:</span>       <strong><span style="color:#0000ff;">print</span></strong><em><span style="color:#9a1900;">*, 'sub2'</span></em>
<span style="color:#000000;">3:</span>       <strong><span style="color:#0000ff;">end</span></strong></code>
</tt></pre>
<p>main.f 파일에서 sub1.f와 sub2.f에 있는 subroutine들을 불러오는 매우 간단한 프로그램입니다. 여기서는 하나의 파일 안에 subroutine을 다 넣는 것이 더 편하지만, Makefile 연습을 위해 세 개의 파일로 나누어 놓았습니다.<br />
이렇게 세 개의 파일을 가지고 실행 파일을 만들기 위한 명령은 다음과 같죠.<br />
<code>f77 -c -O2 -o main.o main.f<br />
f77 -c -O2 -o sub1.o sub1.f<br />
f77 -c -O2 -o sub2.o sub2.f<br />
f77 -o main main.o sub1.o sub2.o<br />
</code><br />
위 명령에서 &#8216;-c&#8217; 옵션은 source code를 가지고 object file을 생성하라는 의미입니다. 각각의 source file들에 대해 object file을 생성하고 나중에 링크시켜서 실행파일을 만듭니다. &#8216;-O2&#8242;는 compile 할 때 optimization level 을 2로 하라는 의미, &#8216;-o 파일명&#8217;  은 output file을 &#8216;-o&#8217; 다음에 나오는 파일명으로 만들라는 의미입니다. 마지막 줄에서 세 개의 objective file들을 링크시켜서 &#8216;main&#8217; 이라는 실행파일을 생성합니다. 실행 파일의 실행 결과는 다음과 같습니다.<br />
<code>$ ./main<br />
main<br />
sub1<br />
sub2<br />
</code><br />
잘 실행됩니다. 그런데 만약 sub1.f 파일을 수정했다면 어떻게 해야할까요? 다시 컴파일하기 위해서는<br />
<code>f77 -c -O2 -o sub1.o sub1.f<br />
f77 -o main main.o sub1.o sub2.o<br />
</code><br />
라고 수정한 파일만 다시 컴파일한 후, 다른 object file들과 링크시켜서 실행파일을 만들어야겠죠. 좀 귀찮습니다. 자동으로 할 수 있으면 좋겠죠. shell script를 하나 만들어서 처음의 컴파일 명령 4줄을 다 써 넣으면 자동으로 실행할 수 있습니다. 하지만, 그렇게 되면 sub1.f 파일을 고쳤을 때 main.f와 sub2.f 파일까지 새로 컴파일하게 됩니다. 프로그램이 간단할 때는 큰 문제가 없지만, 프로그램이 크고 복잡해지면 컴파일 시간이 오래 걸린다는 문제가 생기게 됩니다. Source code 내용에 따라서 특정 code는 다른 code보다 먼저 컴파일해야만 하는 경우도 생길 수 있습니다. 이런 경우에 편리하게 쓸 수 있는 프로그램이 바로 <code>make</code>입니다. <code>make</code>는 실행했을 때 현재 디렉토리에 있는 Makefile 이라는 파일을 찾아 build 작업을 수행합니다.</p>
<p>Makefile의 작성법은<br />
<code>Target: Dependency list<br />
[Tab]  Command<br />
</code><br />
와 같습니다. Target은 만들고 싶은 대상, Dependency list는 Target을 만들기 전에 먼저 만들어져야 할 대상들, Command는 Target을 만드는 방법(command line 명령어)입니다. 한 가지 주의할 점은 Command 앞에는 Tab이 들어가야 한다는거죠. 그럼 위의 세 파일을 컴파일하기 위한 기초적인 Makefile을 살펴보겠습니다.</p>
<pre><tt><code><span style="color:#000000;">01:</span> <em><span style="color:#9a1900;"># target: dependency list</span></em>
<span style="color:#000000;">02:</span> <em><span style="color:#9a1900;"># [tab] command</span></em>
<span style="color:#000000;">03:</span> <span style="color:#009900;">F77=</span>gfortran
<span style="color:#000000;">04:</span>
<span style="color:#000000;">05:</span> <span style="color:#990000;">all:</span> main
<span style="color:#000000;">06:</span>
<span style="color:#000000;">07:</span> <span style="color:#990000;">main:</span> main.o sub1.o sub2.o
<span style="color:#000000;">08:</span>         <span style="color:#009900;">$(F77)</span> -O<span style="color:#993399;">2</span> -o main main.o sub1.o sub2.o
<span style="color:#000000;">09:</span> <span style="color:#990000;">main.o:</span> main.f
<span style="color:#000000;">10:</span>         <span style="color:#009900;">$(F77)</span> -O<span style="color:#993399;">2</span> -c main.f
<span style="color:#000000;">11:</span> <span style="color:#990000;">sub1.o:</span> sub1.f
<span style="color:#000000;">12:</span>         <span style="color:#009900;">$(F77)</span> -O<span style="color:#993399;">2</span> -c sub1.f
<span style="color:#000000;">13:</span> <span style="color:#990000;">sub2.o:</span> sub2.f
<span style="color:#000000;">14:</span>         <span style="color:#009900;">$(F77)</span> -O<span style="color:#993399;">2</span> -c sub2.f
<span style="color:#000000;">15:</span> <span style="color:#990000;">clean:</span>
<span style="color:#000000;">16:</span>         rm main main.o sub1.o sub2.o</code>
</tt></pre>
<p><code>F77=gfortran</code> 이라고 먼저 선언을 했습니다. 여기서 <code>F77</code>은 매크로(일종의 변수)입니다. 이런식으로 선언을 해두면 뒤에 <code>$(F77)</code>과 같이 필요할 때 불러서 쓸 수 있습니다. 컴파일러를 바꿀 때 gfortran 대신에 f77 이나 ifort 등으로 바꿔주면 되겠죠.</p>
<p>다음에 나오는게 <code>all</code> 이라는 Target입니다. Dependency list에는 <code>main</code>이 있고 Command는 없네요. Command line에서 <code>make</code>를 실행하면 현재 디렉토리에 있는 Makefile을 찾아 제일 처음에 나오는 Target만 실행합니다. <code>make target1</code>과 같이 실행하면 Makefile내에서 target1 이라는 Target을 찾아 실행합니다. 따라서 맨 처음 Target을 all 이라고 지정해두고 Dependency list에 자신이 만들고 싶은 Target들을 적어두면 <code>make</code>만 쳐서 원하는 Target들을 한 번에 만들 수 있겠죠. 전체적인 compile 과정은 다음과 같습니다.</p>
<ol>
<li>제일 처음에 나오는 &#8216;all&#8217; 이라는 Target을 만나서 Dependency list를 확인한다. &#8216;main&#8217;이라는 Dependency를 찾았다.</li>
<li>Dependency를 만족하기 위해 &#8216;main&#8217;이라는 Target을 찾는다. 그리고 &#8216;main&#8217;의 Dependency list &#8211; &#8216;main.o&#8217;, &#8216;sub1.o&#8217;, &#8216;sub2.o&#8217; 를 찾았다.</li>
<li>&#8216;main.o&#8217;라는 Target을 찾아서 Dependency &#8216;main.f&#8217;를 찾고 현재 디렉토리에 &#8216;main.o&#8217; 파일이 없거나 &#8216;main.o&#8217; 파일의 수정 시간이 &#8216;main.f&#8217; 파일의 수정시간보다 이전일 때<br />
<code>gfortran -O2 -c main.f</code><br />
라는 Command를 실행한다. 그렇지 않은 경우에는 아무 것도 실행하지 않는다.</li>
<li>&#8216;main.o&#8217;가 잘 만들어졌으면 다시 &#8216;main&#8217; 이라는 Target으로 넘어가 &#8216;sub1.o&#8217;, &#8216;sub2.o&#8217;라는 Dependency를 같은 방법으로 만족하고 돌아온다.</li>
<li>&#8216;main&#8217;의 Dependency 세 개가 다 만족되었으면<br />
<code>gfortran -O2 -o main main.o sub1.o sub2.o</code><br />
라는 Command를 실행하여 &#8216;main&#8217;이라는 Target을 만든다.</li>
<li>&#8216;main&#8217;이라는 Target이 만들어졌으면 &#8216;all&#8217;이라는 Target으로 돌아간다.</li>
<li>&#8216;all&#8217;의 Dependency가 다 만족되었지만, Command가 없으므로 make가 끝난다.</li>
</ol>
<p>&#8216;clean&#8217;이라는 Target은 처음에 나오지도 않고 다른 Target의 Dependency 에도 들어가지 않으니 실행이 안 됩니다. 명령줄에서 <code>make clean</code>이라고 실행했을 때만 실행이 되죠. &#8216;clean&#8217;은 Dependency list가 비어있으니까 <code>make clean</code>이라고 실행하면 해당하는 Command를 항상 실행하게 됩니다. 보통 make로 생성된 파일들을 지우기 위해 &#8216;clean&#8217;이라는 Target을 만듭니다.</p>
<p>여기까지만 배우고 끝내기에는 아쉽습니다. Makefile에는 강력한 기능들이 많기 때문이죠. 몇 개만 더 살펴봅시다. 아래의 Makefile은 compiler과 compile option이 약간 바뀐 것 말고는 위의 Makefile과 같은 기능을 합니다.</p>
<pre><tt><code><span style="color:#000000;">01:</span> <em><span style="color:#9a1900;"># $^ : dependency list</span></em>
<span style="color:#000000;">02:</span> <em><span style="color:#9a1900;"># $@ : target</span></em>
<span style="color:#000000;">03:</span>
<span style="color:#000000;">04:</span> <span style="color:#009900;">F77=</span>ifort
<span style="color:#000000;">05:</span> <span style="color:#009900;">FFLAG=</span>-assume byterecl -O<span style="color:#993399;">2</span>
<span style="color:#000000;">06:</span> <span style="color:#009900;">TARGET=</span>main
<span style="color:#000000;">07:</span> <span style="color:#009900;">OBJECTS=</span>main.o sub1.o sub2.o
<span style="color:#000000;">08:</span>
<span style="color:#000000;">09:</span> <span style="color:#990000;">all:</span> <span style="color:#009900;">$(TARGET)</span>
<span style="color:#000000;">10:</span>
<span style="color:#000000;">11:</span> <span style="color:#009900;">$(TARGET)</span><span style="color:#990000;">:</span> <span style="color:#009900;">$(OBJECTS)</span>
<span style="color:#000000;">12:</span>         <span style="color:#009900;">$(F77)</span> -o <span style="color:#009900;">$@</span> <span style="color:#009900;">$^</span>
<span style="color:#000000;">13:</span>
<span style="color:#000000;">14:</span> <strong><span style="color:#000080;">.SUFFIXES:</span></strong> .o .f
<span style="color:#000000;">15:</span> <span style="color:#990000;">%</span>.o<span style="color:#990000;">:</span> <span style="color:#990000;">%</span>.f
<span style="color:#000000;">16:</span>         <span style="color:#009900;">$(F77)</span> <span style="color:#009900;">${FFLAG}</span> -c <span style="color:#009900;">$&lt;</span>
<span style="color:#000000;">17:</span>
<span style="color:#000000;">18:</span> <span style="color:#990000;">clean:</span>
<span style="color:#000000;">19:</span>         rm <span style="color:#009900;">$(TARGET)</span> <span style="color:#009900;">$(OBJECTS)</span></code>
</tt></pre>
<p>Command 위치에서 &#8216;$^&#8217;는 Dependency list를 자동으로 입력해줍니다. 또한 &#8216;$@&#8217;는 Target 이름을 자동으로 입력해줍니다.</p>
<pre><code>.SUFFIXES: .o .f
%.o: %.f
        $(F77) ${FFLAG} -c $&lt;
</code></pre>
<p>는 확장자 규칙으로, <code>.SUFFIXES: .o .f</code> 는 &#8216;.o&#8217; 라는 확장자와 &#8216;.f&#8217;라는 확장자를 특별히 중요하게 생각하라는 뜻입니다. 그 아래에 나오는 내용은 &#8216;.o&#8217; 확장자를 가진 Target에 대해 &#8216;.f&#8217; 파일을 이용한 Dependency 와 Command를 자동으로 생성해주는 기능을 합니다. 따라서 처음의 Makefile에 있었던 &#8216;main.o&#8217;, &#8216;sub1.o&#8217;, &#8216;sub2.o&#8217; 라는 Target과 Dependency, Command를 자동으로 만들어줍니다. 한 가지 주의할 점은, 확장자 규칙에서는 앞서 나왔던 &#8216;$^&#8217;가 아닌, &#8216;$&lt;&#39;를 사용한다는 점입니다. &#39;$&lt;&#39;는 확장자 규칙에서만 사용되며, 타겟보다 나중에 변경된 종속 항목들을 의미합니다. Build 과정이 복잡할 때 Makefile은 큰 힘을 발휘합니다.</p>
<p>다음에는 Makefile과 비슷한 역할을 하는, Rakefile을 만드는 법을 배워보겠습니다. Rakefile은 Ruby script로, Ruby라는 언어의 강력한 기능들을 그대로 가져다 쓸 수 있다는 장점이 있습니다. Rakefile을 만든 후에는 Python 언어로 만들어진 SConstruct 를 만드는 법도 배워보겠습니다.</p>
<p>더 자세한 내용을 알고 싶으신 분들은 <a href="http://wiki.kldp.org/KoreanDoc/html/GNU-Make/GNU-Make.html">임대영님의 GNU Make 강좌</a>를 참고하세요.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/plusha.wordpress.com/12/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/plusha.wordpress.com/12/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/plusha.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/plusha.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/plusha.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/plusha.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/plusha.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/plusha.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/plusha.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/plusha.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/plusha.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/plusha.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/plusha.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/plusha.wordpress.com/12/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/plusha.wordpress.com/12/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/plusha.wordpress.com/12/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=plusha.com&amp;blog=174108&amp;post=12&amp;subd=plusha&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://plusha.com/2008/05/08/makefile-basic/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">plusha</media:title>
		</media:content>
	</item>
	</channel>
</rss>
