Skip to content

Commit d06be39

Browse files
axwrobpike
authored andcommitted
cmd/cgo, cmd/go: remove #cgo directive parsing from cmd/cgo
This change removes processing of #cgo directives from cmd/cgo, pushing the onus back on cmd/go to pass all necessary flags. Fixes golang#5224. See comments for rationale. R=golang-dev, iant, r CC=golang-dev https://golang.org/cl/8610044
1 parent 082a4a8 commit d06be39

6 files changed

Lines changed: 95 additions & 132 deletions

File tree

misc/cgo/test/cflags.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2013 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// Test that the #cgo CFLAGS directive works,
6+
// with and without platform filters.
7+
// See http://code.google.com/p/go/issues/detail?id=5224 for details.
8+
package cgotest
9+
10+
/*
11+
#cgo CFLAGS: -DCOMMON_VALUE=123
12+
#cgo windows CFLAGS: -DIS_WINDOWS=1
13+
#cgo !windows CFLAGS: -DIS_WINDOWS=0
14+
int common = COMMON_VALUE;
15+
int is_windows = IS_WINDOWS;
16+
*/
17+
import "C"
18+
19+
import (
20+
"runtime"
21+
"testing"
22+
)
23+
24+
func testCflags(t *testing.T) {
25+
is_windows := C.is_windows == 1
26+
if is_windows != (runtime.GOOS == "windows") {
27+
t.Errorf("is_windows: %v, runtime.GOOS: %s", is_windows, runtime.GOOS)
28+
}
29+
if C.common != 123 {
30+
t.Errorf("common: %v (expected 123)", C.common)
31+
}
32+
}

misc/cgo/test/cgo_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,6 @@ func Test3775(t *testing.T) { test3775(t) }
3838
func TestCthread(t *testing.T) { testCthread(t) }
3939
func TestCallbackCallers(t *testing.T) { testCallbackCallers(t) }
4040
func Test5227(t *testing.T) { test5227(t) }
41+
func TestCflags(t *testing.T) { testCflags(t) }
4142

4243
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }

src/cmd/cgo/gcc.go

Lines changed: 4 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -66,71 +66,16 @@ func cname(s string) string {
6666
return s
6767
}
6868

69-
// ParseFlags extracts #cgo CFLAGS and LDFLAGS options from the file
70-
// preamble. Multiple occurrences are concatenated with a separating space,
71-
// even across files.
72-
func (p *Package) ParseFlags(f *File, srcfile string) {
69+
// DiscardCgoDirectives processes the import C preamble, and discards
70+
// all #cgo CFLAGS and LDFLAGS directives, so they don't make their
71+
// way into _cgo_export.h.
72+
func (f *File) DiscardCgoDirectives() {
7373
linesIn := strings.Split(f.Preamble, "\n")
7474
linesOut := make([]string, 0, len(linesIn))
75-
76-
NextLine:
7775
for _, line := range linesIn {
7876
l := strings.TrimSpace(line)
7977
if len(l) < 5 || l[:4] != "#cgo" || !unicode.IsSpace(rune(l[4])) {
8078
linesOut = append(linesOut, line)
81-
continue
82-
}
83-
84-
l = strings.TrimSpace(l[4:])
85-
fields := strings.SplitN(l, ":", 2)
86-
if len(fields) != 2 {
87-
fatalf("%s: bad #cgo line: %s", srcfile, line)
88-
}
89-
90-
var k string
91-
kf := strings.Fields(fields[0])
92-
switch len(kf) {
93-
case 1:
94-
k = kf[0]
95-
case 2:
96-
k = kf[1]
97-
switch kf[0] {
98-
case goos:
99-
case goarch:
100-
case goos + "/" + goarch:
101-
default:
102-
continue NextLine
103-
}
104-
default:
105-
fatalf("%s: bad #cgo option: %s", srcfile, fields[0])
106-
}
107-
108-
args, err := splitQuoted(fields[1])
109-
if err != nil {
110-
fatalf("%s: bad #cgo option %s: %s", srcfile, k, err)
111-
}
112-
for _, arg := range args {
113-
if !safeName(arg) {
114-
fatalf("%s: #cgo option %s is unsafe: %s", srcfile, k, arg)
115-
}
116-
}
117-
118-
switch k {
119-
120-
case "CFLAGS", "LDFLAGS":
121-
p.addToFlag(k, args)
122-
123-
case "pkg-config":
124-
cflags, ldflags, err := pkgConfig(args)
125-
if err != nil {
126-
fatalf("%s: bad #cgo option %s: %s", srcfile, k, err)
127-
}
128-
p.addToFlag("CFLAGS", cflags)
129-
p.addToFlag("LDFLAGS", ldflags)
130-
131-
default:
132-
fatalf("%s: unsupported #cgo option %s", srcfile, k)
133-
13479
}
13580
}
13681
f.Preamble = strings.Join(linesOut, "\n")
@@ -146,36 +91,6 @@ func (p *Package) addToFlag(flag string, args []string) {
14691
}
14792
}
14893

149-
// pkgConfig runs pkg-config and extracts --libs and --cflags information
150-
// for packages.
151-
func pkgConfig(packages []string) (cflags, ldflags []string, err error) {
152-
for _, name := range packages {
153-
if len(name) == 0 || name[0] == '-' {
154-
return nil, nil, errors.New(fmt.Sprintf("invalid name: %q", name))
155-
}
156-
}
157-
158-
args := append([]string{"pkg-config", "--cflags"}, packages...)
159-
stdout, stderr, ok := run(nil, args)
160-
if !ok {
161-
os.Stderr.Write(stderr)
162-
return nil, nil, errors.New("pkg-config failed")
163-
}
164-
cflags, err = splitQuoted(string(stdout))
165-
if err != nil {
166-
return
167-
}
168-
169-
args = append([]string{"pkg-config", "--libs"}, packages...)
170-
stdout, stderr, ok = run(nil, args)
171-
if !ok {
172-
os.Stderr.Write(stderr)
173-
return nil, nil, errors.New("pkg-config failed")
174-
}
175-
ldflags, err = splitQuoted(string(stdout))
176-
return
177-
}
178-
17994
// splitQuoted splits the string s around each instance of one or more consecutive
18095
// white space characters while taking into account quotes and escaping, and
18196
// returns an array of substrings of s or an empty list if s contains only white space.

src/cmd/cgo/main.go

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -235,10 +235,9 @@ func main() {
235235

236236
fs := make([]*File, len(goFiles))
237237
for i, input := range goFiles {
238-
// Parse flags for all files before translating due to CFLAGS.
239238
f := new(File)
240239
f.ReadGo(input)
241-
p.ParseFlags(f, input)
240+
f.DiscardCgoDirectives()
242241
fs[i] = f
243242
}
244243

@@ -291,11 +290,6 @@ func main() {
291290
// newPackage returns a new Package that will invoke
292291
// gcc with the additional arguments specified in args.
293292
func newPackage(args []string) *Package {
294-
// Copy the gcc options to a new slice so the list
295-
// can grow without overwriting the slice that args is in.
296-
gccOptions := make([]string, len(args))
297-
copy(gccOptions, args)
298-
299293
goarch = runtime.GOARCH
300294
if s := os.Getenv("GOARCH"); s != "" {
301295
goarch = s
@@ -318,12 +312,12 @@ func newPackage(args []string) *Package {
318312
os.Setenv("LC_ALL", "C")
319313

320314
p := &Package{
321-
PtrSize: ptrSize,
322-
IntSize: intSize,
323-
GccOptions: gccOptions,
324-
CgoFlags: make(map[string][]string),
325-
Written: make(map[string]bool),
315+
PtrSize: ptrSize,
316+
IntSize: intSize,
317+
CgoFlags: make(map[string][]string),
318+
Written: make(map[string]bool),
326319
}
320+
p.addToFlag("CFLAGS", args)
327321
return p
328322
}
329323

0 commit comments

Comments
 (0)