detached e282e1c

GIR: Rework lookup logic to instead rely on name resolution in `findSo` etc.

Signed-off-by: Felicitas Pojtinger <felicitas@pojtinger.com>
commit
e282e1ceb2e136ac61e2370c2c5b6175505ecd43
author
Felicitas Pojtinger · · 2025-10-18 03:48 UTC
committer
Jeroen Wijenbergh · · 2025-10-22 07:42 UTC
parent
e97e9fe
signature
unsigned
1 file · +21 -85
M internal/core/core.go +21 -85
@@ -65,25 +65,26 @@ func SetSharedLibraries(libName string, sharedLibs []string) {
6565 }
6666 }
6767
68-// findSo tries to find a shared object from a path and a library name
69-// It does this by mapping the library name to a suitable shared object filename and then trying some suffixes
70-func findSo(path string, name string) string {
68+// findSos tries to find all shared objects from a path and a library name
69+// It does this by mapping the library name to all suitable shared object filenames and then trying some suffixes
70+func findSos(path string, name string) []string {
71+ sos := []string{}
7172 for _, n := range names[name] {
7273 suffixes := []string{"", ".0", ".1", ".2"}
7374 fn := filepath.Join(path, n)
7475 for _, s := range suffixes {
7576 if _, err := os.Stat(fn + s); err == nil {
76- return fn + s
77+ sos = append(sos, fn+s)
7778 }
7879 }
7980 }
80- return ""
81+ return sos
8182 }
8283
83-// findPkgConf finds a shared object file with pkg-config
84+// findPkgConf finds all shared object files with pkg-config
8485 // it does this by running pkg-config --libs-only-L libname
85-// and then it loops over the directories returned and finds a suitable one
86-func findPkgConf(name string) string {
86+// and then it loops over the directories returned and finds all suitable ones
87+func findPkgConf(name string) []string {
8788 cmd := exec.Command("pkg-config", "--libs-only-L", pkgConfNames[name])
8889 var out, outerr bytes.Buffer
8990 cmd.Stdout = &out
@@ -91,7 +92,7 @@ func findPkgConf(name string) string {
9192 err := cmd.Run()
9293 if err != nil {
9394 fmt.Fprintf(os.Stderr, "pkg-config, failed with: %v and stderr: %s\n", err, outerr.String())
94- return ""
95+ return []string{}
9596 }
9697 outs := strings.Split(out.String(), "-L")
9798 for _, v := range outs {
@@ -99,15 +100,15 @@ func findPkgConf(name string) string {
99100 if c == "" {
100101 continue
101102 }
102- g := findSo(c, name)
103- if g != "" {
103+ g := findSos(c, name)
104+ if len(g) > 0 {
104105 return g
105106 }
106107 }
107- return ""
108+ return []string{}
108109 }
109110
110-// getPath gets a shared object file from a library name
111+// GetPaths gets all shared object files from a library name
111112 // it does it in the following order
112113 // see if PUREGOTK_LIBNAME_PATH is set (full path to the lib)
113114 // - e.g. PUREGOTK_GTK_PATH
@@ -117,18 +118,18 @@ func findPkgConf(name string) string {
117118 // panic if failed
118119 // TODO: Hardcore a library shared object with linker -X flag
119120 // This is useful for packaging
120-func getPath(name string) string {
121+func GetPaths(name string) []string {
121122 // try to get from env var
122123 ev := fmt.Sprintf("PUREGOTK_%s_PATH", name)
123124 if v := os.Getenv(ev); v != "" {
124- return v
125+ return []string{v}
125126 }
126127
127128 // Or if a general folder is set where everywhere is located, return that
128129 ep := os.Getenv("PUREGOTK_LIB_FOLDER")
129130 if ep != "" {
130- g := findSo(ep, name)
131- if g == "" {
131+ g := findSos(ep, name)
132+ if len(g) == 0 {
132133 panic(fmt.Sprintf("Could not find lib: %s, at path: %s with env: %s", name, ep, "PUREGOTK_FOLDER"))
133134 }
134135 return g
@@ -139,8 +140,8 @@ func getPath(name string) string {
139140 if ok {
140141 // try to loop over paths
141142 for _, p := range gp {
142- g := findSo(p, name)
143- if g != "" {
143+ g := findSos(p, name)
144+ if len(g) > 0 {
144145 return g
145146 }
146147
@@ -148,7 +149,7 @@ func getPath(name string) string {
148149 }
149150 // last effort: pkg-config
150151 g := findPkgConf(name)
151- if g != "" {
152+ if len(g) > 0 {
152153 return g
153154 }
154155
@@ -172,68 +173,3 @@ func GoString(c uintptr) string {
172173 }
173174 return string(unsafe.Slice((*byte)(ptr), length))
174175 }
175-
176-// GetPaths gets all shared object file paths for a library name that may have multiple libraries.
177-// This is used when a package needs to load multiple shared libraries (e.g., GLIB needs both libgobject and libglib).
178-// Returns a slice of full paths to all libraries for this package.
179-func GetPaths(name string) []string {
180- libNames, ok := names[name]
181- if !ok || len(libNames) == 0 {
182- // Fallback to single GetPath for backward compatibility
183- return []string{getPath(name)}
184- }
185-
186- // If only one library, use the original GetPath logic
187- if len(libNames) == 1 {
188- return []string{getPath(name)}
189- }
190-
191- var result []string
192- for _, libName := range libNames {
193- // Try PUREGOTK_LIB_FOLDER first
194- ep := os.Getenv("PUREGOTK_LIB_FOLDER")
195- if ep != "" {
196- suffixes := []string{"", ".0", ".1", ".2"}
197- found := false
198- for _, s := range suffixes {
199- fullPath := filepath.Join(ep, libName+s)
200- if _, err := os.Stat(fullPath); err == nil {
201- result = append(result, fullPath)
202- found = true
203- break
204- }
205- }
206- if found {
207- continue
208- }
209- }
210-
211- // Try hardcoded paths
212- gp, pathsOk := paths[runtime.GOARCH]
213- if pathsOk {
214- found := false
215- for _, p := range gp {
216- suffixes := []string{"", ".0", ".1", ".2"}
217- fn := filepath.Join(p, libName)
218- for _, s := range suffixes {
219- if _, err := os.Stat(fn + s); err == nil {
220- result = append(result, fn+s)
221- found = true
222- break
223- }
224- }
225- if found {
226- break
227- }
228- }
229- if found {
230- continue
231- }
232- }
233-
234- // If we get here, we couldn't find this library
235- 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))
236- }
237-
238- return result
239-}
@@ -65,25 +65,26 @@ func SetSharedLibraries(libName string, sharedLibs []string) {
65 }65 }
66 }66 }
67 67
68-// findSo tries to find a shared object from a path and a library name68+// findSos tries to find all shared objects from a path and a library name
69-// It does this by mapping the library name to a suitable shared object filename and then trying some suffixes69+// It does this by mapping the library name to all suitable shared object filenames and then trying some suffixes
70-func findSo(path string, name string) string {70+func findSos(path string, name string) []string {
71+ sos := []string{}
71 for _, n := range names[name] {72 for _, n := range names[name] {
72 suffixes := []string{"", ".0", ".1", ".2"}73 suffixes := []string{"", ".0", ".1", ".2"}
73 fn := filepath.Join(path, n)74 fn := filepath.Join(path, n)
74 for _, s := range suffixes {75 for _, s := range suffixes {
75 if _, err := os.Stat(fn + s); err == nil {76 if _, err := os.Stat(fn + s); err == nil {
76- return fn + s77+ sos = append(sos, fn+s)
77 }78 }
78 }79 }
79 }80 }
80- return ""81+ return sos
81 }82 }
82 83
83-// findPkgConf finds a shared object file with pkg-config84+// findPkgConf finds all shared object files with pkg-config
84 // it does this by running pkg-config --libs-only-L libname85 // it does this by running pkg-config --libs-only-L libname
85-// and then it loops over the directories returned and finds a suitable one86+// and then it loops over the directories returned and finds all suitable ones
86-func findPkgConf(name string) string {87+func findPkgConf(name string) []string {
87 cmd := exec.Command("pkg-config", "--libs-only-L", pkgConfNames[name])88 cmd := exec.Command("pkg-config", "--libs-only-L", pkgConfNames[name])
88 var out, outerr bytes.Buffer89 var out, outerr bytes.Buffer
89 cmd.Stdout = &out90 cmd.Stdout = &out
@@ -91,7 +92,7 @@ func findPkgConf(name string) string {
91 err := cmd.Run()92 err := cmd.Run()
92 if err != nil {93 if err != nil {
93 fmt.Fprintf(os.Stderr, "pkg-config, failed with: %v and stderr: %s\n", err, outerr.String())94 fmt.Fprintf(os.Stderr, "pkg-config, failed with: %v and stderr: %s\n", err, outerr.String())
94- return ""95+ return []string{}
95 }96 }
96 outs := strings.Split(out.String(), "-L")97 outs := strings.Split(out.String(), "-L")
97 for _, v := range outs {98 for _, v := range outs {
@@ -99,15 +100,15 @@ func findPkgConf(name string) string {
99 if c == "" {100 if c == "" {
100 continue101 continue
101 }102 }
102- g := findSo(c, name)103+ g := findSos(c, name)
103- if g != "" {104+ if len(g) > 0 {
104 return g105 return g
105 }106 }
106 }107 }
107- return ""108+ return []string{}
108 }109 }
109 110
110-// getPath gets a shared object file from a library name111+// GetPaths gets all shared object files from a library name
111 // it does it in the following order112 // it does it in the following order
112 // see if PUREGOTK_LIBNAME_PATH is set (full path to the lib)113 // see if PUREGOTK_LIBNAME_PATH is set (full path to the lib)
113 // - e.g. PUREGOTK_GTK_PATH114 // - e.g. PUREGOTK_GTK_PATH
@@ -117,18 +118,18 @@ func findPkgConf(name string) string {
117 // panic if failed118 // panic if failed
118 // TODO: Hardcore a library shared object with linker -X flag119 // TODO: Hardcore a library shared object with linker -X flag
119 // This is useful for packaging120 // This is useful for packaging
120-func getPath(name string) string {121+func GetPaths(name string) []string {
121 // try to get from env var122 // try to get from env var
122 ev := fmt.Sprintf("PUREGOTK_%s_PATH", name)123 ev := fmt.Sprintf("PUREGOTK_%s_PATH", name)
123 if v := os.Getenv(ev); v != "" {124 if v := os.Getenv(ev); v != "" {
124- return v125+ return []string{v}
125 }126 }
126 127
127 // Or if a general folder is set where everywhere is located, return that128 // Or if a general folder is set where everywhere is located, return that
128 ep := os.Getenv("PUREGOTK_LIB_FOLDER")129 ep := os.Getenv("PUREGOTK_LIB_FOLDER")
129 if ep != "" {130 if ep != "" {
130- g := findSo(ep, name)131+ g := findSos(ep, name)
131- if g == "" {132+ if len(g) == 0 {
132 panic(fmt.Sprintf("Could not find lib: %s, at path: %s with env: %s", name, ep, "PUREGOTK_FOLDER"))133 panic(fmt.Sprintf("Could not find lib: %s, at path: %s with env: %s", name, ep, "PUREGOTK_FOLDER"))
133 }134 }
134 return g135 return g
@@ -139,8 +140,8 @@ func getPath(name string) string {
139 if ok {140 if ok {
140 // try to loop over paths141 // try to loop over paths
141 for _, p := range gp {142 for _, p := range gp {
142- g := findSo(p, name)143+ g := findSos(p, name)
143- if g != "" {144+ if len(g) > 0 {
144 return g145 return g
145 }146 }
146 147
@@ -148,7 +149,7 @@ func getPath(name string) string {
148 }149 }
149 // last effort: pkg-config150 // last effort: pkg-config
150 g := findPkgConf(name)151 g := findPkgConf(name)
151- if g != "" {152+ if len(g) > 0 {
152 return g153 return g
153 }154 }
154 155
@@ -172,68 +173,3 @@ func GoString(c uintptr) string {
172 }173 }
173 return string(unsafe.Slice((*byte)(ptr), length))174 return string(unsafe.Slice((*byte)(ptr), length))
174 }175 }
175-
176-// GetPaths gets all shared object file paths for a library name that may have multiple libraries.
177-// This is used when a package needs to load multiple shared libraries (e.g., GLIB needs both libgobject and libglib).
178-// Returns a slice of full paths to all libraries for this package.
179-func GetPaths(name string) []string {
180- libNames, ok := names[name]
181- if !ok || len(libNames) == 0 {
182- // Fallback to single GetPath for backward compatibility
183- return []string{getPath(name)}
184- }
185-
186- // If only one library, use the original GetPath logic
187- if len(libNames) == 1 {
188- return []string{getPath(name)}
189- }
190-
191- var result []string
192- for _, libName := range libNames {
193- // Try PUREGOTK_LIB_FOLDER first
194- ep := os.Getenv("PUREGOTK_LIB_FOLDER")
195- if ep != "" {
196- suffixes := []string{"", ".0", ".1", ".2"}
197- found := false
198- for _, s := range suffixes {
199- fullPath := filepath.Join(ep, libName+s)
200- if _, err := os.Stat(fullPath); err == nil {
201- result = append(result, fullPath)
202- found = true
203- break
204- }
205- }
206- if found {
207- continue
208- }
209- }
210-
211- // Try hardcoded paths
212- gp, pathsOk := paths[runtime.GOARCH]
213- if pathsOk {
214- found := false
215- for _, p := range gp {
216- suffixes := []string{"", ".0", ".1", ".2"}
217- fn := filepath.Join(p, libName)
218- for _, s := range suffixes {
219- if _, err := os.Stat(fn + s); err == nil {
220- result = append(result, fn+s)
221- found = true
222- break
223- }
224- }
225- if found {
226- break
227- }
228- }
229- if found {
230- continue
231- }
232- }
233-
234- // If we get here, we couldn't find this library
235- 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))
236- }
237-
238- return result
239-}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 102

↑↓ moveenter openesc close