AUTOTOOLS LUKÁŠ KRÍŽIK
ÚVOD
• Portabilita – “The problem is that the world is a mess”.
• Nemožnosť vedieť aký kompiler, knižnice, funkcie, atď. užívateľ používa.
• Skript - configure.
• Balík nástrojov (GNU build system)
• autoconf
• automake
• libtool
• configure.ac
• Makefile.in
AUTOSCAN
• Preskenuje zdrojové kódy v adresári, ktorý dostal na príkazovej riadke alebo aktuálnom, ak nedostal žiadny.
• Výstup je súbor configure.scan určený k manuálnemu spracovaniu.
• Odôvodnenie výberu makier je v súbore autoscan.log.
#include <iostream>
using namespace std;
int main(){
cout << “Hello world!” << endl;}
# Process this file with autoconf ...
AC_PREREQ([2.68])AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-
REPORT-ADDRESS])AC_CONFIG_SRCDIR([main.cpp])AC_CONFIG_HEADERS([config.h])
# Checks for programs.AC_PROG_CXX
# Checks ...
JAZYK AUTOCONF-U
• Skriptovací jazyk m4 – spracovanie makier.
• Žiadne medzery medzi menom makra a otváracou zátvorkou.• AC_INIT ([oops], [1.0]) # nesprávne
• AC_INIT([hello], [1.0]) # správne
• Argumenty by mali byť uzatvorené v hranatých zátvorkách ‘[‘ a ‘]’, a oddelené čiarkami. Úvodné medzery a nové riadky sú v tomto prípade ignorované.
• Tieto pravidlá sa aplikujú rekurzívne na makrá volané z makier. Je preto lepšie uzatvárať argumenty do hranatých zátvoriek
CONFIGURE.AC LAYOUT
• Každý configure.ac musí obsahovať AC_INIT pred všetkými kontrolami a AC_OUTPUT na konci.
Autoconf requirements
AC_INIT(package, version, bug-report-address)
information on the package
checks for programs
checks for libraries
checks for header files
checks for types
checks for structures
checks for compiler characteristics
checks for library functions
checks for system services
AC_CONFIG_FILES([file...])
AC_OUTPUT
KONTROLA KONKRÉTNYCH PROGRAMOV
• AC_PROG_AWK – gawk, mawk, nawk, a awk (v poradí).
• AC_PROG_GREP, AC_PROG_EGREP, AC_PROG_FGREP – grep [option]
• AC_PROG_INSTALL – BSD kompatibilný install.
• AC_PROG_MKDIR_P
• AC_PROG_LEX
• AC_PROG_LN_S
• AC_PROG_RANLIB
• AC_PROG_SED
• AC_PROG_YACC
VŠEOBECNÁ KONTROLA PROGRAMOV
• AC_CHECK_PROG (variable, prog-to-check-for, value-if-found, [value-if-not-found], [path = ‘$PATH’], [reject])
• variable – výstupná premenná.
• prog-to-check-for – program, ktorý sa hľadá.
• value-if-found – hodnota v prípade, že je nájdený.
• value-if-not-found – hodnota v prípade, že nie je nájdený.
• path – cesta, kde sa má hľadať.
• reject – absolútna cesta, ktorá je vždy odmietnutá.
VŠEOBECNÁ KONTROLA SÚBOROV
• AC_CHECK_FILE (file, [action-if-found], [action-if-not-found])
• file – meno súboru, ktorého existencia sa má skontrolovať.
• action-if-found – akcia, ktorá sa má vykonať, ak bude nájdený.
• action-if-not-found – akcia, ktorá sa má vykonať, ak nebude nájdený.
KONTROLA KNIŽNÍC
• AC_CHECK_LIB (library, function, [action-if-found], [action-if-not-found], [other-libraries])
• pokúša sa zlinkovať testovací program ktorý volá function s knižnicou library.
• library – knižnica s ktorou sa má linkovať. (časť za –lmp).
• function – funkcia, ktorá sa bude volať v testovacom programe.
• action-if-found, action-if-not-found – tak ako doteraz.
• other-libraries – ďalšie knižnice, ktoré môže naša knižnica potrebovať (napr. –lX11 –lXt).
KONTROLA KNIŽNÍC 2
• Niektoré funckie ako napríklad gethostname sa môžu nachádzať v štandardných C knižniciach, inde zasa v špeciálnych ako nsl. Tie môžu obsahovať rôzne implementácie, ktoré nechceme použiť.
• AC_SEARCH_LIBS (function, search-libs, [action-if-found], [action-if-not-found], [other-libraries])
• function – funkcia, ktorú chceme nájsť.
• search-libs – knižnice oddelené medzerami, ktoré sa budú prehľadávať v uvedenom poradí.
KONTROLA KONKRÉTNYCH FUNKCIÍ
• AC_FUNC_MALLOC – Ak je malloc kompatibilný s GNU C malloc-om definuj HAVE_MALLOC 1. Inak definuj HAVE_MALLOC 0, spýtaj sa AC_LIBOBJ na náhradu za malloc a definuj malloc ako rpl_malloc.
• AC_FUNC_MEMCMP – Skontroluj, či existuje memcmp, či funguje na 8-bitoch, otestuj porovnanie na 16 a viac bytoch začínajúcich na nezarovnaných adresách. Ak nie, skús nahradiť pomocou AC_LIBOBJ.
• A mnoho ďalších...
VŠEOBECNÁ KONTROLA FUNKCIÍ
• Ak je funckia obsiahnutá v iných než štandardných knižniciach, treba zavolať AC_CHECK_LIB. Ak chceme otestovať funkčnosť, musíme si napísať vlastné testy.
• AC_CHECK_FUNC (function, [action-if-found], [action-if-not-found])
• AC_CHECK_FUNCS (function..., [action-if-found], [action-if-not-found])
• AC_CHECK_FUNCS_ONCE (function...)
• Definujú HAVE_function makro ak funkcia existuje.
KONTROLA KONKRÉTNYCH HLAVIČKOVÝCH SÚBOROV
• AC_CHECK_HEADER_STDBOOL – stdbool.h
• AC_HEADER_ASSERT – assert.h
• AC_HEADER_STDC – C kompatibilné štandardné knižnice.
• AC_HEADER_TIME – time.h a sys/time.h
• A mnoho ďalších...
VŠEOBECNÁ KONTROLA HLAVIČKOVÝCH SÚBOROV
• AC_CHECK_HEADER (header-file, [action-if-found], [action-if-not-found], [includes])
• AC_CHECK_HEADERS (header-file..., [action-if-found], [action-if-not-found], [includes])
• AC_CHECK_HEADERS_ONCE (header-file...)
• header-file – meno hlavičkového súboru, ktorého existenciu kontrolujeme.
• includes – prerekvizity includovania. Default je nastavený na AC_INCLUDES_DEFAULT.
KONTROLA ŠPECIÁLNYCH TYPOV
• AC_TYPE_INT8_T a podobné – Ak nenájde int8_t v štandardných knižniciach, definuj taký, korý mu zodpovedá.(t.j. integer veľkosti 8 bitov).
• AC_TYPE_SIZE_T – Ak nenájde size_t v štandardných knižniciach, definuje nejaký, ktorý mu zodpovedá.
• AC_TYPE_LONG_DOUBLE
• AC_TYPE_UID_T
• AC_TYPE_PID_T
• A mnoho ďalších...
VŠEOBECNÁ KONTROLA TYPOV
• AC_CHECK_TYPE (type, [action-if-found], [action-if-not-found], [includes = ‘AC_INCLUDES_DEFAULT’])
• AC_CHECK_TYPES (types, [action-if-found], [action-if-not-found], [includes = ‘AC_INCLUDES_DEFAULT’])
• type – typ, ktorého existencia sa má skotrolovať. Musí to byť taký typ, pre ktorý je výraz sizeof(type) platný.
• Definujú makro HAVE_type.
AC_CHECK_TYPES([ptrdiff_t])
AC_CHECK_TYPES([unsigned long long int, uintmax_t])
AC_CHECK_TYPES([float_t], [], [], [[#include <math.h>]])
ČO VŠETKO MOŽNO EŠTE KONTROLOVAŤ?
• Deklarácie
• Štruktúry – existencia členov.
• Kompiler a preprocesor
• AC_PROG_CC ([compiler-search-list]) – C kompiler
• AC_PROG_CXX ([compiler-search-list]) – C++ kompiler
• Objective C, Objective C++, Erlang, Fortran, Go
• Služby systému
• Varianty posixu
• Napísať si vlastné testy
MOŽNOSTI BALÍČKU - FEATURES
• AC_ARG_ENABLE (feature, help-string, [action-if-given], [action-if-not-given])
• --enable-feature[=arg] a –disable-feature parametre configure.
• Môžu mať parametre.
• --disable-feature je ekvivalent --enable-feature=no
• --enable-feature má default parameter yes.
• feature – vlastnosť, ktorú chceme akceptovať configure.
• help-string – mal by byť formátovaný pomocou AS_HELP_STRING
• Hodnota je uložená do premennej enableval alebo enable_feature.
PRÁCA S EXTERNÝM SOFTWARE
• AC_ARG_WITH (package, help-string, [action-if-given], [action-if-not-given])
• --with-package[=arg] a --without-package parametre configure.
• package – názov externého balíčku.
• help-string – mal by byť formátovaný pomocou AS_HELP_STRING
• Hodnota argumentu je uložená v premennej withval alebo with_package.
• Ak užívateľ zadá ako parameter configure --enable-package alebo --disable-package, vykoná sa [action-if-given]. Inak sa vykoná [action-if-not-given].
PRÍKLAD – AC_ARG_WITHAC_ARG_WITH([readline],
[AS_HELP_STRING([--with-readline], [enable experimental support for readline])],
[],
[with_readline=no])
LIBREADLINE=
AS_IF([test "x$with_readline" != xno],
[AC_CHECK_LIB([readline], [main],
[AC_SUBST([LIBREADLINE], ["-lreadline -lncurses"])
AC_DEFINE([HAVE_LIBREADLINE], [1], [Define if you have libreadline])
],
[AC_MSG_FAILURE([--with-readline was given, but test for readline failed])], [-lncurses])])
PRÍKLAD – GNU TARAC_PREREQ([2.63]) # verzia GNU autoconf
AC_INIT([GNU tar], [1.26], [[email protected]]) # [package-name], [version], [bug-report-mail]
AC_CONFIG_SRCDIR([src/tar.c]) # unikátny súbor v koreňovom adresáre zdrojových kódov
AC_CONFIG_HEADERS([config.h]) # meno konfiguračného hlavičkového súboru
AC_PROG_CC # kontrola C kompileru
AC_PROG_YACC # kontrola ‘bison –y’
AC_HEADER_STDC # kontrola štandardných C headrov
AC_HEADER_STAT # kontrola makier S_ISDIR, S_ISREG, atď. v sys/stat.h
AC_CHECK_HEADERS_ONCE(fcntl.h linux/fd.h memory.h net/errno.h \sgtty.h string.h \sys/param.h sys/device.h sys/gentape.h \sys/inet.h sys/io/trioctl.h \sys/mtio.h sys/time.h sys/tprintf.h sys/tape.h \unistd.h locale.h) # kontrola špecifických headrov
AC_CHECK_HEADERS([sys/buf.h], [], [],[#if HAVE_SYS_PARAM_H#include <sys/param.h>#endif]) # kontrola sys/buf.h s prerekvizitami.
PRÍKLAD – GNU TAR 2AC_TYPE_PID_T
AC_TYPE_OFF_T
AC_TYPE_SIZE_T
AC_TYPE_UID_T
AC_CHECK_TYPE(major_t, , AC_DEFINE(major_t, int, [Type of major device numbers.])) # kontrola a dodefinovanie major_t
AC_CHECK_TYPE(dev_t, unsigned) # kontrola existencie a porovnanie veľkosti
AC_OUTPUT([Makefile\doc/Makefile\gnu/Makefile\lib/Makefile\po/Makefile.in\scripts/Makefile\rmt/Makefile\src/Makefile])
AUTOCONF
• Vytvorí configure z configure.ac.
• --verbose [v] – trošku viac výstupu.
• --debug [d] – ponechá dočasné súbory
• --force [f] – prepíše configure bez ohľady na dobu úpravy.
• --output [o] – výstup. Defaultne configure.
HELLO WORLD!src/main.cpp
#include <config.h>
#include <stdio.h>
int main(void)
{
puts(“Hello world!”);
puts(“This is “ PACKAGE_STRING “.”);
}
README
This is a demonstration package for GNU Automake.
Type 'info Automake' to read the Automake manual.
HELLO WORLD! 2src/Makefile.am
bin_PROGRAMS = hello
hello_SOURCES = main.c
Makefile.am
SUBDIRS = src
dist_doc_DATA = README
configure.ac
AC_INIT([hello], [1.0], [[email protected]])
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_PROG_CC
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefilesrc/Makefile
])
AC_OUTPUT
AUTORECONF
• Púštenie všetkých autotools programov môže byť náročné.
• Dôvodom môže byť update automake alebo nejakého podporného súboru.
• Môžeme prosto chcieť vytvoriť úplne čerstvý build system.
• Spúšťa autoconf, autoheader, aclocal, automake, libtoolize, a autopoint za účelom updatnutia celého prostredia.
• --install [i] – nainštaluje prídavné súbory do balíčku. Defaultne ich kopíruje. To sa dá zmeniť pomocou --symlink.
JAZYK MAKEFILE.AM
• Má tú istú syntax ako Makefile.
• Automake v podstate skopíruje Makefile.am do Makefile.in s tým, že zareaguje na niektoré definície premenných, tak že vytvorí pravidlá pre build a iné premenné.
• Makefile.am teda môže obsahovať premenné, ktoré ostanú automakeom nepovšimnuté a budú iba skopírované
HELLO WORLD! MAKEFILE.AM
• bin_PROGRAMS = hello
• Premenné končiace _PROGRAMS sú zoznanom programov, ktoré majú byť zbuildené.
• bin_ znamená, že výsledok buildu má byť uložený v bindir.
• hello_SOURCES = main.c
• Uvedenie zdrojových súborov pre program hello.
• SUBDIRS = src
• Adresáre, ktoré majú byť spracované automakeom.
• dist_doc_DATA = README
• doc_ znamená použitie docdir a dist_, že sú data pridané do balíčku.
ZAUJÍMAVEJŠÍ PRÍKLADMakefile.am
bin_PROGRAMS = true false
false_SOURCES =
false_LDADD = false.o
true.o: true.c
$(COMPILE) -DEXIT_CODE=0 -c true.c
false.o: true.c
$(COMPILE) -DEXIT_CODE=1 -o false.o -c true.c
• Chceme vytvoriť dva rôzne programy z jedného zdrojového súboru za použitia rôznych parametrov pri kompilácií.
• Používa sa tu niekoľko implicitných automake vlastností.
BUILDING PROGRAM
• _SOURCES
• Obsahuje zoznam zdrojových súborov.
• Ak je hello_SOURCES prázdne, obsahuje súbor hello.c
• _LADD
• Prilinkovanie knižníc, ktoré nie sú podchytené pomocou configure.
• _CFLAGS
• _CXXFLAGS
• _LDFLAGS
PODMIENÉ PODADRESÁRE
• Ak chceme mať možnosť kompilovať nejaký podadresár projektu ako parameter configure.
• SUBDIRS vs. DIST_SUBDIRS
• SUBDIRS obsahuje podradresáre, ktoré musia byť zbuildené.
• DIST_SUBDIRS je použité v pravidlách, ktoré musie prejsť celý strom adresárov. Napríklad nechcete build /opt/.src ale chcete ho distribuovať.
• AM_CONDITIONAL
configure.ac
...
AM_CONDITIONAL([COND_OPT], [test "$want_opt" = yes])
AC_CONFIG_FILES([Makefile src/Makefile opt/Makefile])
...
Toplevel Makefile.am
if COND_OPT
MAYBE_OPT = opt
endif
SUBDIRS = src $(MAYBE_OPT)
BUILDING LIBRARY
• _LIBRARIES
• Zdrojové súbory pre knižnice sú detekované úplne rovnako ako pre programy.
Makefile.am
noninst_LIBRARIES = libcpio.a
libcpio_a_SOURCES = …
bin_PROGRAMS = cpio
cpio_SOURCES = cpio.c …
cpio_LADD = libcpio.a
ÚVOD
• Libtool zhŕňa zdieľané a statické knižnice do spoločného konceptu, ktorý sa nazýva libtool libraries.
• Súbory majú koncovku .la a môžu byť zdieľanými knižnicami, statickými knižnicami, alebo oboma.
• Objektové súbory vytvorené libtoolom majú koncovku .lo.
• O formáte súborov .lo a .la nemožno nič predpokladať. Treba však do úvahy brať ich existenciu, pretože sú použité v Makefile targetoch.
BULDING LIBTOOL LIBRARIES
• _LTLIBRARIES
• List libtool knižníc, ktoré majú byť vytvorené.
• Príklad
• Vytvorenie knižnice libgettext.la a nainštalovanie do libdir.
Makefile.am
lib_LTLIBRARIES = libgettext.la
libgettext_la_SOURCES = gettext.c …
include_HEADERS = gettext.h …
bin_PROGRAMS = hello
hello_SOURCES =
hello_LADD = libgettext.la