|
| 1 | +#!/usr/bin/env bash |
| 2 | +# requires: msvc |
| 3 | +# mcpp#775: the driver link and COFF resource must target the selected machine. |
| 4 | +set -e |
| 5 | +source "$(dirname "$0")/_host_path.sh" |
| 6 | +TMP=$(mktemp -d) |
| 7 | +trap 'rm -rf "$TMP"' EXIT |
| 8 | +fail() { echo "FAIL: $1"; shift; for f in "$@"; do cat "$f" 2>/dev/null; done; exit 1; } |
| 9 | +MCPP="${MCPP:-mcpp}" |
| 10 | +REGISTRY_HOST=$(host_path "${MCPP_HOME:-$HOME/.mcpp}/registry") |
| 11 | +export MCPP_HOME="$TMP/home" |
| 12 | +mkdir -p "$MCPP_HOME" |
| 13 | +printf '[xlings]\nhome = "%s"\n' "$REGISTRY_HOST" > "$MCPP_HOME/config.toml" |
| 14 | +cd "$TMP" |
| 15 | +hexof() { od -An -v -tx1 "$1" | tr -d ' \n'; } |
| 16 | +pe_machine() { |
| 17 | + local offset |
| 18 | + offset=$(od -An -tu4 -j60 -N4 "$1" | tr -d ' \n') |
| 19 | + od -An -tu2 -j"$((offset + 4))" -N2 "$1" | tr -d ' \n' |
| 20 | +} |
| 21 | +for arch in i686 x86_64; do |
| 22 | + machine=332 |
| 23 | + [ "$arch" != x86_64 ] || machine=34404 |
| 24 | + for case_name in c cxx dll; do |
| 25 | + mkdir -p "$arch/$case_name/src" |
| 26 | + cd "$arch/$case_name" |
| 27 | + kind=bin |
| 28 | + suffix=exe |
| 29 | + main_line='main = "src/main.cpp"' |
| 30 | + if [ "$case_name" = dll ]; then |
| 31 | + kind=shared |
| 32 | + suffix=dll |
| 33 | + main_line='' |
| 34 | + printf 'extern "C" __declspec(dllexport) int answer() { return 42; }\n' > src/main.cpp |
| 35 | + elif [ "$case_name" = c ]; then |
| 36 | + main_line='main = "src/main.c"' |
| 37 | + printf 'int main(void) { return 0; }\n' > src/main.c |
| 38 | + else |
| 39 | + printf 'int main() { return 0; }\n' > src/main.cpp |
| 40 | + fi |
| 41 | + cat > mcpp.toml <<EOF |
| 42 | +[package] |
| 43 | +name = "probe" |
| 44 | +version = "0.1.0" |
| 45 | +[toolchain] |
| 46 | +windows = "llvm@20.1.7" |
| 47 | +[build] |
| 48 | +cxx_runtime = "host-coupled" |
| 49 | +[target.$arch-windows-msvc] |
| 50 | +sysroot = "msvc@system" |
| 51 | +[targets.probe] |
| 52 | +kind = "$kind" |
| 53 | +$main_line |
| 54 | +windows_auto_export = false |
| 55 | +EOF |
| 56 | + # The first build isolates the driver regression from the resource one. |
| 57 | + "$MCPP" build --target "$arch-windows-msvc" > first.log 2>&1 \ |
| 58 | + || fail "$arch/$case_name: driver link failed" first.log |
| 59 | + image=$(find target -name "probe.$suffix" | head -1) |
| 60 | + [ -n "$image" ] || fail "$arch/$case_name: image missing" first.log |
| 61 | + [ "$(pe_machine "$image")" = "$machine" ] || fail "wrong PE machine: $image" |
| 62 | + [ "$kind" != bin ] || "$image" || fail "executable failed: $image" |
| 63 | + printf '\n[resources]\nfiles = ["app.rc"]\n' >> mcpp.toml |
| 64 | + printf '101 RCDATA { 0x1357, 0x2468, 0xabcdef01L }\n' > app.rc |
| 65 | + "$MCPP" build --target "$arch-windows-msvc" > resource.log 2>&1 \ |
| 66 | + || fail "$arch/$case_name: resource link failed" resource.log |
| 67 | + object=$(find target -path '*/res/*.o' | head -1) |
| 68 | + [ -n "$object" ] || fail "$arch/$case_name: COFF resource missing" resource.log |
| 69 | + [ "$(od -An -tu2 -N2 "$object" | tr -d ' \n')" = "$machine" ] \ |
| 70 | + || fail "wrong COFF machine: $object" |
| 71 | + [[ "$(hexof "$image")" == *5713682401efcdab* ]] || fail "resource data missing" |
| 72 | + printf '101 RCDATA { 0x7654, 0x3210, 0xfedcba98L }\n' > app.rc |
| 73 | + "$MCPP" build --target "$arch-windows-msvc" > rebuild.log 2>&1 \ |
| 74 | + || fail "$arch/$case_name: resource rebuild failed" rebuild.log |
| 75 | + [ "$(pe_machine "$image")" = "$machine" ] || fail "rebuild changed PE machine" |
| 76 | + [[ "$(hexof "$image")" == *5476103298badcfe* ]] || fail "resource data stayed stale" |
| 77 | + cd "$TMP" |
| 78 | + done |
| 79 | +done |
| 80 | +echo "PASS: 889 Windows driver target and COFF resources" |
0 commit comments