I've been tasked with giving a legacy codebase some love. The actual code is written in C, but is not very relevant aside from the #include
s each file makes. No, the bulk of this task involves GNU Autotools.
Project hierarchy
.
├── AUTHORS
├── buildall
├── ChangeLog
├── configure.ac
├── COPYING
├── include
│ ├── Makefile.am
│ └── skey.h
├── INSTALL
├── lib
│ ├── Makefile.am
│ ├── md4.c
│ ├── md4.h
│ ├── put.c
│ ├── skeylogin.c
│ └── skeysubr.c
├── Makefile.am
├── man
│ ├── key.1
│ ├── keyinit.1
│ ├── keysh.1
│ └── skey.1
├── NEWS
├── README
├── skey
│ ├── Makefile.am
│ └── skey.c
├── skeyinit
│ ├── Makefile.am
│ └── skeyinit.c
└── skeysh
├── Makefile.am
└── skeysh.c
configure.ac
AC_PREREQ([2.59])
AC_INIT([skey], [2.0], [[email protected]])
AC_CONFIG_SRCDIR([skey/skey.c])
AC_CONFIG_HEADERS([config.h])
AC_CANONICAL_HOST
AM_INIT_AUTOMAKE
# Checks for programs.
AC_C_BIGENDIAN
AC_C_CONST
AC_PROG_CC_STDC
AC_PROG_CPP
AC_PROG_MAKE_SET
AC_PROG_RANLIB
AC_PROG_INSTALL
# Configure the compiler.
CFLAGS+=" -std=gnu99"
# Checks for libraries.
AC_CHECK_LIB([crypt], [crypt])
# Checks for header files.
AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h netdb.h netinet/in.h shadow.h stdlib.h string.h strings.h sys/file.h sys/ioctl.h sys/param.h sys/socket.h sys/systeminfo.h sys/time.h syslog.h termio.h termios.h unistd.h utmp.h utmpx.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_UID_T
AC_TYPE_MODE_T
AC_TYPE_OFF_T
AC_TYPE_PID_T
AC_CHECK_MEMBERS([struct stat.st_blksize])
# Checks for library functions.
AC_FUNC_CHOWN
AC_FUNC_FORK
AC_FUNC_MALLOC
AC_CHECK_FUNCS([alarm bzero endpwent ftruncate getcwd gethostbyaddr gethostbyname gethostname getpass getspnam gettimeofday getusershell inet_ntoa isascii memset mkdir putenv realpath rmdir setenv socket strcasecmp strchr strdup strerror strncasecmp strpbrk strrchr strstr sysinfo tzset])
AC_CONFIG_FILES([Makefile lib/Makefile include/Makefile skey/Makefile skeyinit/Makefile skeysh/Makefile])
AC_OUTPUT
Root Makefile.am
SUBDIRS=lib skey skeyinit skeysh include
man_MANS = man/skey.1
lib:
cd lib && $(MAKE) all
skey: lib
cd skey && $(MAKE) all
skeyinit: lib
cd skeyinit && $(MAKE) all
skeysh: lib
cd skeysh && $(MAKE) all
all: lib skey skeyinit skeysh
install: all
cd lib && $(MAKE) install && cd ..
cd skey && $(MAKE) install && cd ..
cd include && $(MAKE) install && cd ..
cd skeyinit && $(MAKE) install && cd ..
cd skeysh && $(MAKE) install && cd ..
$(INSTALL_DATA) $(man_MANS) $(mandir)
$(INSTALL_DATA) README $(docdir)
lib/Makefile.am
lib_LIBRARIES = libskey.a
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir) -I.
libskey_a_SOURCES = skeylogin.c skeysubr.c md4.c put.c
%.o: %.c
$(CC) -c $(CFLAGS) $(INCLUDES) $< -o $@
$(lib_LIBRARIES): $(libskey_a_SOURCES)
ar -rs $(lib_LIBRARIES) skeylogin.o skeysubr.o md4.o put.o
all: $(lib_LIBRARIES)
install: all
$(INSTALL) $(lib_LIBRARIES) $(libdir)
skey/Makefile.am
bin_PROGRAMS = key
key_SOURCES = skey.c
man_MANS = ../man/key.1
key_LDADD = ../lib/libskey.a
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir) -I.
%.o: %.c
$(CC) -c $(CFLAGS) $(INCLUDES) $< -o $@
$(bin_PROGRAMS): $(key_SOURCES) $(key_LDADD)
$(CC) -o $@ $(CFLAGS) $(INCLUDES) $(key_SOURCES) $(key_LDADD)
chmod +x $(bin_PROGRAMS)
all: $(bin_PROGRAMS)
install: all
$(INSTALL) $(bin_PROGRAMS) $(bindir)
$(INSTALL_DATA) $(man_MANS) $(mandir)
include/Makefile.am
include_HEADERS = skey.h ../config.h
install:
$(INSTALL) $(include_HEADERS) $(includedir)
I'm not gonna show the others because this post is long enough as it is. They're mostly variations of skey/Makefile.am.
My goals
The goal of what I have here is to compile a bunch of subprojects, and then install them (via make install
). There are other targets I'm planning, but their details are not in the scope of this question.
I'm writing most of this code on my personal machine, which runs Kubuntu 15.10.
My questions
- Some constructs in the various 'Makefile.am's may be redundant. How can I eliminate them?
- I need to support nine different OSes, all Unix flavors (not necessarily Linux). Am I doing anything that hampers portability?
- Are there Autotools best practices that I could be employing?
- Can the command I use to compile and link the code be improved? What about the parts that link to the contents of
lib
(which is a static library)? - What standard/conventional
make
targets am I missing (besidesclean
,dist
, andcheck
, which are planned)?
It's entirely possible that I'm unknowingly doing extraneous checks in my configure.ac.