...

Text file src/cmd/go/testdata/script/build_cc_cache_issue64423.txt

Documentation: cmd/go/testdata/script

     1# Regression test for https://go.dev/issue/64423:
     2#
     3# When we parse the version for a Clang binary, we should accept
     4# an arbitrary vendor prefix, which (as of 2023) may be injected
     5# by defining CLANG_VENDOR when building clang itself.
     6#
     7# Since we don't want to actually rebuild the Clang toolchain in
     8# this test, we instead simulate it by injecting a fake "clang"
     9# binary that runs the real one as a subprocess.
    10
    11[!cgo] skip
    12[short] skip 'builds and links a fake clang binary'
    13[!cc:clang] skip 'test is specific to clang version parsing'
    14
    15# Save the location of the real clang command for our fake one to use.
    16go run ./which clang
    17cp stdout $WORK/.realclang
    18
    19# Build a fake clang and ensure that it is the one in $PATH.
    20mkdir $WORK/bin
    21go build -o $WORK/bin/clang$GOEXE ./fakeclang
    22[!GOOS:plan9] env PATH=$WORK${/}bin
    23[GOOS:plan9] env path=$WORK${/}bin
    24
    25# Force CGO_ENABLED=1 so that the following commands should error
    26# out if the fake clang doesn't work.
    27env CGO_ENABLED=1
    28
    29# The bug in https://go.dev/issue/64423 resulted in cache keys that
    30# didn't contain any information about the C compiler.
    31# Since the bug was in cache key computation, isolate the cache:
    32# if we change the way caching works, we want the test to fail
    33# instead of accidentally reusing the cached information from a
    34# previous test run.
    35env GOCACHE=$WORK${/}.cache
    36mkdir $GOCACHE
    37
    38go build -x runtime/cgo
    39
    40	# Tell our fake clang to stop working.
    41	# Previously, 'go build -x runtime/cgo' would continue to
    42	# succeed because both the broken clang and the non-broken one
    43	# resulted in a cache key with no clang version information.
    44env GO_BREAK_CLANG=1
    45! go build -x runtime/cgo
    46stderr '# runtime/cgo\nGO_BREAK_CLANG is set'
    47
    48-- go.mod --
    49module example/issue64423
    50go 1.20
    51-- which/main.go --
    52package main
    53
    54import (
    55	"os"
    56	"os/exec"
    57)
    58
    59func main() {
    60	path, err := exec.LookPath(os.Args[1])
    61	if err != nil {
    62		panic(err)
    63	}
    64	os.Stdout.WriteString(path)
    65}
    66-- fakeclang/main.go --
    67package main
    68
    69import (
    70	"bufio"
    71	"bytes"
    72	"log"
    73	"os"
    74	"os/exec"
    75	"path/filepath"
    76	"strings"
    77)
    78
    79func main() {
    80	if os.Getenv("GO_BREAK_CLANG") != "" {
    81		os.Stderr.WriteString("GO_BREAK_CLANG is set\n")
    82		os.Exit(1)
    83	}
    84
    85	b, err := os.ReadFile(filepath.Join(os.Getenv("WORK"), ".realclang"))
    86	if err != nil {
    87		log.Fatal(err)
    88	}
    89	clang := string(bytes.TrimSpace(b))
    90	cmd := exec.Command(clang, os.Args[1:]...)
    91	cmd.Stdout = os.Stdout
    92	stderr, err := cmd.StderrPipe()
    93	if err != nil {
    94		log.Fatal(err)
    95	}
    96
    97	if err := cmd.Start(); err != nil {
    98		log.Fatal(err)
    99	}
   100
   101	r := bufio.NewReader(stderr)
   102	for {
   103		line, err := r.ReadString('\n')
   104		if line != "" {
   105			if strings.Contains(line, "clang version") {
   106				// Simulate a clang version string with an arbitrary vendor prefix.
   107				const vendorString = "Gopher Solutions Unlimited "
   108				os.Stderr.WriteString(vendorString)
   109			}
   110			os.Stderr.WriteString(line)
   111		}
   112		if err != nil {
   113			break
   114		}
   115	}
   116	os.Stderr.Close()
   117
   118	if err := cmd.Wait(); err != nil {
   119		os.Exit(1)
   120	}
   121}

View as plain text