From 50b9387a91906699997cfccce9955686f2e0f73b Mon Sep 17 00:00:00 2001 From: Greg Date: Tue, 4 Jun 2019 21:18:06 -0400 Subject: [PATCH] Add frameworkdirs: directive to allow the user to point to directories where Objective-C frameworks can be found. Rework the cgoFlags. Search Objective-C protocols when looking for subclass methods to override. --- main.go | 9 +++++-- wrap/main.go | 69 ++++++++++++++++++++++++++++++++-------------------- 2 files changed, 50 insertions(+), 28 deletions(-) diff --git a/main.go b/main.go index 9e116ef..d0f7179 100644 --- a/main.go +++ b/main.go @@ -31,6 +31,7 @@ type conf struct { Delegates map[string]map[string][]string Subclasses map[string]map[string][]string Frameworks []string + Frameworkdirs []string Imports []string Sysimports []string Pragma []string @@ -217,6 +218,9 @@ func Start() (err error) { if Config.Arc { cargs = append(cargs,"-fobjc-arc") } + for _,f := range Config.Frameworkdirs { + cargs = append(cargs,"-F" + f) + } cargs = append(cargs,Config.Inputfiles...) fmt.Printf("Generating AST\n") astPP, err = exec.Command("clang",cargs...).Output() @@ -255,10 +259,11 @@ func Start() (err error) { tree := buildTree(nodes, 0) w := wrap.NewWrapper(Debug) w.Package = Config.Package - w.Frameworks(Config.Frameworks) + w.Frameworks = Config.Frameworks + w.Frameworkdirs = Config.Frameworkdirs w.Import(Config.Imports) w.SysImport(Config.Sysimports) - w.Pragma(Config.Pragma) + w.Pragmas = Config.Pragma w.Delegate(Config.Delegates) w.Subclass(Config.Subclasses) if Config.Vaargs == 0 { diff --git a/wrap/main.go b/wrap/main.go index c110dae..326ccce 100644 --- a/wrap/main.go +++ b/wrap/main.go @@ -28,6 +28,9 @@ type Wrapper struct { Delegates map[string]map[string][]string Subclasses map[string]*Subclass Protocols map[string]*Protocol + Frameworks []string + Frameworkdirs []string + Pragmas []string cgoFlags strings.Builder // put cGo directives here cImports strings.Builder // put C imports and sysimports here @@ -57,13 +60,6 @@ func NewWrapper(debug bool) *Wrapper { ProcessedClassMethods: map[string]bool{}, Vaargs: 16, } - arc := " -fno-objc-arc" - if Arc { - arc = " -fobjc-arc" - } - ret.cgoFlags.WriteString(fmt.Sprintf(`/* -#cgo CFLAGS: -x objective-c%s -`,arc)) ret.goTypes.WriteString(` type Id struct { ptr unsafe.Pointer @@ -73,16 +69,6 @@ func (o Id) Ptr() unsafe.Pointer { return o.ptr } return ret } -func (w *Wrapper) Frameworks(ss []string) { - if len(ss) == 0 { - return - } - for _,s := range ss { - w.cImports.WriteString(fmt.Sprintf("#import <%s/%s.h>\n",s,s)) - } - w.cgoFlags.WriteString("#cgo LDFLAGS: -framework " + strings.Join(ss," -framework ")) -} - func (w *Wrapper) Import(ss []string) { for _,s := range ss { w.cImports.WriteString("\n#import \"" + s + "\"\n") @@ -95,12 +81,6 @@ func (w *Wrapper) SysImport(ss []string) { } } -func (w *Wrapper) Pragma(ss []string) { - for _,s := range ss { - w.cgoFlags.WriteString("\n#pragma " + s + "\n") - } -} - func (w *Wrapper) Delegate(ds map[string]map[string][]string) { w.Delegates = ds } @@ -220,7 +200,10 @@ func Disambiguate(mc *MethodCollection) { sort.Sort(ByParams(v)) for _,m := range v { if len(v) < 2 || len(m.Parameters) < 2 { - mc.Methods = append(mc.Methods,m) + if !used[m.Name] { + mc.Methods = append(mc.Methods,m) + used[m.Name] = true + } continue } i := 2 @@ -1198,7 +1181,7 @@ func (w *Wrapper) _ProcessDelSub(dname string, ps map[string][]string, nms []*Me os.Exit(-1) } //fmt.Printf(" subclass for %s\n",pname) - ms = []*Method{} + mc := NewMethodCollection(dname) var addmeths func(s string) addmeths = func(s string) { if sup := types.Super(s); w.Interfaces[sup] != nil { @@ -1206,11 +1189,18 @@ func (w *Wrapper) _ProcessDelSub(dname string, ps map[string][]string, nms []*Me } //fmt.Printf("Adding methods for %s\n",s) for _,m := range w.Interfaces[s].InstanceMethods.Methods { - ms = append(ms,m) + mc.Methods = append(mc.Methods,m) + } + for _,p := range w.Interfaces[s].Protocols { + for _,m := range w.Protocols[p].InstanceMethods.Methods { + mc.Methods = append(mc.Methods,m) + } } } //for subclasses, add all superclass methods, depth first addmeths(interf.Name) + Disambiguate(mc) + ms = mc.Methods } else { // not a subclass proto := w.Protocols[pname] if proto == nil { @@ -1711,6 +1701,33 @@ void* fmt.Printf("%d enums\n", len(w.NamedEnums) + len(w.AnonEnums)) of.WriteString("package " + w.Package + "\n\n") + arc := " -fno-objc-arc" + if Arc { + arc = " -fobjc-arc" + } + w.cgoFlags.WriteString(fmt.Sprintf(` +/* +#cgo CFLAGS: -x objective-c%s`,arc)) + ldflags := "" + if w.Frameworks != nil && len(w.Frameworks) > 0 { + for _,s := range w.Frameworks { + w.cImports.WriteString(fmt.Sprintf("#import <%s/%s.h>\n",s,s)) + } + ldflags = "-framework " + strings.Join(w.Frameworks," -framework ") + } + if w.Frameworkdirs != nil && len(w.Frameworkdirs) > 0 { + s := strings.Join(w.Frameworkdirs," -F") + w.cgoFlags.WriteString(" -F" + s) + ldflags = ldflags + " -F" + s + } + if ldflags != "" { + w.cgoFlags.WriteString(` +#cgo LDFLAGS: ` + ldflags) + } + for _,s := range w.Pragmas { + w.cgoFlags.WriteString("\n#pragma " + s + "\n") + } + of.WriteString(w.cgoFlags.String() + "\n") of.WriteString(w.cImports.String() + "\n")