Skip to content

Commit ae2e244

Browse files
author
Jay Conrod
committed
go/build: don't include imports from cgo files when CGO_ENABLED=0
Fixes #35873 Fixes #35946 Change-Id: I9f9a9c09006f8957569db6e5cc13382b9b28f829 Reviewed-on: https://go-review.googlesource.com/c/go/+/209660 Run-TryBot: Jay Conrod <[email protected]> Reviewed-by: Bryan C. Mills <[email protected]>
1 parent 7d1d944 commit ae2e244

File tree

6 files changed

+139
-26
lines changed

6 files changed

+139
-26
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# Check that files and their imports are not included in 'go list' output
2+
# when they are excluded by build constraints.
3+
4+
# Linux and cgo files should be included when building in that configuration.
5+
env GOOS=linux
6+
env CGO_ENABLED=1
7+
go list -f '{{range .GoFiles}}{{.}} {{end}}'
8+
stdout '^cgotag.go empty.go suffix_linux.go tag.go $'
9+
go list -f '{{range .CgoFiles}}{{.}} {{end}}'
10+
stdout '^cgoimport.go $'
11+
go list -f '{{range .Imports}}{{.}} {{end}}'
12+
stdout '^C cgoimport cgotag suffix tag $'
13+
14+
# Disabling cgo should exclude cgo files and their imports.
15+
env CGO_ENABLED=0
16+
go list -f '{{range .GoFiles}}{{.}} {{end}}'
17+
stdout 'empty.go suffix_linux.go tag.go'
18+
go list -f '{{range .CgoFiles}}{{.}} {{end}}'
19+
! stdout .
20+
go list -f '{{range .Imports}}{{.}} {{end}}'
21+
stdout '^suffix tag $'
22+
23+
# Changing OS should exclude linux sources.
24+
env GOOS=darwin
25+
go list -f '{{range .GoFiles}}{{.}} {{end}}'
26+
stdout '^empty.go $'
27+
go list -f '{{range .Imports}}{{.}} {{end}}'
28+
stdout '^$'
29+
30+
# Enabling a tag should include files that require it.
31+
go list -tags=extra -f '{{range .GoFiles}}{{.}} {{end}}'
32+
stdout '^empty.go extra.go $'
33+
go list -tags=extra -f '{{range .Imports}}{{.}} {{end}}'
34+
stdout '^extra $'
35+
36+
# Packages that require a tag should not be listed unless the tag is on.
37+
! go list ./tagonly
38+
go list -tags=extra ./tagonly
39+
stdout m/tagonly
40+
41+
-- go.mod --
42+
module m
43+
44+
go 1.13
45+
46+
-- empty.go --
47+
package p
48+
49+
-- extra.go --
50+
// +build extra
51+
52+
package p
53+
54+
import _ "extra"
55+
56+
-- suffix_linux.go --
57+
package p
58+
59+
import _ "suffix"
60+
61+
-- tag.go --
62+
// +build linux
63+
64+
package p
65+
66+
import _ "tag"
67+
68+
-- cgotag.go --
69+
// +build cgo
70+
71+
package p
72+
73+
import _ "cgotag"
74+
75+
-- cgoimport.go --
76+
package p
77+
78+
import "C"
79+
80+
import _ "cgoimport"
81+
82+
-- tagonly/tagonly.go --
83+
// +build extra
84+
85+
package tagonly

src/cmd/go/testdata/script/list_tags.txt

-10
This file was deleted.

src/go/build/build.go

+31-16
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,11 @@ Found:
905905
}
906906

907907
// Record imports and information about cgo.
908+
type importPos struct {
909+
path string
910+
pos token.Pos
911+
}
912+
var fileImports []importPos
908913
isCgo := false
909914
for _, decl := range pf.Decls {
910915
d, ok := decl.(*ast.GenDecl)
@@ -921,13 +926,7 @@ Found:
921926
if err != nil {
922927
log.Panicf("%s: parser returned invalid quoted string: <%s>", filename, quoted)
923928
}
924-
if isXTest {
925-
xTestImported[path] = append(xTestImported[path], fset.Position(spec.Pos()))
926-
} else if isTest {
927-
testImported[path] = append(testImported[path], fset.Position(spec.Pos()))
928-
} else {
929-
imported[path] = append(imported[path], fset.Position(spec.Pos()))
930-
}
929+
fileImports = append(fileImports, importPos{path, spec.Pos()})
931930
if path == "C" {
932931
if isTest {
933932
badFile(fmt.Errorf("use of cgo in test %s not supported", filename))
@@ -946,21 +945,37 @@ Found:
946945
}
947946
}
948947
}
949-
if isCgo {
948+
949+
var fileList *[]string
950+
var importMap map[string][]token.Position
951+
switch {
952+
case isCgo:
950953
allTags["cgo"] = true
951954
if ctxt.CgoEnabled {
952-
p.CgoFiles = append(p.CgoFiles, name)
955+
fileList = &p.CgoFiles
956+
importMap = imported
953957
} else {
954-
p.IgnoredGoFiles = append(p.IgnoredGoFiles, name)
958+
// Ignore imports from cgo files if cgo is disabled.
959+
fileList = &p.IgnoredGoFiles
960+
}
961+
case isXTest:
962+
fileList = &p.XTestGoFiles
963+
importMap = xTestImported
964+
case isTest:
965+
fileList = &p.TestGoFiles
966+
importMap = testImported
967+
default:
968+
fileList = &p.GoFiles
969+
importMap = imported
970+
}
971+
*fileList = append(*fileList, name)
972+
if importMap != nil {
973+
for _, imp := range fileImports {
974+
importMap[imp.path] = append(importMap[imp.path], fset.Position(imp.pos))
955975
}
956-
} else if isXTest {
957-
p.XTestGoFiles = append(p.XTestGoFiles, name)
958-
} else if isTest {
959-
p.TestGoFiles = append(p.TestGoFiles, name)
960-
} else {
961-
p.GoFiles = append(p.GoFiles, name)
962976
}
963977
}
978+
964979
if badGoError != nil {
965980
return p, badGoError
966981
}

src/go/build/build_test.go

+17
Original file line numberDiff line numberDiff line change
@@ -526,3 +526,20 @@ func TestMissingImportErrorRepetition(t *testing.T) {
526526
t.Fatalf("package path %q appears in error %d times; should appear once\nerror: %v", pkgPath, n, err)
527527
}
528528
}
529+
530+
// TestCgoImportsIgnored checks that imports in cgo files are not included
531+
// in the imports list when cgo is disabled.
532+
// Verifies golang.org/issue/35946.
533+
func TestCgoImportsIgnored(t *testing.T) {
534+
ctxt := Default
535+
ctxt.CgoEnabled = false
536+
p, err := ctxt.ImportDir("testdata/cgo_disabled", 0)
537+
if err != nil {
538+
t.Fatal(err)
539+
}
540+
for _, path := range p.Imports {
541+
if path == "should/be/ignored" {
542+
t.Errorf("found import %q in ignored cgo file", path)
543+
}
544+
}
545+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package cgo_disabled
2+
3+
import "C"
4+
5+
import _ "should/be/ignored"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package cgo_disabled

0 commit comments

Comments
 (0)