Build Hello World with Automake

2 minute read

There are lot of IDEs out there can build apps or libraries for you, but this is not the way I like, I prefer the command line, today I am gonna show you how to do build a simple hello world with automake, both shared and static libraries are included, here is how it goes.

Hello World

mkdir -p helloworld/src;cd helloworld
cat << EOF >> src/helloworld.c
#include <stdio.h>

int main()
{
	printf("hello world\n");
	return 0;
}
EOF

cat << EOF >> src/Makefile.am
bin_PROGRAMS = helloworld
helloworld_SOURCES = helloworld.c
EOF

cat << EOF >> Makefile.am
SUBDIRS = src
AUTOMAKE_OPTIONS=foreign
EOF

Minor change needs to be made on the file generated:

autoscan
mv configure.scan configure.ac

sed -i '/AC_CONFIG_SRCDIR/iAM_INIT_AUTOMAKE' configure.ac
autoreconf -fvi

These are all the files needed to build a hello world:

$ tree
.
├── configure.ac
├── Makefile.am
└── src
    ├── helloworld.c
    └── Makefile.am

Generate Static Library

mkdir -p static/lib;cd static
cat << EOF >> lib/hello.c
#include <stdio.h>

void printa(char *msg)
{
	printf("test routine a: %s\n", msg);
}

void printb(char *msg)
{
	printf("test routine b: %s\n", msg);
}
EOF

mkdir include
cat << EOF >> include/hello.h
void printa(char *msg);
void printb(char *msg);
EOF

mkdir src
cat << EOF >> src/helloworld.c
#include <stdio.h>
#include <hello.h>

int main()
{
	printa("hello world call a");
	printb("hello world call b");
	return 0;
}
EOF

cat << EOF >> lib/Makefile.am
noinst_LIBRARIES=libhello.a
libhello_a_SOURCES=hello.c
EOF

cat << EOF >> src/Makefile.am
INCLUDES= -I ../include
bin_PROGRAMS = helloworld
helloworld_SOURCES = helloworld.c
helloworld_LDADD=../lib/libhello.a
EOF

cat << EOF >> Makefile.am
SUBDIRS = lib src       # lib must go first
AUTOMAKE_OPTIONS=foreign
EOF

If there are multiple binaries defined in bin_PROGRAMS, a filename_SOURCES is also needed.

autoscan
mv configure.scan configure.ac

sed -i '/AC_CONFIG_SRCDIR/iAM_INIT_AUTOMAKE' configure.ac
sed -i '/Checks for libraries/a AC_PROG_RANLIB' configure.ac
autoreconf -fvi
 helloworld tree
.
├── include
│   └── hello.h
├── lib
│   ├── hello.c
│   └── Makefile.am
├── Makefile.am
└── src
    ├── helloworld.c
    └── Makefile.am

Generate Shared Library

mkdir -p shared/lib;cd shared
cat << EOF >> lib/hello.c
#include <stdio.h>

void printa(char *msg)
{
	printf("test routine a: %s\n", msg);
}

void printb(char *msg)
{
	printf("test routine b: %s\n", msg);
}
EOF

mkdir include
cat << EOF >> include/hello.h
void printa(char *msg);
void printb(char *msg);
EOF

mkdir src
cat << EOF >> src/helloworld.c
#include <stdio.h>
#include <hello.h>

int main()
{
	printa("hello world call a");
	printb("hello world call b");
	return 0;
}
EOF

cat << EOF >> lib/Makefile.am
lib_LTLIBRARIES=libhello.la

# If this library has more than one source files, seperate them with white space
libhello_la_SOURCES=hello.c
EOF

cat << EOF >> src/Makefile.am
INCLUDES= -I ../include
bin_PROGRAMS = helloworld
helloworld_SOURCES = helloworld.c
helloworld_LDADD = -L../lib -lhello
EOF

cat << EOF >> Makefile.am
SUBDIRS = lib src       # lib must go first
AUTOMAKE_OPTIONS=foreign
EOF

If there are multiple binaries defined in bin_PROGRAMS, a filename_SOURCES is also needed.

autoscan
mv configure.scan configure.ac

sed -i '/AC_CONFIG_SRCDIR/iAM_INIT_AUTOMAKE' configure.ac
sed -i '/Checks for libraries/a AC_PROG_LIBTOOL' configure.ac
autoreconf -fvi