]> Cypherpunks repositories - gostls13.git/commitdiff
cgo: handle references to symbols in shared libraries
authorRuss Cox <rsc@golang.org>
Fri, 17 Dec 2010 19:37:11 +0000 (11:37 -0800)
committerRuss Cox <rsc@golang.org>
Fri, 17 Dec 2010 19:37:11 +0000 (11:37 -0800)
Fixes #1334.

R=r
CC=golang-dev
https://golang.org/cl/3746041

misc/cgo/life/c-life.c
misc/cgo/life/life.go
misc/cgo/life/life.h
misc/cgo/stdio/file.go
src/Make.pkg
src/cmd/cgo/out.go

index 71555a9c7a2b5b5016d30e0da0ef722b2ff4862b..6572455951ca243fa437ebf7aa49b48563be47d6 100644 (file)
@@ -6,6 +6,8 @@
 #include "life.h"
 #include "_cgo_export.h"
 
+const int MYCONST = 0;
+
 // Do the actual manipulation of the life board in C.  This could be
 // done easily in Go, we are just using C for demonstration
 // purposes.
index 0368028537fe9c9dadfa8051a80ce26fbdf2f6b2..ec000ce3a3dedc4692e858cc2299239bba74625c 100644 (file)
@@ -23,7 +23,7 @@ var chans [4]chan bool
 //export GoStart
 // Double return value is just for testing.
 func GoStart(i, xdim, ydim, xstart, xend, ystart, yend C.int, a *C.int, n *C.int) (int, int) {
-       c := make(chan bool)
+       c := make(chan bool, int(C.MYCONST))
        go func() {
                C.DoStep(xdim, ydim, xstart, xend, ystart, yend, a, n)
                c <- true
index b6e94cf1d318cfd95beb98bcaa9f7863a294e125..b2011b25fc8a80fc99b6e494f34dd1978c80e411 100644 (file)
@@ -4,3 +4,4 @@
 
 extern void Step(int, int, int *, int *);
 extern void DoStep(int, int, int, int, int, int, int *, int *);
+extern const int MYCONST;
index 1f461f293917b8af30b45c06818f4d222a02ea96..021cbf909caf2598398d0e9197cce794ab6efa9d 100644 (file)
@@ -26,6 +26,10 @@ type File C.FILE
 var Stdout = (*File)(C.stdout)
 var Stderr = (*File)(C.stderr)
 
+// Test reference to library symbol.
+// Stdout and stderr are too special to be a reliable test.
+var myerr = C.sys_errlist
+
 func (f *File) WriteString(s string) {
        p := C.CString(s)
        C.fputs(p, (*C.FILE)(f))
index 420f61003036aeec86f61a4ee2951ab0e6dc9457..e4cdaae30b75da9227707100dc077189a907f517 100644 (file)
@@ -116,8 +116,8 @@ _cgo_defun.c: $(CGOFILES)
        CGOPKGPATH=$(dir) cgo -- $(CGO_CFLAGS) $(CGOFILES)
 endif
 
-# Ugly but necessary
-_cgo_gotypes.go _cgo_export.c _cgo_export.h: _cgo_defun.c
+# Ugly but necessary - cgo writes these files too.
+_cgo_gotypes.go _cgo_export.c _cgo_export.h _cgo_main.c: _cgo_defun.c
        @true
 
 %.cgo1.go %.cgo2.c: _cgo_defun.c
@@ -134,10 +134,6 @@ _cgo_gotypes.go _cgo_export.c _cgo_export.h: _cgo_defun.c
 # and libraries are involved, instead of duplicating gcc's logic ourselves.
 # After main we have to define all the symbols that will be provided
 # by Go code.  That's crosscall2 and any exported symbols.
-_cgo_main.c: _cgo_defun.c
-       echo 'int main() { return 0; }' >$@
-       echo 'int crosscall2;' >>$@
-       awk -F'(' '/^_cgoexp_/ {print "int " $$1 ";"}' _cgo_defun.c >>$@
 
 _cgo_main.o: _cgo_main.c
        $(HOST_CC) $(_CGO_CFLAGS_$(GOARCH)) -g -fPIC -O2 -o $@ -c $(CGO_CFLAGS) _cgo_main.c
index d960079e1a47156a3af83de9299f6c46af03743c..4be9116169b791c001e511943e93aa50ccd66a29 100644 (file)
@@ -30,6 +30,11 @@ func (p *Package) writeDefs() {
 
        fgo2 := creat("_cgo_gotypes.go")
        fc := creat("_cgo_defun.c")
+       fm := creat("_cgo_main.c")
+
+       // Write C main file for using gcc to resolve imports.
+       fmt.Fprintf(fm, "int main() { return 0; }\n")
+       fmt.Fprintf(fm, "int crosscall2;\n\n")
 
        // Write second Go output: definitions of _C_xxx.
        // In a separate file so that the import of "unsafe" does not
@@ -58,6 +63,9 @@ func (p *Package) writeDefs() {
                }
                cVars = append(cVars, 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(fc, "extern byte *%s;\n", n.C)
                fmt.Fprintf(fc, "void *·%s = &%s;\n", n.Mangle, n.C)
                fmt.Fprintf(fc, "\n")
@@ -81,7 +89,7 @@ func (p *Package) writeDefs() {
                }
        }
 
-       p.writeExports(fgo2, fc)
+       p.writeExports(fgo2, fc, fm)
 
        fgo2.Close()
        fc.Close()
@@ -320,7 +328,7 @@ func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
 
 // Write out the various stubs we need to support functions exported
 // from Go so that they are callable from C.
-func (p *Package) writeExports(fgo2, fc *os.File) {
+func (p *Package) writeExports(fgo2, fc, fm *os.File) {
        fgcc := creat("_cgo_export.c")
        fgcch := creat("_cgo_export.h")
 
@@ -460,6 +468,8 @@ func (p *Package) writeExports(fgo2, fc *os.File) {
                fmt.Fprintf(fc, "\truntime·cgocallback(·%s, a, n);\n", goname)
                fmt.Fprintf(fc, "}\n")
 
+               fmt.Fprintf(fm, "int _cgoexp%s_%s;\n", cPrefix, exp.ExpName)
+
                // Calling a function with a receiver from C requires
                // a Go wrapper function.
                if fn.Recv != nil {