build(macOS): change full library paths to @rpath
This commit is contained in:
@@ -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{
|
||||||
|
|||||||
@@ -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))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user