Skip to content

Commit 4b6252b

Browse files
committed
e2e 744 depended on the host having a C runtime, and on a key mcpp ignores
TWO DEFECTS IN ONE TEST, AND THE SHARD FOUND THE FIRST. The link it examines was an ordinary hosted one, so it needed startup files that the graph's C library --- a marker package supplying no C library at all --- does not provide. They came from the host: present on a developer's machine, absent in the container the Linux shard runs in, where the link died before it ever reached the symbol under examination: /usr/bin/ld: cannot find crt1.o: No such file or directory A test whose subject is a link diagnostic must not depend on anything else about the link succeeding up to that point. It is freestanding now (`-nostdlib -nostartfiles -static`, and an entry point of its own), so exactly one symbol is undefined and it is the one being examined. THE SECOND DEFECT WAS IN THE REPAIR. Those flags were first written as `[targets.<name>] ldflags`, which is not a key mcpp has: the manifest reports `unsupported key 'ldflags' (ignored)` and carries on. The link then still failed, still named the symbol, and still carried the note, so all four legs passed while the arrangement they rest on had not happened. `build.ldflags` is the spelling that exists, and the flags are now measured on the emitted link line rather than assumed. Leg E asserts the arrangement: no key was ignored, and the link never reached the host's C runtime. Putting the flags back in the target fails E and only E --- A through D go on passing, which is the whole reason E is there. A warning printed into a passing test is invisible.
1 parent 4d1748a commit 4b6252b

1 file changed

Lines changed: 45 additions & 1 deletion

File tree

tests/e2e/744_a_declared_absence_explains_the_link_that_asked_for_it.sh

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,27 @@
2121
# THE SYMBOL IS DELIBERATELY ONE NOTHING DEFINES. `fork` is the real row in
2222
# openkal-musl's manifest and is defined by every C library on a Linux host,
2323
# so a test written with it would link and assert nothing.
24+
#
25+
# AND THE LINK IS FREESTANDING, WHICH IS NOT A STYLISTIC CHOICE. Written as an
26+
# ordinary hosted program this test passed here and failed on the shard, where
27+
# the link died before it ever reached the symbol:
28+
#
29+
# /usr/bin/ld: cannot find crt1.o: No such file or directory
30+
#
31+
# The graph's C library is a marker package that supplies no C library at all,
32+
# so the startup files came from the host --- present on a developer's machine,
33+
# absent in the container the shard runs in. A test whose subject is a link
34+
# diagnostic must not depend on anything else about the link succeeding up to
35+
# that point. `-nostdlib -nostartfiles -static` and an entry point of its own
36+
# leave exactly one undefined symbol, which is the one under examination.
37+
#
38+
# THE FLAGS GO IN `[build]`, NOT IN THE TARGET, AND LEG E ASSERTS THAT THEY
39+
# ARRIVED. Written as `[targets.<name>] ldflags` they are not a key mcpp has:
40+
# the manifest reports `unsupported key 'ldflags' (ignored)` and carries on.
41+
# The link then still failed, still named the symbol, and still carried the
42+
# note --- so all four legs below passed while the thing they were arranged
43+
# around had not happened. Leg E is there because a warning printed into a
44+
# passing test is invisible.
2445
set -e
2546

2647
MCPP="${MCPP:-mcpp}"
@@ -34,7 +55,9 @@ int fake_c_library_marker(void) { return 0; }
3455
EOF
3556
cat > src/main.c <<'EOF'
3657
extern int mcpp_absent_probe_fn(void);
37-
int main(void) { return mcpp_absent_probe_fn(); }
58+
/* `_start`, not `main`: this links without startup files, so there is no C
59+
runtime to call main. Nothing runs it -- the subject is the link. */
60+
void _start(void) { mcpp_absent_probe_fn(); }
3861
EOF
3962
cat > mcpp.toml <<'EOF'
4063
[package]
@@ -50,6 +73,7 @@ fakelibc = { path = "libc" }
5073
5174
[build]
5275
allow_host_libs = true
76+
ldflags = ["-nostdlib", "-nostartfiles", "-static"]
5377
EOF
5478
cat > libc/mcpp.toml <<'EOF'
5579
[package]
@@ -107,4 +131,24 @@ echo "$out" | grep -q "not a defect in the build" || {
107131
}
108132
echo "OK: D (the note distinguishes an absence from a defect)"
109133

134+
# ── E. the arrangement this test rests on actually happened ────────────────
135+
# An unsupported manifest key is a warning and not an error, so a misplaced
136+
# `ldflags` leaves every assertion above passing for the wrong reason: the
137+
# link succeeded as far as the host's startup files allowed, which is a
138+
# property of the machine rather than of this graph.
139+
echo "$out" | grep -q "unsupported key" && {
140+
echo "FAIL: the manifest this test builds has a key mcpp ignored, so the" \
141+
"link above was not the one this test describes" >&2
142+
echo "$out" | grep "unsupported key" >&2
143+
exit 1
144+
}
145+
echo "$out" | grep -qiE "crt1|crti|multiple definition" && {
146+
echo "FAIL: the link reached the host's C runtime. The flags that keep it" \
147+
"freestanding did not take effect, and what failed is the machine" \
148+
"this ran on rather than the absence under examination." >&2
149+
echo "$out" >&2
150+
exit 1
151+
}
152+
echo "OK: E (the link was freestanding, as this test requires)"
153+
110154
echo "OK"

0 commit comments

Comments
 (0)