Starting New Project with GNU Autotools

This document describes steps you have to take if you want to start a new automake project. An example presented here assumes that you use both libASSA and Gtkmm, which is optional.

If your new project is an on-line SGML/XML manual, some configuration files will be different (smaller). The differences are noted where applicable.


Contents


Directory Structure

Minimum files are places in a rigid directory structure for your projects. Each file is discussed individually.


project/
  |
  +- configure.in
  +- Makefile.am
  +- bootstrap
  +- project.spec.in
  +- app-docs.make
  |
  +- src/
  |   |
  |   +- Makefile.am
  |
  |- docs/
      |
      +- Makefile.am
      |
      +- C/
         |
         +- Makefile.am
         +- project.sgml
         +- topic.dat
         |
         +- figures/

		  

[up]


configure.in

You need configure.in to generate configure script. Here is an example:

			
dnl ----------------------------------------------------------------------------
dnl configure.in - an example
dnl 
dnl Replace: YOUR-FILE, YOUR-APPLICATION-NAME
dnl ----------------------------------------------------------------------------

dnl Process this file with autoconf to produce a configure script.
AC_INIT(src/YOUR-FILE)
AM_CONFIG_HEADER(config.h)

dnl ----------------------------------------------------------------------------
dnl Package name and release number
dnl
dnl Legend:
dnl
dnl  +1 : ? : +1  == new interface that does not break old one
dnl  +1 : ? : 0   == new interface that breaks old one
dnl   ? : ? : 0   == no new interfaces, but breaks apps
dnl   ? :+1 : ?   == just some internal changes, nothing breaks but might work
dnl                  better
dnl ----------------------------------------------------------------------------

APP_MAJOR_VERSION=1
APP_MINOR_VERSION=0
APP_MICRO_VERSION=0

APP_VERSION=$APP_MAJOR_VERSION.$APP_MINOR_VERSION.$APP_MICRO_VERSION
APP_SUBVERSION=$APP_MAJOR_VERSION.$APP_MINOR_VERSION
APP_RELEASE=$APP_MAJOR_VERSION.$APP_MINOR_VERSION

AC_DEFINE_UNQUOTED(APP_MAJOR_VERSION, $APP_MAJOR_VERSION, [Major version])
AC_DEFINE_UNQUOTED(APP_MINOR_VERSION, $APP_MINOR_VERSION, [Minor version])
AC_DEFINE_UNQUOTED(APP_MICRO_VERSION, $APP_MICRO_VERSION, [Micro version])

AC_SUBST(APP_VERSION)
AC_SUBST(APP_SUBVERSION)
AC_SUBST(APP_RELEASE)

VERSION=$APP_VERSION
SUBVERSION=$APP_SUBVERSION

PACKAGE=YOUR-APPLICATION-NAME

dnl AC_SUBST(VERSION)
dnl AC_SUBST(SUBVERSION)
dnl AC_SUBST(PACKAGE)

AM_INIT_AUTOMAKE($PACKAGE,$VERSION)
AM_MAINTAINER_MODE

dnl ----------------------------------------------------------------------------
dnl Check build environment
dnl ----------------------------------------------------------------------------
AC_ISC_POSIX
AC_HEADER_STDC

AC_PROG_CC
AC_PROG_CXX
AC_PROG_CXXCPP
AM_PROG_LIBTOOL
AM_SANITY_CHECK

dnl ----------------------------------------------------------------------------
dnl Set PACKAGE_LOCALE_DIR in config.h.
dnl ----------------------------------------------------------------------------

if test "x${prefix}" = "xNONE"; then
  AC_DEFINE_UNQUOTED(PACKAGE_LOCALE_DIR, "${ac_default_prefix}/${DATADIRNAME}/locale", [Localized package directory])
else
  AC_DEFINE_UNQUOTED(PACKAGE_LOCALE_DIR, "${prefix}/${DATADIRNAME}/locale", [Localized package directory])
fi

AC_LANG_CPLUSPLUS

dnl ----------------------------------------------------------------------------
dnl Pull in all necessary gtk2 libraries
dnl Replace with the current version number
dnl ----------------------------------------------------------------------------

PKG_CHECK_MODULES(GTKMM, gtkmm-2.0 >= 1.5.1)
AC_SUBST(GTKMM_CFLAGS)
AC_SUBST(GTKMM_LIBS)

dnl ----------------------------------------------------------------------------
dnl Pick up ASSA library flags.
dnl Replace with the current version number
dnl ----------------------------------------------------------------------------

PKG_CHECK_MODULES(ASSA, assa >= 3.2.0)
AC_SUBST(ASSA_CFLAGS)
AC_SUBST(ASSA_LIBS)

dnl ----------------------------------------------------------------------------
dnl Checks for header files.
dnl ----------------------------------------------------------------------------
AC_HEADER_DIRENT
AC_HEADER_STDC
AC_CHECK_HEADERS(limits.h unistd.h)

dnl ----------------------------------------------------------------------------
dnl Checks for typedefs, structures, and compiler characteristics.
dnl ----------------------------------------------------------------------------
AC_TYPE_PID_T
AC_TYPE_SIZE_T

dnl ----------------------------------------------------------------------------
dnl Checks for library functions.
dnl ----------------------------------------------------------------------------
AC_CHECK_FUNCS(getcwd mkdir strerror strtol)

dnl ----------------------------------------------------------------------------
dnl Post-processing - make substitution
dnl ----------------------------------------------------------------------------

AC_SUBST(CFLAGS)
AC_SUBST(CPPFLAGS)
AC_SUBST(CXXFLAGS)
AC_SUBST(LIBS)
AC_SUBST(LDFLAGS)

dnl ----------------------------------------------------------------------------
dnl Generate Make files
dnl ----------------------------------------------------------------------------

AC_OUTPUT([
Makefile 
YOUR-APPLICATION-NAME.spec
src/Makefile 
docs/Makefile
docs/C/Makefile
])
		  

If your new project is an SGML/XML document, then you need a different version of configure.in

			
# Copyright (c) 2003 Vladislav Grinchenko

dnl Process this file with autoconf to produce a configure script.

AC_INIT(docs/C/YOUR-MANUAL.sgml)

dnl ==========================================================================

AM_CONFIG_HEADER(config.h)
AM_INIT_AUTOMAKE(YOUR-MANUAL, 1.0)
AM_PROG_LIBTOOL

AC_OUTPUT(
YOUR-MANUAL.spec
docs/Makefile
docs/C/Makefile
Makefile)
		  

[up]


Top Makefile.am

You also need a top source directory Makefile.am:


# -----------------------------------------------------
# Makefile.am example
# -----------------------------------------------------

SUBDIRS = src 
		  
		  

On-line manual version of Makefile.am is slightly different:

#
# Name: $srcdir/Makefile.am
#
# $Id: start_new_proj.html,v 1.3 2003/09/15 22:19:30 vlad Exp $

DIST_SUBDIRS = docs
SUBDIRS = docs

EXTRA_DIST = \
	YOUR-MANUAL.spec.in \
	COPYING-DOCS \
	sgmldocs.make

dist-hook: YOUR-MANUAL.spec
	cp YOUR-MANUAL.spec $(distdir)

local-clean:
    -rm -f *~ 
		  

[up]


app-docs.make / sgmldocs.make

app-docs.make helps to generate HTML documentation. When you cut-n-paste, make sure TAB characters are preserved.


helpdir = $(datadir)/gnome/help/$(app)/$(lang)
help_DATA = \
    index.html  \
    topic.dat   \
    $(figs)

EXTRA_DIST = $(app).sgml $(help_DATA)

all: index.html

index.html: $(app)/index.html
    -cp $(app)/index.html .

# the wierd srcdir trick is because the db2html from the Cygnus RPMs
# cannot handle relative filenames
$(app)/index.html: $(srcdir)/$(app).sgml
    -srcdir=`cd $(srcdir) && pwd`; \
    db2html $$srcdir/$(app).sgml

app-dist-hook: index.html
    -$(mkinstalldirs) $(distdir)/$(app)/stylesheet-images
    -$(mkinstalldirs) $(distdir)/images
    -cp $(srcdir)/$(app)/*.html $(distdir)/$(app)
    -cp $(srcdir)/$(app)/*.css $(distdir)/$(app)
    -cp $(srcdir)/$(app)/stylesheet-images/*.png \
        $(distdir)/$(app)/stylesheet-images
    -cp $(srcdir)/$(app)/stylesheet-images/*.gif \
        $(distdir)/$(app)/stylesheet-images
    -cp $(srcdir)/images/*.png \
        $(distdir)/images
    -cp $(srcdir)/images/*.gif \
        $(distdir)/images

install-data-am: index.html
    -$(mkinstalldirs) $(DESTDIR)$(helpdir)/stylesheet-images
    -$(mkinstalldirs) $(DESTDIR)$(helpdir)/images
    -cp $(srcdir)/topic.dat $(DESTDIR)$(helpdir)
    -for file in $(srcdir)/$(app)/*.html $(srcdir)/$(app)/*.css $(srcdir)/*.png;
      basefile=`echo $$file | sed -e 's,^.*/,,'`; \
      $(INSTALL_DATA) $$file $(DESTDIR)$(helpdir)/$$basefile; \
    done
    -for file in $(srcdir)/images/*.png; do \
      basefile=`echo $$file | sed -e  's,^.*/,,'`; \
      $(INSTALL_DATA) $$file $(DESTDIR)$(helpdir)/images/$$basefile; \
    done
    -for file in $(srcdir)/$(app)/stylesheet-images/*.png; do \
      basefile=`echo $$file | sed -e  's,^.*/,,'`; \
      $(INSTALL_DATA) $$file $(DESTDIR)$(helpdir)/stylesheet-images/$$basefile;
    done
    -for file in $(srcdir)/$(app)/stylesheet-images/*.gif; do \
      basefile=`echo $$file | sed -e  's,^.*/,,'`; \
      $(INSTALL_DATA) $$file $(DESTDIR)$(helpdir)/stylesheet-images/$$basefile;
    done

$(app).ps: $(srcdir)/$(app).sgml
    -srcdir=`cd $(srcdir) && pwd`; \
    db2ps $$srcdir/$(app).sgml

$(app).rtf: $(srcdir)/$(app).sgml
    -srcdir=`cd $(srcdir) && pwd`; \
    db2ps $$srcdir/$(app).sgml
		  

For your on-line manual project, you would need sgmldocs.make instead.


# Name: sgmldocs.make
#
#        /usr/share/YOUR-MANUAL/C
#

docdir     = $(datadir)/$(docname)/$(lang)
sgml_files = $(sgml_ents) $(docname).sgml
omf_dir    = $(top_srcdir)/omf-install

EXTRA_DIST = $(sgml_files) $(omffile)
CLEANFILES = omf_timestamp

all: index.html omf

omf: omf_timestamp

omf_timestamp: $(omffile)
	-for file in $(omffile); do \
	scrollkeeper-preinstall $(docdir)/$(docname).sgml $$file $(omf_dir)/$$file; \
	done
	touch omf_timestamp

index.html: $(docname)/book1.html
	-cp -f $(docname)/book1.html ./index.html

# Doesn't work! Don't know why.
#
#$(docname).sgml: $(sgml_ents)
#	ourdir=`pwd`;  \
#	cd $(srcdir);   \
#	cp $(sgml_ents) $$ourdir

# The weird srcdir trick is because the db2html from the Cygnus RPMs
# cannot handle relative filenames
#
$(docname)/book1.html: $(srcdir)/$(docname).sgml
	-srcdir=`cd $(srcdir) && pwd`; \
	db2html -i online $$srcdir/$(docname).sgml

# Add files to the standard distribution
#
app-dist-hook: index.html
	-$(mkinstalldirs) $(distdir)/$(docname)
	-$(mkinstalldirs) $(distdir)/$(docname)/stylesheet-images
	-$(mkinstalldirs) $(distdir)/${figdir}
	-cp $(srcdir)/$(docname)/*.html $(distdir)/$(docname)
	-for file in $(srcdir)/$(docname)/stylesheet-images/*.gif; do \
		basefile=`echo $$file | sed -e  's,^.*/,,'`; \
		cp $$file $(distdir)/$(docname)/stylesheet-images/$$basefile ; \
	done 
	-for file in $(srcdir)/$(figdir)/*.png; do \
		basefile=`echo $$file | sed -e 's,^.*/,,'`; \
		cp $$file $(distdir)/$(figdir)/$$basefile; \
	done 
	-if [ -e topic.dat ]; then \
		cp $(srcdir)/topic.dat $(distdir); \
	fi

#	-for file in $(srcdir)/$(figdir)/*.png; do \
#		basefile=`echo $$file | sed -e  's,^.*/,,'`; \
#		cp $$file $(distdir)/$(figdir)/$$basefile ; \
#	done

install-data-am: index.html omf
	-$(mkinstalldirs) $(DESTDIR)$(docdir)/stylesheet-images
	-$(mkinstalldirs) $(DESTDIR)${datadir}/${docname}/$(figdir)
	-cp $(srcdir)/$(sgml_files) $(DESTDIR)$(docdir)
	-for file in $(srcdir)/$(docname)/*.html ; do \
		basefile=`echo $$file | sed -e 's,^.*/,,'`; \
		$(INSTALL_DATA) $$file $(DESTDIR)$(docdir)/$$basefile; \
	done
	-for file in $(srcdir)/$(figdir)/*.png; do \
		basefile=`echo $$file | sed -e  's,^.*/,,'`; \
		$(INSTALL_DATA) $$file $(DESTDIR)/${datadir}/${docname}/$(figdir)/$$basefile; \
	done
	-for file in $(srcdir)/$(docname)/stylesheet-images/*.gif; do \
		basefile=`echo $$file | sed -e  's,^.*/,,'`; \
		$(INSTALL_DATA) $$file $(DESTDIR)$(docdir)/stylesheet-images/$$basefile; \
	done
	-if [ -e $(srcdir)/topic.dat ]; then \
		$(INSTALL_DATA) $(srcdir)/topic.dat $(DESTDIR)$(docdir); \
	fi

$(docname).pdf: $(srcdir)/$(docname).sgml
	-srcdir=`cd $(srcdir) && pwd`; \
	db2pdf -i printout $$srcdir/$(docname).sgml

$(docname).ps: $(srcdir)/$(docname).sgml
	-srcdir=`cd $(srcdir) && pwd`; \
	db2ps -i printout $$srcdir/$(docname).sgml

$(docname).rtf: $(srcdir)/$(docname).sgml
	-srcdir=`cd $(srcdir) && pwd`; \
	db2ps $$srcdir/$(docname).sgml

uninstall-local:
	-for file in $(srcdir)/$(docname)/stylesheet-images/*.gif; do \
		basefile=`echo $$file | sed -e  's,^.*/,,'`; \
		rm -f $(docdir)/stylesheet-images/$$basefile; \
	done
	-for file in $(srcdir)/$(figdir)/*.png; do \
		basefile=`echo $$file | sed -e  's,^.*/,,'`; \
		rm -f $(docdir)/$(figdir)/$$basefile; \
	done
	-for file in $(srcdir)/$(docname)/*.html ; do \
		basefile=`echo $$file | sed -e 's,^.*/,,'`; \
		rm -f $(DESTDIR)$(docdir)/$$basefile; \
	done
	-for file in $(sgml_files); do \
		rm -f $(DESTDIR)$(docdir)/$$file; \
	done
	-rmdir $(DESTDIR)$(docdir)/stylesheet-images
	-rmdir $(DESTDIR)/$(figdir)
	-rmdir $(DESTDIR)$(docdir)
		  

[up]


RPM spec file

If you intend to procude an RPM package for your project, you would need a SPEC file.

			
# Note that this is NOT a relocateable package

%define name            @PACKAGE@
%define ver             @VERSION@
%define RELEASE         0
%define rel             %{?CUSTOM_RELEASE} %{!?CUSTOM_RELEASE:%RELEASE}
%define prefix          /usr
%define mandir          /usr/man
%define datadir         /usr/share
%define sysconfdir      /etc
%define localstatedir   /var/lib

Summary:    YOUR MANUAL
Name:       %name
Version:    %ver
Release:    1
Source:     %{name}-%{version}.tar.gz
Copyright:  GNU Free Documentation License
Group:      Development/Libraries
BuildArch:  noarch
BuildRoot:  /var/tmp/%{name}-%{ver}-root
URL:        http://YOUR-MANUAL-URL/

%description 
YOUR-MANUAL description

#===============================================================================
# preparation section
#===============================================================================

%prep
%setup

#===============================================================================
# build section
#===============================================================================

%build
%configure
if [ "$SMP" != "" ]; then
  make -j$SMP "MAKE=make -j$SMP"
else
  make
fi

#===============================================================================
# install section
#===============================================================================

%install
if [ -d $RPM_BUILD_ROOT ]; then rm -rf $RPM_BUILD_ROOT; fi
make DESTDIR=$RPM_BUILD_ROOT install

#===============================================================================
# clenup section
#===============================================================================

%clean
rm -rf $RPM_BUILD_ROOT

#===============================================================================
# files that go into libassa package
#===============================================================================

%files
%defattr(-,root,root)

%doc COPYING COPYING-DOCS AUTHORS README ChangeLog NEWS INSTALL 
%{prefix}/share

#===============================================================================

%changelog
* Wed Jul 16 2003 YOUR NAME, YOUR E-MAIL ADDRESS
- release 1.0 - first public release

		  

[up]


src/Makefile.am

This file is also required to start coding along with the presence of src/YOUR-FILE mentioned at the top of configure.in.

		  
# -*- makefile -*-
# ------------------------------------------------------------------------------
#                              src/Makefile.am
#
# Replace: YOUR-APPLICATION-NAME, your_application_name
# ------------------------------------------------------------------------------

bin_PROGRAMS = YOUR-APPLICATION-NAME

your_application_name_SOURCES = \
#  list your headers and source files here


INCLUDES = \
    -g \
	@ASSA_CFLAGS@ \
	@GTKMM_CFLAGS@ \
	@CXXFLAGS@

AM_LDFLAGS= -g @LDFLAGS@ 

your_application_name_LDADD = \
	@ASSA_LIBS@ \
	@GTKMM_LIBS@ \
	@LIBS@

clean-local:
	-rm -f log *.log *.log.old *~ *.dat *.gwm

# Disable autoheader.
AUTOHEADER=echo 
		  

Note that you have to repace both YOUR-APPLICATION-NAME and your_application_name the difference being is that the second one is normalized name (i.e. My-Super-Server becomes my_super_server).

[up]


docs/Makefile.am

			
SUBDIRS = C
		  

[up]


docs/C/Makefile.am

This is the makefile that governs how your documentation is built. It actually includes $topsrcdir/app-docs.make that describes build rules.

			
figs =
app = cortexsim
lang = C

include $(top_srcdir)/app-docs.make

dist-hook: app-dist-hook			
		  

Your on-line manual project will have more elaborate structure that might include several different SGML files, each of which might be a separate chapter.

			
# -*- makefile -*-
# ------------------------------------------------------------------------------
#                          docs/C/Makefile.am
# ------------------------------------------------------------------------------
#  $Id: start_new_proj.html,v 1.3 2003/09/15 22:19:30 vlad Exp $
# ------------------------------------------------------------------------------
# Created: Fri Sep 12 10:47:36 EDT 2003
# ------------------------------------------------------------------------------

lang      = C
docname   = YOUR-MANUAL
figdir    = figures
omffile   =

sgml_ents = \
	CHAPTER_1.sgml \
	CHAPTER_2.sgml \
	CHAPTER_3.sgml 

figs = \
	${figdir}/GRANDE-DIAGRAM.png \
	${figdir}/DETAILED-DIAGRAM.png

include $(top_srcdir)/sgmldocs.make

# From 'automake' manual, Ch.  15.3 "The dist hook":
# 
# "Occasionally it is useful to be able to change the distribution before 
#  it is packaged up. If the dist-hook target exists, it is run after the 
#  distribution directory is filled, but before the actual tar (or shar) 
#  file is created. One way to use this is for distributing files in 
#  subdirectories for which a new `Makefile.am' is overkill"

dist-hook: app-dist-hook

clean-local:
	-rm -rf ${docname} ${docname}.junk *~
	-rm -f *.aux *.log *.out *.pdf *.ps	
		  
		  

[up]


docs/C/project.sgml

SGML file that is the manual for your application.

			
<!-- -*- sgml -*- -->
<!doctype book PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
<book id="classes">
  <bookinfo>
	<title>CortexNT Simulator</title>

	<author>
      <firstname>Vladislav</firstname>
      <surname>Grinchenko</surname>
      <affiliation>
		<address><email>vlg@sourceforge.net</email></address>
      </affiliation>
    </author>    
	
	<copyright>
      <year>2003</year>
      <holder role="mailto:vlg@sourceforge.net">Vladislav Grinchenko</holder>
    </copyright>

	<abstract>
	  <para>This document describes configuration of 
		<literal remap="tt">cortexsim</literal> simulator.</para>
	</abstract>
  </bookinfo>

  <toc></toc>

  <!-- CH: INSTALLATION -->
  <chapter>
	<title>Installation</title>

	<sect1>
	  <title>Requirements</title>
	  <para></para>
	</sect1>

	<sect1>
	  <title>Compiling <applicaton>cortexsim</applicaton></title>
	  <para></para>
	</sect1>
  </chapter>

  <!-- CH: CONFIGURATION -->
  <chapter>
	<title>Configuration</title>

	<para></para>

	<sect1>
	  <title>System Configuration Files</title>
	  <para></para>
	</sect1>

	<sect1>
	  <title>Command-Line Arguments</title>
	  <para></para>
	</sect1>

	<sect1>
	  <title>Input/Output Files</title>
	  <para></para>
	</sect1>
  </chapter>

</book>			
		  
		  

Your on-line manual will probably consist of numerous chapters, each of which located in a separate SGML file. Consult "Creating SGML document" notes.

[up]


docs/C/topic.dat

Silly file that does nothing special.

			
index.html      Help
		  

[up]


Generating Configuration Files

Now it is time to generate configuration files. You can use the following bootstrap file.

		  
# bootstrap

aclocal
autoheader
libtoolize --force --copy
touch NEWS README AUTHORS ChangeLog
automake --add-missing --gnu --copy
autoconf
configure --enable-maintainer-mode --enable-compile-warnings
echo "Now type \`make' to compile your package"
		  

Change bootstrap's permission to 755 and run it to generate all Makefile files.

[up]


Last updated on Thu Dec 18 07:23:36 EST 2003
Copyright © 2002-2003 Vladislav Grinchenko