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.
This commit is contained in:
Greg 2019-06-04 21:18:06 -04:00
parent f93a893060
commit 50b9387a91
2 changed files with 50 additions and 28 deletions

View File

@ -31,6 +31,7 @@ type conf struct {
Delegates map[string]map[string][]string Delegates map[string]map[string][]string
Subclasses map[string]map[string][]string Subclasses map[string]map[string][]string
Frameworks []string Frameworks []string
Frameworkdirs []string
Imports []string Imports []string
Sysimports []string Sysimports []string
Pragma []string Pragma []string
@ -217,6 +218,9 @@ func Start() (err error) {
if Config.Arc { if Config.Arc {
cargs = append(cargs,"-fobjc-arc") cargs = append(cargs,"-fobjc-arc")
} }
for _,f := range Config.Frameworkdirs {
cargs = append(cargs,"-F" + f)
}
cargs = append(cargs,Config.Inputfiles...) cargs = append(cargs,Config.Inputfiles...)
fmt.Printf("Generating AST\n") fmt.Printf("Generating AST\n")
astPP, err = exec.Command("clang",cargs...).Output() astPP, err = exec.Command("clang",cargs...).Output()
@ -255,10 +259,11 @@ func Start() (err error) {
tree := buildTree(nodes, 0) tree := buildTree(nodes, 0)
w := wrap.NewWrapper(Debug) w := wrap.NewWrapper(Debug)
w.Package = Config.Package w.Package = Config.Package
w.Frameworks(Config.Frameworks) w.Frameworks = Config.Frameworks
w.Frameworkdirs = Config.Frameworkdirs
w.Import(Config.Imports) w.Import(Config.Imports)
w.SysImport(Config.Sysimports) w.SysImport(Config.Sysimports)
w.Pragma(Config.Pragma) w.Pragmas = Config.Pragma
w.Delegate(Config.Delegates) w.Delegate(Config.Delegates)
w.Subclass(Config.Subclasses) w.Subclass(Config.Subclasses)
if Config.Vaargs == 0 { if Config.Vaargs == 0 {

View File

@ -28,6 +28,9 @@ type Wrapper struct {
Delegates map[string]map[string][]string Delegates map[string]map[string][]string
Subclasses map[string]*Subclass Subclasses map[string]*Subclass
Protocols map[string]*Protocol Protocols map[string]*Protocol
Frameworks []string
Frameworkdirs []string
Pragmas []string
cgoFlags strings.Builder // put cGo directives here cgoFlags strings.Builder // put cGo directives here
cImports strings.Builder // put C imports and sysimports here cImports strings.Builder // put C imports and sysimports here
@ -57,13 +60,6 @@ func NewWrapper(debug bool) *Wrapper {
ProcessedClassMethods: map[string]bool{}, ProcessedClassMethods: map[string]bool{},
Vaargs: 16, 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(` ret.goTypes.WriteString(`
type Id struct { type Id struct {
ptr unsafe.Pointer ptr unsafe.Pointer
@ -73,16 +69,6 @@ func (o Id) Ptr() unsafe.Pointer { return o.ptr }
return ret 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) { func (w *Wrapper) Import(ss []string) {
for _,s := range ss { for _,s := range ss {
w.cImports.WriteString("\n#import \"" + s + "\"\n") 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) { func (w *Wrapper) Delegate(ds map[string]map[string][]string) {
w.Delegates = ds w.Delegates = ds
} }
@ -220,7 +200,10 @@ func Disambiguate(mc *MethodCollection) {
sort.Sort(ByParams(v)) sort.Sort(ByParams(v))
for _,m := range v { for _,m := range v {
if len(v) < 2 || len(m.Parameters) < 2 { 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 continue
} }
i := 2 i := 2
@ -1198,7 +1181,7 @@ func (w *Wrapper) _ProcessDelSub(dname string, ps map[string][]string, nms []*Me
os.Exit(-1) os.Exit(-1)
} }
//fmt.Printf(" subclass for %s\n",pname) //fmt.Printf(" subclass for %s\n",pname)
ms = []*Method{} mc := NewMethodCollection(dname)
var addmeths func(s string) var addmeths func(s string)
addmeths = func(s string) { addmeths = func(s string) {
if sup := types.Super(s); w.Interfaces[sup] != nil { 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) //fmt.Printf("Adding methods for %s\n",s)
for _,m := range w.Interfaces[s].InstanceMethods.Methods { 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 //for subclasses, add all superclass methods, depth first
addmeths(interf.Name) addmeths(interf.Name)
Disambiguate(mc)
ms = mc.Methods
} else { // not a subclass } else { // not a subclass
proto := w.Protocols[pname] proto := w.Protocols[pname]
if proto == nil { if proto == nil {
@ -1711,6 +1701,33 @@ void*
fmt.Printf("%d enums\n", len(w.NamedEnums) + len(w.AnonEnums)) fmt.Printf("%d enums\n", len(w.NamedEnums) + len(w.AnonEnums))
of.WriteString("package " + w.Package + "\n\n") 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.cgoFlags.String() + "\n")
of.WriteString(w.cImports.String() + "\n") of.WriteString(w.cImports.String() + "\n")