1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406
|
--title autoconf und automake
--author Andreas Krennmair
--date today
Praktisch jede Software unter Linux wird mit ./configure ; make ; make
install konfiguriert, compiliert und installiert. Ich mchte heute
zeigen, wie man selbst mit Autoconf und Automake den Konfigurations- und
bersetzungsprozess automatisieren kann, und was das fr portable
Software bringen kann.
--newpage agenda
--heading Agenda
* Einfhrung
* Makefiles
* Autoconf alleine
* Autoconf und Automake
--newpage intro
--heading Einfhrung: Geschichte der automatisierten Compilierung unter Unix
* Anfangs: Shellskripte namens make im Sourceverzeichnis (bis Unix V6)
* Ab Unix V7: Programm make, Information aus Datei makefile
* makefile enthlt Informationen, welchen Dateien (Targets) aus welchen
Dateien (Dependencies) erzeugt werden, und welche Kommandos dazu
aufgerufen werden mssen.
* Makefiles funktionierten anfangs ganz gut, bis die ersten Unix-
Varianten erschienen, die subtil anders als die bisherigen Unixe waren.
Software sollte aber portabel bleiben.
* Einfache Lsung: ein Target pro Zielplattform.
* Nachteil: bei mehr Plattformen ansteigender Wartungsaufwand
--newpage intro-conf
--heading Einfhrung: erste automatisierte Konfiguration
* Makefile-Lsung hrte auf zu skalieren, als immer mehr und immer
obskurere Unix-Varianten auftauchten, auf die die Entwickler von
Software noch dazu keinen Zugriff mehr hatten.
* Erste Lsung Mitte bis Ender der 80er Jahre: Configure
* Larry Wall wollte, dass seine Software (insbesondere Perl) portabel
auf mglichst vielen Unix-Plattformen luft.
* Schreib Shellskript Configure, das Informationen ber das System
sammelte, und aus *.SH-Dateien dementsprechende Dateien generierte
(Makefile.SH -> Makefile)
* Vorteil: Perl konnte ohne grossen Portierungsaufwand auf vielen,
tewilweise recht obskuren Unix-Systemen betrieben werden.
--newpage intro-gnu
--heading Einfhrung: Konfiguration fr GNU
* GNU-Software sollte mglichst portabel sein
* GNU-Projekt griff Larry Wall's Idee auf, und realisierte im
wesentlichen zwei Frameworks, um das Konfigurieren und bersetzen von
GNU-Software mglichst portabel und einfach wartbar zu halten.
* Konfiguration: autoconf
* bersetzung: automake
* Status heute: Autoconf und Automake sind ein Quasi-Standard bei Freier
Software/Open Source
--newpage makefiles
--heading Einfache Makefiles
Makefiles bestehen im wesentlichen aus zwei Bereichen:
* Variablendefinitionen
* Zieldefinitionen
Variablen werden verwendet, um gleiche "Textbausteine", die fters im
Makefile vorkommen, zusammenzufassen und parametrisierbar zu machen, z.B.
Compilerkommandos, Compilerflags, Ausgabedatei, ...
Zieldefinitionen geben an, welche Datei erzeugt werden soll, von welchen
Dateien diese Datei abhngig ist, und mit welchem Kommando die Datei aus
diesen Abhngigkeiten erzeugt wird. Diese Zieldefinition definiert ein
sog. "Target". Wird ein Target aufgerufen, so wird das Kommando nur
ausgefhrt, wenn die zu generierende Datei noch nicht existiert, oder wenn
eine der Abhngigkeiten erst generiert werden muss, oder wenn eine der
Abhngigkeiten neuer ist als die bestehende Datei So werden unntige
Compile-Vorgnge vermieden.
--newpage example1
--heading Beispiel 1: einfaches Makefile
--beginoutput
# Kommentar
LATEX=pdflatex # Variablendefinition
ac-am.pdf: ac-am.tex # Zieldefinition
$(LATEX) ac-am.tex # <Tabulator>Kommando
--endoutput
--newpage example2
--heading Beispiel 2: gleichartige Targets zusammenfassen
--beginoutput
LATEX=pdflatex
RM=rm -f
PDFFILES=ac-am.pdf
all: $(PDFFILES)
%.pdf: %.tex
$(LATEX) $<
clean:
$(RM) $(PDFFILES) *.aux *.log
--endoutput
--newpage
--heading Beispiel 3: modulares C-Programm bersetzen
--beginoutput
CC=gcc
CFLAGS=-Os -Wall
OBJS=foo.o bar.o baz.o quux.o
OUTPUT=xyzzy
all: $(OUTPUT)
$(OUTPUT): $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(OUTPUT) $(OJBS) $(LIBS)
%.o: %.c
$(CC) $(CFLAGS) $(DEFINES) -c $<
clean:
$(RM) $(OBJS) $(OUTPUT) core *.core
.PHONY: all clean
--endoutput
--newpage limitations
--heading Limtationen von Makefiles
Makefiles funktionieren zwar bei kleineren, einfachen Programmen, wer
jedoch grere, portable Software schreiben will, stt mit make und
Makefiles schnell an Grenzen.
Die Unterschied zwischen den einzelnen Unix-Systemen sind z.B. folgende:
* Strukturen unterscheiden sich
* Funktionen sind unterschiedlich deklariert
* #defines sind anders benannt oder existieren nicht
* Manche Funktionen sind nicht mehr in der libc, sondern in externe
Libraries ausgelagert (z.B. Sockets nach libsocket).
Auf diese Unterschiede kann make nicht eingehen. Deswegen muss man einen
Konfigurationsmechanismus einfhren, der dies kann.
--newpage autoconf1
--heading Autoconf, Schritt 1: configure-Skript erzeugen
Autoconf bietet die Mglichkeit, auf eine groe Anzahl von Kommandos und
Tests zurckzugreifen, um mglichst alle relevanten Systemparameter
abzurufen. Diese Tests werden in einer Datei configure.in abgelegt, aus
dem dann mit dem Kommando autoconf die Datei configure erzeugt wird. Mit
dem Kommando autoheader wird die Datei config.h.in erzeugt.
Ruft man ./configure auf, so sammelt das configure-Skript die
Konfigurationsinformationen, und generiert aus config.h.in die Datei
config.h sowie alle in configure.in angegebenen zu konfigurierenden
Dateien, das ist meistens Makefile.in, aus der Makefile erzeugt wird.
Die configure.in-Datei lsst sich brigens erzeugen, indem man autoscan
aufruft, und die resultierende Datei configure.scan in configure.in
umbenennt.
--newpage autoconf2
--heading Autoconf, Schritt 2: Makefile.in erstellen
Die Datei Makefile.in wird wie ein normales Makefile geschrieben,
mit dem Unterschied, dass fr bestimmte Variablen, deren Wert vom
configure-Skript bestimmt werden, spezielle Platzhalter eingefgt
werden. Das sieht dann z.B. so aus:
--beginoutput
CC=@CC@
CFLAGS=@CFLAGS@ @DEFS@
LDFLAGS=@LDFLAGS@
LIBS=@LIBS@
--endoutput
Der Rest des Makefile sieht wie ein normales Makefile aus. Um auf
smtliche ermittelten Parameter zugreifen zu knnen, mssen die
einzelnen C-Sourcefiles nur noch die Datei config.h inkludieren.
Damit ist Autoconf vollstndig integriert und das Buildsystem darauf
angepasst.
--newpage autoconf3
--heading Autoconf, Zusammenfassung
In einer Minute zur Sourcekonfiguration mit Autoconf:
--beginshelloutput
$ autoscan && mv configure.scan configure.in
---
$ $EDITOR configure.in
---
$ autoconf
---
$ autoheader
---
$ $EDITOR Makefile.in
--endshelloutput
Fertig!
--newpage confex1
--heading Beispiel fr configure.in (1)
--beginoutput
AC_PREREQ(2.57)
AC_INIT(akpop3d, 0.7.7, ak@synflood.at)
AC_CONFIG_SRCDIR([authenticate.c])
AC_CONFIG_HEADER([config.h])
# Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL
--endoutput
--newpage confex2
--heading Beispiel fr configure.in (2)
--beginoutput
# Checks for header files.
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h netdb.h
netinet/in.h shadow.h stdlib.h string.h sys/file.h
sys/socket.h sys/time.h syslog.h unistd.h])
# Checks for typedefs, structures, and compiler
# characteristics.
AC_C_CONST
AC_TYPE_UID_T
AC_TYPE_OFF_T
AC_TYPE_PID_T
AC_TYPE_SIZE_T
AC_HEADER_TIME
--endoutput
--newpage confex3
--heading Beispiel fr configure.in (3)
--beginoutput
# Checks for library functions.
AC_FUNC_ALLOCA
AC_FUNC_FORK
AC_FUNC_REALLOC
AC_FUNC_SELECT_ARGTYPES
AC_FUNC_STAT
AC_CHECK_FUNCS([atexit dup2 getspnam inet_ntoa
memchr memset select socket strchr strerror
strncasecmp strrchr])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
--endoutput
--newpage functions
--heading Weitere ntzliche Autoconf-Funktionen
* AC_CHECK_LIB(library,symbol): wenn symbol in Library library
gefunden wird, wird -llibrary zu den LDFLAGS hinzugefgt und
HAVE_LIBLIBRARY=1 in config.h definiert.
* AC_DEFINE([KEY],[VALUE]): in config.h wird #define KEY VALUE
eingetragen.
* AC_ARG_WITH(option,[beschreibung]): das configure-Skript um
eine --with-option Option erweitern.
* AC_ARG_ENABLE(option,[beschreibung]): das configure-Skript um
eine --enable-option Option erweitern.
--newpage funcex1
--heading Beispiele zu ntzlichen Autoconf-Funktionen
--beginoutput
AC_ARG_WITH(openssl, [ --with-openssl use OpenSSL])
if test "$with_openssl" != "no" ; then
AC_CHECK_LIB(crypto,BIO_new)
AC_CHECK_LIB(ssl,SSL_new)
fi
AC_ARG_ENABLE(rfc2449, [ --enable-rfc2449 enable RFC 2449 support])
if test "$enable_rfc2449" != "no" ; then
AC_DEFINE([ENABLE_RFC2449],[1],[rfc2449])
fi
--endoutput
--newpage funcauto
--heading Funktionsweise von Autoconf
* Vorgefertige Tests in Form von m4-Makros verfgbar
* Autoconf lsst configure.in durch m4 laufen, daraus entsteht
configure-Skript, was nicht anders als ein Shellskript ist.
* -> man kann durch Einfgen von eigenem Shellcode eigene Tests
durchfhren.
* -> oder man greift auf http://ac-archive.sourceforge.net/ zurck,
einem umfangreichen Archiv von hunderten Autoconf-Macros.
--beginoutput
if test x`uname -s` = "xDarwin" ; then
AC_DEFINE([HAVE_DARWIN],[1],[define whether we have Darwin])
fi
--endoutput
--newpage macroself
--heading Autoconf-Makros selbst schreiben
Autoconf-Makros sind ein Mischmasch aus m4-Skript und Shellskript.
--beginoutput
AC_DEFUN([AC_C_LONG_LONG],
[AC_CACHE_CHECK(for long long int, ac_cv_c_long_long,
[if test "$GCC" = yes; then
ac_cv_c_long_long=yes
else
AC_TRY_COMPILE(,[long long int i;],
ac_cv_c_long_long=yes,
ac_cv_c_long_long=no)
fi])
if test $ac_cv_c_long_long = yes; then
AC_DEFINE(HAVE_LONG_LONG)
fi
])
--endoutput
--newpage automake1
--heading Automake: Einfhrung
Automake ist dafr gedacht, den eigentlichen bersetzungsprozess so weit
wie mglich zu vereinfachen, und dem User das Schreiben von eigenen
Makefile.in's abzunehmen. Automake setzt Autoconf voraus.
Die Makefile.am-Datei besteht wie ein Makefile aus Targets, die quasi
beliebig benannt werden knnen, und alle Kommandos enthalten wie auch
ein Target in einem Makefile oder Makefile.in.
Zustzlich existieren eine Reihe von speziellen Variablen, mit denen das
bersetzen von Software einfacher wird.
--beginoutput
bin_PROGRAMS = hello
hello_SOURCES = hello.c main.c
EXTRA_DIST = hello.h
--endoutput
--newpage autocmd
--heading Automake: mehr Kommandos
--beginshelloutput
$ $EDITOR Makefile.am
---
$ autoscan && mv configure.scan configure.in
---
$ autoheader
---
$ aclocal
---
AM_INIT_AUTOMAKE(programname,version) in configure.in eintragen.
---
$ automake -a
---
$ autoconf
---
$ ls -l Makefile.in configure
-rw-r--r-- 1 ak staff 16048 16 Mar 20:03 Makefile.in
-rwxr-xr-x 1 ak staff 123354 16 Mar 20:03 configure
$
--endshelloutput
--newpage primaries
--heading Automake: Primaries
Die _PROGRAMS; _SOURCES, etc. Suffixe, die vorher gesehen haben, nennen
sich brigen "Primaries". Weitere Primaries sind z.B.:
* DATA: gibt Datendateien an, die 1:1 mitinstalliert, ansonsten aber
ignoriert werden.
* HEADER: damit werden Headerfiles spezifiziert, die zusammen mit
Libraries installiert werden sollen.
* SCRIPTS: ausfhrbare Skripte, die ebenfalls installiert werden,
jedoch nicht compiliert oder gestripped werden.
* MANS: gibt Manpages an, die ebenfalls mitinstalliert werden.
Die Grundbedrfnisse fr einfache und problemlose Konfigurations-,
bersetzungs- und Installationsroutinen wre damit gedeckt.
--newpage recam
--heading Rekursives Automake
Um den Inhalt von Unterverzeichnissen in den Automake-Vorgang
miteinzubeziehen, muss man lediglich alle relevanten Unterverzeichnisse
ber die SUBDIRS-Variable angeben.
--beginoutput
SUBDIRS = m4 src doc
--endoutput
In jedem Unterverzeichnis muss natrlich wiederum eine Makefile.am
angelegt und daraus eine Makefile.in erzeugt werden. Ausserdem muss das
dann zu erzeugende Makefile in der configure.in angegeben werden, und
zwar via AC_CONFIG_FILES.
--newpage resumee
--heading Resmee
* make mag veraltet und eingerostet wirken (wird seit Ende der
1970er eingesetzt), bietet aber ein mchtiges System, um
Abhngigkeiten zu berprfen, und unntige Compilevorgnge zu
minimieren.
* Autoconf bietet ein mchtiges System, um vielerlei systemabhngige
Konfigurationspunkte in Erfahrung zu bringen, was wiederum einen
Eckpfeiler fr systemnahe und portable Programmierung bildet.
* Automake macht es fr Entwickler besonders einfach, Softwarepakete
in eine Form zu bringen, dass sie bersetzt und installiert werden
knnen.
* Autoconf und Automake mgen suboptimale Lsungen sein
(./configure dauert lange, configure und Makefile.in sind
bei Automake extrem gross), stellen jedoch eine frei verfgbare,
einfach anzuwendende und vor allem weit verbreitete Lsung dar.
--newpage literacy
--heading Literaturempfehlungen
* Das "Autobook": Autoconf, Automake and Libtool
http://sources.redhat.com/autobook/autobook/autobook_toc.html
* Autoconf Dokumentation:
http://www.delorie.com/gnu/docs/autoconf/autoconf_toc.html
* Automake Dokumentation:
http://www.delorie.com/gnu/docs/automake/automake_toc.html
--newpage end
--heading Und jetzt...
--huge Zum praktischen Teil!
|