Простой пример

Простой пример [Вперед] [Вверх] [Назад] [Содержание]
Дальше: Более сложный пример Вверх: Использование Autoconf Назад: Структура и основные принципы

Простой пример

Сначала приведем тривиальный пример. Пусть имеется проект, состоящий из четырех файлов -- foo.c, bar.c, main.h и main.c, и файлы соответственно содержат:

foo.c:

#include "main.h"

void foo (void) {
  printf ("I am foo !\n");
}

bar.c:

#include "main.h"

void bar (void) {
  printf ("I am bar !\n");
}

main.h:

#ifndef __MAIN_H__
#define __MAIN_H__

#include <stdio.h>

extern void foo (void);
extern void bar (void);

#endif /* __MAIN_H__ */

main.c:

#include "main.h"

int main (void) {
  foo ();
  bar ();
  return 0;
}

Пусть также в проект входит Makefile-файл, который выглядит так:

CC=gcc
CFLAGS=-Wall -O3
LDFLAGS=

OBJECTS=main.o foo.o bar.o 
TARGET=prog

RM=rm -f
INSTALL=/usr/bin/install -c

BINDIR=/usr/local/bin

$(TARGET): $(OBJECTS)
        $(CC) $(LDFLAGS) -o $@ $(OBJECTS)

%.o: %.c
        $(CC) $(CFLAGS) -c $< 

foo.o: foo.c main.h
bar.o: bar.c main.h
main.o: main.c main.h

clean:
        $(RM) $(OBJECTS) $(TARGET)

install: $(TARGET)
        $(INSTALL) $(TARGET) $(BINDIR)

Теперь проиллюстрируем использование Autoconf. Зайдем в отдельную директорию, содержащую все файлы проекта и для начала посмотрим, что можно получить применением программы autoscan:

[user@host:homedir] cd prog-0.1
[user@host:prog-0.1] autoscan .

Так как проект очень маленький, выходной файл configure.scan получается не особенно содержательным:

dnl Process this file with autoconf to produce a configure script.
AC_INIT(bar.c)

dnl Checks for programs.
AC_PROG_INSTALL

dnl Checks for libraries.

dnl Checks for header files.

dnl Checks for typedefs, structures, and compiler characteristics.

dnl Checks for library functions.

AC_OUTPUT(Makefile)

(Символом ``dnl'', как можно догадаться, отмечаются комментарии -- они продолжаются до конца строки). Однако для иллюстрации принципов работы мы все-таки вставим несколько тестов: на наличие компилятора и проверку некоторых его возможностей, на наличие заголовочного файла stdio.h и на наличие функции printf(). Макрос AC_OUTPUT используем для генерации Makefile-файла из шаблона. Теперь файл configure.in будет выглядеть так:

dnl Process this file with autoconf to produce a configure script.
AC_INIT(bar.c)

dnl Checks for programs.
AC_PROG_INSTALL
AC_PROG_CC

dnl Checks for libraries.

dnl Checks for header files.
AC_CHECK_HEADER(stdio.h,,exit 1)

dnl Checks for typedefs, structures, and compiler characteristics.

dnl Checks for library functions.
AC_CHECK_FUNC(printf,,exit 1)

AC_OUTPUT(Makefile)

Теперь в процессе конфигурации будет вышолнены следующие действия:

  • определено местонахождение программы install и соответственно установлена переменная INSTALL, т.е. ее значение может быть замещено при генерации Makefile-файла из шаблона;
  • проверена функциональность C-компилятора, и переменная CC будет инициализирована именем (названием выполняемого файла) компилятора;
  • проверено наличие заголовочного файла stdio.h и, если таковой не будет обнаружен, процесс конфигурации завершится;
  • проверено наличие функции printf (функция должна быть доступна при компиляции без указания дополнительных опций компилятору) и, если таковая не будет обнаружена (т.е. тестовая программа не слинкуется), процесс конфигурации завершится;
  • сгенерируется Makefile.

Далее надо подготовить шаблон Makefile-файла, который по соглашению обычно называется Makefile.in. В нашем случае он легко получается из уже имеющегося Makefile-файла:

prefix = @prefix@
exec_prefix = @exec_prefix@
INSTDIR = @bindir@

CC=@CC@
CFLAGS=@CFLAGS@

OBJECTS=main.o foo.o bar.o 
TARGET=prog

RM=rm -f
INSTALL=@INSTALL@

$(TARGET): $(OBJECTS)
        $(CC) $(LDFLAGS) -o $@ $(OBJECTS)

%.o: %.c
        $(CC) $(CFLAGS) -c $< 

foo.o: foo.c main.h
bar.o: bar.c main.h
main.o: main.c main.h

install: $(TARGET)
        $(INSTALL) $(TARGET) $(INSTDIR)

clean:
        $(RM) $(OBJECTS) $(TARGET)

Этот шаблон отличается от исходного Makefile-файла тем, что при выполнении configure всем переменным, имена которых заключены в знаки @, будут присвоены значения, определенные во время конфигурации. Например, если будет указана команда

[user@host:prog-0.1] ./configure --prefix=/some/other/dir

то переменная prefix в созданном Makefile-файле будет иметь значение /some/other/dir, иначе будет установлено значение по умолчанию (обычно /usr/local).

Выполним команду configure и посмотрим, что же произойдет:

[user@host:prog-0.1] ./configure

creating cache ./config.cache
checking for a BSD compatible install... /usr/bin/install -c
checking for gcc... gcc
checking whether the C compiler (gcc  ) works... yes
checking whether the C compiler (gcc  ) is a cross-compiler... no
checking whether we are using GNU C... yes
checking whether gcc accepts -g... yes
checking how to run the C preprocessor... gcc -E
checking for stdio.h... yes
checking for printf... yes
updating cache ./config.cache
creating ./config.status
creating Makefile

Теперь посмотрим сгенерированный Makefile-файл:

# Generated automatically from Makefile.in by configure.
prefix = /usr/local
exec_prefix = ${prefix}
INSTDIR = ${exec_prefix}/bin

CC=gcc
CFLAGS=-g -O2

OBJECTS=main.o foo.o bar.o 
TARGET=prog

RM=rm -f
INSTALL=/usr/bin/install -c

$(TARGET): $(OBJECTS)
        $(CC) $(LDFLAGS) -o $@ $(OBJECTS)

%.o: %.c
        $(CC) $(CFLAGS) -c $< 

foo.o: foo.c main.h
bar.o: bar.c main.h
main.o: main.c main.h

install: $(TARGET)
        $(INSTALL) $(TARGET) $(INSTDIR)

clean:
        $(RM) $(OBJECTS) $(TARGET)

Как можно видеть, переменным prefix, CC, CFLAGS и INSTALL присвоены значения по умолчанию. Используя опцию --help configure, можно получить список параметров, которые можно использовать для их изменения. Теперь можно набирать make или сразу make install.

Понятно, что ``интеллект'' конфигурационного скрипта целиком и полностью зависит от использованных макросов, и в принципе, имея достаточные навыки программирования на языке командного интерпретатора, можно создать какой угодно тест. Другое дело, что всего предусмотреть нельзя, и обычно ограничиваются некоторым разумным числом тестов.



Dmitry A. Antipov
1999-05-26