1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
|
#!/bin/bash
#
# Copyright 2012 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# Generate version information for the EC binary
# Use this symbol as a separator to be able to reliably concatenate strings of
# text.
dc=$'\001'
# Default marker to indicate 'dirty' repositories
dirty_marker='+'
# This function examines the state of the current directory and attempts to
# extract its version information: the latest tag, if any, how many patches
# are there since the latest tag, the top sha1, and if there are local
# modifications.
#
# Local modifications are reported by concatenating the revision string and
# the string '-dirty' using the $dc symbol as the separator.
#
# If there is no tags defined in this git repository, the base version is
# considered to be 0.0.
#
# If current directory is not a git depository, this function prints out
# "no_version"
get_tree_version() {
local marker
local ghash
local numcommits
local tag
local vbase
local ver_branch
local ver_major
if ghash=`git rev-parse --short --verify HEAD 2>/dev/null`; then
if gdesc=`git describe --dirty --match='v*' 2>/dev/null`; then
IFS="-" fields=($gdesc)
tag="${fields[0]}"
IFS="." vernum=($tag)
numcommits=$((${vernum[2]}+${fields[1]:-0}))
ver_major="${vernum[0]}"
ver_branch="${vernum[1]}"
else
numcommits=`git rev-list HEAD | wc -l`
ver_major="v0"
ver_branch="0"
fi
# avoid putting the -dirty attribute if only the timestamp
# changed
git status > /dev/null 2>&1
if [ -n "$(git diff-index --name-only HEAD 2>/dev/null)" ]; then
marker="${dirty_marker}"
else
marker="-"
fi
vbase="${ver_major}.${ver_branch}.${numcommits}${marker}${ghash}"
else
# Fall back to the VCSID provided by the packaging system if available.
if ghash=${VCSID##*-}; then
vbase="1.1.9999-${ghash:0:7}"
else
# then ultimately fails to "no_version"
vbase="no_version"
fi
fi
if [[ "${marker}" == "${dirty_marker}" ]]; then
echo "${vbase}${dc}${marker}"
else
echo "${vbase}${dc}"
fi
}
main() {
local component
local dir_list
local gitdate
local most_recents
local most_recent_file
local root
local timestamp
local tool_ver
local values
local vbase
local ver
IFS="${dc}"
ver="${CR50_DEV:+DBG/}${CRYPTO_TEST:+CT/}${BOARD}_"
tool_ver=""
most_recents=() # Non empty if any of the component repos is 'dirty'.
dir_list=( . ) # list of component directories, always includes the EC tree
if [[ -n ${BOARD} ]]; then
case "${BOARD}" in
(cr50)
dir_list+=( ../../third_party/tpm2 )
;;
(*_fp)
dir_list+=( ./private )
;;
(*)
# For private-crX boards add their git root and cryptoc.
for root in private-cr5*; do
if [[ -d "${root}/board/${BOARD}" ]]; then
dir_list+=( "${root}" ../../third_party/cryptoc )
fi
done
;;
esac
fi
# Create a combined version string for all component directories.
for git_dir in ${dir_list[@]}; do
pushd "${git_dir}" > /dev/null
component="$(basename "${git_dir}")"
values=( $(get_tree_version) )
vbase="${values[0]}" # Retrieved version information.
if [[ -n "${values[1]}" ]]; then
# From each modified repo get the most recently modified file.
most_recent_file="$(git status --porcelain | \
awk '$1 ~ /[M|A|?]/ {print $2}' | \
xargs ls -t | head -1)"
most_recents+=("$(realpath "${most_recent_file}")")
fi
if [ "${component}" != "." ]; then
ver+=" ${component}:"
fi
ver+="${vbase}"
tool_ver+="${vbase}"
popd > /dev/null
done
# On some boards where the version number consists of multiple components we
# want to separate the first word of the version string as the version of the
# EC tree.
IFS=' ' first_word=(${ver})
echo "/* This file is generated by util/getversion.sh */"
echo "/* Version string, truncated to 31 chars (+ terminating null = 32) */"
echo "#define CROS_EC_VERSION32 \"${first_word:0:31}\""
echo "/* Version string for ectool. */"
echo "#define CROS_ECTOOL_VERSION \"${tool_ver}\""
echo "/* Version string for stm32mon. */"
echo "#define CROS_STM32MON_VERSION \"${tool_ver}\""
echo "/* Sub-fields for use in Makefile.rules and to form build info string"
echo " * in common/version.c. */"
echo "#define VERSION \"${ver}\""
if [ "$REPRODUCIBLE_BUILD" = 1 ]; then
echo '#define BUILDER "reproducible@build"'
else
echo "#define BUILDER \"${USER}@`hostname`\""
fi
if [[ ${#most_recents[@]} != 0 ]]; then
# There are modified files, use the timestamp of the most recent one as
# the build version timestamp.
most_recent_file="$(ls -t "${most_recents[@]}" | head -1)"
timestamp="$(stat -c '%y' "${most_recent_file}" | sed 's/\..*//')"
echo "/* Repo is dirty, using time of most recent file modification. */"
echo "#define DATE \"${timestamp}\""
else
echo "/* Repo is clean, use the commit date of the last commit. */"
# If called from an ebuild we won't have a git repo, so redirect stderr
# to avoid annoying 'Not a git repository' errors.
gitdate="$(
for git_dir in "${dir_list[@]}"; do
git -C "${git_dir}" log -1 --format='%ct %ci' HEAD 2>/dev/null
done | sort | tail -1 | cut -d ' ' -f '2 3')"
echo "#define DATE \"${gitdate}\""
fi
}
main
|