autoconf, automake Kullanımı
GNU build sistemi iki temel amacın gerçekleştirilebilmesi için geliştirilmiştir: Programları platformlar arası daha rahat taşınabilir hale getirmek ve kaynak koddan program kurulumlarını mümkün olduğu kadar basite indirgeyebilmek.
Taşınabilir kod yazmak gerçekten oldukça zahmetli bir iştir. Hedef mimarinin ayrıntılı olarak özelliklerinin bilinmesi çoğu zaman mümkün değildir. Bir önceki bölümde örnek olarak yazdığımız Makefile dosyasında mkdir -p /usr/local/bin
komutunu kullanmıştık. Oysa mkdir
komutunun -p
seçeneği tüm Unix sistemlerinde aynı şekilde çalışmaz. Bu ve bunun gibi pek çok farklılık yüzünden her Unix sisteminde çalışabilecek bir Makefile
yazmak oldukça güçtür. Kullanılan kütüphanelerin sistemler arasındaki farklılıkları ise apayrı bir konudur. İşte GNU build sistemi tüm bu zorlukların üstesinden gelebilmek için oluşturulmuştur.
Kdevelop gibi programlar yeni proje oluşturduğunuzda build sistemini de otomatik olarak oluşturmaktadırlar. Ancak oluşan dosyalar fazlasıyla karışık olduğundan bu bölümde çok daha basit örneklerle yapıyı anlatmaya çalışacağız. Buradaki temel bilgilerden yararlandıktan sonra Kdevelop vb. gibi programların ürettiği veya internetten indirmiş olduğunuz herhangi bir uygulamanın kaynak kodu içerisinde gezinerek farklı kullanımları inceleyebilirsiniz.
Gerekli Araçlar
Gnu build sistemi için gerekli araçlar ve kullanım alanları aşağıdaki gibidir:
autoconf: konfigürasyon için kullanılacak configure betik programını üretir. Kodun taşınabilir olmasını etkileyecek özellikleri, üzerinde çalıştığı platform için denetler. Elde ettiği değerleri, daha önceden belirtilmiş şablonlara uygun şekilde birleştirerek özelleştirilmiş Makefile, başlık dosyaları vb. oluşturur. Bu sayede programı derleyecek kullanıcı tek tek elle bu değişiklikleri yapmak zahmetinden kurtulur.
automake:, autoconf için kullanılacak Makefile şablonlarını (Makefile.in) Makefile.am dosyalarını temel alarak üretir. Automake tarafından üretilen Makefile dosyaları GNU makefile standartlarına uygun olup, kullanıcıyı elle Makefile dosyası oluşturma zahmetinden kurtarır. Autoconf'un çalışabilmesi için öncelikle automake'in düzgün olarak çalışması gereklidir.
libtool: özellikle paylaşımlı kütüphanelerin taşınabilir bir yapıda oluşturulabilmesi için gereken pek çok detayı kullanıcıdan soyutlar. Kullanımı için autoconf veya automake gerekli değildir, tek başına da kullanılabilir. Automake ise libtool'u destekler ve onunla birlikte çalışabilir.
autotools: GNU kodlama standartlarına uygun, taşınabilir kod üretmede yardımcı araçlar içeriz.
GNU build sistemi tarafından gerçekleştirilen temel görevler şunlardır:
Çok sayıda alt dizin içeren kaynak kodlardan uygulamaları üretebilir. Her bir dizin için ayrıca make komutunu çağırmak zahmetinden geliştiriciyi kurtarır. Bu sayede tüm kaynak kodları aynı dizinde bulundurmak yerine daha hiyerarşik bir dizin yapısı kullanabilirsiniz.
Konfigürasyon işlemini otomatik olarak yapar. Kullanıcıların Makefile dosyalarını düzenlemelerine gerek kalmaz.
Makefile dosyalarını otomatik olarak üretir. Makefile yazımı büyük projelerde sürekli tekrar gerektirir ve aynı zamanda hata yapmaya elverişli bir yapıdır. GNU build sistemi için sadece
Makefile.am
şablonunun yazımı yeterlidir. Bu sayede hata yapma olasılığı azalır ve yönetimi kolay hale gelir.Hedef platform için özel testler yapabilme imkanı sunar. Makefile.am dosyasına eklenecek bir kaç satırla hedef platformda programın derlenebilesi için aranan özelliklerin var olup olmadığı kontrol edilebilir.
Paylaşımlı kütüphanelerin oluşturulması statik kütüphanelerin oluşturulması kadar kolay hale gelir.
GNU build sistemi için gerekli olan bu araçların sadece geliştirmenin yapıldığı sistemde kurulu olması yeterlidir. Bu programlar çalıştıktan sonra her platformda çalışabilecek betik programları üretirler. Bu sayede uygulamanızın kaynak kodunu indirip kurmak isteyen biri, autoconf
, automake
gibi araçları da sistemine kurmak zorunda kalmaz.
İşlemlere başlamadan önce autoconf
, automake
ve libtool
paketlerini sistemimize kuralım:
$ sudo apt-get install autoconf automake libtool
Zorunlu olmamakla birlikte, configure.ac
dosyalarımız içerisinde temel M4
makro seti içerisinde yer almayan ancak muhtemelen kullanmak zorunda kalacağımız ek makro arşivini içeren autoconf-archive
paketini de kurmamız yerinde olacaktır:
$ sudo apt-get install autoconf-archive
Örnek Makro: AX_FUNC_MKDIR
mkdir()
fonksiyonu bazı platformlarda _mkdir()
şeklinde kullanılmaktadır.
Bazı platfomlarda dizin erişim yetkileri için 2. argüman kullanılıyorken diğerlerinde tek argüman kullanıldığı bilinmektedir.
Aşağıkda mkdir()
fonksiyonunun platformlar arası taşınabilirliğini bizim için kolaylaştıran AX_FUNC_MKDIR
makro örneği verilmiştir:
#if HAVE_MKDIR
# if MKDIR_TAKES_ONE_ARG
/* MinGW32 */
# define mkdir(a, b) mkdir(a)
# endif
#else
# if HAVE__MKDIR
/* plain Windows 32 */
# define mkdir(a, b) _mkdir(a)
# else
# error "Don't know how to create a directory on this system."
# endif
#endif
Örnek Uygulama
Şimdi aşağıdaki örnek uygulamamız için GNU build sistemini nasıl kullanacağımızı öğrenelim.
#include <stdio.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
int main (int argc, char *argv[])
{
printf("Örnek Çalışıyor\n");
if (argc == 2) {
const char *target = argv[1];
int rc;
#ifdef HAVE_MKDIR
#ifdef MKDIR_TAKES_ONE_ARG
rc = mkdir(target);
#else
rc = mkdir(target, 0755);
#endif
if (rc == 0) {
printf("%s dizini oluşturuldu\n", target);
} else {
fprintf(stderr, "%s dizini oluşturulamadı\n", target);
}
#else
fprintf(sdterr, "mkdir() desteklenmiyor\n");
#endif
}
return 0;
}
Programımızı ornek.c olarak kaydedelim. Şimdi programın derlenmesi işlemlerini autoconf ve automake ile yapmaya başlayalım. Bunun için öncelikle automake
ile kullanılmak üzere aşağıdaki gibi bir Makefile.am
dosyasını oluşturalım:
AUTOMAKE_OPTIONS = foreign
bin_PROGRAMS = ornek
ornek_SOURCES = ornek.c
foreign
opsiyonu sayesinde ilerleyen aşamalarda GNU uygulamalarında bulunması zorunlu dosya kontrollerini devre dışı bırakıyoruz (Bu seçeneği kullanmadığımız durumdaki senaryoyu test ediniz)
Ardından aşağıdaki gibi bir configure.ac
dosyasını oluşturalım (eski versiyonlarda dosya ismi configure.in
şeklindeydi):
AC_INIT([ornek], [0.1], [[email protected]])
AC_CONFIG_SRCDIR([ornek.c])
AM_INIT_AUTOMAKE
AC_CONFIG_HEADERS([config.h])
AC_PROG_CC
AC_CHECK_HEADERS([sys/time.h])
AC_CHECK_FUNCS([gettimeofday])
AX_FUNC_MKDIR
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
Dosyaları oluşturup kaydettikten sonra şimdi aclocal
komutunu çalıştıralım:
$ aclocal
$ ls -l
-rw-r--r-- 1 demirten demirten 41928 Dec 27 01:04 aclocal.m4
drwxr-xr-x 2 demirten demirten 4096 Dec 27 01:04 autom4te.cache
-rw-r--r-- 1 demirten demirten 120 Dec 27 01:03 configure.ac
-rw-r--r-- 1 demirten demirten 45 Dec 27 00:51 Makefile.am
-rw-r--r-- 1 demirten demirten 87 Dec 27 00:26 ornek.c
aclocal
çalıştıktan sonra bulunduğumuz dizinde autom4te.cache
dizini ve aclocal.m4
dosyası oluştu.
Sonraki adımda autoheader komutunu çalıştırıyoruz. Eğer configure.ac
dosyasında AC_CONFIG_HEADERS
belirtilmemişse yapılacak kontroller sonrası elde edilen değerler config.h
dosyasına yazılmayacak olduğundan bu adımı atlayabilirsiniz:
$ autoheader
$ ls -l config.h.in
-rw-r--r-- 1 demirten demirten 1825 Dec 27 02:43 config.h.in
İşlem bitiminde config.h
dosyası için kullanılacak config.h.in
şablonu üretildi.
Sıradaki işlem autoconf komutuyla configure betiğini oluşturmak:
$ autoconf
$ ls -l configure
-rwxr-xr-x 1 demirten demirten 140829 Dec 27 01:04 configure
İşlem sonrasında bulununan dizinde configure
adlı tanıdık betik uygulamasını oluşturmuş oluyoruz.
configure
betiği de oluştuktan sonra automake -a
komutuyla gereken diğer dosyaları oluşturuyoruz:
$ automake -a
configure.ac:4: installing './compile'
configure.ac:3: installing './install-sh'
configure.ac:3: installing './missing'
Makefile.am: installing './depcomp'
Yazılımlarda olması beklenen bazı temel dosyaların (ChangeLog, README vb.) çalışma dizinimizde bulunmaması nedeniyle uyarı mesajlarını görmekteyiz ama şu aşamada bunu dikkate almamıza gerek yok.
automake -a
komutu sonrası dizin içeriğimiz aşağıdaki hale gelmektedir:
$ ls
aclocal.m4
autom4te.cache
compile -> /usr/share/automake-1.14/compile
config.h.in
configure
configure.ac
depcomp -> /usr/share/automake-1.14/depcomp
install-sh -> /usr/share/automake-1.14/install-sh
Makefile.am
Makefile.in
missing -> /usr/share/automake-1.14/missing
ornek.c
Bu haliyle ./configure
şeklinde betik uygulamamızı çalıştırıp sonucunu görelim:
$ ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking whether gcc understands -c and -o together... yes
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
checking how to run the C preprocessor... gcc -E
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking sys/time.h usability... yes
checking sys/time.h presence... yes
checking for sys/time.h... yes
checking for gettimeofday... yes
checking for mkdir... yes
checking for _mkdir... no
checking whether mkdir takes one argument... no
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: executing depfiles commands
İşlem bitiminde hem Makefile
hem de config.h
dosyası oluşacaktır:
/* config.h. Generated from config.h.in by configure. */
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the `gettimeofday' function. */
#define HAVE_GETTIMEOFDAY 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `mkdir' function. */
#define HAVE_MKDIR 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the `_mkdir' function. */
/* #undef HAVE__MKDIR */
/* Define if mkdir takes only one argument. */
/* #undef MKDIR_TAKES_ONE_ARG */
/* Name of package */
#define PACKAGE "ornek"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "[email protected]"
/* Define to the full name of this package. */
#define PACKAGE_NAME "ornek"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "ornek 0.1"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "ornek"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "0.1"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "0.1"
Artık Makefile dosyamız hazır olduğunda göre, make
komutu ile derleme işlemini yapabiliriz:
$ make
make all-am
make[1]: Entering directory /tmp/deneme
gcc -DHAVE_CONFIG_H -I. -g -O2 -MT ornek.o -MD -MP -MF \
.deps/ornek.Tpo -c -o ornek.o ornek.c
mv -f .deps/ornek.Tpo .deps/ornek.Po
gcc -g -O2 -o ornek ornek.o
make[1]: Leaving directory /tmp/deneme
Uygulamamızı çalıştıralım:
$ ./ornek dizin1
Örnek Çalışıyor
dizin1 dizini oluşturuldu
Uygulamanın Kurulumu
autotools bileşenleriyle yaptığımız bu çalışma, uygulamanın sadece derlenmesi sürecini değil, kurulum ve sistemden kaldırma süreçlerini de desteklemektedir. Bu noktada dilerseniz uygulamayı sisteme kurabilirsiniz. Bunun için uygulamanın kurulacağı dizinler üzerinde yazma yetkinizin bulunması gerekecektir.
Uygulamayı sistemimize kurmak için:
$ sudo make install
make[1]: Entering directory /tmp/deneme
/bin/mkdir -p /usr/local/bin
/usr/bin/install -c ornek /usr/local/bin
make[1]: Nothing to be done for install-data-am.
make[1]: Leaving directory /tmp/deneme
Sistemden kaldırmak için:
$ sudo make uninstall
( cd /usr/local/bin && rm -f ornek )
autoreconf
Zaman içerisinde Makefile.am
veya configure.ac
dosyalarında değişiklik yaptığınızda, autotools araçlarını doğru sırada yeniden çalıştırmanız gerekecektir.
Alternatif olarak, bu işlemi kolaylaştıran autoreconf
komutunu -vfi
parametresi ile kullanabiliriz. Bu şekilde değişiklik var ise gerekli bileşenler doğru sırada çalışacaktır:
$ autoreconf -vfi
autoreconf: Entering directory `.'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal --force
autoreconf: configure.ac: tracing
autoreconf: configure.ac: not using Libtool
autoreconf: running: /usr/bin/autoconf --force
autoreconf: running: /usr/bin/autoheader --force
autoreconf: running: automake --add-missing --copy --force-missing
Uygulamanın Dağıtıma Hazırlanması
Uygulamanızın artık hazır olduğunu düşündüğünüzde make distcheck
komutu ile onu paket haline getirebilirsiniz (Ekran çıktısı biraz uzun olduğundan burada listelenmemiştir). Bu komut işini tamamladığında bulunduğunuz dizinde ornek-0.1.tar.gz
adında bir dosya oluşacaktır. Artık bu dosya ile programınızın dağıtımını yapabilirsiniz.
Şimdi biraz da yaptığımız bu örneği biraz daha açıklayalım.
Makefile.am içerisinde mantıksal bir dil kullandık. Yazdığımız hiç bir satır çalıştırılmadı.
Diğer yandan configure.in içerisinde kullandığımız dil prosedüreldir, yazdığımız her satır çalıştırılacak bir komutu göstermektedir.
Makefile.am dosyası içerisindeki ilk satır programın ismini belirtirken ikinci satır programı oluşturan kaynak kodları belirtmektedir.
Şimdi daha karışık olan configure.in içerisindeki komutlara sırasıyla bakalım:
AC_INIT komutu configure betiği için ilklendirmeleri yapar. Parametre olarak kaynak dosyaların adlarını alır.
AM_INIT_AUTOMAKE komutu, automake kullanacağımızı gösterir. Parametre olarak programın ismini ve versiyonunu alır. Eğer Makefile.in dosyalarını elle hazırlayacak olsaydık bu komutu kullanmamıza da gerek olmayacaktı.
AC_PROG_CC komutu kullanılan C derleyicisinin ne olduğunu belirler.
AC_PROG_INSTALL komutu BSD uyumlu install uygulamasına sahip olup olmadığımızı denetler. Eğer yoksa bu işlem için install-sh'ı kullanır.
AC_OUTPUT komutu configure betik programının Makefile dosyalarını Makefile.in dosyalarından üretmesi gerektiğini belirtir.
Örneğimizdeki configure.in dosyası içerisinde yer almayan ama sıklıkla kullanacağımız bazı komutlar da şunlardır:
AC_PROG_RANLIB komutuyla bir kütüphane geliştiriyorsak ranlib'in sistemde nasıl kullanılacağını öğrenebiliriz.
AC_PROG_CXX komutuyla sistemdeki C++ derleyicisinin ne olduğunu öğrenebiliriz.
AC_PROG_YACC ve AC_PROG_LEX komutlarıyla kaynak kodlarımız lex veya yacc dosyaları içeriyorsa bu uygulamaların sistemde varlığını denetleyebiliriz.
Eğer alt dizinlerde başka Makefile dosyalarımız da olacaksa bunu
AC_OUTPUT(Makefile \
dizin1/Makefile \
dizin2/Makefile \
)
komutlarıyla belirtebiliriz.
Dosyaların içeriğinden bahsettikten sonra şimdi de biraz önc yaptığımız örnekte çalıştırdığımız komutlardan sonra neler olduğuna tekrar bakalım.
aclocal
komutu çalıştıktan sonra aclocal.m4 dosyası üretilir. Bu dosya içerisinde autoconf tarafından kullanılacak olan makrolar yer almaktadır (kendi özel makrolarımızı nasıl hazırlayacağımıza ileride değinilecektir).autoconf
komutuyla aclocal.m4 ve configure.ac dosyaları işlenerek configure betik programı oluşturulur.automake
komutu Makefile.am dosyasını temel alan bir Makefile.in oluşturur. Ayrıca GNU kodlama standartlarına göre eksik olan dosyalar için örnek birer kopya üretir../configure
komutuyla çalıştırılan betik programı daha önceden belirtilen özellikler için sistemimizi test eder ve Makefile.in dosyasını örnek alarak Makefile dosyalarını oluşturur. AC_OUTPUT() ile belirtilen tüm dosyalardaki @FOO@ şeklindeki kayıtları FOO için elde edilen değerlerle değiştirir (örneğin C derleyicisinin ne olduğu gibi).
Konfigürasyon Başlık Dosyalarının Kullanımı
Çoğu zaman derleme anında bazı makrolar tanımlamak isteriz. -D
seçeneği ile derleyiciye bildirilen bu değerleri programımız içerisinden kullanarak ilgili kod parçacığının çalışma şeklini değiştirebiliriz. autoconf kullandığımız bir uygulama için böylesi seçenekleri kullanmanın yolu konfigürasyon başlık dosyası, config.h
kullanmaktan geçmektedir.
config.h
mantığını kullanabilmemiz için test.c programımızın en başına aşağıdaki üç satırı eklemeliyiz:
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
Burada unutulmaması gereken önemli bir nokta, config.h dosyasının mutlaka ilk olarak include edilmesidir.
Program kaynak kodunu bu şekilde değiştirdikten sonra configure.ac
dosyasına AC_CONFIG_HEADERS([config.h])
satırını ve kontrol etmek istediğimiz ilgili makroları eklemeliyiz.
Automake Değişkenleri
Projemiz büyüdükçe kaynak kodların bulunduğu yerler gittikçe karışmaya başlar. Bunları düzenleyebilmek amacıyla daha hiyerarşik dizin yapıları kurarız. Ancak bu defa da her bir dizin için uygun Makefile dosyalarını üretmemiz gerekecektir. Bunun için bu bölümde Makefile.am dosyalarından daha detaylı bir şekilde bahsedeceğiz.
Makefile.am dosyalarının genel biçimi değişken = değer
şeklindedir. Ancak aynı zamanda, geleneksel Makefile mantığındaki gibi hedef ve soyut kural tanımlamalarını da destekler. Şimdi Makefile.am dosyalarında sıklıkla kullanacağımız satırlara bir bakalım.
INCLUDES = -I/usr/local/include -I/usr/custom/include ...: Obje kodlarını oluştururken derleyiciye include edilen dosyaları hangi dizinlerde araması gerektiğini belirtir. Ayrıca proje kaynak kod yapısı içerisindeki bir dizin seçenek olarak verildi ise alt dizinlerde yer alan kaynak programların hepsinin bu dosyalara erişebilmelerini sağlamak amacıyla tanımlama INCLUDES = -I$(top_srcdir)/src/libxxx şeklinde yapılmalıdır. Buradaki
$top_srcdir
değişkeni kaynak kod yapısı içerisindeki en üst dizini tutar.LDFLAGS = -L/usr/local/lib ...: Derleyici çalıştırılabilir dosyaları üretirken ihtiyaç duyduğu kütüphaneleri hangi dizinlerde araması gerektiğini bu tanımla öğrenecektir.
LDADD = test.o ... $(top_builddir)/lib/libfoo.a ... -lfoo ...: Tüm oluşacak çalıştırılabilir dosyalara linklemek istediğiniz sisteme kurulu olan ve olmayan obje dosyaları burada listelenir. Eğer listelenen obje dosyası sistemde kurulu değilse dosyanı tam adresi verilmelidir ($top_builddir/lib/libfoo.a örneğindeki gibi).
EXTRA_DIST = dosya1 dosya2 ...: Kaynak kod paketinizde bulunmasını istediğiniz her türlü dosyayı burada listeleyebilirsiniz.
SUBDIRS = dizin1 dizin2 ...: Bulunulan dizin için işlem yapmadan önce kuralların çalıştırılması gereken dizinlerdir. make uygulaması bulunulan dizinde işleme başlamadan önce, burada belirtilen dizinlerdeki Makefile kurallarını çalıştırır ve listelenen tüm dizinler için işlemleri bitirdikten sonra bu dizine geri döner.
bin_PROGRAMS = test test2 ...: make komutu çalıştıktan sonra üretilecek ve make install komutuyla belirli bir dizin altına kopyalanacak program adları burada listelenir.
lib_LIBRARIES = libfoo1.a libfoo2.a ...: make komutu çalıştıktan sonra üretilecek ve make install komutuyla belirli bir dizin altına kopyalanacak kütüphane dosyalarının adları burada listelenir.
check_PROGRAMS = program1 program2 ... : make komutunun çalışması esnasında üretilmeyip, sadece make check komutuyla üretilecek, programınızın tümünü veya bir kısmını test edecek uygulamaların çalıştırılabilir dosya adları listelenir.
TESTS = program1 program2 ...: make check komutu sonrasında test amaçlı çalıştırılacak dosya adlarını listeler. Çoğu durumda TEST = $(check_PROGRAMS) şeklinde bir tanımlama yapabilirsiniz.
include_HEADERS = foo1.h foo2.h ... : /prefix/include dizini altına kurulmasını istediğiniz başlık dosyalarını burada listelemelisiniz.
bin_PROGRAMS değişkeninde listelediğiniz her bir program için aşağıdaki tanımlamaları da yapmalısınız (program kelimesi yerine programın adını yazmalısınız):
program_SOURCES = test.c test1.c test2.c test.h test1.h test2.h ...: Automake programı burada belirtmiş olduğunuz dosya adları için, C, C++ ve Fortran dillerine özgün soyut Makefile kurallarını oluşturur. Eğer başka bir dil kullanılıyorsa gerekli kuralları siz vermelisiniz.
program_LDADD = $(top_builddir)/lib/libfoo.a -lnsl ...: Burada programınıza linklenmesi gereken kütüphaneleri listelemelisiniz.
program_LDFLAGS = -L/dizin1 ...: program_LDADD ile belirttiğiniz kütüphanelerin hangi dizinlerde aranması gerektiği burada listelenir.
program_DEPENDENCIES = dep1 dep2 ... : Programınızın derlenebilmesi için bağımlı olduğu diğer hedefleri burada listelemelisiniz.