# The rest of the cgo rules are below, but these variable updates
# must be done here so they apply to the main rules.
ifdef CGOFILES
+CGOTARG=cgo_$(subst /,_,$(TARG))
GOFILES+=$(patsubst %.go,%.cgo1.go,$(CGOFILES))
GOFILES+=_cgo_gotypes.go
OFILES+=_cgo_defun.$O
GCC_OFILES=$(patsubst %.go,%.cgo2.o,$(CGOFILES))
-INSTALLFILES+=$(pkgdir)/$(TARG).so
+INSTALLFILES+=$(pkgdir)/$(CGOTARG).so
endif
PREREQ+=$(patsubst %,%.make,$(DEPS))
_cgo_.so: $(GCC_OFILES) $(CGO_DEPS)
gcc $(_CGO_CFLAGS_$(GOARCH)) -o $@ $(GCC_OFILES) $(CGO_LDFLAGS) $(_CGO_LDFLAGS_$(GOOS))
-$(pkgdir)/$(TARG).so: _cgo_.so
+$(pkgdir)/$(CGOTARG).so: _cgo_.so
@test -d $(QUOTED_GOROOT)/pkg && mkdir -p $(pkgdir)/$(dir)
cp _cgo_.so "$@"
return f
}
+func slashToUnderscore(c int) int {
+ if c == '/' {
+ c = '_'
+ }
+ return c
+}
+
// writeDefs creates output files to be compiled by 6g, 6c, and gcc.
// (The comments here say 6g and 6c but the code applies to the 8 and 5 tools too.)
func (p *Prog) writeDefs() {
path = pkgroot + "/" + path
}
+ // The path for the shared object is slash-free so that ELF loaders
+ // will treat it as a relative path. We rewrite slashes to underscores.
+ sopath := "cgo_" + strings.Map(slashToUnderscore, p.PackagePath)
+ soprefix := ""
+ if os.Getenv("GOOS") == "darwin" {
+ // OS X requires its own prefix for a relative path
+ soprefix = "@rpath/"
+ }
+
fgo2 := creat("_cgo_gotypes.go")
fc := creat("_cgo_defun.c")
}
fmt.Fprintf(fgo2, "type _C_void [0]byte\n")
- fmt.Fprintf(fc, cProlog, pkgroot, pkgroot, pkgroot, pkgroot, pkgroot)
+ fmt.Fprintf(fc, cProlog, soprefix, soprefix, soprefix, soprefix, soprefix)
for name, def := range p.Vardef {
- fmt.Fprintf(fc, "#pragma dynimport ·_C_%s %s \"%s.so\"\n", name, name, path)
+ fmt.Fprintf(fc, "#pragma dynimport ·_C_%s %s \"%s%s.so\"\n", name, name, soprefix, sopath)
fmt.Fprintf(fgo2, "var _C_%s ", name)
printer.Fprint(fgo2, &ast.StarExpr{X: def.Go})
fmt.Fprintf(fgo2, "\n")
// C wrapper calls into gcc, passing a pointer to the argument frame.
// Also emit #pragma to get a pointer to the gcc wrapper.
- fmt.Fprintf(fc, "#pragma dynimport _cgo_%s _cgo_%s \"%s.so\"\n", name, name, path)
+ fmt.Fprintf(fc, "#pragma dynimport _cgo_%s _cgo_%s \"%s%s.so\"\n", name, name, soprefix, sopath)
fmt.Fprintf(fc, "void (*_cgo_%s)(void*);\n", name)
fmt.Fprintf(fc, "\n")
fmt.Fprintf(fc, "void\n")
#include "runtime.h"
#include "cgocall.h"
-#pragma dynimport initcgo initcgo "%s/libcgo.so"
-#pragma dynimport libcgo_thread_start libcgo_thread_start "%s/libcgo.so"
-#pragma dynimport libcgo_set_scheduler libcgo_set_scheduler "%s/libcgo.so"
-#pragma dynimport _cgo_malloc _cgo_malloc "%s/libcgo.so"
-#pragma dynimport _cgo_free _cgo_free "%s/libcgo.so"
+#pragma dynimport initcgo initcgo "%slibcgo.so"
+#pragma dynimport libcgo_thread_start libcgo_thread_start "%slibcgo.so"
+#pragma dynimport libcgo_set_scheduler libcgo_set_scheduler "%slibcgo.so"
+#pragma dynimport _cgo_malloc _cgo_malloc "%slibcgo.so"
+#pragma dynimport _cgo_free _cgo_free "%slibcgo.so"
void
·_C_GoString(int8 *p, String s)
vlong v, w;
vlong va;
int a, i, ptrsize;
+ char *pkgroot;
MachoHdr *mh;
MachoSect *msect;
MachoSeg *ms;
ml->data[0] = 12; /* offset to string */
strcpy((char*)&ml->data[1], "/usr/lib/dyld");
+ if(ndylib > 0) { /* add reference to where .so files are installed */
+ pkgroot = smprint("%s/pkg/%s_%s", goroot, goos, goarch);
+ ml = newMachoLoad(0x80000000 | 0x1c, 1+(strlen(pkgroot)+1+7)/8*2); /* LC_RPATH */
+ ml->data[0] = 12; /* offset of string from beginning of load */
+ strcpy((char*)&ml->data[1], pkgroot);
+ }
for(i=0; i<ndylib; i++) {
ml = newMachoLoad(12, 4+(strlen(dylib[i])+1+7)/8*2); /* LC_LOAD_DYLIB */
ml->data[0] = 24; /* offset of string from beginning of load */