<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress.com" -->
<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/"
	>

<channel>
	<title>makefile &amp;laquo; WordPress.com Tag Feed</title>
	<link>http://en.wordpress.com/tag/makefile/</link>
	<description>Feed of posts on WordPress.com tagged "makefile"</description>
	<pubDate>Sat, 28 Nov 2009 16:11:27 +0000</pubDate>

	<generator>http://en.wordpress.com/tags/</generator>
	<language>en</language>

<item>
<title><![CDATA[VHDL Makefile]]></title>
<link>http://pgraycode.wordpress.com/2009/11/17/vhdl-makefile/</link>
<pubDate>Tue, 17 Nov 2009 20:53:15 +0000</pubDate>
<dc:creator>Mithrandir</dc:creator>
<guid>http://pgraycode.wordpress.com/2009/11/17/vhdl-makefile/</guid>
<description><![CDATA[Here is a short example for the Makefile I&#8217;m currently using to compile and test my VHDL proje]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p style="text-align:justify;">Here is a short example for the Makefile I&#8217;m currently using to compile and test my VHDL project:</p>
<p><code>.PHONY: all clean testbench<br />
&#160;<br />
VCDFILE = tmp<br />
STOPTIME = 42ns<br />
DEBUG = --vcd=$(VCDFILE) --stop-time=$(STOPTIME)<br />
CLEANUP = rm -f $(VCDFILE)<br />
OBJS = clock.o<br />
TARGET = <br />
&#160;<br />
all: <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;make test <br />
&#160;<br />
clean:<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;ghdl --clean<br />
&#160;<br />
testbench:<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;ghdl -m $(TARGET)<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;ghdl -r $(TARGET) $(DEBUG)<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;gtkwave $(VCDFILE)<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;$(CLEANUP)<br />
</code></p>
<p style="text-align:justify;"> Which is used in a terminal (providing you have <a href="http://pgraycode.wordpress.com/2009/10/18/verilog-and-vhdl-on-linux-ubuntu/">gtkwave and ghdl installed</a>) as follows:</p>
<p><code>$ make testbench TARGET=Chien_tb</code></p>
<p style="text-align:justify;">Hoping to be useful, I&#8217;ll retire. I&#8217;ll be back in a few weeks with more details.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Barebones Makefile for nmake]]></title>
<link>http://mmsmatt.wordpress.com/2009/11/16/barebones-makefile-for-nmake/</link>
<pubDate>Mon, 16 Nov 2009 15:08:15 +0000</pubDate>
<dc:creator>mmsmatt</dc:creator>
<guid>http://mmsmatt.wordpress.com/2009/11/16/barebones-makefile-for-nmake/</guid>
<description><![CDATA[To play with C on Windows, I&#8217;m using nmake. Nmake comes with Visual C++ 2008 Express Edition, ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>To play with C on Windows, I&#8217;m using nmake. Nmake comes with <a href="http://www.microsoft.com/Express/VC/">Visual C++ 2008 Express Edition</a>, which is free as in beer.</p>
<p>I am working with two C files: the archetypal &#8220;Hello World&#8221;, and a program explaining pointer operators. I could type</p>
<p><code>cl /nologo /W4 [filename]</code></p>
<p>at a command line every time I need to compile, or I could describe what I want in a Makefile once and type <code>nmake</code> when needed. Nmake will build whichever files I edited since the last run automatically. Note: <code>/nologo</code> suppresses the Microsoft copyright message, and <code>/W4</code> provides a <a href="http://msdn.microsoft.com/en-us/library/thxezb7y%28VS.71%29.aspx">large set of warnings</a>.</p>
<p>Taking the Makefile route:</p>
<pre class="brush: plain;">
# Matt Stephenson's nmake Makefile
# build from build/ directory

cc = cl
cflags = /nologo /W4

all: hello.exe pointers.exe

hello.exe: ../hello.c
    $(cc) $(cflags) ../hello.c

pointers.exe: ../pointers.c
    $(cc) $(cflags) ../pointers.c

clean:
    del *.exe *.obj
</pre>
<p>We define a C compiler and its options independently, then nmake substitutes each when specified. The first &#8220;target&#8221; specified is <code>all</code>; an <code>nmake</code> invocation without arguments will build the first target it finds. In the directory containing this Makefile, running <code>nmake</code> and <code>nmake all</code> are functionally equivalent.</p>
<p><code>all</code> is really a pseudotarget, it instructs nmake to run the hello.exe and pointers.exe targets in that order. Each of these targets describes a single call to <code>cl</code>, which does the compile and link phases for us. We could specify <code>nmake pointers.exe</code> and run only that target.</p>
<p>When defining a target, filenames after the colon specify dependencies. Nmake rebuilds a target when one of its dependencies have been updated since the last build.</p>
<p>Finally, we describe a <code>clean</code> step that erases the results of any of the other targets.</p>
<p>For an example of linking against external libraries, see <a href="http://codediaries.blogspot.com/2009/08/nmake-makefile-tutorial-and-example.html">this Makefile</a>.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[How to quickly navigate an unfamiliar makefile]]></title>
<link>http://blog.electric-cloud.com/2009/11/10/how-to-quickly-navigate-an-unfamiliar-makefile/</link>
<pubDate>Tue, 10 Nov 2009 18:21:37 +0000</pubDate>
<dc:creator>Eric Melski</dc:creator>
<guid>http://blog.electric-cloud.com/2009/11/10/how-to-quickly-navigate-an-unfamiliar-makefile/</guid>
<description><![CDATA[The other day, I was working with an unfamiliar build and I needed to get familiar with it in a hurr]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>The other day, I was working with an unfamiliar build and I needed to get familiar with it in a hurry.  In this case, I was dealing with a makefile generated by the Perl utility <i>h2xs</i>, but the trick I&#8217;ll show you here works any time you need to find your way around a new build system, whether it&#8217;s something you just downloaded or an internal project you just transferred to.</p>
<p>
What I wanted to do was add a few object files to the link command.  Here&#8217;s the build log, with the link command highlighted:
</p>
<p><pre style="font:80% courier, verdana, monospace;border:1px solid #ccc;width:90%;background:#fff7f0;color:#000;overflow:auto;margin:1em auto 2em;padding:1em;">gcc -c  -I. -D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2 -g   -DVERSION=\"0.01\" -DXS_VERSION=\"0.01\" -fPIC "-I/usr/lib/perl/5.10/CORE"   mylib.c
rm -f blib/arch/auto/mylib/mylib.so
<font color="red"><b>gcc  -shared -O2 -g -L/usr/local/lib mylib.o   -o blib/arch/auto/mylib/mylib.so   \
                \
</b></font>
chmod 755 blib/arch/auto/mylib/mylib.so
</pre>
</p>
<p>
Should be easy, right?  I just needed to find that command in the makefile and make my changes.  Wrong.  Read on to see how <i>annotation</i> helped solve this problem.
</p>
<p>
<!--more--><br />
The thing is, the command I&#8217;m looking for doesn&#8217;t appear anywhere in the makefile.  All of the rules look like this:
</p>
<p><pre style="font:80% courier, verdana, monospace;border:1px solid #ccc;width:90%;background:#fff7f0;color:#000;overflow:auto;margin:1em auto 2em;padding:1em;">$(CCCMD) $(CCCDLFLAGS) "-I$(PERL_INC)" $(PASTHRU_DEFINE) $(DEFINE) $*.c</pre>
</p>
<p>
There&#8217;s not a single useful literal string in sight, so <i>grep</i> is right out.  And it&#8217;s not like you could just start reading the makefile top-to-bottom to figure out which variables contribute to the command line that produces the output that you see in the log.  The makefile is nearly a thousand lines long with literally hundreds of variable definitions:
</p>
<p><pre style="font:80% courier, verdana, monospace;border:1px solid #ccc;width:90%;height:30ex;background:#fff7f0;color:#000;overflow:auto;margin:1em auto 2em;padding:1em;"># This Makefile is for the mylib extension to perl.
#
# It was generated automatically by MakeMaker version
# 6.42 (Revision: 41145) from the contents of
# Makefile.PL. Don't edit this file, edit Makefile.PL instead.
#
#       ANY CHANGES MADE HERE WILL BE LOST!
#
#   MakeMaker ARGV: ()
#
#   MakeMaker Parameters:

#     ABSTRACT_FROM =&#62; q[lib/mylib.pm]
#     AUTHOR =&#62; q[Eric Melski ]
#     DEFINE =&#62; q[]
#     INC =&#62; q[-I.]
#     LIBS =&#62; [q[]]
#     NAME =&#62; q[mylib]
#     PREREQ_PM =&#62; {  }
#     VERSION_FROM =&#62; q[lib/mylib.pm]

# --- MakeMaker post_initialize section:

# --- MakeMaker const_config section:

# These definitions are from config.sh (via /usr/lib/perl/5.10/Config.pm)

# They may have been overridden via Makefile.PL or on the command line
AR = ar
CC = gcc
CCCDLFLAGS = -fPIC
CCDLFLAGS = -Wl,-E
DLEXT = so
DLSRC = dl_dlopen.xs
EXE_EXT =
FULL_AR = /usr/bin/ar
LD = gcc
LDDLFLAGS = -shared -O2 -g -L/usr/local/lib
LDFLAGS =  -L/usr/local/lib
LIBC = /lib/libc-2.9.so
LIB_EXT = .a
OBJ_EXT = .o
OSNAME = linux
OSVERS = 2.6.24-23-server
RANLIB = :
SITELIBEXP = /usr/local/share/perl/5.10.0
SITEARCHEXP = /usr/local/lib/perl/5.10.0
SO = so
VENDORARCHEXP = /usr/lib/perl5
VENDORLIBEXP = /usr/share/perl5

# --- MakeMaker constants section:
AR_STATIC_ARGS = cr
DIRFILESEP = /
DFSEP = $(DIRFILESEP)
NAME = mylib
NAME_SYM = mylib
VERSION = 0.01
VERSION_MACRO = VERSION
VERSION_SYM = 0_01
DEFINE_VERSION = -D$(VERSION_MACRO)=\"$(VERSION)\"
XS_VERSION = 0.01
XS_VERSION_MACRO = XS_VERSION
XS_DEFINE_VERSION = -D$(XS_VERSION_MACRO)=\"$(XS_VERSION)\"
INST_ARCHLIB = blib/arch
INST_SCRIPT = blib/script
INST_BIN = blib/bin
INST_LIB = blib/lib
INST_MAN1DIR = blib/man1
INST_MAN3DIR = blib/man3
MAN1EXT = 1p
MAN3EXT = 3pm
INSTALLDIRS = site
DESTDIR =
PREFIX = /usr
PERLPREFIX = $(PREFIX)
SITEPREFIX = $(PREFIX)/local
VENDORPREFIX = $(PREFIX)
INSTALLPRIVLIB = $(PERLPREFIX)/share/perl/5.10
DESTINSTALLPRIVLIB = $(DESTDIR)$(INSTALLPRIVLIB)
INSTALLSITELIB = $(SITEPREFIX)/share/perl/5.10.0
DESTINSTALLSITELIB = $(DESTDIR)$(INSTALLSITELIB)
INSTALLVENDORLIB = $(VENDORPREFIX)/share/perl5
DESTINSTALLVENDORLIB = $(DESTDIR)$(INSTALLVENDORLIB)
INSTALLARCHLIB = $(PERLPREFIX)/lib/perl/5.10
DESTINSTALLARCHLIB = $(DESTDIR)$(INSTALLARCHLIB)
INSTALLSITEARCH = $(SITEPREFIX)/lib/perl/5.10.0
DESTINSTALLSITEARCH = $(DESTDIR)$(INSTALLSITEARCH)
INSTALLVENDORARCH = $(VENDORPREFIX)/lib/perl5
DESTINSTALLVENDORARCH = $(DESTDIR)$(INSTALLVENDORARCH)
INSTALLBIN = $(PERLPREFIX)/bin
DESTINSTALLBIN = $(DESTDIR)$(INSTALLBIN)
INSTALLSITEBIN = $(SITEPREFIX)/bin
DESTINSTALLSITEBIN = $(DESTDIR)$(INSTALLSITEBIN)
INSTALLVENDORBIN = $(VENDORPREFIX)/bin
DESTINSTALLVENDORBIN = $(DESTDIR)$(INSTALLVENDORBIN)
INSTALLSCRIPT = $(PERLPREFIX)/bin
DESTINSTALLSCRIPT = $(DESTDIR)$(INSTALLSCRIPT)
INSTALLSITESCRIPT = $(SITEPREFIX)/bin
DESTINSTALLSITESCRIPT = $(DESTDIR)$(INSTALLSITESCRIPT)
INSTALLVENDORSCRIPT = $(VENDORPREFIX)/bin
DESTINSTALLVENDORSCRIPT = $(DESTDIR)$(INSTALLVENDORSCRIPT)
INSTALLMAN1DIR = $(PERLPREFIX)/share/man/man1
DESTINSTALLMAN1DIR = $(DESTDIR)$(INSTALLMAN1DIR)
INSTALLSITEMAN1DIR = $(SITEPREFIX)/man/man1
DESTINSTALLSITEMAN1DIR = $(DESTDIR)$(INSTALLSITEMAN1DIR)
INSTALLVENDORMAN1DIR = $(VENDORPREFIX)/share/man/man1
DESTINSTALLVENDORMAN1DIR = $(DESTDIR)$(INSTALLVENDORMAN1DIR)
INSTALLMAN3DIR = $(PERLPREFIX)/share/man/man3
DESTINSTALLMAN3DIR = $(DESTDIR)$(INSTALLMAN3DIR)
INSTALLSITEMAN3DIR = $(SITEPREFIX)/man/man3
DESTINSTALLSITEMAN3DIR = $(DESTDIR)$(INSTALLSITEMAN3DIR)
INSTALLVENDORMAN3DIR = $(VENDORPREFIX)/share/man/man3
DESTINSTALLVENDORMAN3DIR = $(DESTDIR)$(INSTALLVENDORMAN3DIR)
PERL_LIB = /usr/share/perl/5.10
PERL_ARCHLIB = /usr/lib/perl/5.10
LIBPERL_A = libperl.a
FIRST_MAKEFILE = Makefile
MAKEFILE_OLD = Makefile.old
MAKE_APERL_FILE = Makefile.aperl
PERLMAINCC = $(CC)
PERL_INC = /usr/lib/perl/5.10/CORE
PERL = /usr/bin/perl
FULLPERL = /usr/bin/perl
ABSPERL = $(PERL)
PERLRUN = $(PERL)
FULLPERLRUN = $(FULLPERL)
ABSPERLRUN = $(ABSPERL)
PERLRUNINST = $(PERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
FULLPERLRUNINST = $(FULLPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
ABSPERLRUNINST = $(ABSPERLRUN) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)"
PERL_CORE = 0
PERM_RW = 644
PERM_RWX = 755

MAKEMAKER   = /usr/share/perl/5.10/ExtUtils/MakeMaker.pm
MM_VERSION  = 6.42
MM_REVISION = 41145

# FULLEXT = Pathname for extension directory (eg Foo/Bar/Oracle).
# BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. (eg Oracle)
# PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar)
# DLBASE  = Basename part of dynamic library. May be just equal BASEEXT.
MAKE = make
FULLEXT = mylib
BASEEXT = mylib
PARENT_NAME =
DLBASE = $(BASEEXT)
VERSION_FROM = lib/mylib.pm
INC = -I.
DEFINE =
OBJECT = $(BASEEXT)$(OBJ_EXT)
LDFROM = $(OBJECT)
LINKTYPE = dynamic
BOOTDEP = 

# Handy lists of source code files:
XS_FILES = mylib.xs
C_FILES  = mylib.c
O_FILES  = mylib.o
H_FILES  = ppport.h
MAN1PODS =
MAN3PODS = lib/mylib.pm

# Where is the Config information that we are using/depend on
CONFIGDEP = $(PERL_ARCHLIB)$(DFSEP)Config.pm $(PERL_INC)$(DFSEP)config.h

# Where to build things
INST_LIBDIR      = $(INST_LIB)
INST_ARCHLIBDIR  = $(INST_ARCHLIB)

INST_AUTODIR     = $(INST_LIB)/auto/$(FULLEXT)
INST_ARCHAUTODIR = $(INST_ARCHLIB)/auto/$(FULLEXT)

INST_STATIC      = $(INST_ARCHAUTODIR)/$(BASEEXT)$(LIB_EXT)
INST_DYNAMIC     = $(INST_ARCHAUTODIR)/$(DLBASE).$(DLEXT)
INST_BOOT        = $(INST_ARCHAUTODIR)/$(BASEEXT).bs

# Extra linker info
EXPORT_LIST        =
PERL_ARCHIVE       =
PERL_ARCHIVE_AFTER = 

TO_INST_PM = lib/mylib.pm

PM_TO_BLIB = lib/mylib.pm \
	blib/lib/mylib.pm

# --- MakeMaker platform_constants section:
MM_Unix_VERSION = 6.42
PERL_MALLOC_DEF = -DPERL_EXTMALLOC_DEF -Dmalloc=Perl_malloc -Dfree=Perl_mfree -Drealloc=Perl_realloc -Dcalloc=Perl_calloc

# --- MakeMaker tool_autosplit section:
# Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto
AUTOSPLITFILE = $(ABSPERLRUN)  -e 'use AutoSplit;  autosplit($$ARGV[0], $$ARGV[1], 0, 1, 1)' --

# --- MakeMaker tool_xsubpp section:

XSUBPPDIR = /usr/share/perl/5.10/ExtUtils
XSUBPP = $(XSUBPPDIR)$(DFSEP)xsubpp
XSUBPPRUN = $(PERLRUN) $(XSUBPP)
XSPROTOARG =
XSUBPPDEPS = /usr/share/perl/5.10/ExtUtils/typemap typemap $(XSUBPP)
XSUBPPARGS = -typemap /usr/share/perl/5.10/ExtUtils/typemap -typemap typemap
XSUBPP_EXTRA_ARGS = 

# --- MakeMaker tools_other section:
SHELL = /bin/sh
CHMOD = chmod
CP = cp
MV = mv
NOOP = $(SHELL) -c true
NOECHO = @
RM_F = rm -f
RM_RF = rm -rf
TEST_F = test -f
TOUCH = touch
UMASK_NULL = umask 0
DEV_NULL = &#62; /dev/null 2&#62;&#38;1
MKPATH = $(ABSPERLRUN) "-MExtUtils::Command" -e mkpath
EQUALIZE_TIMESTAMP = $(ABSPERLRUN) "-MExtUtils::Command" -e eqtime
ECHO = echo
ECHO_N = echo -n
UNINST = 0
VERBINST = 0
MOD_INSTALL = $(ABSPERLRUN) -MExtUtils::Install -e 'install({@ARGV}, '\''$(VERBINST)'\'', 0, '\''$(UNINST)'\'');' --
DOC_INSTALL = $(ABSPERLRUN) "-MExtUtils::Command::MM" -e perllocal_install
UNINSTALL = $(ABSPERLRUN) "-MExtUtils::Command::MM" -e uninstall
WARN_IF_OLD_PACKLIST = $(ABSPERLRUN) "-MExtUtils::Command::MM" -e warn_if_old_packlist
MACROSTART =
MACROEND =
USEMAKEFILE = -f
FIXIN = $(PERLRUN) "-MExtUtils::MY" -e "MY-&#62;fixin(shift)"

# --- MakeMaker makemakerdflt section:
makemakerdflt : all
	$(NOECHO) $(NOOP)

# --- MakeMaker dist section:
TAR = tar
TARFLAGS = cvf
ZIP = zip
ZIPFLAGS = -r
COMPRESS = gzip --best
SUFFIX = .gz
SHAR = shar
PREOP = $(NOECHO) $(NOOP)
POSTOP = $(NOECHO) $(NOOP)
TO_UNIX = $(NOECHO) $(NOOP)
CI = ci -u
RCS_LABEL = rcs -Nv$(VERSION_SYM): -q
DIST_CP = best
DIST_DEFAULT = tardist
DISTNAME = mylib
DISTVNAME = mylib-0.01

# --- MakeMaker macro section:

# --- MakeMaker depend section:

# --- MakeMaker cflags section:

CCFLAGS = -D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
OPTIMIZE = -O2 -g
PERLTYPE =
MPOLLUTE = 

# --- MakeMaker const_loadlibs section:

# mylib might depend on some other libraries:
# See ExtUtils::Liblist for details
#

# --- MakeMaker const_cccmd section:
CCCMD = $(CC) -c $(PASTHRU_INC) $(INC) \
	$(CCFLAGS) $(OPTIMIZE) \
	$(PERLTYPE) $(MPOLLUTE) $(DEFINE_VERSION) \
	$(XS_DEFINE_VERSION)

# --- MakeMaker post_constants section:

# --- MakeMaker pasthru section:

PASTHRU = LIBPERL_A="$(LIBPERL_A)"\
	LINKTYPE="$(LINKTYPE)"\
	OPTIMIZE="$(OPTIMIZE)"\
	PREFIX="$(PREFIX)"\
	PASTHRU_DEFINE="$(PASTHRU_DEFINE)"\
	PASTHRU_INC="$(PASTHRU_INC)"

# --- MakeMaker special_targets section:
.SUFFIXES : .xs .c .C .cpp .i .s .cxx .cc $(OBJ_EXT)

.PHONY: all config static dynamic test linkext manifest blibdirs clean realclean disttest distdir

# --- MakeMaker c_o section:

.c.i:
	cc -E -c $(PASTHRU_INC) $(INC) \
	$(CCFLAGS) $(OPTIMIZE) \
	$(PERLTYPE) $(MPOLLUTE) $(DEFINE_VERSION) \
	$(XS_DEFINE_VERSION) $(CCCDLFLAGS) "-I$(PERL_INC)" $(PASTHRU_DEFINE) $(DEFINE) $*.c &#62; $*.i

.c.s:
	$(CCCMD) -S $(CCCDLFLAGS) "-I$(PERL_INC)" $(PASTHRU_DEFINE) $(DEFINE) $*.c

.c$(OBJ_EXT):
	$(CCCMD) $(CCCDLFLAGS) "-I$(PERL_INC)" $(PASTHRU_DEFINE) $(DEFINE) $*.c

.cpp$(OBJ_EXT):
	$(CCCMD) $(CCCDLFLAGS) "-I$(PERL_INC)" $(PASTHRU_DEFINE) $(DEFINE) $*.cpp

.cxx$(OBJ_EXT):
	$(CCCMD) $(CCCDLFLAGS) "-I$(PERL_INC)" $(PASTHRU_DEFINE) $(DEFINE) $*.cxx

.cc$(OBJ_EXT):
	$(CCCMD) $(CCCDLFLAGS) "-I$(PERL_INC)" $(PASTHRU_DEFINE) $(DEFINE) $*.cc

.C$(OBJ_EXT):
	$(CCCMD) $*.C

# --- MakeMaker xs_c section:

.xs.c:
	$(XSUBPPRUN) $(XSPROTOARG) $(XSUBPPARGS) $(XSUBPP_EXTRA_ARGS) $*.xs &#62; $*.xsc &#38;&#38; $(MV) $*.xsc $*.c

# --- MakeMaker xs_o section:

.xs$(OBJ_EXT):
	$(XSUBPPRUN) $(XSPROTOARG) $(XSUBPPARGS) $*.xs &#62; $*.xsc &#38;&#38; $(MV) $*.xsc $*.c
	$(CCCMD) $(CCCDLFLAGS) "-I$(PERL_INC)" $(PASTHRU_DEFINE) $(DEFINE) $*.c

# --- MakeMaker top_targets section:
all :: pure_all manifypods
	$(NOECHO) $(NOOP)

pure_all :: config pm_to_blib subdirs linkext
	$(NOECHO) $(NOOP)

subdirs :: $(MYEXTLIB)
	$(NOECHO) $(NOOP)

config :: $(FIRST_MAKEFILE) blibdirs
	$(NOECHO) $(NOOP)

$(O_FILES): $(H_FILES)

help :
	perldoc ExtUtils::MakeMaker

# --- MakeMaker blibdirs section:
blibdirs : $(INST_LIBDIR)$(DFSEP).exists $(INST_ARCHLIB)$(DFSEP).exists $(INST_AUTODIR)$(DFSEP).exists $(INST_ARCHAUTODIR)$(DFSEP).exists $(INST_BIN)$(DFSEP).exists $(INST_SCRIPT)$(DFSEP).exists $(INST_MAN1DIR)$(DFSEP).exists $(INST_MAN3DIR)$(DFSEP).exists
	$(NOECHO) $(NOOP)

# Backwards compat with 6.18 through 6.25
blibdirs.ts : blibdirs
	$(NOECHO) $(NOOP)

$(INST_LIBDIR)$(DFSEP).exists :: Makefile.PL
	$(NOECHO) $(MKPATH) $(INST_LIBDIR)
	$(NOECHO) $(CHMOD) 755 $(INST_LIBDIR)
	$(NOECHO) $(TOUCH) $(INST_LIBDIR)$(DFSEP).exists

$(INST_ARCHLIB)$(DFSEP).exists :: Makefile.PL
	$(NOECHO) $(MKPATH) $(INST_ARCHLIB)
	$(NOECHO) $(CHMOD) 755 $(INST_ARCHLIB)
	$(NOECHO) $(TOUCH) $(INST_ARCHLIB)$(DFSEP).exists

$(INST_AUTODIR)$(DFSEP).exists :: Makefile.PL
	$(NOECHO) $(MKPATH) $(INST_AUTODIR)
	$(NOECHO) $(CHMOD) 755 $(INST_AUTODIR)
	$(NOECHO) $(TOUCH) $(INST_AUTODIR)$(DFSEP).exists

$(INST_ARCHAUTODIR)$(DFSEP).exists :: Makefile.PL
	$(NOECHO) $(MKPATH) $(INST_ARCHAUTODIR)
	$(NOECHO) $(CHMOD) 755 $(INST_ARCHAUTODIR)
	$(NOECHO) $(TOUCH) $(INST_ARCHAUTODIR)$(DFSEP).exists

$(INST_BIN)$(DFSEP).exists :: Makefile.PL
	$(NOECHO) $(MKPATH) $(INST_BIN)
	$(NOECHO) $(CHMOD) 755 $(INST_BIN)
	$(NOECHO) $(TOUCH) $(INST_BIN)$(DFSEP).exists

$(INST_SCRIPT)$(DFSEP).exists :: Makefile.PL
	$(NOECHO) $(MKPATH) $(INST_SCRIPT)
	$(NOECHO) $(CHMOD) 755 $(INST_SCRIPT)
	$(NOECHO) $(TOUCH) $(INST_SCRIPT)$(DFSEP).exists

$(INST_MAN1DIR)$(DFSEP).exists :: Makefile.PL
	$(NOECHO) $(MKPATH) $(INST_MAN1DIR)
	$(NOECHO) $(CHMOD) 755 $(INST_MAN1DIR)
	$(NOECHO) $(TOUCH) $(INST_MAN1DIR)$(DFSEP).exists

$(INST_MAN3DIR)$(DFSEP).exists :: Makefile.PL
	$(NOECHO) $(MKPATH) $(INST_MAN3DIR)
	$(NOECHO) $(CHMOD) 755 $(INST_MAN3DIR)
	$(NOECHO) $(TOUCH) $(INST_MAN3DIR)$(DFSEP).exists

# --- MakeMaker linkext section:

linkext :: $(LINKTYPE)
	$(NOECHO) $(NOOP)

# --- MakeMaker dlsyms section:

# --- MakeMaker dynamic section:

dynamic :: $(FIRST_MAKEFILE) $(INST_DYNAMIC) $(INST_BOOT)
	$(NOECHO) $(NOOP)

# --- MakeMaker dynamic_bs section:
BOOTSTRAP = $(BASEEXT).bs

# As Mkbootstrap might not write a file (if none is required)
# we use touch to prevent make continually trying to remake it.
# The DynaLoader only reads a non-empty file.
$(BOOTSTRAP) : $(FIRST_MAKEFILE) $(BOOTDEP) $(INST_ARCHAUTODIR)$(DFSEP).exists
	$(NOECHO) $(ECHO) "Running Mkbootstrap for $(NAME) ($(BSLOADLIBS))"
	$(NOECHO) $(PERLRUN) \
		"-MExtUtils::Mkbootstrap" \
		-e "Mkbootstrap('$(BASEEXT)','$(BSLOADLIBS)');"
	$(NOECHO) $(TOUCH) $@
	$(CHMOD) $(PERM_RW) $@

$(INST_BOOT) : $(BOOTSTRAP) $(INST_ARCHAUTODIR)$(DFSEP).exists
	$(NOECHO) $(RM_RF) $@
	- $(CP) $(BOOTSTRAP) $@
	$(CHMOD) $(PERM_RW) $@

# --- MakeMaker dynamic_lib section:

# This section creates the dynamically loadable $(INST_DYNAMIC)
# from $(OBJECT) and possibly $(MYEXTLIB).
ARMAYBE = :
OTHERLDFLAGS =
INST_DYNAMIC_DEP =
INST_DYNAMIC_FIX = 

$(INST_DYNAMIC): $(OBJECT) $(MYEXTLIB) $(BOOTSTRAP) $(INST_ARCHAUTODIR)$(DFSEP).exists $(EXPORT_LIST) $(PERL_ARCHIVE) $(PERL_ARCHIVE_AFTER) $(INST_DYNAMIC_DEP)
	$(RM_F) $@
	$(LD)  $(LDDLFLAGS) $(LDFROM) $(OTHERLDFLAGS) -o $@ $(MYEXTLIB)	\
	  $(PERL_ARCHIVE) $(LDLOADLIBS) $(PERL_ARCHIVE_AFTER) $(EXPORT_LIST)	\
	  $(INST_DYNAMIC_FIX)
	$(CHMOD) $(PERM_RWX) $@

# --- MakeMaker static section:

## $(INST_PM) has been moved to the all: target.
## It remains here for awhile to allow for old usage: "make static"
static :: $(FIRST_MAKEFILE) $(INST_STATIC)
	$(NOECHO) $(NOOP)

# --- MakeMaker static_lib section:

$(INST_STATIC) : $(OBJECT) $(MYEXTLIB) $(INST_ARCHAUTODIR)$(DFSEP).exists
	$(RM_RF) $@
	$(FULL_AR) $(AR_STATIC_ARGS) $@ $(OBJECT) &#38;&#38; $(RANLIB) $@
	$(CHMOD) $(PERM_RWX) $@
	$(NOECHO) $(ECHO) "$(EXTRALIBS)" &#62; $(INST_ARCHAUTODIR)/extralibs.ld

# --- MakeMaker manifypods section:

POD2MAN_EXE = $(PERLRUN) "-MExtUtils::Command::MM" -e pod2man "--"
POD2MAN = $(POD2MAN_EXE)

manifypods : pure_all  \
	lib/mylib.pm
	$(NOECHO) $(POD2MAN) --section=$(MAN3EXT) --perm_rw=$(PERM_RW) \
	  lib/mylib.pm $(INST_MAN3DIR)/mylib.$(MAN3EXT) 

# --- MakeMaker processPL section:

# --- MakeMaker installbin section:

# --- MakeMaker subdirs section:

# none

# --- MakeMaker clean_subdirs section:
clean_subdirs :
	$(NOECHO) $(NOOP)

# --- MakeMaker clean section:

# Delete temporary files but do not touch installed files. We don't delete
# the Makefile here so a later make realclean still has a makefile to use.

clean :: clean_subdirs
	- $(RM_F) \
	  *$(LIB_EXT) core \
	  core.[0-9] $(INST_ARCHAUTODIR)/extralibs.all \
	  core.[0-9][0-9] $(BASEEXT).bso \
	  pm_to_blib.ts core.[0-9][0-9][0-9][0-9] \
	  $(BASEEXT).x $(BOOTSTRAP) \
	  perl$(EXE_EXT) tmon.out \
	  *$(OBJ_EXT) pm_to_blib \
	  $(INST_ARCHAUTODIR)/extralibs.ld blibdirs.ts \
	  core.[0-9][0-9][0-9][0-9][0-9] mylib.c \
	  *perl.core core.*perl.*.? \
	  $(MAKE_APERL_FILE) $(BASEEXT).def \
	  perl core.[0-9][0-9][0-9] \
	  mon.out lib$(BASEEXT).def \
	  perlmain.c perl.exe \
	  so_locations $(BASEEXT).exp
	- $(RM_RF) \
	  blib
	- $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD) $(DEV_NULL)

# --- MakeMaker realclean_subdirs section:
realclean_subdirs :
	$(NOECHO) $(NOOP)

# --- MakeMaker realclean section:
# Delete temporary files (via clean) and also delete dist files
realclean purge ::  clean realclean_subdirs
	- $(RM_F) \
	  $(OBJECT) $(MAKEFILE_OLD) \
	  $(FIRST_MAKEFILE)
	- $(RM_RF) \
	  $(DISTVNAME) 

# --- MakeMaker metafile section:
metafile : create_distdir
	$(NOECHO) $(ECHO) Generating META.yml
	$(NOECHO) $(ECHO) '--- #YAML:1.0' &#62; META_new.yml
	$(NOECHO) $(ECHO) 'name:                mylib' &#62;&#62; META_new.yml
	$(NOECHO) $(ECHO) 'version:             0.01' &#62;&#62; META_new.yml
	$(NOECHO) $(ECHO) 'abstract:            Perl extension for blah blah blah' &#62;&#62; META_new.yml
	$(NOECHO) $(ECHO) 'license:             ~' &#62;&#62; META_new.yml
	$(NOECHO) $(ECHO) 'author:              ' &#62;&#62; META_new.yml
	$(NOECHO) $(ECHO) '    - Eric Melski ' &#62;&#62; META_new.yml
	$(NOECHO) $(ECHO) 'generated_by:        ExtUtils::MakeMaker version 6.42' &#62;&#62; META_new.yml
	$(NOECHO) $(ECHO) 'distribution_type:   module' &#62;&#62; META_new.yml
	$(NOECHO) $(ECHO) 'requires:     ' &#62;&#62; META_new.yml
	$(NOECHO) $(ECHO) 'meta-spec:' &#62;&#62; META_new.yml
	$(NOECHO) $(ECHO) '    url:     http://module-build.sourceforge.net/META-spec-v1.3.html' &#62;&#62; META_new.yml
	$(NOECHO) $(ECHO) '    version: 1.3' &#62;&#62; META_new.yml
	-$(NOECHO) $(MV) META_new.yml $(DISTVNAME)/META.yml

# --- MakeMaker signature section:
signature :
	cpansign -s

# --- MakeMaker dist_basics section:
distclean :: realclean distcheck
	$(NOECHO) $(NOOP)

distcheck :
	$(PERLRUN) "-MExtUtils::Manifest=fullcheck" -e fullcheck

skipcheck :
	$(PERLRUN) "-MExtUtils::Manifest=skipcheck" -e skipcheck

manifest :
	$(PERLRUN) "-MExtUtils::Manifest=mkmanifest" -e mkmanifest

veryclean : realclean
	$(RM_F) *~ */*~ *.orig */*.orig *.bak */*.bak *.old */*.old 

# --- MakeMaker dist_core section:

dist : $(DIST_DEFAULT) $(FIRST_MAKEFILE)
	$(NOECHO) $(ABSPERLRUN) -l -e 'print '\''Warning: Makefile possibly out of date with $(VERSION_FROM)'\''' \
	  -e '    if -e '\''$(VERSION_FROM)'\'' and -M '\''$(VERSION_FROM)'\''  $(DISTVNAME).tar$(SUFFIX)_uu

$(DISTVNAME).tar$(SUFFIX) : distdir
	$(PREOP)
	$(TO_UNIX)
	$(TAR) $(TARFLAGS) $(DISTVNAME).tar $(DISTVNAME)
	$(RM_RF) $(DISTVNAME)
	$(COMPRESS) $(DISTVNAME).tar
	$(POSTOP)

zipdist : $(DISTVNAME).zip
	$(NOECHO) $(NOOP)

$(DISTVNAME).zip : distdir
	$(PREOP)
	$(ZIP) $(ZIPFLAGS) $(DISTVNAME).zip $(DISTVNAME)
	$(RM_RF) $(DISTVNAME)
	$(POSTOP)

shdist : distdir
	$(PREOP)
	$(SHAR) $(DISTVNAME) &#62; $(DISTVNAME).shar
	$(RM_RF) $(DISTVNAME)
	$(POSTOP)

# --- MakeMaker distdir section:
create_distdir :
	$(RM_RF) $(DISTVNAME)
	$(PERLRUN) "-MExtUtils::Manifest=manicopy,maniread" \
		-e "manicopy(maniread(),'$(DISTVNAME)', '$(DIST_CP)');"

distdir : create_distdir distmeta
	$(NOECHO) $(NOOP)

# --- MakeMaker dist_test section:
disttest : distdir
	cd $(DISTVNAME) &#38;&#38; $(ABSPERLRUN) Makefile.PL
	cd $(DISTVNAME) &#38;&#38; $(MAKE) $(PASTHRU)
	cd $(DISTVNAME) &#38;&#38; $(MAKE) test $(PASTHRU)

# --- MakeMaker dist_ci section:

ci :
	$(PERLRUN) "-MExtUtils::Manifest=maniread" \
	  -e "@all = keys %{ maniread() };" \
	  -e "print(qq{Executing $(CI) @all\n}); system(qq{$(CI) @all});" \
	  -e "print(qq{Executing $(RCS_LABEL) ...\n}); system(qq{$(RCS_LABEL) @all});"

# --- MakeMaker distmeta section:
distmeta : create_distdir metafile
	$(NOECHO) cd $(DISTVNAME) &#38;&#38; $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'eval { maniadd({q{META.yml} =&#62; q{Module meta-data (added by MakeMaker)}}) } ' \
	  -e '    or print "Could not add META.yml to MANIFEST: $${'\''@'\''}\n"' --

# --- MakeMaker distsignature section:
distsignature : create_distdir
	$(NOECHO) cd $(DISTVNAME) &#38;&#38; $(ABSPERLRUN) -MExtUtils::Manifest=maniadd -e 'eval { maniadd({q{SIGNATURE} =&#62; q{Public-key signature (added by MakeMaker)}}) } ' \
	  -e '    or print "Could not add SIGNATURE to MANIFEST: $${'\''@'\''}\n"' --
	$(NOECHO) cd $(DISTVNAME) &#38;&#38; $(TOUCH) SIGNATURE
	cd $(DISTVNAME) &#38;&#38; cpansign -s

# --- MakeMaker install section:

install :: pure_install doc_install
	$(NOECHO) $(NOOP)

install_perl :: pure_perl_install doc_perl_install
	$(NOECHO) $(NOOP)

install_site :: pure_site_install doc_site_install
	$(NOECHO) $(NOOP)

install_vendor :: pure_vendor_install doc_vendor_install
	$(NOECHO) $(NOOP)

pure_install :: pure_$(INSTALLDIRS)_install
	$(NOECHO) $(NOOP)

doc_install :: doc_$(INSTALLDIRS)_install
	$(NOECHO) $(NOOP)

pure__install : pure_site_install
	$(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site

doc__install : doc_site_install
	$(NOECHO) $(ECHO) INSTALLDIRS not defined, defaulting to INSTALLDIRS=site

pure_perl_install :: all
	$(NOECHO) umask 022; $(MOD_INSTALL) \
		$(INST_LIB) $(DESTINSTALLPRIVLIB) \
		$(INST_ARCHLIB) $(DESTINSTALLARCHLIB) \
		$(INST_BIN) $(DESTINSTALLBIN) \
		$(INST_SCRIPT) $(DESTINSTALLSCRIPT) \
		$(INST_MAN1DIR) $(DESTINSTALLMAN1DIR) \
		$(INST_MAN3DIR) $(DESTINSTALLMAN3DIR)
	$(NOECHO) $(WARN_IF_OLD_PACKLIST) \
		$(SITEARCHEXP)/auto/$(FULLEXT)

pure_site_install :: all
	$(NOECHO) umask 02; $(MOD_INSTALL) \
		read $(SITEARCHEXP)/auto/$(FULLEXT)/.packlist \
		write $(DESTINSTALLSITEARCH)/auto/$(FULLEXT)/.packlist \
		$(INST_LIB) $(DESTINSTALLSITELIB) \
		$(INST_ARCHLIB) $(DESTINSTALLSITEARCH) \
		$(INST_BIN) $(DESTINSTALLSITEBIN) \
		$(INST_SCRIPT) $(DESTINSTALLSITESCRIPT) \
		$(INST_MAN1DIR) $(DESTINSTALLSITEMAN1DIR) \
		$(INST_MAN3DIR) $(DESTINSTALLSITEMAN3DIR)
	$(NOECHO) $(WARN_IF_OLD_PACKLIST) \
		$(PERL_ARCHLIB)/auto/$(FULLEXT)

pure_vendor_install :: all
	$(NOECHO) umask 022; $(MOD_INSTALL) \
		$(INST_LIB) $(DESTINSTALLVENDORLIB) \
		$(INST_ARCHLIB) $(DESTINSTALLVENDORARCH) \
		$(INST_BIN) $(DESTINSTALLVENDORBIN) \
		$(INST_SCRIPT) $(DESTINSTALLVENDORSCRIPT) \
		$(INST_MAN1DIR) $(DESTINSTALLVENDORMAN1DIR) \
		$(INST_MAN3DIR) $(DESTINSTALLVENDORMAN3DIR)

doc_perl_install :: all

doc_site_install :: all
	$(NOECHO) $(ECHO) Appending installation info to $(DESTINSTALLSITEARCH)/perllocal.pod
	-$(NOECHO) umask 02; $(MKPATH) $(DESTINSTALLSITEARCH)
	-$(NOECHO) umask 02; $(DOC_INSTALL) \
		"Module" "$(NAME)" \
		"installed into" "$(INSTALLSITELIB)" \
		LINKTYPE "$(LINKTYPE)" \
		VERSION "$(VERSION)" \
		EXE_FILES "$(EXE_FILES)" \
		&#62;&#62; $(DESTINSTALLSITEARCH)/perllocal.pod

doc_vendor_install :: all

uninstall :: uninstall_from_$(INSTALLDIRS)dirs
	$(NOECHO) $(NOOP)

uninstall_from_perldirs ::

uninstall_from_sitedirs ::
	$(NOECHO) $(UNINSTALL) $(SITEARCHEXP)/auto/$(FULLEXT)/.packlist

uninstall_from_vendordirs ::

# --- MakeMaker force section:
# Phony target to force checking subdirectories.
FORCE :
	$(NOECHO) $(NOOP)

# --- MakeMaker perldepend section:

PERL_HDRS = \
	$(PERL_INC)/EXTERN.h		\
	$(PERL_INC)/INTERN.h		\
	$(PERL_INC)/XSUB.h		\
	$(PERL_INC)/av.h		\
	$(PERL_INC)/cc_runtime.h	\
	$(PERL_INC)/config.h		\
	$(PERL_INC)/cop.h		\
	$(PERL_INC)/cv.h		\
	$(PERL_INC)/dosish.h		\
	$(PERL_INC)/embed.h		\
	$(PERL_INC)/embedvar.h		\
	$(PERL_INC)/fakethr.h		\
	$(PERL_INC)/form.h		\
	$(PERL_INC)/gv.h		\
	$(PERL_INC)/handy.h		\
	$(PERL_INC)/hv.h		\
	$(PERL_INC)/intrpvar.h		\
	$(PERL_INC)/iperlsys.h		\
	$(PERL_INC)/keywords.h		\
	$(PERL_INC)/mg.h		\
	$(PERL_INC)/nostdio.h		\
	$(PERL_INC)/op.h		\
	$(PERL_INC)/opcode.h		\
	$(PERL_INC)/patchlevel.h	\
	$(PERL_INC)/perl.h		\
	$(PERL_INC)/perlio.h		\
	$(PERL_INC)/perlsdio.h		\
	$(PERL_INC)/perlsfio.h		\
	$(PERL_INC)/perlvars.h		\
	$(PERL_INC)/perly.h		\
	$(PERL_INC)/pp.h		\
	$(PERL_INC)/pp_proto.h		\
	$(PERL_INC)/proto.h		\
	$(PERL_INC)/regcomp.h		\
	$(PERL_INC)/regexp.h		\
	$(PERL_INC)/regnodes.h		\
	$(PERL_INC)/scope.h		\
	$(PERL_INC)/sv.h		\
	$(PERL_INC)/thread.h		\
	$(PERL_INC)/unixish.h		\
	$(PERL_INC)/util.h

$(OBJECT) : $(PERL_HDRS)

mylib.c : $(XSUBPPDEPS)

# --- MakeMaker makefile section:

$(OBJECT) : $(FIRST_MAKEFILE)

# We take a very conservative approach here, but it's worth it.
# We move Makefile to Makefile.old here to avoid gnu make looping.
$(FIRST_MAKEFILE) : Makefile.PL $(CONFIGDEP)
	$(NOECHO) $(ECHO) "Makefile out-of-date with respect to $?"
	$(NOECHO) $(ECHO) "Cleaning current config before rebuilding Makefile..."
	-$(NOECHO) $(RM_F) $(MAKEFILE_OLD)
	-$(NOECHO) $(MV)   $(FIRST_MAKEFILE) $(MAKEFILE_OLD)
	- $(MAKE) $(USEMAKEFILE) $(MAKEFILE_OLD) clean $(DEV_NULL)
	$(PERLRUN) Makefile.PL
	$(NOECHO) $(ECHO) "==&#62; Your Makefile has been rebuilt.  Please rerun the $(MAKE) command.  &#60;==&#34;
	false

# --- MakeMaker staticmake section:

# --- MakeMaker makeaperl section ---
MAP_TARGET    = perl
FULLPERL      = /usr/bin/perl

$(MAP_TARGET) :: static $(MAKE_APERL_FILE)
	$(MAKE) $(USEMAKEFILE) $(MAKE_APERL_FILE) $@

$(MAKE_APERL_FILE) : $(FIRST_MAKEFILE) pm_to_blib
	$(NOECHO) $(ECHO) Writing \&#34;$(MAKE_APERL_FILE)\&#34; for this $(MAP_TARGET)
	$(NOECHO) $(PERLRUNINST) \
		Makefile.PL DIR= \
		MAKEFILE=$(MAKE_APERL_FILE) LINKTYPE=static \
		MAKEAPERL=1 NORECURS=1 CCCDLFLAGS=

# --- MakeMaker test section:

TEST_VERBOSE=0
TEST_TYPE=test_$(LINKTYPE)
TEST_FILE = test.pl
TEST_FILES = t/*.t
TESTDB_SW = -d

testdb :: testdb_$(LINKTYPE)

test :: $(TEST_TYPE) subdirs-test

subdirs-test ::
	$(NOECHO) $(NOOP)

test_dynamic :: pure_all
	PERL_DL_NONLAZY=1 $(FULLPERLRUN) &#34;-MExtUtils::Command::MM&#34; &#34;-e&#34; &#34;test_harness($(TEST_VERBOSE), &#39;$(INST_LIB)&#39;, &#39;$(INST_ARCHLIB)&#39;)&#34; $(TEST_FILES)

testdb_dynamic :: pure_all
	PERL_DL_NONLAZY=1 $(FULLPERLRUN) $(TESTDB_SW) &#34;-I$(INST_LIB)&#34; &#34;-I$(INST_ARCHLIB)&#34; $(TEST_FILE)

test_ : test_dynamic

test_static :: pure_all $(MAP_TARGET)
	PERL_DL_NONLAZY=1 ./$(MAP_TARGET) &#34;-MExtUtils::Command::MM&#34; &#34;-e&#34; &#34;test_harness($(TEST_VERBOSE), &#39;$(INST_LIB)&#39;, &#39;$(INST_ARCHLIB)&#39;)&#34; $(TEST_FILES)

testdb_static :: pure_all $(MAP_TARGET)
	PERL_DL_NONLAZY=1 ./$(MAP_TARGET) $(TESTDB_SW) &#34;-I$(INST_LIB)&#34; &#34;-I$(INST_ARCHLIB)&#34; $(TEST_FILE)

# --- MakeMaker ppd section:
# Creates a PPD (Perl Package Description) for a binary distribution.
ppd :
	$(NOECHO) $(ECHO) &#39;&#60;SOFTPKG NAME=&#34;$(DISTNAME)&#34; VERSION=&#34;0,01,0,0&#34;&#62;&#39; &#62; $(DISTNAME).ppd
	$(NOECHO) $(ECHO) &#39;    &#60;TITLE&#62;$(DISTNAME)&#60;/TITLE&#62;&#39; &#62;&#62; $(DISTNAME).ppd
	$(NOECHO) $(ECHO) &#39;    &#60;ABSTRACT&#62;Perl extension for blah blah blah&#60;/ABSTRACT&#62;&#39; &#62;&#62; $(DISTNAME).ppd
	$(NOECHO) $(ECHO) &#39;    &#60;AUTHOR&#62;Eric Melski &#60;ericm@&#62;&#60;/AUTHOR&#62;&#39; &#62;&#62; $(DISTNAME).ppd
	$(NOECHO) $(ECHO) &#39;    &#60;IMPLEMENTATION&#62;&#39; &#62;&#62; $(DISTNAME).ppd
	$(NOECHO) $(ECHO) &#39;        &#60;OS NAME=&#34;$(OSNAME)&#34; /&#62;&#39; &#62;&#62; $(DISTNAME).ppd
	$(NOECHO) $(ECHO) &#39;        &#60;ARCHITECTURE NAME=&#34;i486-linux-gnu-thread-multi-5.1&#34; /&#62;&#39; &#62;&#62; $(DISTNAME).ppd
	$(NOECHO) $(ECHO) &#39;        &#60;CODEBASE HREF=&#34;&#34; /&#62;&#39; &#62;&#62; $(DISTNAME).ppd
	$(NOECHO) $(ECHO) &#39;    &#60;/IMPLEMENTATION&#62;&#39; &#62;&#62; $(DISTNAME).ppd
	$(NOECHO) $(ECHO) &#39;&#60;/SOFTPKG&#62;&#39; &#62;&#62; $(DISTNAME).ppd

# --- MakeMaker pm_to_blib section:

pm_to_blib : $(TO_INST_PM)
	$(NOECHO) $(ABSPERLRUN) -MExtUtils::Install -e &#39;pm_to_blib({@ARGV}, &#39;\&#39;&#39;$(INST_LIB)/auto&#39;\&#39;&#39;, &#39;\&#39;&#39;$(PM_FILTER)&#39;\&#39;&#39;)&#39; -- \
	  lib/mylib.pm blib/lib/mylib.pm
	$(NOECHO) $(TOUCH) pm_to_blib

# --- MakeMaker selfdocument section:

# --- MakeMaker postamble section:

# End.
</pre>
</p>
<p>
It seems hopeless.  This makefile suffers from a classic problem:  unless you&#8217;re the guy who wrote it in the first place, it&#8217;s an impenetrable fog.  You&#8217;re in for a world of hurt when you try to understand it, or worse, try to modify it.  Lucky for me &#8212; and for you if you ever find yourself in this situation &#8212; there&#8217;s a powerful new tool in your toolbox:  emake&#8217;s annotated build logs, or simply <i>annotation</i>.
</p>
<p>
If you have ElectricAccelerator or <a href="http://www.sparkbuild.com/">SparkBuild</a>, a free gmake- and NMAKE-compatible make replacement, you just need to enable annotation on your next build:</p>
<pre style="font:80% courier, verdana, monospace;border:1px solid #ccc;width:90%;background:#fff7f0;color:#000;overflow:auto;margin:1em auto 2em;padding:1em;">emake --emake-annodetail=basic &#62; build.xml 2&#62;&#38;1</pre>
</p>
<p>
Now you can search <tt>build.xml</tt> for the log output or the command-line that you&#8217;re interested in.  You can use ElectricInsight or SparkBuild Insight, of course, but for a simple query like this I just use <i>less</i>.  Searching for the log output of the command I&#8217;m looking for (<i>gcc -shared</i>) leads me to this:
</p>
<p><pre style="font:80% courier, verdana, monospace;border:1px solid #ccc;width:90%;background:#fff7f0;color:#000;overflow:auto;margin:1em auto 2em;padding:1em;">...
&#60;job id="J09be71b8" thread="b7b34940" type="rule" name="blib/arch/auto/mylib/mylib.so" file="Makefile" line="469" neededby="J09be7138"&#62;
&#60;output&#62;&#60;![CDATA[]]&#62;&#60;/output&#62;
&#60;command line="470"&#62;
&#60;argv&#62;&#60;![CDATA[rm -f blib/arch/auto/mylib/mylib.so]]&#62;&#60;/argv&#62;
&#60;output&#62;&#60;![CDATA[rm -f blib/arch/auto/mylib/mylib.so
]]&#62;&#60;/output&#62;
&#60;output src="prog"&#62;&#60;![CDATA[]]&#62;&#60;/output&#62;
&#60;/command&#62;
&#60;command line="471-473"&#62;
&#60;argv&#62;&#60;![CDATA[<font color="red"><b>gcc  -shared </b></font>-O2 -g -L/usr/local/lib mylib.o  -o blib/arch/auto/mylib/mylib.so      \
                \
          ]]&#62;&#60;/argv&#62;
&#60;output&#62;&#60;![CDATA[<font color="red"><b>gcc  -shared </b></font>-O2 -g -L/usr/local/lib mylib.o  -o blib/arch/auto/mylib/mylib.so    \
                \

]]&#62;&#60;/output&#62;
&#60;output src="prog"&#62;&#60;![CDATA[]]&#62;&#60;/output&#62;
&#60;/command&#62;
...</pre>
</p>
<p>
Now, I just scan back a few lines to find the start of the <i>&#60;job&#62;</i> tag containing that text.  The <i>file</i> attribute tells me which makefile contains the rule definition, and the <i>line</i> attribute tells me which line it starts on:
</p>
<p><pre style="font:80% courier, verdana, monospace;border:1px solid #ccc;width:90%;background:#fff7f0;color:#000;overflow:auto;margin:1em auto 2em;padding:1em;">...
&#60;job id="J09be71b8" thread="b7b34940" type="rule" name="blib/arch/auto/mylib/mylib.so" <font color="red"><b>file="Makefile" line="469"</b></font> neededby="J09be7138"&#62;
...</pre>
</p>
<p>
<b>Bingo!</b>  The rule I want starts on line 469 of the file <i>Makefile</i>.  Using that as an anchor it&#8217;s now trivial to see how to modify the makefile to produce the result I&#8217;m after.
</p>
<p><h3>The best tool for the job</h3>
</p>
<p>
Trying to figure out how a build system is put together can feel like being dropped in the middle of a dense jungle.  Annotated build logs are like a map leading you back to daylight.  There&#8217;s nothing else like them.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Módulo cargable en Linux]]></title>
<link>http://neobrr.wordpress.com/2009/10/27/modulo-cargable-en-linux/</link>
<pubDate>Tue, 27 Oct 2009 08:00:19 +0000</pubDate>
<dc:creator>G10</dc:creator>
<guid>http://neobrr.wordpress.com/2009/10/27/modulo-cargable-en-linux/</guid>
<description><![CDATA[Como parte de uno de los cursos que estoy llevando este semestre tuvimos que realizar un módulo carg]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p style="text-align:justify;">Como parte de uno de los cursos que estoy llevando este semestre tuvimos que realizar un módulo cargable &#8220;en tiempo de ejecución&#8221; en Linux. Este aparte de mostrar mensajes de carga y descarga mediante dmesg, tenía que crear un archivo en el directorio /proc. A continuación la solución.</p>
<p style="text-align:justify;">Primeramente hay que crear el archivo con el código fuente del módulo y agregar el código para el mismo. Abrimos una terminal de comandos y creamos una carpeta para tener un mejor orden y ahí dentro creamos el archivo.</p>
<blockquote><p><span style="color:#000080;"><em>mkdir modulo</em></span></p>
<p><span style="color:#000080;"><em>cd modulo<br />
</em></span></p>
<p><span style="color:#000080;"><em>nano primerModulo.c</em></span></p></blockquote>
<p style="text-align:justify;">A continuación el código fuente para el módulo.</p>
<blockquote><p><span style="color:#000080;"><em>/* El nombre del archivo es primerModulo */<br />
#include &#60;linux/module.h&#62;          //para los detalles del modulo (Author, License&#8230;)<br />
#include &#60;linux/kernel.h&#62;          //para usar la macro printk, KERN_INFO y KERN_ALERT<br />
#include &#60;linux/sched.h&#62;           //para usar la estructura &#8220;task_struct&#8221;<br />
#include &#60;linux/proc_fs.h&#62;    //para poder hacer la escritura en el archivo que estara en /proc</em></span></p>
<p><span style="color:#000080;"><em>struct proc_dir_entry *structDirEntrada= NULL;<br />
#define procfs_name &#8220;miprimermodulo&#8221;    //Nombre del archivo que se creara en /proc<br />
char buff[500];        //buffer para escribir al archivo /proc/miprimermodulo</em></span></p>
<p><span style="color:#000080;"><em>/*A continuacion viene la funcion de escritura en el archivo en /proc*/<br />
int procfile_read(char *buffer, char **buffer_location, off_t offset, int buffer_length, int *eof, void *data){<br />
int len;<br />
static int count=1;<br />
static char bufo[500];<br />
if(offset&#62;0)<br />
return 0;<br />
len=sprintf(bufo, &#8220;%s&#8221;, buff);<br />
count++;<br />
*buffer_location=bufo;<br />
return len;<br />
}</em></span></p>
<p><span style="color:#000080;"><em>static int cargar(void){<br />
//create_proc_entry lleva parametros nombre, modo, y padre de la estructura a la que se hace la asignacion.<br />
structDirEntrada = create_proc_entry(procfs_name, 0644, NULL);</em></span></p>
<p><span style="color:#000080;"><em>if (structDirEntrada == NULL) {<br />
remove_proc_entry(buff, structDirEntrada);<br />
printk(KERN_ALERT &#8220;Error: Could not initialize /proc/%s\n&#8221;, procfs_name);<br />
return -ENOMEM;<br />
}</em></span></p>
<p><span style="color:#000080;"><em>//Ingresa el texto que se guardara en el archivo al buffer &#8220;buff&#8221;<br />
sprintf(buff, &#8220;\n*** Hola soy el primer modulo de G10 &#8211; 200413044 ***\n\n&#8221;);</em></span></p>
<p><span style="color:#000080;"><em>//A continuacion se setean varios de los parametros a los elementos de la estructura proc_dir_entry<br />
structDirEntrada-&#62;read_proc = procfile_read;<br />
structDirEntrada-&#62;owner = THIS_MODULE;<br />
structDirEntrada-&#62;mode = S_IFREG &#124; S_IRUGO;<br />
structDirEntrada-&#62;uid = 0;<br />
structDirEntrada-&#62;gid = 0;<br />
structDirEntrada-&#62;size = 100000; //Se establece el tamaño del archivo en /proc (bytes)</em></span></p>
<p><span style="color:#000080;"><em>//Lo siguiente tiene que ir hasta aca porque el estandar ISO C90 prohíbe las declaraciones mezcladas y código<br />
printk(KERN_INFO &#8220;********************************************************\n&#8221;);<br />
printk(KERN_INFO &#8220;* Hola, ahora se inicia la carga del modulo&#8230;\n&#8221;);<br />
printk(KERN_INFO &#8220;* El user space del proceso es &#8216;%s&#8217;\n&#8221;, current-&#62;comm);<br />
printk(KERN_INFO &#8220;* El PID del programa que lo inserto&#8230; %i\n&#8221;, current-&#62;pid);<br />
printk(KERN_INFO &#8220;********************************************************\n&#8221;);<br />
printk(KERN_INFO &#8220;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;\n&#8221;);<br />
printk(KERN_INFO &#8220;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;\n&#8221;);<br />
return 0;    //Se retorna 0 para indicar que todo salio bien, de lo contrario retorna != 0<br />
}</em></span></p>
<p><span style="color:#000080;"><em>static void descargar(void){<br />
printk(KERN_INFO &#8220;#######################################\n&#8221;);<br />
printk(KERN_INFO &#8220;# Se inicia la descarga del modulo&#8230; #\n&#8221;);<br />
printk(KERN_INFO &#8220;#######################################\n&#8221;);<br />
remove_proc_entry(buff, structDirEntrada);<br />
}</em></span></p>
<p><span style="color:#000080;"><em>module_init(cargar);    // Lo que se debe llamar al cargar un modulo<br />
module_exit(descargar);    // Lo que se debe llamar al remover un modulo</em></span></p>
<p><span style="color:#000080;"><em>MODULE_AUTHOR(&#8220;G10 &#8211; 200413044&#8243;);<br />
MODULE_LICENSE(&#8220;Dual MIT/GPL&#8221;);<br />
MODULE_DESCRIPTION(&#8220;Este es un modulo para la practica 3 de Sistemas Operativos 2.&#8221;);<br />
MODULE_VERSION(&#8220;1:1.0-Beta1&#8243;);<br />
//Existen mas licencias en module.h, y es quiza uno de los paramatros mas importantes.</em></span></p></blockquote>
<p style="text-align:justify;"><em> </em>Cuando terminanos de agregar el código, guardamos y cerramos el archivo. A continuación debemos crear el archivo make para la construcción del modulo. Esto se hace con los comandos siguientes.</p>
<blockquote><p><span style="color:#000080;"><em>nano Makefile</em></span></p>
<p><span style="color:#000080;"><em><br />
</em></span></p>
<p><span style="color:#000080;"><em>#Codigo del Makefile para la compilacion del modulo&#8230;<br />
ifeq ($(KERNELRELEASE),)<br />
KERNELDIR ?= /lib/modules/$(shell uname -r)/build<br />
PWD := $(shell pwd)<br />
.PHONY: build clean<br />
build:<br />
#&#8212; Importante la linea siguiente debe ir tabulada &#8212;<br />
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules<br />
clean:<br />
#&#8212; Importante la linea siguiente debe ir tabulada &#8212;<br />
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c<br />
else<br />
$(info Building with KERNELRELEASE = ${KERNELRELEASE})<br />
obj-m :=    primerModulo.o<br />
endif</em></span></p></blockquote>
<p style="text-align:justify;">Guardamos y cerramos el archivo, a continuación para construirlo, en la terminal de comandos tecleamos el comando. Esto nos crea varios archivos, entre ellos uno con extensión .ko, el cual es módulo a cargar en sí.</p>
<blockquote><p><em><span style="color:#000080;">make</span></em></p></blockquote>
<p style="text-align:justify;">Podemos ver las propiedades del modulo con el comando</p>
<blockquote><p><em><span style="color:#000080;">modinfo primerModulo.ko</span></em></p></blockquote>
<p style="text-align:justify;">A continuación montamos/insertamos el módulo en el sistema, esto se hace con el comando</p>
<blockquote><p><em><span style="color:#000080;">sudo insmod primerModulo.ko</span></em></p></blockquote>
<p style="text-align:justify;">Podemos ver los mensajes de bitacora del módulo con el comando</p>
<blockquote><p><em><span style="color:#000080;">dmesg</span></em></p></blockquote>
<p style="text-align:justify;">Con el modulo ya cargado podemos ver que en /proc se creó el archivo que tiene como objetivo el módulo, este lo podemos abrir con programas como nano, cat o less. Cabe mencionar que este archivo es accesible unicamente mientras el módulo este cargado, cuando se descarga aparece, pero no es accesible.</p>
<blockquote><p><em><span style="color:#000080;">cat /proc/miprimermodulo</span></em></p></blockquote>
<p style="text-align:justify;">Ahora tenemos que descargar el módulo, esto se hace con el comando.</p>
<blockquote><p><em><span style="color:#000080;">sudo rmmod primerModulo</span></em></p></blockquote>
<p style="text-align:justify;">Para ver todos los mensajes de bitácora del módulo, podemos teclear el comando siguiente.</p>
<blockquote><p><em><span style="color:#000080;">tail /var/log/messages</span></em></p></blockquote>
<p style="text-align:justify;">Este es un módulo bastante básico, sin embargo, bastante interesante para iniciarse en la programación de los mismo o simplemente para saber como funcionan los mismos.</p>
<p>Referencias:</p>
<ul>
<li><a href="http://casidiablo.net/desarrollar-compilar-modulo-linux/" target="_blank">http://casidiablo.net/desarrollar-compilar-modulo-linux/</a></li>
<li><a href="http://doc.ubuntu-es.org/El_Kernel" target="_blank">http://doc.ubuntu-es.org/El_Kernel</a></li>
<li><a href="http://www.linuxtopia.org/online_books/Linux_Kernel_Module_Programming_Guide/" target="_blank">http://www.linuxtopia.org/online_books/Linux_Kernel_Module_Programming_Guide/</a></li>
</ul>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Subbuilds: build avoidance done right]]></title>
<link>http://blog.electric-cloud.com/2009/10/21/subbuilds-build-avoidance-done-right/</link>
<pubDate>Wed, 21 Oct 2009 23:12:37 +0000</pubDate>
<dc:creator>Eric Melski</dc:creator>
<guid>http://blog.electric-cloud.com/2009/10/21/subbuilds-build-avoidance-done-right/</guid>
<description><![CDATA[I&#8217;ve heard it said that the best programmer is a lazy programmer. I&#8217;ve always taken that]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I&#8217;ve heard it said that the best programmer is a lazy programmer.  I&#8217;ve always taken that to mean that the best programmers avoid unnecessary work, by working smarter and not harder; and that they focus on building only those features that are really required <i>now</i>, not allowing speculative work to distract them.</p>
<p>
I wouldn&#8217;t presume to call myself a great programmer, but I definitely hate doing unnecessary work.  That&#8217;s why the concept of <i>build avoidance</i> is so intriguing.  If you&#8217;ve spent any time on the build speed problem, you&#8217;ve probably come across this term.  Unfortunately it&#8217;s been conflated with the single technique implemented by tools like <a href="http://ccache.samba.org/">ccache</a> and <a href="http://en.wikipedia.org/wiki/ClearCase#Features">ClearCase winkins</a>.  I say &#8220;unfortunate&#8221; for two reasons:  first, those tools don&#8217;t really work all that well, at least not for individual developers; and second, the technique they employ is not really build avoidance at all, but rather <i>object reuse</i>.  But by co-opting the term <i>build avoidance</i> and associating it with such lackluster results, many people have become dismissive of build avoidance.
</p>
<p>
<i>Subbuilds</i> are a more literal, and more effective, approach to build avoidance:  reduce build time by building only the stuff required for your active component.  Don&#8217;t waste time building the stuff that&#8217;s not related to what you&#8217;re working on <i>now</i>.  It seems so obvious I&#8217;m almost embarrassed to be explaining it.  But the payoff is anything but embarrassing.  On my project, after making changes to one of the prerequisites libraries for the application I&#8217;m working on, a regular incremental takes 10 minutes; a subbuild incremental takes just 77 seconds:
</p>
<table>
<tr>
<td align="right">Standard&#160;incremental:</td>
<td>
<div style="background:#85aef7;width:305px;">609s</div>
</td>
</tr>
<tr>
<td align="right">Subbuild&#160;incremental:</td>
<td>
<div style="background:#a3ffa3;width:39px;">77s</div>
</td>
</tr>
</table>
<p>Not bad!  Read on for more about how subbuilds work and how you can get <a href="http://www.sparkbuild.com/"><b>SparkBuild</b></a>, a free gmake- and NMAKE-compatible build tool, so you can try subbuilds yourself.<br />
<!--more--></p>
<p><h3>What is a subbuild?</h3>
</p>
<p>
A subbuild is just the smallest part of a full build tree that must be built in order to completely build a single component of the build, including all its prerequisites.  For example, my project consists of several applications and the libraries they depend on.  Each of these components resides in a separate directory, and we use recursive make invocations to build everything.  (<i>Nota bene</i>:  if you have a non-recursive make then you probably already enjoy many of the benefits of subbuilds, but you should definitely still <a href="http://blog.electric-cloud.com/2009/10/27/what-is-sparkbuild/">check out the other features of SparkBuild</a>!)
</p>
<p>
The dependency graph for my project looks like this:
</p>
<p>
<img src="http://ecloud.wordpress.com/files/2009/10/depgraph.png"/>
</p>
<p>
You can see that to build the <i>agent</i> component, for example, we only need to build the <i>util</i>, <i>xml</i>, and <i>http</i> libraries, and the <i>agent</i> application code, of course:
</p>
<p>
<img src="http://ecloud.wordpress.com/files/2009/10/subbuild.png"/>
</p>
<p>
This subset defines the agent subbuild.
</p>
<p><h3>Subbuilds and developers</h3>
</p>
<p>
What makes subbuilds really interesting for developers is the realization that usually you&#8217;re working on just one component at a time.  For example, on any given day I might be working on the agent component, or the cm, but rarely both.  Most of the edits I make will be on code in the <i>agent</i> directory, with occassional edits to the agent&#8217;s prerequisites.  As I&#8217;m running through the edit-compile-test cycle, I have some choices about how to run the build.  The most natural thing for me is to simply run <i>make</i> in the <i>agent</i> directory.  After all, most of the changes I make are in that directory, so that will do the right thing most of the time.  Of course, if I have made changes to any of the prerequisites, or if I resync with the source depot and pick up somebody else&#8217;s changes in one of those prerequisites, I&#8217;ll probably get a busted build.
</p>
<p>
The next most obvious approach is a rebuild from the root of my source tree.  This ensures that I always update all the pieces I need for the agent, but at the cost of also building components that are irrelevant to my current focus:  if I&#8217;m just trying to rebuild to run the agent&#8217;s unit tests, there&#8217;s no need for me to rebuild the <i>cm</i> application, or the <i>ldap</i> library.
</p>
<p>
The best choice is the agent subbuild, the minimum set of things that must be built to be sure that the agent component is fully up-to-date.  But although it&#8217;s possible on a small project like this to execute the subbuild manually, it&#8217;s a nuisance, and on a bigger project it may not be practical or even possible.  You need a build tool that can <i>automatically</i> determine which parts of the build make up the subbuild for any component, and then <i>automatically</i> execute that subbuild.  That tool is SparkBuild emake.
</p>
<p><h3>Subbuilds with SparkBuild</h3>
</p>
<p>
Subbuilds with SparkBuild start with a full build, during which emake captures information about which targets are produced by each submake.  In subsequent builds, emake references that database anytime it can&#8217;t find a rule to build a particular target.  If a match is found, emake runs the corresponding submake before proceeding.  For example, the rule for the actual agent target looks like this:
</p>
<p><pre>$(OUT)/agent/agent: $(OUT)/agent/*.o $(OUT)/xml/xml.a $(OUT)/http/http.a
	g++ -o $@ $^
</pre>
</p>
<p>
In a normal build, gmake would see the dependency on <i>$(OUT)/xml/xml.a</i> and use that file if it existed already, regardless of whether it was actually up-to-date; or report &#8220;no rule to make&#8221; if the file did not exist.  With SparkBuild, emake checks the subbuild database for an entry matching <i>$(OUT)/xml/xml.a</i> and sees that it must run <i>make</i> in the <i>xml</i> directory before proceeding.  Like magic, each of the agent&#8217;s prerequisites is updated without requiring me to take any action other than swapping <i>emake &#8211;emake-subbuild-db=my.db</i> for <i>gmake</i> in my build command-line.
</p>
<p>
Still not convinced that it&#8217;s worth a look?  Here&#8217;s some more concrete results comparing a few different build scenarios from my project.  These comparisons assume that I&#8217;m actively working on the <i>agent</i> component, and that I ran either a standard incremental, from the root of the source tree, or a subbuild using SparkBuild emake:
</p>
<table>
<caption align="bottom"><font size="-1">Normal builds versus subbuilds (serial build time, shorter is better)</font></caption>
<tr>
<td>No&#160;changes,&#160;standard:</td>
<td>
<div style="background:#85aef7;width:10px;">19s</div>
</td>
</tr>
<tr>
<td>No&#160;changes,&#160;subbuild:</td>
<td>
<div style="background:#a3ffa3;width:0;">0.5s</div>
</td>
</tr>
<tr>
<td colspan="2">
<hr /></td>
</tr>
<tr>
<td>Changes&#160;in&#160;<i>agent</i>,&#160;standard:</td>
<td>
<div style="background:#85aef7;width:41px;">81s</div>
</td>
</tr>
<tr>
<td>Changes&#160;in&#160;<i>agent</i>,&#160;subbuild:</td>
<td>
<div style="background:#a3ffa3;width:16px;">31s</div>
</td>
</tr>
<tr>
<td colspan="2">
<hr /></td>
</tr>
<tr>
<td>Changes&#160;in&#160;<i>util</i>,&#160;standard:</td>
<td>
<div style="background:#85aef7;width:305px;">609s</div>
</td>
</tr>
<tr>
<td>Changes&#160;in&#160;<i>util</i>,&#160;subbuild:</td>
<td>
<div style="background:#a3ffa3;width:39px;">77s</div>
</td>
</tr>
<tr>
<td colspan="2">
<hr /></td>
</tr>
<tr>
<td>Full&#160;build:</td>
<td>
<div style="background:#85aef7;width:364px;">729s</div>
</td>
</tr>
<tr>
<td>Subbuild&#160;build:</td>
<td>
<div style="background:#a3ffa3;width:59px;">118s</div>
</td>
</tr>
</table>
<p><h3>Conclusion and Availability</h3>
</p>
<p>
Tools like ccache and ClearCase winkins have co-opted the term <i>build avoidance</i>, but in fact they do <i>object reuse</i>, not build avoidance, and they are not very useful for developer builds.  Subbuilds are a simple but highly effective approach to build avoidance that save significant time during developer builds by literally skipping parts of the build tree that are unrelated to your current focus.
</p>
<p>
If you want to try out subbuilds yourself, you can download SparkBuild from <a href="http://www.sparkbuild.com/">www.sparkbuild.com</a>.  It&#8217;s completely free (<a href="http://en.wikipedia.org/wiki/Gratis_versus_Libre#.22Free_as_in_beer.22_vs_.22Free_as_in_speech.22">as in beer</a>), so you&#8217;ve got nothing to lose&#8230; except those long coffee breaks, of course!</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Verilog and VHDL on Linux (Ubuntu)]]></title>
<link>http://pgraycode.wordpress.com/2009/10/18/verilog-and-vhdl-on-linux-ubuntu/</link>
<pubDate>Sun, 18 Oct 2009 17:02:17 +0000</pubDate>
<dc:creator>Mithrandir</dc:creator>
<guid>http://pgraycode.wordpress.com/2009/10/18/verilog-and-vhdl-on-linux-ubuntu/</guid>
<description><![CDATA[For those interested in programming electronic components there is always the possibility to use Xil]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p style="text-align:justify;">For those interested in programming electronic components there is always the possibility to use <a href="http://www.xilinx.com/">Xilinx</a> if you are on Windows. Of course, there is a Xilinx port for Linux but it is buggy application and a very large download. This article aims to give an alternative to this application. One that will need only a few KB of download from an apt-get source.</p>
<p><!--more--></p>
<p style="text-align:justify;">Of course, we are speaking about <a href="http://www.icarus.com/eda/verilog/">Icarus Verilog (iverilog)</a>, <a href="http://ghdl.free.fr/">GHDL</a> and <a href="http://gtkwave.sourceforge.net/">GtkWave</a>.</p>
<p style="text-align:justify;">After installing each of them (command line, download, whatever), you can start desgning. Suppose we have the following source:</p>
<p><code>module bser(en, clk, in, out, done);<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;input en, clk;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;input [7:0]in;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;output out, done;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;reg [2:0]cst;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;reg out, done;<br />
&#160;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;initial<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;begin<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;done = 0;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;cst = 3'b0;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;out = 0;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;end<br />
&#160;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;always @(posedge en)<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;begin<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;done = 0;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;cst = 3'b0;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;out = 0;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;end<br />
&#160;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;always @(posedge clk)<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if (en)<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;begin<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;out = in[cst];<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;cst = cst + 1;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if (cst == <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /> <br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;begin<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;done = 1;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;cst = 0;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;end<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;end<br />
endmodule<br />
</code></p>
<p style="text-align:justify;">We need to test our source manually, so we will write a benchmark file (consult the documentation for the syntax) in which we will introduce two lines for dumping information about variables:</p>
<p><code>module bser_tb;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;reg en, clk;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;reg [7:0]in;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;bser g(en, clk, in, out, done);<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;initial<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;begin<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;en = 0; in=8'b00010111; clk=0;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<font color="#ff40ff">$dumpfile(&#34;bser_tb&#34;);<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;$dumpvars;</font><br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;#10000 $finish;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;end<br />
&#160;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;always<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;begin<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;#1 clk = ~clk;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;end<br />
&#160;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;initial<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;begin<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;#2 en=1;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;end<br />
endmodule<br /></code></p>
<p style="text-align:justify;">Now, we will compile the source, run it and then use gtkwave to see the results. All of this is very repetitive, so a Makefile was needed:</p>
<p><code><br />
test_bser:<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;iverilog bser.v bser_tb.v<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;./a.out<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;gtkwave bser_tb<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;rm -f a.out bser_tb<br />
</code></p>
<p style="text-align:justify;">This is what we will obtain after a few milliseconds:</p>
<p style="text-align:center;"><a href="http://photos.piry.net/view/49846Screenshot.png"><img src="http://photos.piry.net/view/49846Screenshot.png" alt="GtkWave result" /></img></a></p>
<p style="text-align:justify;">That&#8217;s all.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Tutorial membuat makefile]]></title>
<link>http://hqjomblo.wordpress.com/2009/10/15/tutorial-membuat-makefile/</link>
<pubDate>Thu, 15 Oct 2009 04:29:20 +0000</pubDate>
<dc:creator>imelwa</dc:creator>
<guid>http://hqjomblo.wordpress.com/2009/10/15/tutorial-membuat-makefile/</guid>
<description><![CDATA[Mengkompile source code satu persatu menggunakan command line bisa jadi akan sangat membosankan, ter]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Mengkompile source code satu persatu menggunakan <em>command line</em> bisa jadi akan sangat membosankan, terutama jika berhadapan dengan beberapa include file dan keharusan mengetikkan command tiap kali akan melakukan compiling. Namun  telah dibuat suatu cara untuk mempermudah pekerjaan tersebut, yaitu dengan penggunaan makefile. Makefile adalah suatu format file yang digunakan bersama dengan make untuk membantu membangun dan memanage project secara otomatis.</p>
<p><strong>Tentang Make</strong></p>
<p>Jika kita menjalankan</p>
<blockquote><p>make</p></blockquote>
<p>Program ini akan mencari sebuah file bernama makefile pada direktori, lalu mengeksekusinya. Jika terdapat beberapa makefile, maka dapat pula dieksekusi dengan perintah :</p>
<blockquote><p>make –f makefile</p></blockquote>
<p>Adapun lebih lengkap mengenai make dapat dilihat dengan <em>man make</em>.</p>
<p><strong>Proses Build</strong></p>
<p>Proses yang terjadi ketika build program adalah kompiler akan mengambil file source untuk menghasilkan file object, kemudian linker mengambil file object dan menghasilkan executable file.</p>
<p>Teknik dasar melakukan kompilasi file dan mendapatkan executable adalah dengan menjalankan perintah :</p>
<blockquote><p>gcc filename.c -o filename</p></blockquote>
<p><strong>Dasar makefile</strong></p>
<p>makefile pada dasarnya berisikan :</p>
<blockquote><p>target: dependencies</p>
<p>[tab] system command</p></blockquote>
<p>Sebagai contoh aplikasi dari sintaks ini :</p>
<blockquote><p>all :</p>
<p>gcc filename.c –o filename</p></blockquote>
<p>Pada contoh ini dapat kita lihat bahwa target adalah all. Ini adalah target default dari makefile. Make akan mengeksekusi target jika tidak ada target lain yang ditentukan. Dapat dilihat pula bahwa tidak ada dependensi untuk target all sehingga make dapat mengeksekusi system command dengan aman.</p>
<p><strong>Menggunakan dependencies</strong></p>
<p>Kita dapat melakukan pengaturan dependencies apabila kita ingin melakukan modifikasi terhadap sebuah file, namun tidak ingin melakukan recompile terhadap seluruh file yang ada. Sebagai contoh :</p>
<blockquote><p>all: hello</p>
<p>hello: main.o hello.o</p>
<p>gcc main.o hello.o –o hello</p>
<p>main.o: main.c</p>
<p>gcc –c –Wall main.c</p>
<p>hello.o: hello.c</p>
<p>gcc –c –Wall hello.c</p>
<p>clean:</p>
<p>rm –rf *o hello</p></blockquote>
<p>Dapat dilihat bahwa target all hanya memiliki dependencies tanpa system command. Make dapat mengeksekusi secara tepat ketika seluruh dependencies dari target terpenuhi. Tiap dependencies dipanggil dan dieksekusi apabila ditemukan. Pada contoh diatas terdapat target clean yang berfungsi untuk menghapus seluruh file object dan executable.</p>
<p><strong>Menggunakan variabel dan komentar</strong></p>
<p>Dalam pembuatan makefile dapat pula melibatkan variabel dan komentar yang akan mempermudah misalkan dalam pendefinisian compiler maupun optionnya.</p>
<blockquote><p># komentar 1, pendefinisian compiler yang digunakan</p>
<p>CC=gcc</p>
<p># komentar2, pendefinisian option yang akan dilewatkan kedalam compiler</p>
<p>CFLAGS =-c –Wall</p>
<p>all: hello</p>
<p>hello: main.o hello.o</p>
<p>$(CC) $(CFLAGS) main.o hello.o –o hello</p>
<p>main.o: main.c</p>
<p>$(CC)  $(CFLAGS) main.c</p>
<p>hello.o: hello.c</p>
<p>$(CC)  $(CFLAGS) hello.c</p>
<p>clean:</p>
<p>rm –rf *o hello</p></blockquote>
<p>Nilai variable dapat didefinisikan sebelum pendefinisian target dengan operator dereference $(VAR), sedangkan untuk penggunaan komentar diawali dengan #.</p>
<p>Demikian penjelasan singkat mengenai makefile, untuk keterangan lebih lanjut dapat dirujuk ke make documentation.</p>
<p>*nb : ada yg tau cara masukin [tab] ketika posting di wordpress?</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Notepad++ 5.5.1]]></title>
<link>http://netvietnam.org/2009/10/09/notepad-5-5-1/</link>
<pubDate>Fri, 09 Oct 2009 12:15:09 +0000</pubDate>
<dc:creator>Nhân Mã</dc:creator>
<guid>http://netvietnam.org/2009/10/09/notepad-5-5-1/</guid>
<description><![CDATA[Notepad++ là trình biên tập mã nguồn miễn phí (và là công cụ thay thế cho Notepad), hỗ trợ nhiều ngô]]></description>
<content:encoded><![CDATA[Notepad++ là trình biên tập mã nguồn miễn phí (và là công cụ thay thế cho Notepad), hỗ trợ nhiều ngô]]></content:encoded>
</item>
<item>
<title><![CDATA[Handy Latex Metapost Bibtex Makefile]]></title>
<link>http://ryanmlayer.wordpress.com/2009/10/08/handy-latex-metapost-bibtex-makefile/</link>
<pubDate>Thu, 08 Oct 2009 13:08:22 +0000</pubDate>
<dc:creator>ryanlayer</dc:creator>
<guid>http://ryanmlayer.wordpress.com/2009/10/08/handy-latex-metapost-bibtex-makefile/</guid>
<description><![CDATA[This Makefile is not the most robust thing in the world, but it is generic enough for me to use on a]]></description>
<content:encoded><![CDATA[This Makefile is not the most robust thing in the world, but it is generic enough for me to use on a]]></content:encoded>
</item>
<item>
<title><![CDATA[A long night ... fedX + get rpmfusion repo]]></title>
<link>http://ratnadeepdebnath.wordpress.com/2009/10/04/a-long-night-fedx-get-rpmfusion-repo/</link>
<pubDate>Sun, 04 Oct 2009 08:56:02 +0000</pubDate>
<dc:creator>rtnpro</dc:creator>
<guid>http://ratnadeepdebnath.wordpress.com/2009/10/04/a-long-night-fedx-get-rpmfusion-repo/</guid>
<description><![CDATA[I became desperate yesterday night to do some useful things, anything. Had a long offline Puja Holid]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I became desperate yesterday night to do some useful things, anything. Had a long offline Puja Holidays. I was struggling to understand &#8220;How to write Makefiles&#8221;, and yesterday it clicked and I ended up writing a Makefile for the ongoing fedX project. Though the makefile which I wrote is not that great, but I have a start now. Committed the changes to the fedX repository at</p>
<p><a href="http://gitorious.org/~rtnpro/fedx/rtnpros-fedx-clone/">http://gitorious.org/~rtnpro/fedx/rtnpros-fedx-clone/</a></p>
<p>It was around 4:00 AM in the morning already. Made some changes in my gitorious project clones. Apart from that, I was trying to download the rpmfusion repositories for Fedora 11. I was using rsync on multiple screens for the purpose. But again and again, rsync used to stop downloading after working for sometime. Then I tried a Firefox addon &#8220;DownThemAll&#8221; and was very happy to see it work. All I needed was to browse the repository page listing all the packages, right click and select DownThemAll. And then I just needed to select where I want to save the downloaded files and start it. It downloads multiple files simultaneously and does not halt when one of the files cannot be downloaded, rather it pauses it and moves to others. It also supports resume, and has an option to skip the already downloaded files.</p>
<p>But I could not download the directories with DownThemAll. I guess it works only for files. Need to do some research on it. Any way, you can try to use DownThemAll. I think you will like it.</p>
<p>Finally, I went to sleep at 4:45 AM with my laptop running DownThemAll to download the rpmfusion repository. When I got up today morning, it was running fine. <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[CUDA + OCTAVE]]></title>
<link>http://billbrouwer.wordpress.com/2009/09/30/cuda-octave/</link>
<pubDate>Wed, 30 Sep 2009 19:36:48 +0000</pubDate>
<dc:creator>bbrouwer</dc:creator>
<guid>http://billbrouwer.wordpress.com/2009/09/30/cuda-octave/</guid>
<description><![CDATA[I&#8217;ve been experimenting with CUDA and OCTAVE; there is at least one company who have produced ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I&#8217;ve been experimenting with CUDA and OCTAVE; there is at least one company who have produced GPU enabled MEX functions. The big difficulty is of course that there is no support for internal floats  within OCTAVE (afaik) and similarly with Matlab. However if one can leave the data and work with it on the device for some time, then there are only two explicit conversions btwn float &#60;-&#62; double needed. Or you could sacrifice some performance in CUDA in return for using doubles. At any rate here&#8217;s an example Makefile, happy experimenting. For this example I gutted the matrix Mul example from the CUDA sdk; the wrapper *oct source code (*cc, really C++ with octave extensions) contains an extern C section which references the cuda kernel (*cu). Don&#8217;t forget to indent instructions under &#8216;all&#8217; with a single tab for make.</p>
<hr />
<p style="font-family:courier new;font-size:12px;">#! /usr/bin/env make<br />
#make file for octfile/cuda<br />
#Mac OSX 10.5.8 intel core 2 duo<br />
#cuda include/lib<br />
CUDA_INC_PATH=/usr/local/cuda/include<br />
CUDA_LIB_PATH=/usr/local/cuda/lib<br />
#octfile compiler<br />
CC=mkoctfile<br />
#basic flags<br />
CFLAGS= -I$(CUDA_INC_PATH)<br />
LDFLAGS= -L$(CUDA_LIB_PATH) -lcudart -lcuda</p>
<p style="font-family:courier new;font-size:12px;">all:<br />
$(CC) $(CFLAGS) -c cudaMatrixMul.cc -o cudaMatrixMul.o<br />
nvcc  -c matMul_kernel.cu -o matMul_kernel.o -Wall<br />
$(CC) $(LDFLAGS) cudaMatrixMul.o matMul_kernel.o -o cudaMatrixMul.oct</p>
<p style="font-family:courier new;font-size:12px;">#clean:<br />
rm -f  cudaMatrixMul.o matMul_kernel.o</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[GNU make : a very short and quick tutorial]]></title>
<link>http://sumanta679.wordpress.com/2009/09/24/gnu-make-a-very-short-and-quick-tutorial/</link>
<pubDate>Thu, 24 Sep 2009 06:35:32 +0000</pubDate>
<dc:creator>sumanta679</dc:creator>
<guid>http://sumanta679.wordpress.com/2009/09/24/gnu-make-a-very-short-and-quick-tutorial/</guid>
<description><![CDATA[First thing to know about makefiles is that the contents are basically arranged as: TARGET: DEPENDEN]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>First thing to know about makefiles is that the contents are basically arranged as:</p>
<blockquote><p>TARGET: DEPENDENCIES<br />
RULE</p></blockquote>
<p>where TARGET is the product of this set, whose production is dependent on DEPENDENCIES, and the process of production is stated in RULE.<br />
Makefile usually starts with the ultimate product of the whole project and is followed by the set for producing the dependency files using the same structure. For example:</p>
<blockquote><p>myProduct: main.o file1.o file2.o<br />
gcc -o myProduct main.o file1.o file2.o</p>
<p>main.o: src/main.c src/file1.h<br />
gcc -c -o main.o src/main.c</p>
<p>file1.o: src/file1.c src/file1.h<br />
gcc -c -o file1.o src/file1.c</p>
<p>file2.o: src/file2.c src/file2.h<br />
gcc -c -o file2.o src/file2.c</p></blockquote>
<p>Good thing about make is that it can do incremental compiling and linking based upon the files&#8217; timestamp information.<br />
Next thing to know is about variables. make allows the use of variables to ease writing large files. The syntax is really easy. Just declare a variable name followed by an equal sign and then arbitrarily long string of characters. Then, to refer to that variable use ${variable-name}. Concatanation of variable values is possible using plus (+) sign. for example:</p>
<blockquote><p>MY_VAR = hello there<br />
ANOTHER_VAR += how are you</p></blockquote>
<p>There are also some string manipulation functions available for substituting, sorting etc. Substitution can be used to automatically generate header and object file names from the source file names. For example:</p>
<blockquote><p>SRC_FILES=main.c file1.c file2.c<br />
OBJ_FILES=$(patsubst %.c, %.o, ${SRC_FILES})<br />
DEP_FILES=$(patsubst %.c, %.dep, ${SRC_FILES})</p></blockquote>
<p>Next interesting thing is pattern matching characters provided by GNU make. These characters can be used to avoid repeatedly write similar commands and rules. Consider:</p>
<blockquote><p>CFLAGS = -c -g<br />
%.o:%.c<br />
gcc ${CFLAGS} -o $@ $</p></blockquote>
<p>Here, first the necessary switches for compiling are kept in a variable. This allows changing of switches without having to modify all the commands in the makefile. Next the interesting part begins. The command %.o:%.c indicates how .o files have to be produced from .c files in general. And then the rule to produce is given in the line below. Where we use some more predefined characters of make. $@ indicates the left hand side pattern matching (i.e. %.o) and $ means the right hand side pattern matching characters (i.e. %.c). Therefore, for each object file (.o) make will use this generic command and create respective .o files from each .c file. However, to find these .c files, make just checks the current directory. If the source files are in some other directory, then we are in trouble. But, the predefined VPATH variable is the solution. It provides make with the listing of directories that it needs to include in its search path. So, we should write VPATH = src, to make MAKE search in src folder also for source files.<br />
Dependency check is also a very powerful feature of MAKE, but I will study them a li&#8217;l bit more before writing anything about them.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Notepad++ 5.5.0]]></title>
<link>http://netvietnam.org/2009/09/21/notepad-5-5-0/</link>
<pubDate>Mon, 21 Sep 2009 13:14:16 +0000</pubDate>
<dc:creator>Nhân Mã</dc:creator>
<guid>http://netvietnam.org/2009/09/21/notepad-5-5-0/</guid>
<description><![CDATA[Notepad++ là trình biên tập mã nguồn miễn phí (và là công cụ thay thế cho Notepad), hỗ trợ nhiều ngô]]></description>
<content:encoded><![CDATA[Notepad++ là trình biên tập mã nguồn miễn phí (và là công cụ thay thế cho Notepad), hỗ trợ nhiều ngô]]></content:encoded>
</item>
<item>
<title><![CDATA[compilation error : undefined reference to 'main']]></title>
<link>http://getch.wordpress.com/2009/09/18/compilation-error-undefined-reference-to-main/</link>
<pubDate>Fri, 18 Sep 2009 13:58:06 +0000</pubDate>
<dc:creator>manoj1987</dc:creator>
<guid>http://getch.wordpress.com/2009/09/18/compilation-error-undefined-reference-to-main/</guid>
<description><![CDATA[I have been learning C back from basics. Recently i tried out a simple program myHello.c , which con]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p style="text-align:center;"><span style="color:#333300;"><img class="size-medium wp-image-1439 aligncenter" title="Question" src="http://getch.wordpress.com/files/2009/09/faq.jpg?w=282" alt="Question" width="87" height="93" /></span></p>
<p style="text-align:center;"><span style="color:#333300;"></p>
<p></span></p>
<p style="text-align:left;"><span style="color:#333300;">I have been learning C back from basics. Recently i tried out a simple program myHello.c , which contained the following code :</span></p>
<p>1.<span style="color:#800000;"> //myHello.c</span></p>
<p>2.<span style="color:#800000;"> #include&#8221;hello.h&#8221;</span></p>
<p>3.<span style="color:#800000;"> int main(void)</span></p>
<p>4. <span style="color:#800000;">{</span><span style="color:#333300;"> </span><span style="color:#333300;"></p>
<p>5. <span style="color:#800000;">hello(&#8220;WORLD&#8221;);</span></p>
<p>6. <span style="color:#800000;">return 0;</span></p>
<p>7.<span style="color:#800000;"> }</span></span></p>
<p><span style="color:#333300;">next, i created </span><span style="color:#800000;">hello.h</span> <span style="color:#333300;">that contained the following code :</span></p>
<p><span style="color:#333300;"> 1. <span style="color:#800000;">//hello.h</span></p>
<p>2. <span style="color:#800000;">void hello(const char* name);</span></span></p>
<p><span style="color:#333300;">Finally i created helloFunc.c that contained the declaration for hello() :</span></p>
<p>1. <span style="color:#800000;">//helloFunc.c</span></p>
<p>2. <span style="color:#800000;">#include&#60;stdio.h&#62;</span></p>
<p>3. <span style="color:#800000;">#include&#8221;hello.h&#8221;</span></p>
<p>4.<span style="color:#800000;"> void hello(const char* name)</span></p>
<p>5. <span style="color:#800000;">{</span></p>
<p>6. <span style="color:#800000;">printf(&#8220;hello, %s \n&#8221;,name);</span></p>
<p>7. <span style="color:#800000;">}</span></p>
<p><span style="color:#333300;">I compiled the C sources as follow :</span></p>
<p><span style="color:#800000;">gcc -Wall myHello.c helloFunc.c -o newHello</span></p>
<p><span style="color:#333300;">I received the following error :</span></p>
<p><span style="color:#800000;">/usr/lib/gcc/i486-linux-gnu-4.3.3/../../../../libcrt1.o: In function &#8216;_start&#8217; :</p>
<p></span><span style="color:#800000;">/build/buildd/libc-2.9/csu/../sysdeps/i386/elf/start.S:115: undefined reference to &#8216;main&#8217;</span></p>
<p><span style="color:#800000;">collect2: ld returned 1 exit status</span></p>
<p style="text-align:left;"><span style="color:#003366;">Solution:</span></p>
<p style="text-align:left;"><span style="color:#333300;">just use a</span> <span style="color:#ff6600;">Makefile</span>.</p>
<p><span style="color:#333300;">You need to build them using:</span></p>
<p><span style="color:#ff6600;">gcc -c helloFunc.c -o helloFunc.o</p>
<p>gcc -c myHello.c -o myHello.o</p>
<p>gcc myHello.o helloFunc.o -o hello</span></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Makefile em detalhes]]></title>
<link>http://processolinux.wordpress.com/2009/08/26/makefile-em-detalhes/</link>
<pubDate>Wed, 26 Aug 2009 03:48:14 +0000</pubDate>
<dc:creator>eddye</dc:creator>
<guid>http://processolinux.wordpress.com/2009/08/26/makefile-em-detalhes/</guid>
<description><![CDATA[Navegando na net achei este ótimo artigo sobre makefile, nem muito complexo nem muito básico, e aind]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Navegando na net achei este ótimo artigo sobre makefile, nem muito complexo nem muito básico, e ainda trata sobre latex <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> .</p>
<p>Introdução ao make:<br />
<a href="http://jfmitre.com/2009/06/uma-introducao-ao-comando-make.html">http://jfmitre.com/2009/06/uma-introducao-ao-comando-make.html</a></p>
<p>makefile detalhado:<br />
<a href="http://jfmitre.com/2009/06/apresentando-um-makefile-em-detalhes.html">http://jfmitre.com/2009/06/apresentando-um-makefile-em-detalhes.html</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Makefile performance: built-in rules]]></title>
<link>http://blog.electric-cloud.com/2009/08/19/makefile-performance-built-in-rules/</link>
<pubDate>Wed, 19 Aug 2009 14:50:19 +0000</pubDate>
<dc:creator>Eric Melski</dc:creator>
<guid>http://blog.electric-cloud.com/2009/08/19/makefile-performance-built-in-rules/</guid>
<description><![CDATA[Like any system that has evolved over many years, GNU Make is rife with appendages of questionable u]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Like any system that has evolved over many years, GNU Make is rife with appendages of questionable utility.  One area this is especially noticeable is the collection of <i>built-in rules</i> in gmake.  These rules make it possible to do things like compile a C source file to an executable without even having a makefile, or compile and link several source files with a makefile that simply names the executable and each of the objects that go into it.</p>
<p>
But this convience comes at a price.  Although some of the built-in rules are still relevant in modern environments, many are obsolete or uncommonly used at best.  When&#8217;s the last time you compiled Pascal code, or used SCCS or RCS as your version control system?  And yet every time you run a build, gmake must check every source file against each of these rules, on the off chance that one of them might apply.  <b>A simple tweak to your GNU Make command-line is all it takes to get a performance improvement of up to 30% out of your makefiles</b>.  Don&#8217;t believe me?  Read on.<br />
<!--more-->
</p>
<p>
Let&#8217;s look at a trivial example:
</p>
<p><div style="background:#deffde;border:dashed thin;">
<pre>
all: input
	@echo done
</pre>
</div>
<p>
Touch the file <i>input</i>, then run gmake with the <i>-d</i> option, so you can see as gmake tries each of the built-in rules.  GMake will ramble on for hundreds of lines, as you&#8217;ll see.  Here&#8217;s a sample of that output:</p>
<div style="background:#dee7f7;border:dashed thin;">
<pre>
Considering target file `all'.
 File `all' does not exist.
  Considering target file `input'.
   Looking for an implicit rule for `input'.
   <i>... many lines omitted ... </i>
   Trying pattern rule with stem `input'.
   Trying implicit prerequisite `RCS/input,v'.
   Trying pattern rule with stem `input'.
   Trying implicit prerequisite `RCS/input'.
   Trying pattern rule with stem `input'.
   Trying implicit prerequisite `s.input'.
   Trying pattern rule with stem `input'.
   Trying implicit prerequisite `SCCS/s.input'.
   Trying pattern rule with stem `input'.
   <i>... hundreds more lines omitted ...</i>
  No implicit rule found for `input'.
  Finished prerequisites of target file `input'.
</pre>
</div>
<p>
What&#8217;s going on here?  Well, we didn&#8217;t provide a rule describing how to build the file <i>input</i>, so gmake is checking to see if any of the built-in rules could be used to generate it.  Of course none of them do, so this is all wasted effort.  Lucky for us, a single command-line option is all you need to tell gmake not to bother with the default built-in rules:  <i>-r</i>.  Try that trivial makefile again, this time with <i>-d -r</i>:
</p>
<p><div style="background:#dee7f7;border:dashed thin;">
<pre>
Considering target file `all'.
 File `all' does not exist.
  Considering target file `input'.
   Looking for an implicit rule for `input'.
   No implicit rule found for `input'.
   Finished prerequisites of target file `input'.
</pre>
</div>
<p>
All the extra nonsense is gone!  And even on this toy example, there is a measurable performance improvement:  originally, this makefile runs in about 0.015s (average over three runs); with the built-in rules disabled, it&#8217;s just 0.012s.  But I can see you won&#8217;t be convinced by such a trivial example.  So let&#8217;s try something a bit bigger:
</p>
<p><div style="background:#deffde;border:dashed thin;">
<pre>
SOURCES:=$(wildcard sub/*.x)
TARGETS:=$(SOURCES:.x=.o)
all: $(TARGETS)
        @echo done

%.o: %.x
        @echo $@
</pre>
</div>
<p>
The directory <i>sub</i> contains 15,000 files named 00001.x through 15000.x.  With the built-in rules (and redirecting output to /dev/null), this makefile runs in about 60.2s; without the built-in rules, 42.9s &#8212; <b>28% faster</b>.
</p>
<p>
Finally, let&#8217;s try this optimization on a real build.  I built one component of the Accelerator project completely, then ran &#8220;no-op&#8221; builds (ie, no work to be done, just checking that everything is up-to-date).  With built-in rules, this took 6.0s; without, it took 5.2s &#8212; <b>13% faster</b>:
</p>
<table rules="none" cellpadding="4">
<caption align="bottom"><font size="-1">Test results (shorter is better)</font></caption>
<tr>
<td>Large test, with built-ins:</td>
<td>
<div style="background:#85aef7;width:240px;">60.2s</div>
</td>
</tr>
<tr>
<td>Large test, no built-ins;</td>
<td>
<div style="background:#a3ffa3;width:172px;">42.9s</div>
</td>
</tr>
<tr>
<td>No-op build, with built-ins:</td>
<td>
<div style="background:#85aef7;width:24px;">6.0s</div>
</td>
</tr>
<tr>
<td>No-op build, no built-ins:</td>
<td>
<div style="background:#a3ffa3;width:21px;">5.2s</div>
</td>
</tr>
</table>
<p>
Now, if your build actually relies on built-in rules obviously you can&#8217;t simply disable them.  But you could explicitly define just those rules that you require and disable the rest.  For example, if you use the default <i>%.o: %.cpp</i> rule, you could add just that rule to your makefiles:
</p>
<p><div style="background:#deffde;border:dashed thin;">
<pre>
%.o: %.cpp
	$(COMPILE.cpp) $(OUTPUT_OPTION) $&#60;
</pre>
</div>
<p>
Once you&#8217;ve done that, you can add <i>-r</i> to your command-line and enjoy the benefits.  If you go this route, you can see the list of built-in rules by running <i>gmake -p</i>; the built-ins are marked as &#8220;built-in&#8221; in that output.
</p>
<p><h3>Conclusion</h3>
</p>
<p>
Disabling gmake&#8217;s array of built-in rules is an easy way to squeeze extra performance out of your makefiles, particularly on large builds and on no-op builds.  All you have to do is add <i>-r</i> to your commmand-line.  (NB: If you prefer more descriptive command-lines, you can use <i>&#8211;no-builtin-rules</i> instead!)
</p>
<p><hr />
This article is the latest of several looking at different aspects of makefile performance.  If you liked this article, you may enjoy the others in the series:</p>
<ul>
<li><a href="http://blog.electric-cloud.com/2009/03/18/it-goes-to-11/">Makefile performance: recursive make</a></li>
<li><a href="http://blog.electric-cloud.com/2009/03/23/makefile-performance-shell/">Makefile performance: $(shell)</a></li>
<li><a href="http://blog.electric-cloud.com/2009/04/13/makefile-performance-pattern-specific-variables/">Makefile performance: pattern-specific variables</a></li>
<li>Makefile performance: built-in rules (this post)</li>
</ul>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Philosophy of Make]]></title>
<link>http://aikhan.wordpress.com/2009/08/16/philosophy-of-make/</link>
<pubDate>Sun, 16 Aug 2009 15:27:39 +0000</pubDate>
<dc:creator>aikhan</dc:creator>
<guid>http://aikhan.wordpress.com/2009/08/16/philosophy-of-make/</guid>
<description><![CDATA[Introduction. In this blog post I will try to explain to you the anatomy of a typical make file, as ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><h2>Introduction.</h2>
<p>In this blog post I will try to explain to you the anatomy of a typical make file, as most of the new comers to Unix/Linux arena often find it difficult comprehend the philosophy behind the make &#38; they often do get imitated by its weird looking syntax and structure. We’ll first describe why a make is needed and then I will highlight the basic structure and syntax of a make file and will then we will wrap up the post by presenting some examples to make your concepts clear.</p>
<h2>The case for make</h2>
<p>Make is a tool that is used to control the build process of your software.</p>
<p>Make automates what is built, how it gets built, when it gets built etc. A makefile is a place where you store all of your commands to build the software.</p>
<p>Similar concept exists in the Java world in shape of Ant and more recently Maven that even provide more functionality and flexibility to compile, test &#38; even deploy your applications through simple xml files.</p>
<p>Suppose you have multiple source files that require long &#38; complex compiler invocations, “make” simplifies this by storing these commands in a single makefile so that they can be managed from a single location. You can also specify which files &#38; directories you want create and delete based upon certain circumstances. Like for example you want all your library files to be compiled into the lib folder of the installation directory. “Make” also makes it easier for other people who want to compile and execute your application; in place of creating huge documentation on how to build your software you can just tell them to run make &#38; it would take care of the rest.</p>
<p>Finally as the final argument in favor of make I think it really speeds up the build process of your application. Make is intelligent enough to recognize which files have changed and thus only builds those files whose components have changed. Plus makefiles also constitute a database of dependency information allowing you to automatically verify that all the files for the build are present.</p>
<h2>Anatomy of a MakeFile</h2>
<p>A make file is a simple text file containing rules that tell make what to build and how to build it. A makefile consists of number of rules, at its basic the general structure of make looks likes this:-</p>
<p># Comments use the hash symbol</p>
<p>Target : dependency [dependency] [ … ]</p>
<p>Command 1</p>
<p>Command</p>
<p>…</p>
<p>…</p>
<p>Command n</p>
<p>Target is what we are trying to build a binary or an object file. Dependency is a list of one or more files required for the compilation, commands are the steps either compiler invocations or shell scripts required to create the target.</p>
<p>The spaces before commands are TABS &#38; should be used as such, empty spaces would not suffice in their place &#38; you would get the missing separator error. This is the most common problem people new to make get stucked with.</p>
<h2><strong>Example of a Make File<br />
</strong></h2>
<p>edit : main.o kbd.o command.o display.o \</p>
<p>insert.o search.o files.o utils.o</p>
<p>cc -o edit main.o kbd.o command.o display.o \</p>
<p>insert.o search.o files.o utils.o</p>
<pre>main.o : main.c defs.h</pre>
<pre>              cc -c main.c</pre>
<pre>kbd.o : kbd.c defs.h command.h</pre>
<pre>              cc -c kbd.c</pre>
<pre>command.o : command.c defs.h command.h</pre>
<pre>              cc -c command.c</pre>
<pre>display.o : display.c defs.h buffer.h</pre>
<pre>              cc -c display.c</pre>
<pre>insert.o : insert.c defs.h buffer.h</pre>
<pre>              cc -c insert.c</pre>
<pre>search.o : search.c defs.h buffer.h</pre>
<pre>              cc -c search.c</pre>
<pre>files.o : files.c defs.h buffer.h command.h</pre>
<pre>              cc -c files.c</pre>
<pre>utils.o : utils.c defs.h</pre>
<pre>              cc -c utils.c</pre>
<pre>clean :</pre>
<pre>      rm edit main.o kbd.o command.o display.o \                               
      insert.o search.o files.o utils.o</pre>
<p>Two long lines are split into two by using backslash-newline. This make file will create an executable “edit”.</p>
<p>To compile the program simply just type make on the command prompt.</p>
<p>This make file has 10 rules. The first target edit is the default target which is the binary we are trying to create. Edit has eight dependencies from main.o to utils.o, all of these files must exist to create the edit binary. The next line is the command that make executes to actually create the binary. Here make would actually build the executable from all these object files that are named .o.</p>
<p>When make encounters a dependency and it does not exists make executes the command to build it &#38; if the dependency has further dependencies make tries to find them &#38; if they does not exist make tries to build them using the command specified and so likewise make is able to traverse through all of the dependencies if present and build the software smoothly.</p>
<p>Clean target as you can see is the simple command that removes all the object files and as well as the final binary using the rm command.</p>
<h3>Phony Targets</h3>
<p>A phony target is one that is not really the name of a file. It is just a name for some commands to be executed when you make an explicit request. There are two reasons to use a phony target: to avoid a conflict with a file of the same name, and to improve performance.</p>
<p>Like for example there is a file named clean it would be disregarded by make. Phony targets are defined like this in a make file for example</p>
<p>.PHONY : clean zip</p>
<p>rm abc.o xyz</p>
<p>zip : clean</p>
<p>zip abc.zip *.c *.h Makefile</p>
<p>There are a lot of command line arguments that make can take the following is a short list of useful command options.</p>
<p>-f file                         Read the file name file instead of standard names</p>
<p>-n                         Display the commands make would executes without actually executing them</p>
<p>-s                        Execute silently ie not printing the commands make executes</p>
<p>-w                        print directory names when make changes directory</p>
<p>-r                         disable all of makes built-in rules.</p>
<p>-d                         print lots of debugging information</p>
<p>-k                         keep executing even if one target fails to build.</p>
<p>-jN                        Run N commands in parallel, where n is an non-zero integer.</p>
<p>More exhaustive list can be found at <a href="http://www.gnu.org/software/make/manual/make.html#Options-Summary">http://www.gnu.org/software/make/manual/make.html#Options-Summary</a></p>
<h2>Variables</h2>
<p>To simplify editing and maintenance make allows us to use variables. There are four kinds of variables</p>
<ol>
<li>User defined variables</li>
<li>Environment variables</li>
<li>Automatic variables and</li>
<li>Pre-defined variables</li>
</ol>
<h3>User-Defined Variables</h3>
<p>We define variables using the general form:</p>
<p>VARNAME = value [ … ]</p>
<p>It is a convention to use upper case letters for variables names, to obtain a variables value we just parenthesize the variable and add a dollar sign as a prefix.</p>
<p>There are two kinds of variables in “make” simply expanded variables and recursively expanded variables. Recursively expanded variables as the name suggest expands variables within variables until there are no further variables. For example</p>
<p>HOME_DIR = /home/asad</p>
<p>DEV_DIR = $(HOME-DIR)/development</p>
<p>PROJ_DIR = $(HOME-DIR)$(DEV-DIR)/project</p>
<p>SRC_DIR = $(HOME-DIR)$(DEV-DIR)$(PROJ_DIR)/src</p>
<p>If you use SRC_DIR variable somewhere all of the variables would get expanded.</p>
<p>Simply expanded variables are scanned once where they are defined and all embedded variable references are immediately resolved. Syntax is slightly different</p>
<p>CC := gcc</p>
<p>CC += -g</p>
<p>This would result in gcc –g when resolved.</p>
<p>If you consider using recursively expanded variables for this for example</p>
<p>CC = gcc</p>
<p>CC = $(CC) – g</p>
<p>We would get stuck in an infinite loop as $(CC) would keep on getting resolved to the same expression $(CC) &#38; make would throw an error.</p>
<h2>Environment Variables</h2>
<p>Every environment variable that make sees when it starts up is transformed into a make variable with the same name and value. However, an explicit assignment in the makefile, or with a command argument, overrides the environment. $(HOME) variable for example can be used in make to refer to the users home directory.</p>
<h2>Automatic Variables</h2>
<p>Automatic variables are those variables whose value is evaluated each time a rule is executed, based on target and dependencies of that rule. Automatic variables are used to create pattern rules, patterns are generic instructions on how to compile an arbitrary .c file to its corresponding .o file.</p>
<p>Here is a partial list of automatic variables</p>
<p>$@                        The file name of the target of the rule.</p>
<p>$&#60;                        The name of the first prerequisite/dependency.</p>
<p>$?                        The names of all the prerequisites that are newer than the target, with spaces between them.</p>
<p>$*                         The basename (or stem) of a filename.</p>
<p>$^                        Expands to a space-delimited list of all of a rules depedencies.</p>
<p>$(@D)                        The directory part of targets path name, if named target is in the sub-directory.</p>
<p>$(@F)                        The file part of targets path name, if named target is in the sub-directory.</p>
<p>For an exhaustive list please visit</p>
<p><a href="http://www.gnu.org/software/make/manual/make.html#Automatic-Variables">http://www.gnu.org/software/make/manual/make.html#Automatic-Variables</a></p>
<p>example:</p>
<p>CFLAGS := -g</p>
<p>CC := gcc</p>
<p>.c .o:</p>
<p>$(CC) $CFLAGS –c $* .c</p>
<p>lock: lock.c</p>
<p>$(CC) $(CFLAGS) $&#60; -o $@</p>
<p>for each filename ending in .c make would create an object file ending with .o, while executing $&#60; would be replace with lock.c similarly target name $@ will be replaced by lock.</p>
<h2>Pre-Defined Variables</h2>
<p>These are the variables that as the name suggests are predefined by make. A few of them are listed below.</p>
<p>AR                        Archive-maintaining program; default `ar&#8217;.</p>
<p>AS                        Program for compiling assembly files; default `as&#8217;.</p>
<p>CC                        Program for compiling C programs; default `cc&#8217;.</p>
<p>CO                        Program for checking out files from RCS; default `co&#8217;.</p>
<p>CXX                        Program for compiling C++ programs; default `g++&#8217;.</p>
<p>CO                         Program for extracting a file from RCS; default `co&#8217;.</p>
<p>CPP                        Program for running the C preprocessor, with results to standard output; default `$(CC) -E&#8217;.</p>
<p>RM                        Command to remove a file; default `rm -f&#8217;.</p>
<p>ARFLAGS            Flags to give the archive-maintaining program; default `rv&#8217;.</p>
<p>ASFLAGS            Extra flags to give to the assembler (when explicitly invoked on a `.s&#8217; or `.S&#8217; file).</p>
<p>CFLAGS            Extra flags to give to the C compiler.</p>
<p>For an exhaustive list please see</p>
<p><a href="http://www.gnu.org/software/make/manual/make.html#Implicit-Variables">http://www.gnu.org/software/make/manual/make.html#Implicit-Variables</a></p>
<h2>Conditional Statements</h2>
<p>Conditional expressions can be applied to a make file so that parts of make file execute or not based on certain conditions. Generic syntax is as follows</p>
<p><em>conditional-directive</em></p>
<p><em>text-if-true</em></p>
<p>else</p>
<p><em>text-if-false</em></p>
<p>endif</p>
<p>The following example of a conditional tells make to use one set of libraries if the CC variable is `gcc&#8217;, and a different set of libraries otherwise. It works by controlling which of two command lines will be used as the command for a rule. The result is that `CC=gcc&#8217; as an argument to make changes not only which compiler is used but also which libraries are linked.</p>
<p>libs_for_gcc = -lgnu</p>
<p>normal_libs =</p>
<p>foo: $(objects)</p>
<p>ifeq ($(CC),gcc)</p>
<p>$(CC) -o foo $(objects) $(libs_for_gcc)</p>
<p>else</p>
<p>$(CC) -o foo $(objects) $(normal_libs)</p>
<p>endif</p>
<p>This conditional uses three directives: one ifeq, one else and one endif.</p>
<h2>Last Example</h2>
<p>In the last example I would like to show you how to create install, dist and uninstall targets that you can most probably use while distributing your applications.</p>
<p>Hello: hello.c</p>
<p>install : hello</p>
<p>install $&#60; $(HOME)</p>
<p>.PHONY : dist unistall</p>
<p>dist :</p>
<p>$(RM) hello *.o core</p>
<p>tar czvf hello.tar.gz hello.c Makefile</p>
<p>uninstall:</p>
<p>$(RM) $(HOME)/hello</p>
<p>and you can use make install, make dist &#38; make uninstall commands for respective functions.</p>
<p>With this I think we should wrap up our tutorial on make. This is not a fully exhaustive tutorial but it would place you on the right grounds &#38; will get you started with make hopefully. If you have any questions please don’t hesitate to ask and If you want to know more about specific details &#38; I don’t impress you much you can always access the online documentation at <a href="http://www.gnu.org/software/make/manual/">http://www.gnu.org/software/make/manual/</a>.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Friday Fun: Generating Fibonacci Numbers with GNU Make]]></title>
<link>http://blog.electric-cloud.com/2009/08/14/friday-fun-generating-fibonacci-numbers-with-gnu-make/</link>
<pubDate>Fri, 14 Aug 2009 21:01:19 +0000</pubDate>
<dc:creator>Eric Melski</dc:creator>
<guid>http://blog.electric-cloud.com/2009/08/14/friday-fun-generating-fibonacci-numbers-with-gnu-make/</guid>
<description><![CDATA[Nobody would ever claim that GNU Make is a general purpose programming language, but with a little w]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Nobody would ever claim that GNU Make is a general purpose programming language, but with a little work, we can coerce it into generating <a href="http://en.wikipedia.org/wiki/Fibonacci_number">Fibonacci numbers</a> for us.  Why bother?  <b>Because we can</b>.<br />
<!--more--></p>
<p>
First, let me give a simple demonstration.  Here&#8217;s the makefile:
</p>
<p><pre class="brush: python;">
16:=x x x x x x x x x x x x x x x x
input_int:=$(foreach a,$(16),$(foreach b,$(16),$(foreach c,$(16),$(16))))
decode=$(words $1)
encode=$(wordlist 1,$1,$(input_int))
decr=$(wordlist 2,$(words $1),$1)
decr2=$(wordlist 3,$(words $1),$1)
eq=$(filter $(words $1),$(words $2))
g0:=
g1:=x

fib=$(if $(filter-out undefined,$(origin f$1)),\
           $(f$1),\
           $(if $(call eq,$1,$(g0)),\
	          $(eval f$1:=$(g0))$(g0),\
                  $(if $(call eq,$1,$(g1)),\
                         $(eval f$1:=$(g1))$(g1),\
                         $(eval f$1:=$(call fib,$(call decr2,$1)) $(call fib,$(call decr,$1)))$(f$1))))

print=$(if $1,\
$(call print,$(call decr,$1))$(info $(call decode,$1): $(call decode,$(f$1))),\
$(info 0: 0))

%:
	@:$(if x$(call fib,$(call encode,$@)),$(call print,$(call encode,$@)),)
</pre>
</p>
<p>
Invoke it with a single argument, the length of the sequence to generate:
</p>
<p><div style="background:#deffde;border:dashed thin;width:80ex;">
<pre>ericm@chester:~/blog/fibonacci$ gmake 10
0: 0
1: 1
2: 1
3: 2
4: 3
5: 5
6: 8
7: 13
8: 21
9: 34
10: 55</pre>
</div>
<p>
Nifty!
</p>
<p>
Now, although this demonstration is not especially practical, it does make use of a few advanced gmake concepts:  arithmetic; caching dynamically generated variables; and recursive functions.
</p>
<p><h3>Arithmetic</h3>
</p>
<p>
None of this would be possible without support for arithmetic operations.  Here&#8217;s a brief explanation of how this works (for more details, the Mr. Make article <a href="http://www.cmcrossroads.com/content/view/6504/268/">Learning GNU Make Functions with Arithmetic</a>):  we use strings of space-separated <i>x</i> characters to represent values; for example, the number five is represented as <i>x x x x x</i>.  To add numbers together, we concatenate the string representations, and to subtract, we trim the appropriate number of <i>x</i>&#8217;s from the string.  To convert from the string representation to the numeric value, we just count the number of <i>x</i>&#8217;s in the string, using the <i>$(words)</i> builtin, and finally, to convert from the numeric value to the string representation we extract the appropriate number of <i>x</i>&#8217;s from a canonical string that just has a series of several thousand <i>x</i>&#8217;s.
</p>
<p>
This is inefficient, in both memory and time.  The representation of a number requires double the value in bytes, so the number 50,000 requires 100,000 bytes of storage.  Converting to a numeric value from the string representation is a linear operation that scales with the magnitude of the value &#8212; the bigger the value, the longer the conversion takes.  These factors together limit the range of numbers that you can practically work with using this scheme, although it works fine for small values (up to around 10,000 or so).  For the Fibonacci makefile, the inefficiencies mean that we can only generate the sequence out to about the 40th value.  At that point, gmake has already sucked up 1.4 GB of memory!
</p>
<p><h3>Caching dynamic values</h3>
</p>
<p>
Because it is time-consuming to compute Fibonacci numbers this way, we&#8217;d like to cache the results, so we don&#8217;t ever duplicate work.  But the values are dynamically generated.  For that matter, the variables themselves must be dynamically generated &#8212; we don&#8217;t know beforehand which Fibonacci numbers we&#8217;re going to have to compute.  So how do you dynamically generate variables and cache their values in gmake?  With <i>$(eval)</i>.  You can read all about it in another Mr. Make article, <a href="http://www.cmcrossroads.com/content/view/7382/268/">$(eval) and macro caching</a>.  In our Fibonacci makefile, you can see that as we determine each Fibonacci number, we invoke $(eval) to save the value.  The <i>fib</i> function is then setup to first check for the existence of a cached value and only bother with the computation if there is no cache entry.
</p>
<p><h3>Recursive functions</h3>
</p>
<p>
The Fibonacci sequence is defined recursively as <i>f(n) = f(n &#8211; 1) + f(n &#8211; 2)</i>, so naturally we use a recursive function in our implementation.  The <i>fib</i> function takes one argument, the index of the Fibonacci number to compute, encoded using the scheme described above.  After checking the cache, <i>fib</i> checks if the current index is either zero or one.  By convention, these Fibonacci numbers are defined to have value zero and one, respectively, so there is no need to compute them.  This also serves as a terminating condition so we don&#8217;t recurse infinitely.
</p>
<p>
If the current index is neither zero nor one, then <i>fib</i> calls itself recursively twice, to compute the two preceding Fibonacci values.  The recursive results are combined, cached, and returned as the overall result of the <i>fib</i> function itself.
</p>
<p><h3>Conclusion</h3>
</p>
<p>
I&#8217;m surprised at how quickly gmake computes the sequence, actually.  On my laptop, gmake computes the first 30 values in a fraction of a second.  After that the inefficiencies in the arithmetic operations really come into play:  it takes about 3.5 seconds to compute 35 values, and 25 seconds to compute 39 values.  Still, considering the limitations of the environment, I think it&#8217;s impressive that it works at all.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Fundstück - Direkt nutzbares LaTeX-Makefile]]></title>
<link>http://kapaneus.wordpress.com/2009/08/12/fundstuck-direkt-nutzbares-latex-makefile/</link>
<pubDate>Wed, 12 Aug 2009 17:24:24 +0000</pubDate>
<dc:creator>kapaneus</dc:creator>
<guid>http://kapaneus.wordpress.com/2009/08/12/fundstuck-direkt-nutzbares-latex-makefile/</guid>
<description><![CDATA[Durch beiläufiges, nicht-zielgerichtetes Umherlesen finden sich erstaunliche, mithin direkt produkti]]></description>
<content:encoded><![CDATA[Durch beiläufiges, nicht-zielgerichtetes Umherlesen finden sich erstaunliche, mithin direkt produkti]]></content:encoded>
</item>
<item>
<title><![CDATA[Rules with Multiple Outputs in GNU Make]]></title>
<link>http://blog.electric-cloud.com/2009/08/04/rules-with-multiple-outputs-in-gnu-make/</link>
<pubDate>Wed, 05 Aug 2009 02:49:25 +0000</pubDate>
<dc:creator>Eric Melski</dc:creator>
<guid>http://blog.electric-cloud.com/2009/08/04/rules-with-multiple-outputs-in-gnu-make/</guid>
<description><![CDATA[I recently wrote an article for CM Crossroads exploring various strategies for handling rules that g]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I recently wrote an article for CM Crossroads exploring various strategies for handling rules that generate multiple output files in GNU make.  If you&#8217;ve ever struggled with this problem, you should <a href="http://www.cmcrossroads.com/cm-articles/cm-basics/12905-rules-with-multiple-outputs-in-gnu-make">check out the article</a>.  I don&#8217;t want to spoil the exciting conclusion, but it turns out that the only way to really correctly capture this relationship in GNU make syntax is with pattern rules.  That&#8217;s great if your input and output files share a common stem (eg, &#8220;parser&#8221; in parser.i, parser.c and parser.h), but if your files don&#8217;t adhere to that convention, you&#8217;re stuck with one of the alternatives, each of which have some strange caveats and limitations.</p>
<p>
Here&#8217;s a question for you:  if ElectricAccelerator had an extension that allowed you to explicitly mark a non-pattern rule as having multiple outputs, would you use it?  For example:
</p>
<p><div style="background:#deffde;border:dashed thin;">
<pre>
<font color="red">#pragma multi</font>
something otherthing: input
	@echo Generating something and otherthing from input...
</pre>
</div>
<p>
What do you think?  Comments encouraged.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Sandwich makefile]]></title>
<link>http://overbenny.wordpress.com/2009/07/25/sandwich-makefile/</link>
<pubDate>Fri, 24 Jul 2009 23:51:53 +0000</pubDate>
<dc:creator>overbenny</dc:creator>
<guid>http://overbenny.wordpress.com/2009/07/25/sandwich-makefile/</guid>
<description><![CDATA[Sandwich webcomic from xkcd.com If you like this comic from xkcd.com, you are now able to reproduce ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><div id="attachment_79" class="wp-caption aligncenter" style="width: 370px"><a href="http://xkcd.com/149/"><img class="size-full wp-image-79" title="sandwich" src="http://overbenny.wordpress.com/files/2009/07/sandwich.png" alt="Sandwich webcomic from xkcd.com" width="360" height="299" /></a><p class="wp-caption-text">Sandwich webcomic from xkcd.com</p></div>
<p>If you like this comic from <a href="http://xkcd.com">xkcd.com</a>, you are now able to reproduce the conversation in your shell. You only need this makefile:<br />
<code style="border:1px solid #cccccc;background-color:#eeeeee;display:block;color:#666688;font-size:1.2em;margin:1em 1em 1.5em 1.5em;padding:.4em .5em;">me a:<br />
&#160;&#160;&#160;&#160;@true<br />
sandwich.:<br />
ifeq ($(shell if touch / 2&#62; /dev/null; then id -u; fi),0)<br />
&#160;&#160;&#160;&#160;@echo "Okay."<br />
else<br />
&#160;&#160;&#160;&#160;@echo "What? Make it yourself."<br />
endif<br />
.PHONY: me a sandwich.</code><br />
Download the <a href="http://bazaar.launchpad.net/%7Ebdrung/%2Bjunk/sandwich/download/head%3A/makefile-20090724214206-syr49vgfm7zl18wf-1/Makefile">Makefile</a> from my <a href="https://code.launchpad.net/~bdrung/+junk/sandwich">sandwich</a> branch or copy &#38; paste the text above into your preferred editor (you have to convert the spaces to tabs) and save it as Makefile. Then you can run &#8220;make me a sandwich.&#8221; in your terminal and see what happens.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Notepad++ 5.4.5]]></title>
<link>http://netvietnam.org/2009/07/15/notepad-5-4-5/</link>
<pubDate>Wed, 15 Jul 2009 12:23:02 +0000</pubDate>
<dc:creator>Nhân Mã</dc:creator>
<guid>http://netvietnam.org/2009/07/15/notepad-5-4-5/</guid>
<description><![CDATA[Notepad++ là trình biên tập mã nguồn miễn phí (và là công cụ thay thế cho Notepad), hỗ trợ nhiều ngô]]></description>
<content:encoded><![CDATA[Notepad++ là trình biên tập mã nguồn miễn phí (và là công cụ thay thế cho Notepad), hỗ trợ nhiều ngô]]></content:encoded>
</item>
<item>
<title><![CDATA[Notepad++ 5.4.4]]></title>
<link>http://netvietnam.org/2009/07/06/notepad-5-4-4/</link>
<pubDate>Mon, 06 Jul 2009 12:22:56 +0000</pubDate>
<dc:creator>Nhân Mã</dc:creator>
<guid>http://netvietnam.org/2009/07/06/notepad-5-4-4/</guid>
<description><![CDATA[Notepad++ là trình biên tập mã nguồn miễn phí (và là công cụ thay thế cho Notepad), hỗ trợ nhiều ngô]]></description>
<content:encoded><![CDATA[Notepad++ là trình biên tập mã nguồn miễn phí (và là công cụ thay thế cho Notepad), hỗ trợ nhiều ngô]]></content:encoded>
</item>
<item>
<title><![CDATA[Makefile Generator, version 2]]></title>
<link>http://justcheckingonall.wordpress.com/2009/06/24/makefile-generator-version-2/</link>
<pubDate>Wed, 24 Jun 2009 01:42:50 +0000</pubDate>
<dc:creator>JustChecking</dc:creator>
<guid>http://justcheckingonall.wordpress.com/2009/06/24/makefile-generator-version-2/</guid>
<description><![CDATA[genmake, the Not so Simple Makefile Generator Bash Script, is now hosted on Google Code (for older v]]></description>
<content:encoded><![CDATA[genmake, the Not so Simple Makefile Generator Bash Script, is now hosted on Google Code (for older v]]></content:encoded>
</item>
<item>
<title><![CDATA[Compilação de programas]]></title>
<link>http://ivanix.wordpress.com/2009/06/21/compilacao-de-programas/</link>
<pubDate>Mon, 22 Jun 2009 02:21:41 +0000</pubDate>
<dc:creator>Nix</dc:creator>
<guid>http://ivanix.wordpress.com/2009/06/21/compilacao-de-programas/</guid>
<description><![CDATA[Nesse post, vou falar sobre compilação de programas. É importante saber sobre compilação de programa]]></description>
<content:encoded><![CDATA[Nesse post, vou falar sobre compilação de programas. É importante saber sobre compilação de programa]]></content:encoded>
</item>

</channel>
</rss>
