Created
April 16, 2024 04:32
-
-
Save mofosyne/21fca0eb74fbc788983c1068af92bc83 to your computer and use it in GitHub Desktop.
This is a helper script to generate a minimum gnu autotools C based repo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# INITIALIZE MINIMAL AUTOTOOLS BASED C PROGRAM (Brian Khuu 2024) | |
# https://briankhuu.com/blog/2024/04/11/initialise-minimal-autotools-script/ | |
set -euo pipefail | |
# Function to display usage | |
show_usage() { | |
echo "Usage: $0 [PACKAGE_NAME]" | |
exit 1 | |
} | |
# Parse command-line arguments | |
if [ "$#" -eq 0 ]; then | |
read -p "Enter project name: " PACKAGE_NAME | |
elif [ "$#" -eq 1 ]; then | |
PACKAGE_NAME="$1" | |
else | |
show_usage | |
fi | |
# Create project directory if it doesn't exist | |
if [ ! -d "$PACKAGE_NAME" ]; then | |
mkdir "$PACKAGE_NAME" | |
fi | |
cd "$PACKAGE_NAME" || exit 1 | |
echo "== GENERATING FILES ==" | |
# Create README.md | |
cat <<EOF >README.md | |
# $PACKAGE_NAME | |
A minimal Autotools-based C project. | |
Quickstart Tip: Just run \`./bootstrap.sh && ./build.sh && ./test.sh\` to build and test. | |
Your executable will be located at \`./$PACKAGE_NAME\`. | |
Use \`./clean.sh\ && ./bootstrap.sh\` to reset to a clean slate. | |
EOF | |
# Create M4 folder | |
mkdir -p m4 | |
cat <<EOF >m4/readme.md | |
# Autotools M4 Macro Directory | |
This directory contains custom or third-party macros used by Autotools. | |
## Purpose | |
These macros are included in the Autotools build process via the \`AC_CONFIG_MACRO_DIRS([m4])\` directive in the \`configure.ac\` file. | |
It is also accessible within \`configure.ac\` as well as m4 does a double pass as well. | |
## Usage | |
Ensure to include \`-I m4\` in the \`ACLOCAL_AMFLAGS\` variable within the \`Makefile.am\` file to instruct \`aclocal\` to search for macros in this directory. | |
EOF | |
# Create configure.ac | |
cat <<EOF >configure.ac | |
m4_define([program_version], [0.1]) | |
AC_INIT([$PACKAGE_NAME], [program_version]) | |
AC_PREREQ([2.65]) # Minimum version number for autoconf build system | |
AC_CONFIG_SRCDIR([src/main.c]) # Ensure the main source file exists | |
AC_CONFIG_HEADERS([src/config.h:config_h.in]) # Generate config header | |
AC_CONFIG_AUX_DIR([build-aux]) # Put autotools auxiliary files into a seperate dir to reduce clutter | |
AC_CONFIG_MACRO_DIRS([m4]) # Put autotools M4 macros files into a seperate dir to reduce clutter | |
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects]) # Initialize Automake with options | |
AC_CONFIG_FILES([Makefile]) # Specify Makefile generation for main directory and src directory | |
AC_PROG_CC # Find and set up C compiler | |
AC_OUTPUT # Generate output files | |
EOF | |
# Create Makefile.am | |
cat <<EOF >Makefile.am | |
bin_PROGRAMS = $PACKAGE_NAME | |
${PACKAGE_NAME}_SOURCES = src/main.c src/hello.h | |
check_PROGRAMS = unit_test | |
unit_test_SOURCES = tests/unit_test.c src/hello.h | |
# ACLOCAL_AMFLAGS specifies additional flags for aclocal. | |
# -I m4: Include the m4 directory for additional macros. | |
# --install: Automatically install missing macros into the system-wide directory. | |
ACLOCAL_AMFLAGS = -I m4 --install | |
EOF | |
# Create source files | |
mkdir -p src | |
cat <<'EOF' >src/main.c | |
#include <stdio.h> | |
#include "config.h" | |
#include "hello.h" | |
int main() { | |
printf("%s! (version: %s)\n", HELLO_MESSAGE, PACKAGE_VERSION); | |
return 0; | |
} | |
EOF | |
# Create header file src/hello.h | |
cat <<'EOF' >src/hello.h | |
#ifndef HELLO_H | |
#define HELLO_H | |
#define HELLO_MESSAGE "Hello, world" | |
#endif /* HELLO_H */ | |
EOF | |
# Create test source files | |
mkdir -p tests | |
cat <<'EOF' >tests/unit_test.c | |
#include <stdio.h> | |
#include <string.h> | |
#include "config.h" | |
#include "hello.h" | |
int main() { | |
if(strcmp(HELLO_MESSAGE, "Hello, world") != 0) { | |
printf("Unit test failed: Message does not match expected output.\n"); | |
return 1; | |
} | |
printf("All Unit Test Passed\n"); | |
return 0; | |
} | |
EOF | |
# Create bootstrap.sh | |
cat <<EOF >bootstrap.sh | |
#!/bin/bash | |
# Setup Autotools Enviroment | |
set -euo pipefail | |
echo "== BOOTSTRAPPING ==" | |
# Run autoreconf to generate configure script and Makefile.in files | |
echo "Running autoreconf..." | |
[ -e configure ] || autoreconf -vim | |
# Configure and build the project | |
echo "Configuring and building the project..." | |
[ -e Makefile ] || ( ./configure && make ) | |
EOF | |
chmod +x bootstrap.sh | |
# Create build.sh | |
cat <<EOF >build.sh | |
#!/bin/bash | |
# Run the main program | |
set -euo pipefail | |
echo "== BUILD AND RUN $PACKAGE_NAME ==" | |
make | |
./$PACKAGE_NAME | |
if [ $? -eq 0 ]; then | |
echo "build completed." | |
else | |
echo "build failed." | |
exit 1 | |
fi | |
EOF | |
chmod +x build.sh | |
# Create test.sh | |
cat <<EOF >test.sh | |
#!/bin/bash | |
# Run the unit test program | |
set -euo pipefail | |
echo "== BUILD AND RUN UNIT TEST ==" | |
make check | |
./unit_test | |
if [ $? -eq 0 ]; then | |
echo "Unit tests passed successfully." | |
else | |
echo "Unit tests failed." | |
exit 1 | |
fi | |
EOF | |
chmod +x test.sh | |
# Create clean.sh | |
cat <<EOF >clean.sh | |
#!/bin/bash | |
# Clean out everything as much as possible | |
set -euo pipefail | |
echo "== CLEANING ==" | |
make clean | |
make maintainer-clean | |
# Extra cleaning is possible if inside a git repo | |
if git rev-parse --is-inside-work-tree > /dev/null 2>&1; then | |
echo "Using .gitignore in an active git repo to clean out autotool files and directories" | |
git clean -Xdf | |
fi | |
EOF | |
chmod +x clean.sh | |
# Create .gitignore | |
cat <<EOF >.gitignore | |
# http://www.gnu.org/software/automake | |
Makefile.in | |
/ar-lib | |
/mdate-sh | |
/py-compile | |
/test-driver | |
/ylwrap | |
.deps/ | |
.dirstamp | |
# http://www.gnu.org/software/autoconf | |
autom4te.cache | |
/autoscan.log | |
/autoscan-*.log | |
/aclocal.m4 | |
/compile | |
/config.cache | |
/config.guess | |
/config.h.in | |
/config.log | |
/config.status | |
/config.sub | |
/configure | |
/configure.scan | |
/depcomp | |
/install-sh | |
/missing | |
/stamp-h1 | |
# https://www.gnu.org/software/libtool/ | |
/ltmain.sh | |
# http://www.gnu.org/software/texinfo | |
/texinfo.tex | |
# http://www.gnu.org/software/m4/ | |
m4/libtool.m4 | |
m4/ltoptions.m4 | |
m4/ltsugar.m4 | |
m4/ltversion.m4 | |
m4/lt~obsolete.m4 | |
# Generated Makefile | |
# (meta build system like autotools, | |
# can automatically generate from config.status script | |
# (which is called by configure script)) | |
Makefile | |
# Generated from configure.ac by autoheader | |
config_h.in | |
src/config.h | |
src/stamp-h1 | |
# Generated by autoreconf -i because of AC_CONFIG_AUX_DIR() | |
build-aux/ | |
EOF | |
# Check overall compilation flow | |
./bootstrap.sh && ./build.sh && ./test.sh && ./clean.sh | |
echo "== COMPLETE ==" | |
echo "Project '$PACKAGE_NAME' initialized. Run './bootstrap.sh' to set up the Autotools project." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Full writeup located in https://briankhuu.com/blog/2024/04/11/initialise-minimal-autotools-script/