1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2026-06-17 18:16:07 -05:00

Build: replace fixed SOURCE_DATE_EPOCH fallback

Keep caller-provided SOURCE_DATE_EPOCH authoritative and derive the automatic default through a shared helper used by the Makefile, direct CMake/CPack packaging, and the deb packaging wrapper.

When repository metadata is available, use the HEAD commit timestamp without relying on git -C. Resolve the source root before probing Git so symlinked source paths still use the checkout HEAD. For source tarballs without .git, derive the fallback timestamp from the release date encoded in Common/Tcdefs.h instead of the stale 2020-01-01 constant.

Add TC_RELEASE_DATE_DAY and validate it together with TC_RELEASE_DATE_YEAR, TC_RELEASE_DATE_MONTH, and TC_STR_RELEASE_DATE. Abort when no valid timestamp can be derived.

For direct CMake invocation, initialize SOURCEPATH when the wrapper has not provided it, use the shared helper for derivation, validate the result, and export it for package targets. Also persist the configured epoch through CPACK_PROJECT_CONFIG_FILE so later standalone cpack --config runs export the same value before invoking package generators.

Document that automatic git-checkout builds and release-tarball builds intentionally use different epochs; release reproducers should build from the tarball or set SOURCE_DATE_EPOCH explicitly.
This commit is contained in:
Mounir IDRASSI
2026-06-05 17:44:10 +09:00
parent fd80bc0679
commit f77d0c0760
7 changed files with 198 additions and 30 deletions
@@ -0,0 +1,3 @@
# Preserve configure-time SOURCE_DATE_EPOCH for standalone cpack --config runs.
set(SOURCE_DATE_EPOCH "@SOURCE_DATE_EPOCH@")
set(ENV{SOURCE_DATE_EPOCH} "${SOURCE_DATE_EPOCH}")
+121
View File
@@ -0,0 +1,121 @@
#!/bin/sh
#
# Derive SOURCE_DATE_EPOCH for VeraCrypt build and packaging paths.
# Precedence inside this helper is git HEAD, then the release date encoded in
# Common/Tcdefs.h. Callers remain responsible for honoring an explicit
# SOURCE_DATE_EPOCH before invoking this helper. The source root is resolved
# before probing Git so symlinked build paths still use the checkout HEAD,
# while release tarballs unpacked below unrelated repositories ignore the
# parent repository and fall back to Common/Tcdefs.h.
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <source-root>" >&2
exit 2
fi
SOURCE_ROOT_INPUT=${1%/}
if [ -z "$SOURCE_ROOT_INPUT" ]; then
SOURCE_ROOT_INPUT=/
fi
SOURCE_ROOT=$(cd "$SOURCE_ROOT_INPUT" 2>/dev/null && pwd -P) || {
echo "Error: $1 is not a readable directory" >&2
exit 1
}
TCDEFS_H="$SOURCE_ROOT/Common/Tcdefs.h"
GIT_WORKTREE=
GIT_SOURCE_PREFIX=
SOURCE_ROOT_BASENAME=${SOURCE_ROOT##*/}
if [ -e "$SOURCE_ROOT/.git" ]; then
GIT_WORKTREE="$SOURCE_ROOT"
elif [ -e "$SOURCE_ROOT/../.git" ]; then
GIT_WORKTREE=$(cd "$SOURCE_ROOT/.." 2>/dev/null && pwd -P)
GIT_SOURCE_PREFIX="$SOURCE_ROOT_BASENAME/"
fi
GIT_EPOCH=
if [ -n "$GIT_WORKTREE" ] &&
(cd "$GIT_WORKTREE" &&
git rev-parse --is-inside-work-tree >/dev/null 2>&1 &&
git ls-files --error-unmatch \
"${GIT_SOURCE_PREFIX}Common/Tcdefs.h" \
"${GIT_SOURCE_PREFIX}Build/Tools/source_date_epoch.sh" >/dev/null 2>&1); then
GIT_EPOCH=$(cd "$GIT_WORKTREE" && git log -1 --pretty=%ct 2>/dev/null)
fi
case "$GIT_EPOCH" in
''|*[!0-9]*)
;;
*)
printf '%s\n' "$GIT_EPOCH"
exit 0
;;
esac
if [ ! -r "$TCDEFS_H" ]; then
echo "Error: $TCDEFS_H is not readable" >&2
exit 1
fi
RELEASE_EPOCH=$(awk '
function leap(y) { return ((y % 4 == 0 && y % 100 != 0) || (y % 400 == 0)) }
function month_number(name) {
return (name == "January" ? 1 : name == "February" ? 2 : name == "March" ? 3 :
name == "April" ? 4 : name == "May" ? 5 : name == "June" ? 6 :
name == "July" ? 7 : name == "August" ? 8 : name == "September" ? 9 :
name == "October" ? 10 : name == "November" ? 11 : name == "December" ? 12 : 0);
}
function mdays(m, y) { return (m == 2 ? 28 + leap(y) : (m == 4 || m == 6 || m == 9 || m == 11 ? 30 : 31)) }
function epoch(y, m, d, days, i) {
days = 0;
for (i = 1970; i < y; i++) days += 365 + leap(i);
for (i = 1; i < m; i++) days += mdays(i, y);
days += d - 1;
return days * 86400;
}
function is_number(value) { return (value ~ /^[0-9]+$/) }
/^[[:space:]]*#define[[:space:]]+TC_STR_RELEASE_DATE[[:space:]]+L"/ {
date = $0;
sub(/^.*L"/, "", date);
sub(/".*$/, "", date);
split(date, parts, /[ ,]+/);
if (month_number(parts[1]) == 0 || !is_number(parts[2]) || !is_number(parts[3])) exit 1;
date_month = month_number(parts[1]);
date_day = parts[2] + 0;
date_year = parts[3] + 0;
seen_date = 1;
}
/^[[:space:]]*#define[[:space:]]+TC_RELEASE_DATE_YEAR[[:space:]]+/ {
if (!is_number($3)) exit 1;
year = $3 + 0;
seen_year = 1;
}
/^[[:space:]]*#define[[:space:]]+TC_RELEASE_DATE_MONTH[[:space:]]+/ {
if (!is_number($3)) exit 1;
month = $3 + 0;
seen_month = 1;
}
/^[[:space:]]*#define[[:space:]]+TC_RELEASE_DATE_DAY[[:space:]]+/ {
if (!is_number($3)) exit 1;
day = $3 + 0;
seen_day = 1;
}
END {
if (!seen_date || !seen_year || !seen_month || !seen_day) exit 1;
if (year < 1970 || month < 1 || month > 12 || day < 1 || day > mdays(month, year)) exit 1;
if (date_month != month || date_day != day || date_year != year) exit 1;
printf "%d", epoch(year, month, day);
}' "$TCDEFS_H") || {
echo "Error: unable to derive SOURCE_DATE_EPOCH from $TCDEFS_H" >&2
exit 1
}
case "$RELEASE_EPOCH" in
''|*[!0-9]*)
echo "Error: unable to derive SOURCE_DATE_EPOCH from $TCDEFS_H" >&2
exit 1
;;
esac
printf '%s\n' "$RELEASE_EPOCH"