build(macOS): change full library paths to @rpath

This commit is contained in:
Aofei Sheng
2024-07-16 08:09:57 +08:00
parent 2935ae7bf1
commit 74012d4869
2 changed files with 35 additions and 3 deletions

View File

@@ -17,6 +17,7 @@
package build package build
import ( import (
"debug/macho"
"fmt" "fmt"
"go/constant" "go/constant"
"go/token" "go/token"
@@ -403,11 +404,14 @@ func linkMainPkg(ctx *context, pkg *packages.Package, pkgs []*aPackage, llFiles
} }
}() }()
// add rpath // add rpath and find libs
exargs := make([]string, 0, ctx.nLibdir<<1) exargs := make([]string, 0, ctx.nLibdir<<1)
libs := make([]string, 0, ctx.nLibdir*3)
for _, arg := range args { for _, arg := range args {
if strings.HasPrefix(arg, "-L") { if strings.HasPrefix(arg, "-L") {
exargs = append(exargs, "-rpath", arg[2:]) exargs = append(exargs, "-rpath", arg[2:])
} else if strings.HasPrefix(arg, "-l") {
libs = append(libs, arg[2:])
} }
} }
args = append(args, exargs...) args = append(args, exargs...)
@@ -419,6 +423,18 @@ func linkMainPkg(ctx *context, pkg *packages.Package, pkgs []*aPackage, llFiles
err := ctx.env.Clang().Exec(args...) err := ctx.env.Clang().Exec(args...)
check(err) check(err)
if runtime.GOOS == "darwin" {
dylibDeps := make([]string, 0, len(libs))
for _, lib := range libs {
dylibDep := findDylibDep(app, lib)
if dylibDep != "" {
dylibDeps = append(dylibDeps, dylibDep)
}
}
err := ctx.env.InstallNameTool().ChangeToRpath(app, dylibDeps...)
check(err)
}
switch mode { switch mode {
case ModeRun: case ModeRun:
cmd := exec.Command(app, conf.RunArgs...) cmd := exec.Command(app, conf.RunArgs...)
@@ -706,6 +722,22 @@ func canSkipToBuild(pkgPath string) bool {
} }
} }
// findDylibDep finds the dylib dependency in the executable. It returns empty
// string if not found.
func findDylibDep(exe, lib string) string {
file, err := macho.Open(exe)
check(err)
defer file.Close()
for _, load := range file.Loads {
if dylib, ok := load.(*macho.Dylib); ok {
if strings.HasPrefix(filepath.Base(dylib.Name), fmt.Sprintf("lib%s.", lib)) {
return dylib.Name
}
}
}
return ""
}
type none struct{} type none struct{}
var hasAltPkg = map[string]none{ var hasAltPkg = map[string]none{

View File

@@ -54,7 +54,7 @@ type Change struct {
// Change changes dependent shared library install name. // Change changes dependent shared library install name.
func (p *Cmd) Change(target string, chgs ...Change) error { func (p *Cmd) Change(target string, chgs ...Change) error {
args := make([]string, len(chgs)*3+1) args := make([]string, 0, len(chgs)*3+1)
for _, chg := range chgs { for _, chg := range chgs {
args = append(args, "-change", chg.Old, chg.New) args = append(args, "-change", chg.Old, chg.New)
} }
@@ -64,7 +64,7 @@ func (p *Cmd) Change(target string, chgs ...Change) error {
// ChangeToRpath changes dependent shared library install name to @rpath. // ChangeToRpath changes dependent shared library install name to @rpath.
func (p *Cmd) ChangeToRpath(target string, dylibDeps ...string) error { func (p *Cmd) ChangeToRpath(target string, dylibDeps ...string) error {
args := make([]string, len(dylibDeps)*3+1) args := make([]string, 0, len(dylibDeps)*3+1)
for _, dep := range dylibDeps { for _, dep := range dylibDeps {
args = append(args, "-change", dep, "@rpath/"+filepath.Base(dep)) args = append(args, "-change", dep, "@rpath/"+filepath.Base(dep))
} }