Plaintext
Practical Auto-confiscation
Revision 1.6
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled
This work is licensed under a Creative Commons License
http://creativecommons.org/licenses/by-sa/
1.0/
Part-I Practical Auto-confiscation
Part-I
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled (Rev. 1.6) 1
Part-I Practical Auto-confiscation
Portability
• Is always an issue! When you hear “not in our company” someone is:
– Inexperienced – “It never happened to me”.
– Naive – “it won’t happen to me”.
• Eventually some code will need porting:
– Different processor (handheld, 64bit, etc.)
– Different compiler (gcc is too slow, you must use the new Wizbang-7).
– Another OS.
– New/old version of the same OS (NPTL anybody?)
• Unix crowd has learned this ages ago... “MS-camp” are learning it now.
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled (Rev. 1.6) 2
Part-I Practical Auto-confiscation
Strategy
• Sticking to standards will solve 90% of the problems:
Formal standards - POSIX + SUS, IETF, W3C, OMG
Portable free code - ACE, Qt/Gtk, etc.
• But those pesky 10% differences are not fun.
• We aim at the “last-mile” problem.
note
• If your project manager “selected” for you: COM, MFC, ADO, ...
• Than prepare to walk the full 100 miles :-(
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled (Rev. 1.6) 3
Part-I Practical Auto-confiscation
Tactics
• Portability of both code and build process.
• Tough requirements:
– Linear categorization (Linux/HPUX/Solaris/Windows) is naive.
Life are multi-valued:
kernel × processor × compiler × libraries.
– Should have minimal prerequisites on build host.
– Non-interactive builds should be possible.
– But user should be able to supply some options.
– Extensible (future proof :-)
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled (Rev. 1.6) 4
Part-I Practical Auto-confiscation
Example Scenario
Library interface luser.h # i f d e f LUSER H
# d e f i n e LUSER H
v o i d s h o u t ( c o n s t char ∗ msg ) ;
/ ∗ LUSER H ∗ /
# endif
Library implementation luser.c # i n c l u d e < l u s e r . h>
# i n c l u d e < s t d i o . h>
v o i d s h o u t ( c o n s t char ∗ msg )
{
p r i n t f ( ” S h o u t i n g on t h e l u s e r : % s\n ” , msg ) ;
}
A useful program lart.c # i n c l u d e < l u s e r . h>
i n t main ( )
{
s h o u t ( ” Watch my d i f f e r e n t i a l SCSI c a b l e ! ” ) ;
}
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled (Rev. 1.6) 5
Part-I Practical Auto-confiscation
Library Problems
• How a shared library is built:
gcc -shared ... But what if it’s not gcc?
• The library file name:
libuser.so? libuser.sl? libuser.dll?
• Pre-install usage:
Debugging, testing, etc. Before committing.
• How the run-time loader will find it:
LD LIBRARY PATH? SHLIB PATH? LIBPATH? PATH?
• Installation procedures:
Locations, ldconfig?
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled (Rev. 1.6) 6
Part-I Practical Auto-confiscation
More Problems
• Writing a makefile is easy.
• Writing a good makefile is hard:
– Maintenance targets (install, clean, distclean, dist, ...)
– Dependency tracking (per-file please).
– Recursive builds (and use the same make program).
– User install options (paths, names, ...)
• Writing a portable makefile is harder (tools location, names, ...)
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled (Rev. 1.6) 7
Part-I Practical Auto-confiscation
The Players
• Central tools:
libtool For handling shared/static libraries.
autoconf For build configuration (generates ./configure)
autoheader For code portability.
automake Write makefiles for us.
... Optional tools: gettext, regression testing, ...
• Each can be used separately but integrated operation is easier.
• They are not required on the final build host.
• The main input for autoconf, autoheader and automake is:
configure.ac 1
1 Used to be configure.in in older versions
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled (Rev. 1.6) 8
Part-I Practical Auto-confiscation
A Draft of configure.ac
• autoscan parses our project and creates configure.scan
# −∗− A u t o c o n f −∗−
# Process t h i s f i l e with autoconf to produce a configure s c r i p t .
AC PREREQ ( 2 . 6 1 )
AC INIT ( FULL−PACKAGE−NAME , VERSION , BUG−REPORT−ADDRESS)
AC CONFIG SRCDIR ( [ l u s e r . h ] )
AC CONFIG HEADER ( [ c o n f i g . h ] )
# Checks f o r p r o g r a m s .
AC PROG CC
# Checks f o r l i b r a r i e s .
# Checks f o r h e a d e r f i l e s .
# Checks f o r t y p e d e f s , s t r u c t u r e s , and c o m p i l e r c h a r a c t e r i s t i c s .
AC C CONST
# Checks f o r l i b r a r y f u n c t i o n s .
AC OUTPUT
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled (Rev. 1.6) 9
Part-I Practical Auto-confiscation
What in this file?
• configure.ac contains comments and m4 macros:
• The basic process is:
configure.ac =⇒ autoconf (m4 processing) =⇒ ./configure
• The first macro1 must be AC INIT... which expands to:
# ! / bin / sh
...
• The last macro must be AC OUTPUT which creates the outputs.
1 Except for AC PREREQ() which does not generate output
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled (Rev. 1.6) 10
Part-I Practical Auto-confiscation
configure.ac After Editing
• Our code is (almost) portable – no need for AC CONFIG
HEADER
# −∗− A u t o c o n f −∗−
# Process t h i s f i l e with autoconf to produce a configure s c r i p t .
AC PREREQ ( 2 . 6 1 )
AC INIT ( [ l u r s e r ] , [ 1 . 1 ] , [ oron@actcom . co . i l ] )
AC CONFIG SRCDIR ( [ l u s e r . h ] )
# Checks f o r p r o g r a m s .
AC PROG CC
# Checks f o r l i b r a r i e s .
# Checks f o r h e a d e r f i l e s .
# Checks f o r t y p e d e f s , s t r u c t u r e s , and c o m p i l e r c h a r a c t e r i s t i c s .
AC C CONST
# Checks f o r l i b r a r y f u n c t i o n s .
AC CONFIG FILES ( [ M a k e f i l e ] )
AC OUTPUT
• We can run autoconf now...
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled (Rev. 1.6) 11
Part-I Practical Auto-confiscation
First run of ./configure
• autoconf generated ./configure
• So we try it:
$ . / configure
checking f o r gcc . . . gcc
c h e c k i n g f o r C c o m p i l e r d e f a u l t o u t p u t f i l e name . . . a . o u t
c h e c k i n g w h e t h e r t h e C c o m p i l e r works . . . y e s
c h e c k i n g w h e t h e r we a r e c r o s s c o m p i l i n g . . . no
checking for s u f f i x of e x e c u t a b l e s . . .
checking for s u f f i x of o b j e c t f i l e s . . . o
c h e c k i n g w h e t h e r we a r e u s i n g t h e GNU C c o m p i l e r . . . y e s
checking whether gcc a c c e p t s −g . . . yes
c h e c k i n g f o r g c c o p t i o n t o a c c e p t ISO C89 . . . none n e e d e d
c h e c k i n g f o r an ANSI C−c o n f o r m i n g c o n s t . . . y e s
configure : creating . / config . status
config . s t a t u s : e r r o r : cannot find input f i l e : Makefile . in
• But something is missing...
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled (Rev. 1.6) 12
Part-I Practical Auto-confiscation
Outputs of ./configure
• ./configure won’t generate outputs without inputs :-)
• The generation pattern is1 :
Makefile.in =⇒ Makefile
config.h.in =⇒ config.h
foo.in =⇒ foo
• In our specific example we need only a Makefile.in.
• But instead of writing it – let’s call automake.
1 config.h is generated only if the AC CONFIG HEADER macro is used (not in our case).
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled (Rev. 1.6) 13
Part-I Practical Auto-confiscation
automake
• The basic process is:
Makefile.am =⇒ automake (perl processing) =⇒ Makefile.in
$ automake
c o n f i g u r e . a c : no p r o p e r i n v o c a t i o n o f AM INIT AUTOMAKE was f o u n d .
c o n f i g u r e . a c : You s h o u l d v e r i f y t h a t c o n f i g u r e . a c i n v o k e s AM INIT AUTOMAKE ,
c o n f i g u r e . a c : t h a t a c l o c a l . m4 i s p r e s e n t i n t h e t o p−l e v e l d i r e c t o r y ,
c o n f i g u r e . a c : and t h a t a c l o c a l . m4 was r e c e n t l y r e g e n e r a t e d ( u s i n g a c l o c a l ) .
a u t o m a k e : no ‘ M a k e f i l e . am ’ f o u n d f o r any c o n f i g u r e o u t p u t
• Problems:
– automake needs some tools for its generated makefiles.
– ./configure must be told to check for these – AM INIT AUTOMAKE
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled (Rev. 1.6) 14
Part-I Practical Auto-confiscation
Missing Macros
• Extending autoconf:
– It can read macros from an aclocal.m4 and acsite.m4 files.
– aclocal.m4 is generated by the aclocal command.
• How does aclocal work?
– It reads our configure.ac.
– And fetches needed macros from a macro repository.
• In our case we:
– Add the AM INIT AUTOMAKE macro to the first section of configure.ac.
– Run aclocal to fetch it.
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled (Rev. 1.6) 15
Part-I Practical Auto-confiscation
Missing files
• Some are required for proper operation.
• Others are meant to comply with GNU packaging rules1 .
• Created:
– By running automake with the ’--add’ flag: INSTALL, COPYING, mkinstalldir
install-sh, depcomp, ...
– Manually: README, AUTHORS, NEWS, ChangeLog.
• So after running automake -a:
We are ready to learn about Makefile.am .
1 We can force automake to ignore them by the --foreign option.
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled (Rev. 1.6) 16
Part-I Practical Auto-confiscation
Makefile.am
• Is technically a makefile:
– Hand crafted rules may be added if we wish.
– Makefile syntax must be obeyed.
• But we normally only want to specify:
– What to build? PROGRAMS, SCRIPTS, LIBRARIES, MANS, DATA, ...
– Where to install it? bin, sbin, lib, mans, data, sysconfig, ...
• This is described via “specification variables” syntax:
where WHAT = ...
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled (Rev. 1.6) 17
Part-I Practical Auto-confiscation
A Complete and Trivial Example
• configure.ac):
We have hello.c (assume we wrote
# i n c l u d e < s t d i o . h>
i n t main ( )
{
p r i n t f ( ” h e l l o K&R\n ” ) ;
return 0 ;
}
• Here is our Makefile.am:
bin PROGRAMS = hello
• The bootstrap sequence is:
$ touch README AUTHORS NEWS ChangeLog
$ aclocal; autoconf; automake -a
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled (Rev. 1.6) 18
Part-I Practical Auto-confiscation
Revisit the Original Example
• But we wanted to build libuser and lart...
• Here is Makefile.am:
bin PROGRAMS = lart
lib LIBRARIES = libuser . a
libuser a SOURCES = luser . c
include HEADERS = luser .h
lart LDADD = libuser . a
– “bad” characters in target name are replaced with an ’ ’
– The HEADERS target is meant to install headers.
– Other (internal) headers should be added to the SOURCES directive.
– The LDADD adds parameters and flags to the link phase.
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled (Rev. 1.6) 19
Part-I Practical Auto-confiscation
What About Dynamic Libraries?
• We need to use libtool to have portable solution.
• With autoconf + automake all we need is:
– Change the LIBRARIES into LTLIBRARIES.
– Rename each libfoo.a into libfoo.la.
– Run libtoolize to bring required tools (ltmain.sh, config.guess,
config.sub).
– Add AC PROG LIBTOOL to configure.ac.
• Now for a test:
aclocal; autoconf; automake
./configure
make
make dist
make distcheck
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled (Rev. 1.6) 20
Part-II Practical Auto-confiscation
Part-II
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled (Rev. 1.6) 21
Part-II Practical Auto-confiscation
And Now to Something Completely Different
• Let’s auto-confiscate a non-trivial software package – OpenGUI1 :
– A fast, non-X11, GUI library.
– Many platform – Linux, Solaris, Windows, QNX, DOS.
– On DOS/Windows Several compilers – Cygwin, Watcom, Visual-c, Borland.
– Build at three color depths (compile time): 8bpp, 16bpp, 32bpp.
– Optionally interface with Mesa (OpenGL) using some glue code.
• Current build environment for library only (without examples):
13 makefile.* + 6 *.mak + 1 *.bat
1 OpenGUI home http://www.tutok.sk/fastgl/
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled (Rev. 1.6) 22
Part-II Practical Auto-confiscation
Crisis? What Crisis?
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled (Rev. 1.6) 23
References Practical Auto-confiscation
References
[1] G. V. Vaughan, B. Elliston, T. Tromey, and I. L. Taylor, GNU Autoconf, Au-
tomake, and Libtool. SAMS, October 2000.
Copyright 2004, 2005, 2006, 2007, 2008 c Oron Peled (Rev. 1.6) 24