GIR: Implement support for multiple libraries to be in `shared-library` key in GIR by iterating over all registered ones in the GIR and using the first one that linking succeeds with
Signed-off-by: Felicitas Pojtinger <felicitas@pojtinger.com>
- commit
- 2fa804aa19107cdfdf7f446b17491b83171c64d5
- author
- Felicitas Pojtinger · · 2025-10-16 03:14 UTC
- committer
- Jeroen Wijenbergh · · 2025-10-22 07:42 UTC
- parent
- edf23b7
- signature
- unsigned
5 files · +118 -26
M internal/core/core.go +75 -5
| @@ -44,7 +44,7 @@ var names = map[string][]string{ | |||
| 44 | 44 | "CAIRO": {"libcairo.so"}, | |
| 45 | 45 | "GDKPIXBUF": {"libgdk_pixbuf-2.0.so"}, | |
| 46 | 46 | "GIO": {"libgio-2.0.so"}, | |
| 47 | - | "GLIB": {"libglib-2.0.so"}, | |
| 47 | + | "GLIB": {"libglib-2.0.so", "libgobject-2.0.so"}, | |
| 48 | 48 | "GMODULE": {"libgmodule-2.0.so"}, | |
| 49 | 49 | "GOBJECT": {"libgobject-2.0.so"}, | |
| 50 | 50 | "GRAPHENE": {"libgraphene-1.0.so"}, | |
| @@ -85,12 +85,12 @@ func SetPackageName(libName, pkgName string) { | |||
| 85 | 85 | } | |
| 86 | 86 | } | |
| 87 | 87 | ||
| 88 | - | // SetSharedLibrary registers a shared library name for a library. | |
| 88 | + | // SetSharedLibraries registers shared library names for a library. | |
| 89 | 89 | // This is used by the code generator to set library names from GIR files. | |
| 90 | 90 | // It won't override existing entries to preserve defaults. | |
| 91 | - | func SetSharedLibrary(libName, sharedLib string) { | |
| 92 | - | if _, exists := names[libName]; !exists && sharedLib != "" { | |
| 93 | - | names[libName] = []string{sharedLib} | |
| 91 | + | func SetSharedLibraries(libName string, sharedLibs []string) { | |
| 92 | + | if _, exists := names[libName]; !exists && len(sharedLibs) > 0 { | |
| 93 | + | names[libName] = sharedLibs | |
| 94 | 94 | } | |
| 95 | 95 | } | |
| 96 | 96 | ||
| @@ -205,3 +205,73 @@ func GoString(c uintptr) string { | |||
| 205 | 205 | } | |
| 206 | 206 | return string(unsafe.Slice((*byte)(ptr), length)) | |
| 207 | 207 | } | |
| 208 | + | ||
| 209 | + | // GetPaths gets all shared object file paths for a library name that may have multiple libraries. | |
| 210 | + | // This is used when a package needs to load multiple shared libraries (e.g., GLIB needs both libgobject and libglib). | |
| 211 | + | // Returns a slice of full paths to all libraries for this package. | |
| 212 | + | func GetPaths(name string) []string { | |
| 213 | + | // resolve alias | |
| 214 | + | if v, ok := aliases[name]; ok { | |
| 215 | + | name = v | |
| 216 | + | } | |
| 217 | + | ||
| 218 | + | libNames, ok := names[name] | |
| 219 | + | if !ok || len(libNames) == 0 { | |
| 220 | + | // Fallback to single GetPath for backward compatibility | |
| 221 | + | return []string{GetPath(name)} | |
| 222 | + | } | |
| 223 | + | ||
| 224 | + | // If only one library, use the original GetPath logic | |
| 225 | + | if len(libNames) == 1 { | |
| 226 | + | return []string{GetPath(name)} | |
| 227 | + | } | |
| 228 | + | ||
| 229 | + | var result []string | |
| 230 | + | for _, libName := range libNames { | |
| 231 | + | // Try PUREGOTK_LIB_FOLDER first | |
| 232 | + | ep := os.Getenv("PUREGOTK_LIB_FOLDER") | |
| 233 | + | if ep != "" { | |
| 234 | + | suffixes := []string{"", ".0", ".1", ".2"} | |
| 235 | + | found := false | |
| 236 | + | for _, s := range suffixes { | |
| 237 | + | fullPath := filepath.Join(ep, libName+s) | |
| 238 | + | if _, err := os.Stat(fullPath); err == nil { | |
| 239 | + | result = append(result, fullPath) | |
| 240 | + | found = true | |
| 241 | + | break | |
| 242 | + | } | |
| 243 | + | } | |
| 244 | + | if found { | |
| 245 | + | continue | |
| 246 | + | } | |
| 247 | + | } | |
| 248 | + | ||
| 249 | + | // Try hardcoded paths | |
| 250 | + | gp, pathsOk := paths[runtime.GOARCH] | |
| 251 | + | if pathsOk { | |
| 252 | + | found := false | |
| 253 | + | for _, p := range gp { | |
| 254 | + | suffixes := []string{"", ".0", ".1", ".2"} | |
| 255 | + | fn := filepath.Join(p, libName) | |
| 256 | + | for _, s := range suffixes { | |
| 257 | + | if _, err := os.Stat(fn + s); err == nil { | |
| 258 | + | result = append(result, fn+s) | |
| 259 | + | found = true | |
| 260 | + | break | |
| 261 | + | } | |
| 262 | + | } | |
| 263 | + | if found { | |
| 264 | + | break | |
| 265 | + | } | |
| 266 | + | } | |
| 267 | + | if found { | |
| 268 | + | continue | |
| 269 | + | } | |
| 270 | + | } | |
| 271 | + | ||
| 272 | + | // If we get here, we couldn't find this library | |
| 273 | + | panic(fmt.Sprintf("Path for library %s (package %s) not found. Please set PUREGOTK_LIB_FOLDER or ensure the library is in standard paths", libName, name)) | |
| 274 | + | } | |
| 275 | + | ||
| 276 | + | return result | |
| 277 | + | } | |
| @@ -44,7 +44,7 @@ var names = map[string][]string{ | |||||
| 44 | "CAIRO": {"libcairo.so"}, | 44 | "CAIRO": {"libcairo.so"}, | ||
| 45 | "GDKPIXBUF": {"libgdk_pixbuf-2.0.so"}, | 45 | "GDKPIXBUF": {"libgdk_pixbuf-2.0.so"}, | ||
| 46 | "GIO": {"libgio-2.0.so"}, | 46 | "GIO": {"libgio-2.0.so"}, | ||
| 47 | - | "GLIB": {"libglib-2.0.so"}, | 47 | + | "GLIB": {"libglib-2.0.so", "libgobject-2.0.so"}, |
| 48 | "GMODULE": {"libgmodule-2.0.so"}, | 48 | "GMODULE": {"libgmodule-2.0.so"}, | ||
| 49 | "GOBJECT": {"libgobject-2.0.so"}, | 49 | "GOBJECT": {"libgobject-2.0.so"}, | ||
| 50 | "GRAPHENE": {"libgraphene-1.0.so"}, | 50 | "GRAPHENE": {"libgraphene-1.0.so"}, | ||
| @@ -85,12 +85,12 @@ func SetPackageName(libName, pkgName string) { | |||||
| 85 | } | 85 | } | ||
| 86 | } | 86 | } | ||
| 87 | 87 | ||||
| 88 | - | // SetSharedLibrary registers a shared library name for a library. | 88 | + | // SetSharedLibraries registers shared library names for a library. |
| 89 | // This is used by the code generator to set library names from GIR files. | 89 | // This is used by the code generator to set library names from GIR files. | ||
| 90 | // It won't override existing entries to preserve defaults. | 90 | // It won't override existing entries to preserve defaults. | ||
| 91 | - | func SetSharedLibrary(libName, sharedLib string) { | 91 | + | func SetSharedLibraries(libName string, sharedLibs []string) { |
| 92 | - | if _, exists := names[libName]; !exists && sharedLib != "" { | 92 | + | if _, exists := names[libName]; !exists && len(sharedLibs) > 0 { |
| 93 | - | names[libName] = []string{sharedLib} | 93 | + | names[libName] = sharedLibs |
| 94 | } | 94 | } | ||
| 95 | } | 95 | } | ||
| 96 | 96 | ||||
| @@ -205,3 +205,73 @@ func GoString(c uintptr) string { | |||||
| 205 | } | 205 | } | ||
| 206 | return string(unsafe.Slice((*byte)(ptr), length)) | 206 | return string(unsafe.Slice((*byte)(ptr), length)) | ||
| 207 | } | 207 | } | ||
| 208 | + | ||||
| 209 | + | // GetPaths gets all shared object file paths for a library name that may have multiple libraries. | |||
| 210 | + | // This is used when a package needs to load multiple shared libraries (e.g., GLIB needs both libgobject and libglib). | |||
| 211 | + | // Returns a slice of full paths to all libraries for this package. | |||
| 212 | + | func GetPaths(name string) []string { | |||
| 213 | + | // resolve alias | |||
| 214 | + | if v, ok := aliases[name]; ok { | |||
| 215 | + | name = v | |||
| 216 | + | } | |||
| 217 | + | ||||
| 218 | + | libNames, ok := names[name] | |||
| 219 | + | if !ok || len(libNames) == 0 { | |||
| 220 | + | // Fallback to single GetPath for backward compatibility | |||
| 221 | + | return []string{GetPath(name)} | |||
| 222 | + | } | |||
| 223 | + | ||||
| 224 | + | // If only one library, use the original GetPath logic | |||
| 225 | + | if len(libNames) == 1 { | |||
| 226 | + | return []string{GetPath(name)} | |||
| 227 | + | } | |||
| 228 | + | ||||
| 229 | + | var result []string | |||
| 230 | + | for _, libName := range libNames { | |||
| 231 | + | // Try PUREGOTK_LIB_FOLDER first | |||
| 232 | + | ep := os.Getenv("PUREGOTK_LIB_FOLDER") | |||
| 233 | + | if ep != "" { | |||
| 234 | + | suffixes := []string{"", ".0", ".1", ".2"} | |||
| 235 | + | found := false | |||
| 236 | + | for _, s := range suffixes { | |||
| 237 | + | fullPath := filepath.Join(ep, libName+s) | |||
| 238 | + | if _, err := os.Stat(fullPath); err == nil { | |||
| 239 | + | result = append(result, fullPath) | |||
| 240 | + | found = true | |||
| 241 | + | break | |||
| 242 | + | } | |||
| 243 | + | } | |||
| 244 | + | if found { | |||
| 245 | + | continue | |||
| 246 | + | } | |||
| 247 | + | } | |||
| 248 | + | ||||
| 249 | + | // Try hardcoded paths | |||
| 250 | + | gp, pathsOk := paths[runtime.GOARCH] | |||
| 251 | + | if pathsOk { | |||
| 252 | + | found := false | |||
| 253 | + | for _, p := range gp { | |||
| 254 | + | suffixes := []string{"", ".0", ".1", ".2"} | |||
| 255 | + | fn := filepath.Join(p, libName) | |||
| 256 | + | for _, s := range suffixes { | |||
| 257 | + | if _, err := os.Stat(fn + s); err == nil { | |||
| 258 | + | result = append(result, fn+s) | |||
| 259 | + | found = true | |||
| 260 | + | break | |||
| 261 | + | } | |||
| 262 | + | } | |||
| 263 | + | if found { | |||
| 264 | + | break | |||
| 265 | + | } | |||
| 266 | + | } | |||
| 267 | + | if found { | |||
| 268 | + | continue | |||
| 269 | + | } | |||
| 270 | + | } | |||
| 271 | + | ||||
| 272 | + | // If we get here, we couldn't find this library | |||
| 273 | + | panic(fmt.Sprintf("Path for library %s (package %s) not found. Please set PUREGOTK_LIB_FOLDER or ensure the library is in standard paths", libName, name)) | |||
| 274 | + | } | |||
| 275 | + | ||||
| 276 | + | return result | |||
| 277 | + | } | |||
M internal/gir/pass/pass.go +9 -2
| @@ -385,7 +385,14 @@ func (p *Pass) writeGo(r types.Repository, gotemp *template.Template, dir string | |||
| 385 | 385 | pkgConfigName = r.Packages[0].Name | |
| 386 | 386 | } | |
| 387 | 387 | ||
| 388 | - | sharedLibrary := ns.SharedLibrary | |
| 388 | + | var sharedLibraries []string | |
| 389 | + | if ns.SharedLibrary != "" { | |
| 390 | + | for _, lib := range libs := strings.Split(ns.SharedLibrary, ",") { | |
| 391 | + | if trimmed := strings.TrimSpace(lib); trimmed != "" { | |
| 392 | + | sharedLibraries = append(sharedLibraries, trimmed) | |
| 393 | + | } | |
| 394 | + | } | |
| 395 | + | } | |
| 389 | 396 | ||
| 390 | 397 | for _, fn := range files { | |
| 391 | 398 | methods := 0 | |
| @@ -409,7 +416,7 @@ func (p *Pass) writeGo(r types.Repository, gotemp *template.Template, dir string | |||
| 409 | 416 | PkgName: pkgName, | |
| 410 | 417 | PkgEnv: strings.ToUpper(pkgName), | |
| 411 | 418 | PkgConfigName: pkgConfigName, | |
| 412 | - | SharedLibrary: sharedLibrary, | |
| 419 | + | SharedLibraries: sharedLibraries, | |
| 413 | 420 | NeedsInit: needsInit, | |
| 414 | 421 | Aliases: aliases[fn], | |
| 415 | 422 | Callbacks: callbacks[fn], | |
| @@ -385,7 +385,14 @@ func (p *Pass) writeGo(r types.Repository, gotemp *template.Template, dir string | |||||
| 385 | pkgConfigName = r.Packages[0].Name | 385 | pkgConfigName = r.Packages[0].Name | ||
| 386 | } | 386 | } | ||
| 387 | 387 | ||||
| 388 | - | sharedLibrary := ns.SharedLibrary | 388 | + | var sharedLibraries []string |
| 389 | + | if ns.SharedLibrary != "" { | |||
| 390 | + | for _, lib := range libs := strings.Split(ns.SharedLibrary, ",") { | |||
| 391 | + | if trimmed := strings.TrimSpace(lib); trimmed != "" { | |||
| 392 | + | sharedLibraries = append(sharedLibraries, trimmed) | |||
| 393 | + | } | |||
| 394 | + | } | |||
| 395 | + | } | |||
| 389 | 396 | ||||
| 390 | for _, fn := range files { | 397 | for _, fn := range files { | ||
| 391 | methods := 0 | 398 | methods := 0 | ||
| @@ -409,7 +416,7 @@ func (p *Pass) writeGo(r types.Repository, gotemp *template.Template, dir string | |||||
| 409 | PkgName: pkgName, | 416 | PkgName: pkgName, | ||
| 410 | PkgEnv: strings.ToUpper(pkgName), | 417 | PkgEnv: strings.ToUpper(pkgName), | ||
| 411 | PkgConfigName: pkgConfigName, | 418 | PkgConfigName: pkgConfigName, | ||
| 412 | - | SharedLibrary: sharedLibrary, | 419 | + | SharedLibraries: sharedLibraries, |
| 413 | NeedsInit: needsInit, | 420 | NeedsInit: needsInit, | ||
| 414 | Aliases: aliases[fn], | 421 | Aliases: aliases[fn], | ||
| 415 | Callbacks: callbacks[fn], | 422 | Callbacks: callbacks[fn], | ||
M internal/gir/types/template.go +2 -2
| @@ -428,8 +428,8 @@ type TemplateArg struct { | |||
| 428 | 428 | PkgEnv string | |
| 429 | 429 | // PkgConfigName is the pkg-config package name from the GIR file | |
| 430 | 430 | PkgConfigName string | |
| 431 | - | // SharedLibrary is the shared library name from the GIR file | |
| 432 | - | SharedLibrary string | |
| 431 | + | // SharedLibraries is the list of shared library names from the GIR file | |
| 432 | + | SharedLibraries []string | |
| 433 | 433 | // NeedsInit declares whether or not this file needs an init code to register functions with purego | |
| 434 | 434 | NeedsInit bool | |
| 435 | 435 | // Imports defines the package imports that we need | |
| @@ -428,8 +428,8 @@ type TemplateArg struct { | |||||
| 428 | PkgEnv string | 428 | PkgEnv string | ||
| 429 | // PkgConfigName is the pkg-config package name from the GIR file | 429 | // PkgConfigName is the pkg-config package name from the GIR file | ||
| 430 | PkgConfigName string | 430 | PkgConfigName string | ||
| 431 | - | // SharedLibrary is the shared library name from the GIR file | 431 | + | // SharedLibraries is the list of shared library names from the GIR file |
| 432 | - | SharedLibrary string | 432 | + | SharedLibraries []string |
| 433 | // NeedsInit declares whether or not this file needs an init code to register functions with purego | 433 | // NeedsInit declares whether or not this file needs an init code to register functions with purego | ||
| 434 | NeedsInit bool | 434 | NeedsInit bool | ||
| 435 | // Imports defines the package imports that we need | 435 | // Imports defines the package imports that we need | ||
M pkg/core/core.go +2 -1
| @@ -5,7 +5,8 @@ import "github.com/jwijenbergh/puregotk/internal/core" | |||
| 5 | 5 | var ( | |
| 6 | 6 | PuregoSafeRegister = core.PuregoSafeRegister | |
| 7 | 7 | GetPath = core.GetPath | |
| 8 | + | GetPaths = core.GetPaths | |
| 8 | 9 | GoString = core.GoString | |
| 9 | 10 | SetPackageName = core.SetPackageName | |
| 10 | - | SetSharedLibrary = core.SetSharedLibrary | |
| 11 | + | SetSharedLibraries = core.SetSharedLibraries | |
| 11 | 12 | ) | |
| @@ -5,7 +5,8 @@ import "github.com/jwijenbergh/puregotk/internal/core" | |||||
| 5 | var ( | 5 | var ( | ||
| 6 | PuregoSafeRegister = core.PuregoSafeRegister | 6 | PuregoSafeRegister = core.PuregoSafeRegister | ||
| 7 | GetPath = core.GetPath | 7 | GetPath = core.GetPath | ||
| 8 | + | GetPaths = core.GetPaths | |||
| 8 | GoString = core.GoString | 9 | GoString = core.GoString | ||
| 9 | SetPackageName = core.SetPackageName | 10 | SetPackageName = core.SetPackageName | ||
| 10 | - | SetSharedLibrary = core.SetSharedLibrary | 11 | + | SetSharedLibraries = core.SetSharedLibraries |
| 11 | ) | 12 | ) | ||
M templates/go +30 -16
| @@ -335,62 +335,76 @@ func init() { | |||
| 335 | 335 | {{if .PkgConfigName -}} | |
| 336 | 336 | core.SetPackageName("{{.PkgEnv}}", "{{.PkgConfigName}}") | |
| 337 | 337 | {{end -}} | |
| 338 | - | {{if .SharedLibrary -}} | |
| 339 | - | core.SetSharedLibrary("{{.PkgEnv}}", "{{.SharedLibrary}}") | |
| 338 | + | {{if .SharedLibraries -}} | |
| 339 | + | core.SetSharedLibraries("{{.PkgEnv}}", []string{ {{range .SharedLibraries}}"{{.}}", {{end}} }) | |
| 340 | 340 | {{end -}} | |
| 341 | - | lib, err := purego.Dlopen(core.GetPath("{{.PkgEnv}}"), purego.RTLD_NOW|purego.RTLD_GLOBAL) | |
| 342 | - | if err != nil { | |
| 341 | + | ||
| 342 | + | var libs []uintptr | |
| 343 | + | for _, libPath := range core.GetPaths("{{.PkgEnv}}") { | |
| 344 | + | lib, err := purego.Dlopen(libPath, purego.RTLD_NOW|purego.RTLD_GLOBAL) | |
| 345 | + | if err != nil { | |
| 343 | 346 | panic(err) | |
| 347 | + | } | |
| 348 | + | libs = append(libs, lib) | |
| 349 | + | } | |
| 350 | + | ||
| 351 | + | tryRegister := func(fptr interface{}, name string) { | |
| 352 | + | for _, lib := range libs { | |
| 353 | + | if err := core.PuregoSafeRegister(fptr, lib, name); err == nil { | |
| 354 | + | return | |
| 355 | + | } | |
| 356 | + | } | |
| 344 | 357 | } | |
| 358 | + | ||
| 345 | 359 | {{range .Aliases -}} | |
| 346 | 360 | {{if .TypeGetter -}} | |
| 347 | - | core.PuregoSafeRegister(&x{{.Name}}GLibType, lib, "{{.TypeGetter}}") | |
| 361 | + | tryRegister(&x{{.Name}}GLibType, "{{.TypeGetter}}") | |
| 348 | 362 | {{end}} | |
| 349 | 363 | {{end}} | |
| 350 | 364 | {{range .Enums -}} | |
| 351 | 365 | {{if .TypeGetter -}} | |
| 352 | - | core.PuregoSafeRegister(&x{{.Name}}GLibType, lib, "{{.TypeGetter}}") | |
| 366 | + | tryRegister(&x{{.Name}}GLibType, "{{.TypeGetter}}") | |
| 353 | 367 | {{end}} | |
| 354 | 368 | {{end}} | |
| 355 | 369 | {{range .Functions -}} | |
| 356 | - | core.PuregoSafeRegister(&x{{.Name}}, lib, "{{.CName}}") | |
| 370 | + | tryRegister(&x{{.Name}}, "{{.CName}}") | |
| 357 | 371 | {{end}} | |
| 358 | 372 | ||
| 359 | 373 | {{range .Records -}} | |
| 360 | 374 | {{$rec := .}} | |
| 361 | 375 | {{if .TypeGetter -}} | |
| 362 | - | core.PuregoSafeRegister(&x{{.Name}}GLibType, lib, "{{.TypeGetter}}") | |
| 376 | + | tryRegister(&x{{.Name}}GLibType, "{{.TypeGetter}}") | |
| 363 | 377 | {{end}} | |
| 364 | 378 | {{range .Constructors -}} | |
| 365 | - | core.PuregoSafeRegister(&x{{.Name}}, lib, "{{.CName}}") | |
| 379 | + | tryRegister(&x{{.Name}}, "{{.CName}}") | |
| 366 | 380 | {{end}} | |
| 367 | 381 | {{range .Receivers -}} | |
| 368 | - | core.PuregoSafeRegister(&x{{$rec.Name}}{{.Name}}, lib, "{{.CName}}") | |
| 382 | + | tryRegister(&x{{$rec.Name}}{{.Name}}, "{{.CName}}") | |
| 369 | 383 | {{end}} | |
| 370 | 384 | {{end}} | |
| 371 | 385 | ||
| 372 | 386 | {{range .Classes -}} | |
| 373 | 387 | {{$cls := .}} | |
| 374 | 388 | {{if .TypeGetter -}} | |
| 375 | - | core.PuregoSafeRegister(&x{{.Name}}GLibType, lib, "{{.TypeGetter}}") | |
| 389 | + | tryRegister(&x{{.Name}}GLibType, "{{.TypeGetter}}") | |
| 376 | 390 | {{end}} | |
| 377 | 391 | {{range .Constructors -}} | |
| 378 | - | core.PuregoSafeRegister(&x{{.Name}}, lib, "{{.CName}}") | |
| 392 | + | tryRegister(&x{{.Name}}, "{{.CName}}") | |
| 379 | 393 | {{end}} | |
| 380 | 394 | {{range .Receivers -}} | |
| 381 | - | core.PuregoSafeRegister(&x{{$cls.Name}}{{.Name}}, lib, "{{.CName}}") | |
| 395 | + | tryRegister(&x{{$cls.Name}}{{.Name}}, "{{.CName}}") | |
| 382 | 396 | {{end}} | |
| 383 | 397 | {{range .Functions -}} | |
| 384 | - | core.PuregoSafeRegister(&x{{.Name}}, lib, "{{.CName}}") | |
| 398 | + | tryRegister(&x{{.Name}}, "{{.CName}}") | |
| 385 | 399 | {{end}} | |
| 386 | 400 | {{end}} | |
| 387 | 401 | ||
| 388 | 402 | {{range .Interfaces -}} | |
| 389 | 403 | {{if .TypeGetter -}} | |
| 390 | - | core.PuregoSafeRegister(&x{{.Name}}GLibType, lib, "{{.TypeGetter}}") | |
| 404 | + | tryRegister(&x{{.Name}}GLibType, "{{.TypeGetter}}") | |
| 391 | 405 | {{end}} | |
| 392 | 406 | {{range .Methods -}} | |
| 393 | - | core.PuregoSafeRegister(&{{.Namespace}}X{{.FullName}}, lib, "{{.CName}}") | |
| 407 | + | tryRegister(&{{.Namespace}}X{{.FullName}}, "{{.CName}}") | |
| 394 | 408 | {{end}} | |
| 395 | 409 | {{end}} | |
| 396 | 410 | } | |
| @@ -335,62 +335,76 @@ func init() { | |||||
| 335 | {{if .PkgConfigName -}} | 335 | {{if .PkgConfigName -}} | ||
| 336 | core.SetPackageName("{{.PkgEnv}}", "{{.PkgConfigName}}") | 336 | core.SetPackageName("{{.PkgEnv}}", "{{.PkgConfigName}}") | ||
| 337 | {{end -}} | 337 | {{end -}} | ||
| 338 | - | {{if .SharedLibrary -}} | 338 | + | {{if .SharedLibraries -}} |
| 339 | - | core.SetSharedLibrary("{{.PkgEnv}}", "{{.SharedLibrary}}") | 339 | + | core.SetSharedLibraries("{{.PkgEnv}}", []string{ {{range .SharedLibraries}}"{{.}}", {{end}} }) |
| 340 | {{end -}} | 340 | {{end -}} | ||
| 341 | - | lib, err := purego.Dlopen(core.GetPath("{{.PkgEnv}}"), purego.RTLD_NOW|purego.RTLD_GLOBAL) | 341 | + | |
| 342 | - | if err != nil { | 342 | + | var libs []uintptr |
| 343 | + | for _, libPath := range core.GetPaths("{{.PkgEnv}}") { | |||
| 344 | + | lib, err := purego.Dlopen(libPath, purego.RTLD_NOW|purego.RTLD_GLOBAL) | |||
| 345 | + | if err != nil { | |||
| 343 | panic(err) | 346 | panic(err) | ||
| 347 | + | } | |||
| 348 | + | libs = append(libs, lib) | |||
| 349 | + | } | |||
| 350 | + | ||||
| 351 | + | tryRegister := func(fptr interface{}, name string) { | |||
| 352 | + | for _, lib := range libs { | |||
| 353 | + | if err := core.PuregoSafeRegister(fptr, lib, name); err == nil { | |||
| 354 | + | return | |||
| 355 | + | } | |||
| 356 | + | } | |||
| 344 | } | 357 | } | ||
| 358 | + | ||||
| 345 | {{range .Aliases -}} | 359 | {{range .Aliases -}} | ||
| 346 | {{if .TypeGetter -}} | 360 | {{if .TypeGetter -}} | ||
| 347 | - | core.PuregoSafeRegister(&x{{.Name}}GLibType, lib, "{{.TypeGetter}}") | 361 | + | tryRegister(&x{{.Name}}GLibType, "{{.TypeGetter}}") |
| 348 | {{end}} | 362 | {{end}} | ||
| 349 | {{end}} | 363 | {{end}} | ||
| 350 | {{range .Enums -}} | 364 | {{range .Enums -}} | ||
| 351 | {{if .TypeGetter -}} | 365 | {{if .TypeGetter -}} | ||
| 352 | - | core.PuregoSafeRegister(&x{{.Name}}GLibType, lib, "{{.TypeGetter}}") | 366 | + | tryRegister(&x{{.Name}}GLibType, "{{.TypeGetter}}") |
| 353 | {{end}} | 367 | {{end}} | ||
| 354 | {{end}} | 368 | {{end}} | ||
| 355 | {{range .Functions -}} | 369 | {{range .Functions -}} | ||
| 356 | - | core.PuregoSafeRegister(&x{{.Name}}, lib, "{{.CName}}") | 370 | + | tryRegister(&x{{.Name}}, "{{.CName}}") |
| 357 | {{end}} | 371 | {{end}} | ||
| 358 | 372 | ||||
| 359 | {{range .Records -}} | 373 | {{range .Records -}} | ||
| 360 | {{$rec := .}} | 374 | {{$rec := .}} | ||
| 361 | {{if .TypeGetter -}} | 375 | {{if .TypeGetter -}} | ||
| 362 | - | core.PuregoSafeRegister(&x{{.Name}}GLibType, lib, "{{.TypeGetter}}") | 376 | + | tryRegister(&x{{.Name}}GLibType, "{{.TypeGetter}}") |
| 363 | {{end}} | 377 | {{end}} | ||
| 364 | {{range .Constructors -}} | 378 | {{range .Constructors -}} | ||
| 365 | - | core.PuregoSafeRegister(&x{{.Name}}, lib, "{{.CName}}") | 379 | + | tryRegister(&x{{.Name}}, "{{.CName}}") |
| 366 | {{end}} | 380 | {{end}} | ||
| 367 | {{range .Receivers -}} | 381 | {{range .Receivers -}} | ||
| 368 | - | core.PuregoSafeRegister(&x{{$rec.Name}}{{.Name}}, lib, "{{.CName}}") | 382 | + | tryRegister(&x{{$rec.Name}}{{.Name}}, "{{.CName}}") |
| 369 | {{end}} | 383 | {{end}} | ||
| 370 | {{end}} | 384 | {{end}} | ||
| 371 | 385 | ||||
| 372 | {{range .Classes -}} | 386 | {{range .Classes -}} | ||
| 373 | {{$cls := .}} | 387 | {{$cls := .}} | ||
| 374 | {{if .TypeGetter -}} | 388 | {{if .TypeGetter -}} | ||
| 375 | - | core.PuregoSafeRegister(&x{{.Name}}GLibType, lib, "{{.TypeGetter}}") | 389 | + | tryRegister(&x{{.Name}}GLibType, "{{.TypeGetter}}") |
| 376 | {{end}} | 390 | {{end}} | ||
| 377 | {{range .Constructors -}} | 391 | {{range .Constructors -}} | ||
| 378 | - | core.PuregoSafeRegister(&x{{.Name}}, lib, "{{.CName}}") | 392 | + | tryRegister(&x{{.Name}}, "{{.CName}}") |
| 379 | {{end}} | 393 | {{end}} | ||
| 380 | {{range .Receivers -}} | 394 | {{range .Receivers -}} | ||
| 381 | - | core.PuregoSafeRegister(&x{{$cls.Name}}{{.Name}}, lib, "{{.CName}}") | 395 | + | tryRegister(&x{{$cls.Name}}{{.Name}}, "{{.CName}}") |
| 382 | {{end}} | 396 | {{end}} | ||
| 383 | {{range .Functions -}} | 397 | {{range .Functions -}} | ||
| 384 | - | core.PuregoSafeRegister(&x{{.Name}}, lib, "{{.CName}}") | 398 | + | tryRegister(&x{{.Name}}, "{{.CName}}") |
| 385 | {{end}} | 399 | {{end}} | ||
| 386 | {{end}} | 400 | {{end}} | ||
| 387 | 401 | ||||
| 388 | {{range .Interfaces -}} | 402 | {{range .Interfaces -}} | ||
| 389 | {{if .TypeGetter -}} | 403 | {{if .TypeGetter -}} | ||
| 390 | - | core.PuregoSafeRegister(&x{{.Name}}GLibType, lib, "{{.TypeGetter}}") | 404 | + | tryRegister(&x{{.Name}}GLibType, "{{.TypeGetter}}") |
| 391 | {{end}} | 405 | {{end}} | ||
| 392 | {{range .Methods -}} | 406 | {{range .Methods -}} | ||
| 393 | - | core.PuregoSafeRegister(&{{.Namespace}}X{{.FullName}}, lib, "{{.CName}}") | 407 | + | tryRegister(&{{.Namespace}}X{{.FullName}}, "{{.CName}}") |
| 394 | {{end}} | 408 | {{end}} | ||
| 395 | {{end}} | 409 | {{end}} | ||
| 396 | } | 410 | } | ||