GIR: Read pkg-config and shared library names from GIR file, then extend list of known libraries at `init` time
Signed-off-by: Felicitas Pojtinger <felicitas@pojtinger.com>
- commit
- cdca4b5948efe8997d56b21d5c4f24b12675f9fb
- author
- Felicitas Pojtinger · · 2025-08-26 21:10 UTC
- committer
- Jeroen Wijenbergh · · 2025-10-13 08:22 UTC
- parent
- ddbf717
- signature
- unsigned
5 files · +55 -16
M internal/core/core.go +20 -1
| @@ -38,6 +38,7 @@ var paths = map[string][]string{ | |||
| 38 | 38 | } | |
| 39 | 39 | ||
| 40 | 40 | // names is a lookup from library names to shared object filenames | |
| 41 | + | // This is populated dynamically via SetSharedLibrary and has defaults for common libraries | |
| 41 | 42 | var names = map[string][]string{ | |
| 42 | 43 | "ADW": {"libadwaita-1.so"}, | |
| 43 | 44 | "CAIRO": {"libcairo.so"}, | |
| @@ -60,7 +61,7 @@ var aliases = map[string]string{ | |||
| 60 | 61 | } | |
| 61 | 62 | ||
| 62 | 63 | // pkgConfNames is a lookup from library names to pkg-config library names | |
| 63 | - | // TODO: Get this from the package name in the gir files with a fallback to gtk's package name | |
| 64 | + | // This is populated dynamically via SetPackageName and has defaults for common libraries | |
| 64 | 65 | var pkgConfNames = map[string]string{ | |
| 65 | 66 | "ADW": "libadwaita-1", | |
| 66 | 67 | "CAIRO": "cairo", | |
| @@ -75,6 +76,24 @@ var pkgConfNames = map[string]string{ | |||
| 75 | 76 | "PANGOCAIRO": "pangocairo", | |
| 76 | 77 | } | |
| 77 | 78 | ||
| 79 | + | // SetPackageName registers a pkg-config package name for a library. | |
| 80 | + | // This is used by the code generator to set package names from GIR files. | |
| 81 | + | // It won't override existing entries to preserve defaults. | |
| 82 | + | func SetPackageName(libName, pkgName string) { | |
| 83 | + | if _, exists := pkgConfNames[libName]; !exists && pkgName != "" { | |
| 84 | + | pkgConfNames[libName] = pkgName | |
| 85 | + | } | |
| 86 | + | } | |
| 87 | + | ||
| 88 | + | // SetSharedLibrary registers a shared library name for a library. | |
| 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. | |
| 91 | + | func SetSharedLibrary(libName, sharedLib string) { | |
| 92 | + | if _, exists := names[libName]; !exists && sharedLib != "" { | |
| 93 | + | names[libName] = []string{sharedLib} | |
| 94 | + | } | |
| 95 | + | } | |
| 96 | + | ||
| 78 | 97 | // findSo tries to find a shared object from a path and a library name | |
| 79 | 98 | // It does this by mapping the library name to a suitable shared object filename and then trying some suffixes | |
| 80 | 99 | func findSo(path string, name string) string { | |
| @@ -38,6 +38,7 @@ var paths = map[string][]string{ | |||||
| 38 | } | 38 | } | ||
| 39 | 39 | ||||
| 40 | // names is a lookup from library names to shared object filenames | 40 | // names is a lookup from library names to shared object filenames | ||
| 41 | + | // This is populated dynamically via SetSharedLibrary and has defaults for common libraries | |||
| 41 | var names = map[string][]string{ | 42 | var names = map[string][]string{ | ||
| 42 | "ADW": {"libadwaita-1.so"}, | 43 | "ADW": {"libadwaita-1.so"}, | ||
| 43 | "CAIRO": {"libcairo.so"}, | 44 | "CAIRO": {"libcairo.so"}, | ||
| @@ -60,7 +61,7 @@ var aliases = map[string]string{ | |||||
| 60 | } | 61 | } | ||
| 61 | 62 | ||||
| 62 | // pkgConfNames is a lookup from library names to pkg-config library names | 63 | // pkgConfNames is a lookup from library names to pkg-config library names | ||
| 63 | - | // TODO: Get this from the package name in the gir files with a fallback to gtk's package name | 64 | + | // This is populated dynamically via SetPackageName and has defaults for common libraries |
| 64 | var pkgConfNames = map[string]string{ | 65 | var pkgConfNames = map[string]string{ | ||
| 65 | "ADW": "libadwaita-1", | 66 | "ADW": "libadwaita-1", | ||
| 66 | "CAIRO": "cairo", | 67 | "CAIRO": "cairo", | ||
| @@ -75,6 +76,24 @@ var pkgConfNames = map[string]string{ | |||||
| 75 | "PANGOCAIRO": "pangocairo", | 76 | "PANGOCAIRO": "pangocairo", | ||
| 76 | } | 77 | } | ||
| 77 | 78 | ||||
| 79 | + | // SetPackageName registers a pkg-config package name for a library. | |||
| 80 | + | // This is used by the code generator to set package names from GIR files. | |||
| 81 | + | // It won't override existing entries to preserve defaults. | |||
| 82 | + | func SetPackageName(libName, pkgName string) { | |||
| 83 | + | if _, exists := pkgConfNames[libName]; !exists && pkgName != "" { | |||
| 84 | + | pkgConfNames[libName] = pkgName | |||
| 85 | + | } | |||
| 86 | + | } | |||
| 87 | + | ||||
| 88 | + | // SetSharedLibrary registers a shared library name for a library. | |||
| 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. | |||
| 91 | + | func SetSharedLibrary(libName, sharedLib string) { | |||
| 92 | + | if _, exists := names[libName]; !exists && sharedLib != "" { | |||
| 93 | + | names[libName] = []string{sharedLib} | |||
| 94 | + | } | |||
| 95 | + | } | |||
| 96 | + | ||||
| 78 | // findSo tries to find a shared object from a path and a library name | 97 | // findSo tries to find a shared object from a path and a library name | ||
| 79 | // It does this by mapping the library name to a suitable shared object filename and then trying some suffixes | 98 | // It does this by mapping the library name to a suitable shared object filename and then trying some suffixes | ||
| 80 | func findSo(path string, name string) string { | 99 | func findSo(path string, name string) string { | ||
M internal/gir/pass/pass.go +21 -11
| @@ -319,6 +319,14 @@ func (p *Pass) writeGo(r types.Repository, gotemp *template.Template, dir string | |||
| 319 | 319 | } | |
| 320 | 320 | ||
| 321 | 321 | pkgName := strings.ToLower(ns.Name) | |
| 322 | + | ||
| 323 | + | var pkgConfigName string | |
| 324 | + | if len(r.Packages) > 0 { | |
| 325 | + | pkgConfigName = r.Packages[0].Name | |
| 326 | + | } | |
| 327 | + | ||
| 328 | + | sharedLibrary := ns.SharedLibrary | |
| 329 | + | ||
| 322 | 330 | for _, fn := range files { | |
| 323 | 331 | methods := 0 | |
| 324 | 332 | for _, i := range interfaces[fn] { | |
| @@ -338,17 +346,19 @@ func (p *Pass) writeGo(r types.Repository, gotemp *template.Template, dir string | |||
| 338 | 346 | needsInit := (len(functions[fn]) + methods) > 0 | |
| 339 | 347 | ||
| 340 | 348 | args := types.TemplateArg{ | |
| 341 | - | PkgName: pkgName, | |
| 342 | - | PkgEnv: strings.ToUpper(pkgName), | |
| 343 | - | NeedsInit: needsInit, | |
| 344 | - | Aliases: aliases[fn], | |
| 345 | - | Callbacks: callbacks[fn], | |
| 346 | - | Records: records[fn], | |
| 347 | - | Enums: enums[fn], | |
| 348 | - | Constants: constants[fn], | |
| 349 | - | Functions: functions[fn], | |
| 350 | - | Interfaces: interfaces[fn], | |
| 351 | - | Classes: classes[fn], | |
| 349 | + | PkgName: pkgName, | |
| 350 | + | PkgEnv: strings.ToUpper(pkgName), | |
| 351 | + | PkgConfigName: pkgConfigName, | |
| 352 | + | SharedLibrary: sharedLibrary, | |
| 353 | + | NeedsInit: needsInit, | |
| 354 | + | Aliases: aliases[fn], | |
| 355 | + | Callbacks: callbacks[fn], | |
| 356 | + | Records: records[fn], | |
| 357 | + | Enums: enums[fn], | |
| 358 | + | Constants: constants[fn], | |
| 359 | + | Functions: functions[fn], | |
| 360 | + | Interfaces: interfaces[fn], | |
| 361 | + | Classes: classes[fn], | |
| 352 | 362 | } | |
| 353 | 363 | ||
| 354 | 364 | os.MkdirAll(fmt.Sprintf(dir+"/%s", pkgName), 0o755) | |
| @@ -319,6 +319,14 @@ func (p *Pass) writeGo(r types.Repository, gotemp *template.Template, dir string | |||||
| 319 | } | 319 | } | ||
| 320 | 320 | ||||
| 321 | pkgName := strings.ToLower(ns.Name) | 321 | pkgName := strings.ToLower(ns.Name) | ||
| 322 | + | ||||
| 323 | + | var pkgConfigName string | |||
| 324 | + | if len(r.Packages) > 0 { | |||
| 325 | + | pkgConfigName = r.Packages[0].Name | |||
| 326 | + | } | |||
| 327 | + | ||||
| 328 | + | sharedLibrary := ns.SharedLibrary | |||
| 329 | + | ||||
| 322 | for _, fn := range files { | 330 | for _, fn := range files { | ||
| 323 | methods := 0 | 331 | methods := 0 | ||
| 324 | for _, i := range interfaces[fn] { | 332 | for _, i := range interfaces[fn] { | ||
| @@ -338,17 +346,19 @@ func (p *Pass) writeGo(r types.Repository, gotemp *template.Template, dir string | |||||
| 338 | needsInit := (len(functions[fn]) + methods) > 0 | 346 | needsInit := (len(functions[fn]) + methods) > 0 | ||
| 339 | 347 | ||||
| 340 | args := types.TemplateArg{ | 348 | args := types.TemplateArg{ | ||
| 341 | - | PkgName: pkgName, | 349 | + | PkgName: pkgName, |
| 342 | - | PkgEnv: strings.ToUpper(pkgName), | 350 | + | PkgEnv: strings.ToUpper(pkgName), |
| 343 | - | NeedsInit: needsInit, | 351 | + | PkgConfigName: pkgConfigName, |
| 344 | - | Aliases: aliases[fn], | 352 | + | SharedLibrary: sharedLibrary, |
| 345 | - | Callbacks: callbacks[fn], | 353 | + | NeedsInit: needsInit, |
| 346 | - | Records: records[fn], | 354 | + | Aliases: aliases[fn], |
| 347 | - | Enums: enums[fn], | 355 | + | Callbacks: callbacks[fn], |
| 348 | - | Constants: constants[fn], | 356 | + | Records: records[fn], |
| 349 | - | Functions: functions[fn], | 357 | + | Enums: enums[fn], |
| 350 | - | Interfaces: interfaces[fn], | 358 | + | Constants: constants[fn], |
| 351 | - | Classes: classes[fn], | 359 | + | Functions: functions[fn], |
| 360 | + | Interfaces: interfaces[fn], | |||
| 361 | + | Classes: classes[fn], | |||
| 352 | } | 362 | } | ||
| 353 | 363 | ||||
| 354 | os.MkdirAll(fmt.Sprintf(dir+"/%s", pkgName), 0o755) | 364 | os.MkdirAll(fmt.Sprintf(dir+"/%s", pkgName), 0o755) | ||
M internal/gir/types/template.go +4 -0
| @@ -398,6 +398,10 @@ type TemplateArg struct { | |||
| 398 | 398 | PkgName string | |
| 399 | 399 | // PkgEnv is the name of the package in the load environment variable | |
| 400 | 400 | PkgEnv string | |
| 401 | + | // PkgConfigName is the pkg-config package name from the GIR file | |
| 402 | + | PkgConfigName string | |
| 403 | + | // SharedLibrary is the shared library name from the GIR file | |
| 404 | + | SharedLibrary string | |
| 401 | 405 | // NeedsInit declares whether or not this file needs an init code to register functions with purego | |
| 402 | 406 | NeedsInit bool | |
| 403 | 407 | // Imports defines the package imports that we need | |
| @@ -398,6 +398,10 @@ type TemplateArg struct { | |||||
| 398 | PkgName string | 398 | PkgName string | ||
| 399 | // PkgEnv is the name of the package in the load environment variable | 399 | // PkgEnv is the name of the package in the load environment variable | ||
| 400 | PkgEnv string | 400 | PkgEnv string | ||
| 401 | + | // PkgConfigName is the pkg-config package name from the GIR file | |||
| 402 | + | PkgConfigName string | |||
| 403 | + | // SharedLibrary is the shared library name from the GIR file | |||
| 404 | + | SharedLibrary string | |||
| 401 | // NeedsInit declares whether or not this file needs an init code to register functions with purego | 405 | // NeedsInit declares whether or not this file needs an init code to register functions with purego | ||
| 402 | NeedsInit bool | 406 | NeedsInit bool | ||
| 403 | // Imports defines the package imports that we need | 407 | // Imports defines the package imports that we need | ||
M pkg/core/core.go +5 -3
| @@ -4,6 +4,8 @@ import "github.com/jwijenbergh/puregotk/internal/core" | |||
| 4 | 4 | ||
| 5 | 5 | var ( | |
| 6 | 6 | PuregoSafeRegister = core.PuregoSafeRegister | |
| 7 | - | GetPath = core.GetPath | |
| 8 | - | GoString = core.GoString | |
| 9 | - | )⏎̸ | |
| 7 | + | GetPath = core.GetPath | |
| 8 | + | GoString = core.GoString | |
| 9 | + | SetPackageName = core.SetPackageName | |
| 10 | + | SetSharedLibrary = core.SetSharedLibrary | |
| 11 | + | ) | |
| @@ -4,6 +4,8 @@ import "github.com/jwijenbergh/puregotk/internal/core" | |||||
| 4 | 4 | ||||
| 5 | var ( | 5 | var ( | ||
| 6 | PuregoSafeRegister = core.PuregoSafeRegister | 6 | PuregoSafeRegister = core.PuregoSafeRegister | ||
| 7 | - | GetPath = core.GetPath | 7 | + | GetPath = core.GetPath |
| 8 | - | GoString = core.GoString | 8 | + | GoString = core.GoString |
| 9 | - | )⏎̸ | 9 | + | SetPackageName = core.SetPackageName |
| 10 | + | SetSharedLibrary = core.SetSharedLibrary | |||
| 11 | + | ) | |||
M templates/go +5 -1
| @@ -279,7 +279,11 @@ func {{.Name}}({{conv .Args.API.Full}}) {{.Ret.Return}} { | |||
| 279 | 279 | {{if .NeedsInit}} | |
| 280 | 280 | ||
| 281 | 281 | func init() { | |
| 282 | - | lib, err := purego.Dlopen(core.GetPath("{{.PkgEnv}}"), purego.RTLD_NOW|purego.RTLD_GLOBAL) | |
| 282 | + | {{if .PkgConfigName}} | |
| 283 | + | core.SetPackageName("{{.PkgEnv}}", "{{.PkgConfigName}}") | |
| 284 | + | {{end}}{{if .SharedLibrary}} | |
| 285 | + | core.SetSharedLibrary("{{.PkgEnv}}", "{{.SharedLibrary}}") | |
| 286 | + | {{end}}lib, err := purego.Dlopen(core.GetPath("{{.PkgEnv}}"), purego.RTLD_NOW|purego.RTLD_GLOBAL) | |
| 283 | 287 | if err != nil { | |
| 284 | 288 | panic(err) | |
| 285 | 289 | } | |
| @@ -279,7 +279,11 @@ func {{.Name}}({{conv .Args.API.Full}}) {{.Ret.Return}} { | |||||
| 279 | {{if .NeedsInit}} | 279 | {{if .NeedsInit}} | ||
| 280 | 280 | ||||
| 281 | func init() { | 281 | func init() { | ||
| 282 | - | lib, err := purego.Dlopen(core.GetPath("{{.PkgEnv}}"), purego.RTLD_NOW|purego.RTLD_GLOBAL) | 282 | + | {{if .PkgConfigName}} |
| 283 | + | core.SetPackageName("{{.PkgEnv}}", "{{.PkgConfigName}}") | |||
| 284 | + | {{end}}{{if .SharedLibrary}} | |||
| 285 | + | core.SetSharedLibrary("{{.PkgEnv}}", "{{.SharedLibrary}}") | |||
| 286 | + | {{end}}lib, err := purego.Dlopen(core.GetPath("{{.PkgEnv}}"), purego.RTLD_NOW|purego.RTLD_GLOBAL) | |||
| 283 | if err != nil { | 287 | if err != nil { | ||
| 284 | panic(err) | 288 | panic(err) | ||
| 285 | } | 289 | } | ||