Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
4fd867b2
Commit
4fd867b2
authored
Feb 01, 2011
by
Gustavo Niemeyer
Committed by
Russ Cox
Feb 01, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cgo: define CGO_CFLAGS and CGO_LDFLAGS in Go files
R=rsc, binet CC=golang-dev
https://golang.org/cl/3921043
parent
0e474609
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
150 additions
and
10 deletions
+150
-10
Make.pkg
src/Make.pkg
+16
-6
doc.go
src/cmd/cgo/doc.go
+9
-0
gcc.go
src/cmd/cgo/gcc.go
+102
-0
main.go
src/cmd/cgo/main.go
+17
-4
out.go
src/cmd/cgo/out.go
+6
-0
No files found.
src/Make.pkg
View file @
4fd867b2
...
...
@@ -48,7 +48,7 @@ coverage:
6cov -g $(shell pwd) $O.out | grep -v '_test\.go:'
CLEANFILES+=*.cgo1.go *.cgo2.c _cgo_defun.c _cgo_gotypes.go _cgo_export.*
CLEANFILES+=_cgo_.c _cgo_import.c _cgo_main.c
CLEANFILES+=_cgo_.c _cgo_import.c _cgo_main.c
_cgo_flags _cgo_run
CLEANFILES+=*.so _obj _test _testmain.go *.exe
test:
...
...
@@ -112,11 +112,21 @@ dir:
#
ifdef CGOFILES
_cgo_defun.c: $(CGOFILES)
_cgo_run: $(CGOFILES)
@touch _cgo_run
CGOPKGPATH=$(dir) cgo -- $(CGO_CFLAGS) $(CGOFILES)
# _CGO_CFLAGS and _CGO_LDFLAGS are defined via the evaluation of _cgo_flags.
# The include happens before the commands in the recipe run,
# so it cannot be done in the same recipe that runs cgo.
_cgo_flags: _cgo_run
$(eval include _cgo_flags)
# Include any previous flags in case cgo files are up to date.
-include _cgo_flags
# Ugly but necessary - cgo writes these files too.
_cgo_gotypes.go _cgo_export.c _cgo_export.h _cgo_main.c
: _cgo_defun.c
_cgo_gotypes.go _cgo_export.c _cgo_export.h _cgo_main.c
_cgo_defun.c: _cgo_flags
@true
%.cgo1.go %.cgo2.c: _cgo_defun.c
...
...
@@ -125,7 +135,7 @@ endif
# Compile rules for gcc source files.
%.o: %.c
$(HOST_CC) $(_CGO_CFLAGS_$(GOARCH)) -g -fPIC -O2 -o $@ -c $(CGO_CFLAGS) $*.c
$(HOST_CC) $(_CGO_CFLAGS_$(GOARCH)) -g -fPIC -O2 -o $@ -c $(CGO_CFLAGS) $
(_CGO_CFLAGS) $
*.c
# To find out which symbols are needed from external libraries
# and which libraries are needed, we build a simple a.out that
...
...
@@ -136,10 +146,10 @@ endif
# by Go code. That's crosscall2 and any exported symbols.
_cgo_main.o: _cgo_main.c
$(HOST_CC) $(_CGO_CFLAGS_$(GOARCH)) -g -fPIC -O2 -o $@ -c $(CGO_CFLAGS) _cgo_main.c
$(HOST_CC) $(_CGO_CFLAGS_$(GOARCH)) -g -fPIC -O2 -o $@ -c $(CGO_CFLAGS)
$(_CGO_CFLAGS)
_cgo_main.c
_cgo1_.o: _cgo_main.o $(CGO_OFILES)
$(HOST_CC) $(_CGO_CFLAGS_$(GOARCH)) -g -fPIC -O2 -o $@ $^ $(CGO_LDFLAGS)
$(HOST_CC) $(_CGO_CFLAGS_$(GOARCH)) -g -fPIC -O2 -o $@ $^ $(CGO_LDFLAGS)
$(_CGO_LDFLAGS)
_cgo_import.c: _cgo1_.o
cgo -dynimport _cgo1_.o >_$@ && mv -f _$@ $@
...
...
src/cmd/cgo/doc.go
View file @
4fd867b2
...
...
@@ -23,6 +23,15 @@ the package. For example:
// #include <errno.h>
import "C"
CFLAGS and LDFLAGS may be defined with pseudo #cgo directives
within these comments to tweak the behavior of gcc. Values defined
in multiple directives are concatenated together. For example:
// #cgo CFLAGS: -DPNG_DEBUG=1
// #cgo LDFLAGS: -lpng
// #include <png.h>
import "C"
C identifiers or field names that are keywords in Go can be
accessed by prefixing them with an underscore: if x points at
a C struct with a field named "type", x._type accesses the field.
...
...
src/cmd/cgo/gcc.go
View file @
4fd867b2
...
...
@@ -21,6 +21,7 @@ import (
"os"
"strconv"
"strings"
"unicode"
)
var
debugDefine
=
flag
.
Bool
(
"debug-define"
,
false
,
"print relevant #defines"
)
...
...
@@ -59,6 +60,107 @@ func cname(s string) string {
return
s
}
// ParseFlags extracts #cgo CFLAGS and LDFLAGS options from the file
// preamble. Multiple occurrences are concatenated with a separating space,
// even across files.
func
(
p
*
Package
)
ParseFlags
(
f
*
File
,
srcfile
string
)
{
linesIn
:=
strings
.
Split
(
f
.
Preamble
,
"
\n
"
,
-
1
)
linesOut
:=
make
([]
string
,
0
,
len
(
linesIn
))
for
_
,
line
:=
range
linesIn
{
l
:=
strings
.
TrimSpace
(
line
)
if
len
(
l
)
<
5
||
l
[
:
4
]
!=
"#cgo"
||
!
unicode
.
IsSpace
(
int
(
l
[
4
]))
{
linesOut
=
append
(
linesOut
,
line
)
continue
}
l
=
strings
.
TrimSpace
(
l
[
4
:
])
fields
:=
strings
.
Split
(
l
,
":"
,
2
)
if
len
(
fields
)
!=
2
{
fatal
(
"%s: bad #cgo line: %s"
,
srcfile
,
line
)
}
k
:=
fields
[
0
]
v
:=
strings
.
TrimSpace
(
fields
[
1
])
if
k
!=
"CFLAGS"
&&
k
!=
"LDFLAGS"
{
fatal
(
"%s: unsupported #cgo option %s"
,
srcfile
,
k
)
}
args
,
err
:=
splitQuoted
(
v
)
if
err
!=
nil
{
fatal
(
"%s: bad #cgo option %s: %s"
,
srcfile
,
k
,
err
.
String
())
}
if
oldv
,
ok
:=
p
.
CgoFlags
[
k
];
ok
{
p
.
CgoFlags
[
k
]
=
oldv
+
" "
+
v
}
else
{
p
.
CgoFlags
[
k
]
=
v
}
if
k
==
"CFLAGS"
{
p
.
GccOptions
=
append
(
p
.
GccOptions
,
args
...
)
}
}
f
.
Preamble
=
strings
.
Join
(
linesOut
,
"
\n
"
)
}
// splitQuoted splits the string s around each instance of one or more consecutive
// white space characters while taking into account quotes and escaping, and
// returns an array of substrings of s or an empty list if s contains only white space.
// Single quotes and double quotes are recognized to prevent splitting within the
// quoted region, and are removed from the resulting substrings. If a quote in s
// isn't closed err will be set and r will have the unclosed argument as the
// last element. The backslash is used for escaping.
//
// For example, the following string:
//
// `a b:"c d" 'e''f' "g\""`
//
// Would be parsed as:
//
// []string{"a", "b:c d", "ef", `g"`}
//
func
splitQuoted
(
s
string
)
(
r
[]
string
,
err
os
.
Error
)
{
var
args
[]
string
arg
:=
make
([]
int
,
len
(
s
))
escaped
:=
false
quoted
:=
false
quote
:=
0
i
:=
0
for
_
,
rune
:=
range
s
{
switch
{
case
escaped
:
escaped
=
false
case
rune
==
'\\'
:
escaped
=
true
continue
case
quote
!=
0
:
if
rune
==
quote
{
quote
=
0
continue
}
case
rune
==
'"'
||
rune
==
'\'
'
:
quoted
=
true
quote
=
rune
continue
case
unicode
.
IsSpace
(
rune
)
:
if
quoted
||
i
>
0
{
quoted
=
false
args
=
append
(
args
,
string
(
arg
[
:
i
]))
i
=
0
}
continue
}
arg
[
i
]
=
rune
i
++
}
if
quoted
||
i
>
0
{
args
=
append
(
args
,
string
(
arg
[
:
i
]))
}
if
quote
!=
0
{
err
=
os
.
ErrorString
(
"unclosed quote"
)
}
else
if
escaped
{
err
=
os
.
ErrorString
(
"unfinished escaping"
)
}
return
args
,
err
}
// Translate rewrites f.AST, the original Go input, to remove
// references to the imported package C, replacing them with
// references to the equivalent Go types, functions, and variables.
...
...
src/cmd/cgo/main.go
View file @
4fd867b2
...
...
@@ -29,6 +29,7 @@ type Package struct {
PackagePath
string
PtrSize
int64
GccOptions
[]
string
CgoFlags
map
[
string
]
string
// #cgo flags (CFLAGS, LDFLAGS)
Written
map
[
string
]
bool
Name
map
[
string
]
*
Name
// accumulated Name from Files
Typedef
map
[
string
]
ast
.
Expr
// accumulated Typedef from Files
...
...
@@ -161,7 +162,12 @@ func main() {
if
i
==
len
(
args
)
{
usage
()
}
gccOptions
,
goFiles
:=
args
[
0
:
i
],
args
[
i
:
]
// Copy it to a new slice so it can grow.
gccOptions
:=
make
([]
string
,
i
)
copy
(
gccOptions
,
args
[
0
:
i
])
goFiles
:=
args
[
i
:
]
arch
:=
os
.
Getenv
(
"GOARCH"
)
if
arch
==
""
{
...
...
@@ -180,6 +186,7 @@ func main() {
p
:=
&
Package
{
PtrSize
:
ptrSize
,
GccOptions
:
gccOptions
,
CgoFlags
:
make
(
map
[
string
]
string
),
Written
:
make
(
map
[
string
]
bool
),
}
...
...
@@ -199,11 +206,17 @@ func main() {
}
cPrefix
=
fmt
.
Sprintf
(
"_%x"
,
h
.
Sum
()[
0
:
6
])
for
_
,
input
:=
range
goFiles
{
fs
:=
make
([]
*
File
,
len
(
goFiles
))
for
i
,
input
:=
range
goFiles
{
// Parse flags for all files before translating due to CFLAGS.
f
:=
new
(
File
)
// Reset f.Preamble so that we don't end up with conflicting headers / defines
f
.
Preamble
=
""
f
.
ReadGo
(
input
)
p
.
ParseFlags
(
f
,
input
)
fs
[
i
]
=
f
}
for
i
,
input
:=
range
goFiles
{
f
:=
fs
[
i
]
p
.
Translate
(
f
)
for
_
,
cref
:=
range
f
.
Ref
{
switch
cref
.
Context
{
...
...
src/cmd/cgo/out.go
View file @
4fd867b2
...
...
@@ -33,6 +33,12 @@ func (p *Package) writeDefs() {
fc
:=
creat
(
"_cgo_defun.c"
)
fm
:=
creat
(
"_cgo_main.c"
)
fflg
:=
creat
(
"_cgo_flags"
)
for
k
,
v
:=
range
p
.
CgoFlags
{
fmt
.
Fprintf
(
fflg
,
"_CGO_%s=%s
\n
"
,
k
,
v
)
}
fflg
.
Close
()
// Write C main file for using gcc to resolve imports.
fmt
.
Fprintf
(
fm
,
"int main() { return 0; }
\n
"
)
fmt
.
Fprintf
(
fm
,
"void crosscall2(void(*fn)(void*, int), void *a, int c) { }
\n
"
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment