1 #!/usr/bin/env bash
2 3 # Usage: env [ CC=... ] [ C_STANDARD=...] [ CXX=... ] [CXX_STANDARD=...] \
4 # [ CPPFLAGS=... ] [CFLAGS=...] [CXXFLAGS=...] [LDFLAGS=...] \
5 # [ AR=... ] [ NM=... ] [ RANLIB=... ] [ STRIP=... ] [ DEBUG=... ] \
6 # [ LTO=... ] [ NO_HARDEN=... ] ./gen_id [ID_SALT]...
7 #
8 # Prints to stdout a SHA256 hash representing the current toolset, used by
9 # depends/Makefile as a build id for caching purposes (detecting when the
10 # toolset has changed and the cache needs to be invalidated).
11 #
12 # If the DEBUG environment variable is non-empty and the system has `tee`
13 # available in its $PATH, the pre-image to the SHA256 hash will be printed to
14 # stderr. This is to help developers debug caching issues in depends.
15 16 # This script explicitly does not `set -e` because id determination is mostly
17 # opportunistic: it is fine that things fail, as long as they fail consistently.
18 19 # Command variables (CC/CXX/AR) which can be blank are invoked with `bash -c`,
20 # because the "command not found" error message printed by shells often include
21 # the line number, like so:
22 #
23 # ./depends/gen_id: line 43: --version: command not found
24 #
25 # By invoking with `bash -c`, we ensure that the line number is always 1
26 27 (
28 # Redirect stderr to stdout
29 exec 2>&1
30 31 echo "BEGIN ALL"
32 33 # Include any ID salts supplied via command line
34 echo "BEGIN ID SALT"
35 echo "$@"
36 echo "END ID SALT"
37 38 echo "BEGIN FLAGS"
39 echo "CPPFLAGS=${CPPFLAGS}"
40 echo "CFLAGS=${CFLAGS}"
41 echo "CXXFLAGS=${CXXFLAGS}"
42 echo "LDFLAGS=${LDFLAGS}"
43 echo "END FLAGS"
44 45 # GCC only prints COLLECT_LTO_WRAPPER when invoked with just "-v", but we want
46 # the information from "-v -E -" as well, so just include both.
47 echo "BEGIN CC"
48 bash -c "${CC} -v"
49 bash -c "${CC} -v -E -xc -o /dev/null - < /dev/null"
50 bash -c "${CC} -v -E -xobjective-c -o /dev/null - < /dev/null"
51 echo "C_STANDARD=${C_STANDARD}"
52 echo "END CC"
53 54 echo "BEGIN CXX"
55 bash -c "${CXX} -v"
56 bash -c "${CXX} -v -E -xc++ -o /dev/null - < /dev/null"
57 bash -c "${CXX} -v -E -xobjective-c++ -o /dev/null - < /dev/null"
58 echo "CXX_STANDARD=${CXX_STANDARD}"
59 echo "END CXX"
60 61 # We use lld when cross-compiling for macOS, and it's version should
62 # be tied to LLVM. However someone compiling with GCC and -fuse-ld=lld
63 # would not see a cache bust if the LLVM toolchain was updated.
64 echo "BEGIN lld"
65 bash -c "ld.lld --version"
66 echo "END lld"
67 68 echo "BEGIN mold"
69 bash -c "mold --version"
70 echo "END mold"
71 72 echo "BEGIN AR"
73 bash -c "${AR} --version"
74 env | grep '^AR_'
75 echo "END AR"
76 77 echo "BEGIN NM"
78 bash -c "${NM} --version"
79 env | grep '^NM_'
80 echo "END NM"
81 82 echo "BEGIN RANLIB"
83 bash -c "${RANLIB} --version"
84 env | grep '^RANLIB_'
85 echo "END RANLIB"
86 87 echo "BEGIN STRIP"
88 bash -c "${STRIP} --version"
89 env | grep '^STRIP_'
90 echo "END STRIP"
91 92 echo "BEGIN LTO"
93 echo "LTO=${LTO}"
94 echo "END LTO"
95 96 echo "BEGIN NO_HARDEN"
97 echo "NO_HARDEN=${NO_HARDEN}"
98 echo "END NO_HARDEN"
99 100 echo "END ALL"
101 ) | if [ -n "$DEBUG" ] && command -v tee > /dev/null 2>&1; then
102 # When debugging and `tee` is available, output the preimage to stderr
103 # in addition to passing through stdin to stdout
104 tee >(cat 1>&2)
105 else
106 # Otherwise, passthrough stdin to stdout
107 cat
108 fi | ${SHA256SUM} - | cut -d' ' -f1
109