blob: 87ecb633d3442be9c1e259d6a05d3dd4928b58fe (
plain)
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
|
#!/bin/sh
set -eu
base="${TMPDIR-/tmp}/mcpu-cpp-deps-$$"
mkdir -p "$base/user" "$base/sys" "$base/cfg-user" "$base/cfg-sys" "$base/after" "$base/cfg-after"
trap 'rm -rf "$base"' EXIT HUP INT TERM
cat > "$base/config.conf" <<EOT
MCPU_CPP_INCLUDE_PATH = $base/cfg-user;
MCPU_CPP_SYSTEM_INCLUDE_PATH = $base/cfg-sys;
MCPU_CPP_AFTER_INCLUDE_PATH = $base/cfg-after;
EOT
cat > "$base/main.c" <<'EOT'
#include "local.h"
#include "local-alias.h"
#include <user.h>
#include <cfg-user.h>
#include "sys-explicit.h"
#include <sys-config.h>
#include <after-explicit.h>
#include <after-config.h>
#include <same.h>
#include <shared.h>
SHOULD_NOT_APPEAR_IN_DEP_OUTPUT
EOT
cat > "$base/local.h" <<'EOT'
#pragma once
#line 100 "logical-local.h"
LOCAL_BODY
EOT
ln "$base/local.h" "$base/local-alias.h"
cat > "$base/user/user.h" <<'EOT'
USER_HEADER
EOT
cat > "$base/cfg-user/cfg-user.h" <<'EOT'
CONFIG_USER_HEADER
EOT
cat > "$base/user/shared.h" <<'EOT'
SHARED_USER_HEADER
EOT
cat > "$base/user/transitive-only.h" <<'EOT'
TRANSITIVE_USER_HEADER
EOT
cat > "$base/sys/sys-explicit.h" <<'EOT'
#include <transitive-only.h>
#include <shared.h>
#include "sys-child.h"
EOT
cat > "$base/sys/sys-child.h" <<'EOT'
SYSTEM_CHILD
EOT
cat > "$base/cfg-sys/sys-config.h" <<'EOT'
SYSTEM_CONFIG
EOT
cat > "$base/after/after-explicit.h" <<'EOT'
AFTER_EXPLICIT
EOT
cat > "$base/cfg-after/after-config.h" <<'EOT'
AFTER_CONFIG
EOT
cat > "$base/user/same.h" <<'EOT'
USER_WRAPPER
#include_next <same.h>
EOT
cat > "$base/sys/same.h" <<'EOT'
SYSTEM_WRAPPED
EOT
"$MCPU_CPP" --config-file "$base/config.conf" \
-I "$base/user" -isystem "$base/sys" -idirafter "$base/after" \
-M "$base/main.c" > "$base/M.out"
# -M emits only a make rule and includes every physical dependency.
grep "^main\\.o:" "$base/M.out" >/dev/null
! grep 'SHOULD_NOT_APPEAR_IN_DEP_OUTPUT' "$base/M.out" >/dev/null
for f in \
"$base/main.c" "$base/local.h" "$base/user/user.h" \
"$base/cfg-user/cfg-user.h" "$base/sys/sys-explicit.h" \
"$base/user/transitive-only.h" "$base/user/shared.h" \
"$base/sys/sys-child.h" "$base/cfg-sys/sys-config.h" \
"$base/after/after-explicit.h" "$base/cfg-after/after-config.h" \
"$base/user/same.h" "$base/sys/same.h"
do
grep -F "$f" "$base/M.out" >/dev/null || {
echo "-M omitted dependency: $f" >&2
exit 1
}
done
# local-alias.h is a hard link to local.h and must not create a duplicate
# physical dependency. The logical #line name is not a dependency either.
! grep -F "$base/local-alias.h" "$base/M.out" >/dev/null
! grep -F 'logical-local.h' "$base/M.out" >/dev/null
"$MCPU_CPP" --config-file "$base/config.conf" \
-I "$base/user" -isystem "$base/sys" -idirafter "$base/after" \
-MM "$base/main.c" > "$base/MM.out"
grep "^main\\.o:" "$base/MM.out" >/dev/null
for f in "$base/main.c" "$base/local.h" "$base/user/user.h" \
"$base/cfg-user/cfg-user.h" "$base/user/same.h" "$base/user/shared.h"
do
grep -F "$f" "$base/MM.out" >/dev/null || {
echo "-MM omitted user dependency: $f" >&2
exit 1
}
done
# Quoting style does not define system-ness. sys-explicit.h was included
# with quotes but found in -isystem, and all descendants reachable only from
# that system header are excluded. -idirafter/config AFTER are system class.
for f in "$base/sys/sys-explicit.h" "$base/user/transitive-only.h" \
"$base/sys/sys-child.h" "$base/cfg-sys/sys-config.h" \
"$base/after/after-explicit.h" "$base/cfg-after/after-config.h" \
"$base/sys/same.h"
do
if grep -F "$f" "$base/MM.out" >/dev/null; then
echo "-MM kept system dependency: $f" >&2
exit 1
fi
done
# The same physical shared.h is first reached transitively from a system
# header, then directly from main. The direct user inclusion makes it a user
# dependency, so -MM must retain it (checked above).
# Normal mcpu-cpp output-file syntax remains usable for dependency output.
"$MCPU_CPP" --config-file "$base/config.conf" -I "$base/user" \
-isystem "$base/sys" -idirafter "$base/after" \
-MM "$base/main.c" -o "$base/deps.mk"
test -s "$base/deps.mk"
grep '^main\.o:' "$base/deps.mk" >/dev/null
# stdin follows GNU cpp's useful default target convention.
printf 'int x;\n' | "$MCPU_CPP" --no-config -M > "$base/stdin.dep"
grep '^-: -$' "$base/stdin.dep" >/dev/null
|