diff --git a/.gitignore b/.gitignore index dcabf0f38..c47a39dc8 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,7 @@ ylwrap tags cscope.out /src/avrdude-[1-9].*.tar.* +/src/GNUmakefile *.o *.lo diff --git a/src/GNUmakefile.in b/src/GNUmakefile.in new file mode 100644 index 000000000..760ec9268 --- /dev/null +++ b/src/GNUmakefile.in @@ -0,0 +1,15 @@ +# Helps update the version number automatically if using GNU make. +include Makefile + +AUTORECONF ?= autoreconf +AUTORECONF_OPTS ?= -vis + +script_version := $(shell $(top_srcdir)/build-helpers/package-version $(top_srcdir) version-stamp) +ifneq ($(PACKAGE_VERSION),$(script_version)) +$(info autoconf and script versions do not match: $(PACKAGE_VERSION) vs $(script_version)) +$(info Removing autom4te.cache and related files and re-running autoreconf) +dummy1 := $(shell rm -rf $(top_srcdir)/autom4te.cache) +dummy2 := $(shell $(AUTORECONF) $(AUTORECONF_OPTS) $(top_srcdir)) +endif + +# vim: syntax=make diff --git a/src/Makefile.am b/src/Makefile.am index c708b68de..58bd116b7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -40,6 +40,8 @@ CLEANFILES = \ config_gram.h \ lexer.c +include build-helpers/package-version.mk + BUILT_SOURCES = $(CLEANFILES) #SUBDIRS = doc diff --git a/src/build-helpers/package-version b/src/build-helpers/package-version new file mode 100755 index 000000000..cc87d13ee --- /dev/null +++ b/src/build-helpers/package-version @@ -0,0 +1,102 @@ +#!/bin/sh +# Syntax: +# $0 +# +# may be relative +# is relative to the dist top_srcdir +# +# Test this script by running +# rm -rf autom4te.cache/ && autoreconf -vis . && sed -n "/^# Generated by GNU/p" configure +# +# If we run into an error, we cannot abort the "autoreconf" run by +# exiting with a non-0 error code. (We do exit non-0 in that case +# anyway for help when testing this script.) +# The only thing we can do to report an error is to write to stderr +# which appears as "autoreconf" output, and to write a version number +# to stdout which indicates an error. The "configure" script can +# then check whether $PACKAGE_VERSION indicates such an error. + +# Parse the command line arguments +prog="$(basename "$0")" +top_srcdir="${1-.}" +test -d "$top_srcdir" || { \ + echo "$prog: Error: Could not change to top_srcdir '$1'" >&2; \ + echo "version_error_1" | ${TR-tr} -d '\012' + exit 2; \ +} +version_stamp="${2-version-stamp}" + +# echo "$prog: Error: Some error happend." >&2 +# echo "version_error_2" | ${TR-tr} -d '\012' +# exit 2 + +# Is this a dist source tree? +# If so, use the version number from the version_stamp file. +if test -f "$top_srcdir/$version_stamp"; then + cat "$top_srcdir/$version_stamp" | ${TR-tr} -d '\012' + exit +fi + +# Is this part of a git checkout or an expanded github snapshot tarball? +test -f "$top_srcdir/../CMakeLists.txt" || { \ + echo "$prog: Error: top-level avrdude CMakeLists.txt file not found" >&2; \ + echo "version_error_3" | ${TR-tr} -d '\012' + exit 2; \ +} + +if PROJECT_VERSION="$(${SED-sed} -n 's/project(avrdude[[:space:]]\{1,\}VERSION[[:space:]]\{1,\}\([0-9\.]\{1,\}\)[[:space:]]\{1,\}.*/\1/p' "$top_srcdir/../CMakeLists.txt")"; then + : +else + echo "$prog: Error parsing top-level avrdude 'CMakeLists.txt'." >&2 + echo "version_error_4" | ${TR-tr} -d '\012' + exit 2 +fi + +test -n "$PROJECT_VERSION" || { \ + echo "$prog: Error: Could not find project(...) in top-level avrdude 'CMakeLists.txt'" >&2; \ + echo "version_error_5" | ${TR-tr} -d '\012' + exit 2; \ +} + +# If GIT_DIR is set, use it. If not, try "$top_srcdir/../.git". +test -n "$GIT_DIR" || { \ + GIT_DIR="$top_srcdir/../.git"; \ + export GIT_DIR; \ +} + +# Working with a git source tree +if test -d "$GIT_DIR"; then + GIT_COMMIT_HASH="$(${GIT-git} log -1 --format=%h)" || { \ + echo "$prog: Error: Cannot run 'git log' for commit hash" >&2; \ + echo "version_error_71" | ${TR-tr} -d '\012'; \ + exit 2; \ + } + GIT_COMMIT_DATE="$(${GIT-git} log -1 --format=%ad --date=format:%Y%m%d)" || { \ + echo "$prog: Error: Cannot run 'git log' for commit date" >&2; \ + echo "version_error_72" | ${TR-tr} -d '\012'; \ + exit 2; \ + } + GIT_TAG_HASH="$(${GIT-git} log -1 --tags --format=%h)" || { \ + echo "$prog: Error: Cannot run 'git log' for tag hash" >&2; \ + echo "version_error_73" | ${TR-tr} -d '\012'; \ + exit 2; \ + } + if test "x$GIT_COMMIT_HASH" = "x$GIT_TAG_HASH"; then + echo "${PROJECT_VERSION}" | ${TR-tr} -d '\012' + exit + else + echo "${PROJECT_VERSION}-${GIT_COMMIT_DATE}" | ${TR-tr} -d '\012' + exit + fi +else + # Building a github release tarball or github snapshot tarball. + # + # Presume this is a release version, because who would build a + # non-release version from a snapshot tarball? + echo "${PROJECT_VERSION}" | ${TR-tr} -d '\012' + exit +fi + +# If everything else has failed, call this version "devel" +echo "devel" | ${TR-tr} -d '\012' +exit 2 diff --git a/src/build-helpers/package-version.mk b/src/build-helpers/package-version.mk new file mode 100644 index 000000000..01502dfd5 --- /dev/null +++ b/src/build-helpers/package-version.mk @@ -0,0 +1,26 @@ +BUILD_SCRIPT_DIR = build-helpers + +# Check that package version matches git version before creating dist tarballs +dist-hook: cur-version-check cur-version-stamp +distcheck-hook: cur-version-check + +# Note: We cannot run autoreconf from here, because we would need some way to +# restart the whole dist process from the start and there is none. +EXTRA_DIST += $(top_srcdir)/$(BUILD_SCRIPT_DIR)/package-version +cur-version-check: + @cur_ver=`$(top_srcdir)/$(BUILD_SCRIPT_DIR)/package-version $(top_srcdir) version-stamp`; \ + if test "x$${cur_ver}" = "x$(PACKAGE_VERSION)"; then :; else \ + echo "ERROR: Recorded PACKAGE_VERSION and current version do not match:"; \ + echo " current version: $${cur_ver}"; \ + echo " recorded PACKAGE_VERSION: $(PACKAGE_VERSION)"; \ + rm -rf "$(top_srcdir)/autom4te.cache"; \ + echo "Update PACKAGE_VERSION by running autoreconf(1)."; \ + exit 1; \ + fi + +# Version stamp files can only exist in tarball source trees. +# +# So there is no need to generate them anywhere else or to clean them +# up anywhere. +cur-version-stamp: + echo "$(PACKAGE_VERSION)" > "$(distdir)/version-stamp" diff --git a/src/configure.ac b/src/configure.ac index 1f7671058..e4bc82be6 100644 --- a/src/configure.ac +++ b/src/configure.ac @@ -24,7 +24,7 @@ AC_PREREQ(2.60) AC_INIT([avrdude], - [7.2-20230720], + m4_esyscmd([./build-helpers/package-version . version-stamp]), [https://github.com/avrdudes/avrdude/issues]) AC_CANONICAL_BUILD @@ -36,6 +36,21 @@ AM_INIT_AUTOMAKE([foreign]) AC_CONFIG_HEADERS(ac_cfg.h) AC_CONFIG_MACRO_DIR([m4]) +# Check that the build-helpers/package-version script has worked properly. +case "$PACKAGE_VERSION" in + devel|version_error_*) + AC_MSG_ERROR([ +Autogenerating the package version (${PACKAGE_VERSION}) has failed. + +Please file an issue at ${PACKAGE_BUGREPORT} + +You can write some version number to the file version-stamp as a +workaround to allow building avrdude until the filed issue has been +fixed. +]) + ;; +esac + LT_INIT() m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) @@ -545,9 +560,23 @@ AC_CONFIG_FILES([ Makefile ]) +AC_CONFIG_FILES([ + GNUmakefile +]) +dnl TODO: Add GIT_COMMIT_HASH to the AVRDUDE_FULL_VERSION like cmake build does +dnl # Detect GIT +dnl AC_ARG_VAR([GIT], [git revision control system]) +dnl AS_VAR_IF([GIT], [], [dnl +dnl AC_PATH_PROG([GIT], [git], [no]) +dnl ]) +dnl AM_CONDITIONAL([HAVE_GIT], [test "x$GIT" != xno]) +dnl AS_IF([test -d "../.git/info/exclude"], [dnl +dnl GIT_COMMIT_HASH="$(${GIT} --version)" +dnl ]) + # Pass version number into avrdude.conf -AVRDUDE_FULL_VERSION=$PACKAGE_VERSION -AC_SUBST(AVRDUDE_FULL_VERSION, $AVRDUDE_FULL_VERSION) +dnl AVRDUDE_FULL_VERSION="${PACKAGE_VERSION} (${GIT_COMMIT_HASH})" +AC_SUBST([AVRDUDE_FULL_VERSION], ["$PACKAGE_VERSION"]) # The procedure to create avrdude.conf involves two steps. First, # normal autoconf substitution will be applied, resulting in