1
0
mirror of https://github.com/golang/go synced 2024-11-26 18:16:48 -07:00

cmd/cgo: split cgo_export into cgo_export_static and cgo_export_dynamic

Also emit cgo_ldflag pragmas.

R=golang-dev, remyoudompheng, iant
CC=golang-dev
https://golang.org/cl/7530043
This commit is contained in:
Russ Cox 2013-03-06 16:57:14 -05:00
parent 56d1faa8b6
commit fb59aed60b
7 changed files with 65 additions and 23 deletions

View File

@ -692,22 +692,24 @@ pragcgo(char *verb)
goto out; goto out;
} }
if(strcmp(verb, "cgo_export") == 0 || strcmp(verb, "dynexport") == 0) { if(strcmp(verb, "dynexport") == 0)
verb = "cgo_export_dynamic";
if(strcmp(verb, "cgo_export_static") == 0 || strcmp(verb, "cgo_export_dynamic") == 0) {
local = getimpsym(); local = getimpsym();
if(local == nil) if(local == nil)
goto err2; goto err2;
if(!more()) { if(!more()) {
fmtprint(&pragcgobuf, "cgo_export %q\n", local->name); fmtprint(&pragcgobuf, "%s %q\n", verb, local->name);
goto out; goto out;
} }
remote = getimpsym(); remote = getimpsym();
if(remote == nil) if(remote == nil)
goto err2; goto err2;
fmtprint(&pragcgobuf, "cgo_export %q %q\n", local->name, remote->name); fmtprint(&pragcgobuf, "%s %q %q\n", verb, local->name, remote->name);
goto out; goto out;
err2: err2:
yyerror("usage: #pragma cgo_export local [remote]"); yyerror("usage: #pragma %s local [remote]", verb);
goto out; goto out;
} }
@ -749,6 +751,18 @@ pragcgo(char *verb)
goto out; goto out;
} }
if(strcmp(verb, "cgo_ldflag") == 0) {
p = getquoted();
if(p == nil)
goto err5;
fmtprint(&pragcgobuf, "cgo_ldflag %q\n", p);
goto out;
err5:
yyerror("usage: #pragma cgo_ldflag \"arg\"");
goto out;
}
out: out:
while(getnsc() != '\n') while(getnsc() != '\n')
; ;

View File

@ -484,16 +484,16 @@ The directives are:
Example: Example:
#pragma cgo_dynamic_linker "/lib/ld-linux.so.2" #pragma cgo_dynamic_linker "/lib/ld-linux.so.2"
#pragma cgo_export <local> <remote> #pragma cgo_export_dynamic <local> <remote>
In both internal and external linking modes, put the Go symbol In internal linking mode, put the Go symbol
named <local> into the program's exported symbol table as named <local> into the program's exported symbol table as
<remote>, so that C code can refer to it by that name. This <remote>, so that C code can refer to it by that name. This
mechanism makes it possible for C code to call back into Go or mechanism makes it possible for C code to call back into Go or
to share Go's data. to share Go's data.
For compatibility with current versions of SWIG, For compatibility with current versions of SWIG,
#pragma dynexport is an alias for #pragma cgo_export. #pragma dynexport is an alias for #pragma cgo_export_dynamic.
#pragma cgo_import_static <local> #pragma cgo_import_static <local>
@ -505,6 +505,14 @@ The directives are:
Example: Example:
#pragma cgo_import_static puts_wrapper #pragma cgo_import_static puts_wrapper
#pragma cgo_export_static <local> <remote>
In external linking mode, put the Go symbol
named <local> into the program's exported symbol table as
<remote>, so that C code can refer to it by that name. This
mechanism makes it possible for C code to call back into Go or
to share Go's data.
#pragma cgo_ldflag "<arg>" #pragma cgo_ldflag "<arg>"
In external linking mode, invoke the host linker (usually gcc) In external linking mode, invoke the host linker (usually gcc)

View File

@ -139,11 +139,7 @@ NextLine:
// addToFlag appends args to flag. All flags are later written out onto the // addToFlag appends args to flag. All flags are later written out onto the
// _cgo_flags file for the build system to use. // _cgo_flags file for the build system to use.
func (p *Package) addToFlag(flag string, args []string) { func (p *Package) addToFlag(flag string, args []string) {
if oldv, ok := p.CgoFlags[flag]; ok { p.CgoFlags[flag] = append(p.CgoFlags[flag], args...)
p.CgoFlags[flag] = oldv + " " + strings.Join(args, " ")
} else {
p.CgoFlags[flag] = strings.Join(args, " ")
}
if flag == "CFLAGS" { if flag == "CFLAGS" {
// We'll also need these when preprocessing for dwarf information. // We'll also need these when preprocessing for dwarf information.
p.GccOptions = append(p.GccOptions, args...) p.GccOptions = append(p.GccOptions, args...)

View File

@ -33,7 +33,7 @@ type Package struct {
PtrSize int64 PtrSize int64
IntSize int64 IntSize int64
GccOptions []string GccOptions []string
CgoFlags map[string]string // #cgo flags (CFLAGS, LDFLAGS) CgoFlags map[string][]string // #cgo flags (CFLAGS, LDFLAGS)
Written map[string]bool Written map[string]bool
Name map[string]*Name // accumulated Name from Files Name map[string]*Name // accumulated Name from Files
ExpFunc []*ExpFunc // accumulated ExpFunc from Files ExpFunc []*ExpFunc // accumulated ExpFunc from Files
@ -312,7 +312,7 @@ func newPackage(args []string) *Package {
PtrSize: ptrSize, PtrSize: ptrSize,
IntSize: intSize, IntSize: intSize,
GccOptions: gccOptions, GccOptions: gccOptions,
CgoFlags: make(map[string]string), CgoFlags: make(map[string][]string),
Written: make(map[string]bool), Written: make(map[string]bool),
} }
return p return p

View File

@ -31,7 +31,12 @@ func (p *Package) writeDefs() {
fflg := creat(*objDir + "_cgo_flags") fflg := creat(*objDir + "_cgo_flags")
for k, v := range p.CgoFlags { for k, v := range p.CgoFlags {
fmt.Fprintf(fflg, "_CGO_%s=%s\n", k, v) fmt.Fprintf(fflg, "_CGO_%s=%s\n", k, strings.Join(v, " "))
if k == "LDFLAGS" {
for _, arg := range v {
fmt.Fprintf(fc, "#pragma cgo_ldflag %q\n", arg)
}
}
} }
fflg.Close() fflg.Close()
@ -100,6 +105,7 @@ func (p *Package) writeDefs() {
fmt.Fprintf(fm, "extern char %s[];\n", n.C) fmt.Fprintf(fm, "extern char %s[];\n", n.C)
fmt.Fprintf(fm, "void *_cgohack_%s = %s;\n\n", n.C, n.C) fmt.Fprintf(fm, "void *_cgohack_%s = %s;\n\n", n.C, n.C)
fmt.Fprintf(fc, "#pragma cgo_import_static %s\n", n.C)
fmt.Fprintf(fc, "extern byte *%s;\n", n.C) fmt.Fprintf(fc, "extern byte *%s;\n", n.C)
cVars[n.C] = true cVars[n.C] = true
@ -651,8 +657,9 @@ func (p *Package) writeExports(fgo2, fc, fm *os.File) {
if fn.Recv != nil { if fn.Recv != nil {
goname = "_cgoexpwrap" + cPrefix + "_" + fn.Recv.List[0].Names[0].Name + "_" + goname goname = "_cgoexpwrap" + cPrefix + "_" + fn.Recv.List[0].Names[0].Name + "_" + goname
} }
fmt.Fprintf(fc, "#pragma cgo_export %s\n", goname) fmt.Fprintf(fc, "#pragma cgo_export_dynamic %s\n", goname)
fmt.Fprintf(fc, "extern void ·%s();\n\n", goname) fmt.Fprintf(fc, "extern void ·%s();\n\n", goname)
fmt.Fprintf(fc, "#pragma cgo_export_static _cgoexp%s_%s\n", cPrefix, exp.ExpName)
fmt.Fprintf(fc, "#pragma textflag 7\n") // no split stack, so no use of m or g fmt.Fprintf(fc, "#pragma textflag 7\n") // no split stack, so no use of m or g
fmt.Fprintf(fc, "void\n") fmt.Fprintf(fc, "void\n")
fmt.Fprintf(fc, "_cgoexp%s_%s(void *a, int32 n)\n", cPrefix, exp.ExpName) fmt.Fprintf(fc, "_cgoexp%s_%s(void *a, int32 n)\n", cPrefix, exp.ExpName)

View File

@ -487,7 +487,9 @@ loadcgo(char *file, char *pkg, char *p, int n)
continue; continue;
} }
if(strcmp(f[0], "cgo_export") == 0) { // TODO: cgo_export_static
if(strcmp(f[0], "cgo_export_dynamic") == 0) {
if(nf < 2 || nf > 3) if(nf < 2 || nf > 3)
goto err; goto err;
local = f[1]; local = f[1];
@ -501,13 +503,17 @@ loadcgo(char *file, char *pkg, char *p, int n)
fprint(2, "%s: symbol is both imported and exported: %s\n", argv0, local); fprint(2, "%s: symbol is both imported and exported: %s\n", argv0, local);
nerrors++; nerrors++;
} }
s->dynimpname = remote;
s->dynexport = 1; s->dynexport = 1;
if(s->dynimpname == nil) {
if(ndynexp%32 == 0) s->dynimpname = remote;
dynexp = realloc(dynexp, (ndynexp+32)*sizeof dynexp[0]); if(ndynexp%32 == 0)
dynexp[ndynexp++] = s; dynexp = realloc(dynexp, (ndynexp+32)*sizeof dynexp[0]);
dynexp[ndynexp++] = s;
} else if(strcmp(s->dynimpname, remote) != 0) {
fprint(2, "%s: conflicting cgo_export directives: %s as %s and %s\n", argv0, s->name, s->dynimpname, remote);
nerrors++;
return;
}
if(local != f[1]) if(local != f[1])
free(local); free(local);
continue; continue;
@ -528,6 +534,15 @@ loadcgo(char *file, char *pkg, char *p, int n)
} }
continue; continue;
} }
if(strcmp(f[0], "cgo_ldflag") == 0) {
if(nf != 2)
goto err;
if(nldflag%32 == 0)
ldflag = realloc(ldflag, (nldflag+32)*sizeof ldflag[0]);
ldflag[nldflag++] = strdup(f[1]);
continue;
}
} }
free(p0); free(p0);
return; return;

View File

@ -138,6 +138,8 @@ EXTERN char* outfile;
EXTERN int32 nsymbol; EXTERN int32 nsymbol;
EXTERN char* thestring; EXTERN char* thestring;
EXTERN int ndynexp; EXTERN int ndynexp;
EXTERN int nldflag;
EXTERN char** ldflag;
EXTERN int havedynamic; EXTERN int havedynamic;
EXTERN int iscgo; EXTERN int iscgo;
EXTERN int isobj; EXTERN int isobj;