]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: import runtime/cgo when externally linking
authorIan Lance Taylor <iant@golang.org>
Fri, 17 Mar 2023 00:45:02 +0000 (17:45 -0700)
committerGopher Robot <gobot@golang.org>
Fri, 17 Mar 2023 19:55:13 +0000 (19:55 +0000)
Fixes #31544

Change-Id: Ic99875ad227876eb741e93653589310327c9c0ca
Reviewed-on: https://go-review.googlesource.com/c/go/+/477195
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
src/cmd/go/internal/load/pkg.go
src/cmd/go/testdata/script/build_static.txt [new file with mode: 0644]

index 40278dda4d2c992d335a6720259e0b365cfc2937..922dc99e6916a95f6b7988e46a2d92f0e5e05fe7 100644 (file)
@@ -684,6 +684,15 @@ const (
        // GetTestDeps is for download (part of "go get") and indicates
        // that test dependencies should be fetched too.
        GetTestDeps
+
+       // The remainder are internal modes for calls to loadImport.
+
+       // cmdlinePkg is for a package mentioned on the command line.
+       cmdlinePkg
+
+       // cmdlinePkgLiteral is for a package mentioned on the command line
+       // without using any wildcards or meta-patterns.
+       cmdlinePkgLiteral
 )
 
 // LoadImport scans the directory named by path, which must be an import path,
@@ -738,18 +747,30 @@ func loadImport(ctx context.Context, opts PackageOpts, pre *preload, path, srcDi
                return p
        }
 
+       setCmdline := func(p *Package) {
+               if mode&cmdlinePkg != 0 {
+                       p.Internal.CmdlinePkg = true
+               }
+               if mode&cmdlinePkgLiteral != 0 {
+                       p.Internal.CmdlinePkgLiteral = true
+               }
+       }
+
        importPath := bp.ImportPath
        p := packageCache[importPath]
        if p != nil {
                stk.Push(path)
                p = reusePackage(p, stk)
                stk.Pop()
+               setCmdline(p)
        } else {
                p = new(Package)
                p.Internal.Local = build.IsLocalImport(path)
                p.ImportPath = importPath
                packageCache[importPath] = p
 
+               setCmdline(p)
+
                // Load package.
                // loadPackageData may return bp != nil even if an error occurs,
                // in order to return partial information.
@@ -2849,15 +2870,15 @@ func PackagesAndErrors(ctx context.Context, opts PackageOpts, patterns []string)
                        if pkg == "" {
                                panic(fmt.Sprintf("ImportPaths returned empty package for pattern %s", m.Pattern()))
                        }
-                       p := loadImport(ctx, opts, pre, pkg, base.Cwd(), nil, &stk, nil, 0)
-                       p.Match = append(p.Match, m.Pattern())
-                       p.Internal.CmdlinePkg = true
+                       mode := cmdlinePkg
                        if m.IsLiteral() {
                                // Note: do not set = m.IsLiteral unconditionally
                                // because maybe we'll see p matching both
                                // a literal and also a non-literal pattern.
-                               p.Internal.CmdlinePkgLiteral = true
+                               mode |= cmdlinePkgLiteral
                        }
+                       p := loadImport(ctx, opts, pre, pkg, base.Cwd(), nil, &stk, nil, mode)
+                       p.Match = append(p.Match, m.Pattern())
                        if seenPkg[p] {
                                continue
                        }
diff --git a/src/cmd/go/testdata/script/build_static.txt b/src/cmd/go/testdata/script/build_static.txt
new file mode 100644 (file)
index 0000000..611d94d
--- /dev/null
@@ -0,0 +1,38 @@
+# This test requires external linking. Assume that if cgo is supported
+# then external linking works.
+[!cgo] skip 'links and runs binaries'
+
+# Only run on Unix systems that support -static.
+[GOOS:windows] skip
+[GOOS:plan9] skip
+
+# Ordinary build should work.
+go build
+exec ./hello
+stdout Hello
+
+# Building with -linkmode=external should not say anything about
+# runtime/cgo (issue #31544).
+go build -ldflags=-linkmode=external
+! stderr runtime/cgo
+exec ./hello
+stdout Hello
+
+# Building with -linkmode=external -extldflags=-static should work.
+go build -ldflags='-linkmode=external -extldflags=-static'
+! stderr runtime/cgo
+exec ./hello
+stdout Hello
+
+-- go.mod --
+module hello
+
+go 1.20
+-- hello.go --
+package main
+
+import "fmt"
+
+func main() {
+       fmt.Println("Hello, world")
+}