...

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

Documentation: cmd/go/testdata/script

     1# Test case to verify that when we have a package that uses CGO in
     2# combination with selected "unusual" flags (involving plugins, LTO)
     3# that we force external linking.  See related
     4# issues 58619,  58620, and 58848.
     5
     6[compiler:gccgo] skip # only external linking for gccgo
     7
     8[!cgo] skip 'test verifies behavior that depends on CGO_CFLAGS'
     9[mustlinkext] skip 'test expects internal linking for non-cgo programs'
    10
    11# Here we build three program: one with explicit CGO use, one with no
    12# CGO use, and one that uses a stdlib package ("runtime/cgo") that has
    13# CGO in it. It used to be that only the explicit use of CGO would
    14# trigger external linking, and that the program that only used
    15# "runtime/cgo" would always be handled with internal linking. This caused
    16# issues when users included odd/unusual flags (ex: -fplugin, -flto)
    17# in CGO_CFLAGS, causing the Go linker to have to read and interpret
    18# non-standard host objects.
    19#
    20# As of 1.21 we continue to use internal linking for programs whose
    21# CGO use comes only from stdlib packages in the absence of any flag
    22# funny business, however if the Go command sees flags that may be suspicious,
    23# it signals the Go linker to invoke the external linker.
    24
    25# The next few tests run builds passing "-n" to the Go command, then
    26# checking the output to see if the Go command is trying to pass a
    27# "preferlinkext" token to the linker to request external linking.
    28
    29#-----------------------
    30
    31# Use a fresh GOCACHE for these next steps, so as to have the real
    32# actions for the runtime/cgo package appear in the "-n -x" output.
    33env GOCACHE=$WORK/gocache
    34mkdir $GOCACHE
    35
    36# First build: there is no CGO in use, so no token should be present regardless
    37# of weird CGO flags.
    38go build -x -n -o dummy.exe ./noUseOfCgo
    39! stderr preferlinkext
    40env CGO_CFLAGS=-flto
    41go build -x -n -o dummy.exe ./noUseOfCgo
    42! stderr preferlinkext
    43env CGO_CFLAGS=
    44
    45# Second build uses CGO, so we expect to see the token present in the
    46# -n output only when strange flags are used.
    47go build -x -n -o dummy.exe ./usesInternalCgo
    48! stderr preferlinkext
    49env CGO_CFLAGS=-flto
    50go build -x -n -o dummy.exe ./usesInternalCgo
    51stderr preferlinkext
    52env CGO_CFLAGS=-fplugin
    53go build -x -n -o dummy.exe ./usesInternalCgo
    54stderr preferlinkext
    55env CGO_CFLAGS=-fprofile-instr-generate
    56go build -x -n -o dummy.exe ./usesInternalCgo
    57stderr preferlinkext
    58
    59# Trimming file information for the UndefinedBehaviorSanitizer is permitted for internal linking.
    60env CGO_CFLAGS=-fsanitize-undefined-strip-path-components=-1
    61go build -x -n -o dummy.exe ./usesInternalCgo
    62! stderr preferlinkext
    63env CGO_CFLAGS=-fsanitize-undefined-strip-path-components=2
    64go build -x -n -o dummy.exe ./usesInternalCgo
    65! stderr preferlinkext
    66
    67# The -fdebug-prefix-map=path is permitted for internal linking.
    68env CGO_CFLAGS=-fdebug-prefix-map=/some/sandbox/execroot/workspace=/tmp/new
    69go build -x -n -o dummy.exe ./usesInternalCgo
    70! stderr preferlinkext
    71env CGO_CFLAGS=-fdebug-prefix-map=/Users/someone/.cache/bazel/_bazel_someone/3fa7e4650c43657ead684537951f49e2/sandbox/linux-sandbox/10/execroot/rules_go_static=.
    72go build -x -n -o dummy.exe ./usesInternalCgo
    73! stderr preferlinkext
    74# The -ffile-prefix-map=path is permitted for internal linking too.
    75env CGO_CFLAGS=-ffile-prefix-map=/Users/someone/.cache/bazel/_bazel_someone/3fa7e4650c43657ead684537951f49e2/sandbox/linux-sandbox/10/execroot/rules_go_static/bazel-out/aarch64-fastbuild-ST-b33d65c724e6/bin/external/io_bazel_rules_go/stdlib_=.
    76go build -x -n -o dummy.exe ./usesInternalCgo
    77! stderr preferlinkext
    78# Verifying that -fdebug-prefix-map=path, -ffile-prefix-map, -no-canonical-prefixes
    79# and -fno-canonical-systemd-headers are permitted for internal linking.
    80env CGO_CFLAGS=-fdebug-prefix-map=old=/tmp/new
    81go build -x -n -o dummy.exe ./usesInternalCgo
    82! stderr preferlinkext
    83env CGO_CFLAGS=-ffile-prefix-map=/Users/someone/_11233/things=new
    84go build -x -n -o dummy.exe ./usesInternalCgo
    85! stderr preferlinkext
    86env CGO_CFLAGS=-no-canonical-prefixes
    87go build -x -n -o dummy.exe ./usesInternalCgo
    88! stderr preferlinkext
    89env CGO_CFLAGS=-fno-canonical-system-headers
    90go build -x -n -o dummy.exe ./usesInternalCgo
    91! stderr preferlinkext
    92env CGO_CFLAGS=
    93
    94[short] skip
    95
    96# In the remaining tests below we do actual builds (without -n) to
    97# verify that the Go linker is going the right thing in addition to the
    98# Go command. Here the idea is to pass "-tmpdir" to the linker, then
    99# check after the link is done for the presence of the file
   100# <tmpdir>/go.o, which the Go linker creates prior to kicking off the
   101# external linker.
   102
   103mkdir tmp1
   104mkdir tmp2
   105mkdir tmp3
   106mkdir tmp4
   107mkdir tmp5
   108
   109# First build: no external linking expected
   110go build -ldflags=-tmpdir=tmp1 -o $devnull ./noUseOfCgo &
   111
   112# Second build: using only "runtime/cgo", expect internal linking.
   113go build -ldflags=-tmpdir=tmp2 -o $devnull ./usesInternalCgo &
   114
   115# Third build: program uses only "runtime/cgo", so we would normally
   116# expect internal linking, except that cflags contain suspicious entries
   117# (in this case, a flag that does not appear on the allow list).
   118env CGO_CFLAGS=-fmerge-all-constants
   119env CGO_LDFLAGS=-fmerge-all-constants
   120go build -ldflags=-tmpdir=tmp3 -o $devnull ./usesInternalCgo &
   121env CGO_CFLAGS=
   122env CGO_LDFLAGS=
   123
   124# Fourth build: explicit CGO, expect external linking.
   125go build -ldflags=-tmpdir=tmp4 -o $devnull ./usesExplicitCgo &
   126
   127# Fifth build: explicit CGO, but we specifically asked for internal linking
   128# via a flag, so using internal linking it is.
   129[cgolinkext] go list ./usesInternalCgo
   130[!cgolinkext] go build '-ldflags=-tmpdir=tmp5 -linkmode=internal' -o $devnull ./usesInternalCgo &
   131
   132# Sixth build: explicit CGO use in a non-main package.
   133go build -o p.a ./nonMainPackageUsesExplicitCgo &
   134
   135wait
   136
   137# Check first build: no external linking expected
   138! exists tmp1/go.o
   139
   140# Check second build: using only "runtime/cgo", expect internal linking.
   141[!cgolinkext] ! exists tmp2/go.o
   142[cgolinkext] exists tmp2/go.o
   143
   144# Check third build: has suspicious flag.
   145exists tmp3/go.o
   146
   147# Fourth build: explicit CGO, expect external linking.
   148exists tmp4/go.o
   149
   150# Fifth build: explicit CGO, -linkmode=internal.
   151! exists tmp5/go.o
   152
   153# Sixth build: make sure that "go tool nm" doesn't get confused
   154# by the presence of the "preferlinkext" sentinel.
   155go tool nm p.a
   156
   157-- go.mod --
   158
   159module cgo.example
   160
   161go 1.20
   162
   163-- noUseOfCgo/main.go --
   164
   165package main
   166
   167func main() {
   168	println("clean as a whistle")
   169}
   170
   171-- usesInternalCgo/main.go --
   172
   173package main
   174
   175import (
   176	"runtime/cgo"
   177)
   178
   179func main() {
   180	q := "hello"
   181	h := cgo.NewHandle(q)
   182	h.Delete()
   183}
   184
   185-- usesExplicitCgo/main.go --
   186
   187package main
   188
   189/*
   190int meaningOfLife() { return 42; }
   191*/
   192import "C"
   193
   194func main() {
   195     println(C.meaningOfLife())
   196}
   197
   198-- nonMainPackageUsesExplicitCgo/main.go --
   199
   200package p
   201
   202/*
   203int meaningOfLife() { return 42; }
   204*/
   205import "C"
   206
   207func PrintIt() {
   208     println(C.meaningOfLife())
   209}

View as plain text