Skip to content

Commit

Permalink
cmd/link: use path from "cc --print-prog-name ar" for c-archive build…
Browse files Browse the repository at this point in the history
…mode

When external linking with -buildmode=c-archive, the Go linker
eventually invokes the "ar" tool to create the final archive library.
Prior to this patch, if the '-extar' flag was not in use, we would
just run "ar". This works well in most cases but breaks down if we're
doing cross-compilation targeting Windows (macos system "ar"
apparently doesn't create the windows symdef section correctly). To
fix the problem, capture the output of "cc --print-prog-name ar" and
invoke "ar" using the path returned by that command.

Fixes #59221.

Change-Id: I9de66e98947c42633b16fde7208c2958d62fe7cc
Reviewed-on: https://go-review.googlesource.com/c/go/+/479775
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
  • Loading branch information
thanm committed Mar 28, 2023
1 parent c02e1bf commit 422f448
Showing 1 changed file with 23 additions and 16 deletions.
39 changes: 23 additions & 16 deletions src/cmd/link/internal/ld/lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -1316,7 +1316,12 @@ func (ctxt *Link) archive() {
exitIfErrors()

if *flagExtar == "" {
const printProgName = "--print-prog-name=ar"
cc := ctxt.extld()
*flagExtar = "ar"
if linkerFlagSupported(ctxt.Arch, cc[0], "", printProgName) {
*flagExtar = ctxt.findExtLinkTool("ar")
}
}

mayberemoveoutfile()
Expand Down Expand Up @@ -1875,22 +1880,8 @@ func (ctxt *Link) hostlink() {

if combineDwarf {
// Find "dsymutils" and "strip" tools using CC --print-prog-name.
var cc []string
cc = append(cc, ctxt.extld()...)
cc = append(cc, hostlinkArchArgs(ctxt.Arch)...)
cc = append(cc, "--print-prog-name", "dsymutil")
out, err := exec.Command(cc[0], cc[1:]...).CombinedOutput()
if err != nil {
Exitf("%s: finding dsymutil failed: %v\n%s", os.Args[0], err, out)
}
dsymutilCmd := strings.TrimSuffix(string(out), "\n")

cc[len(cc)-1] = "strip"
out, err = exec.Command(cc[0], cc[1:]...).CombinedOutput()
if err != nil {
Exitf("%s: finding strip failed: %v\n%s", os.Args[0], err, out)
}
stripCmd := strings.TrimSuffix(string(out), "\n")
dsymutilCmd := ctxt.findExtLinkTool("dsymutil")
stripCmd := ctxt.findExtLinkTool("dsymutil")

dsym := filepath.Join(*flagTmpdir, "go.dwarf")
if out, err := exec.Command(dsymutilCmd, "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil {
Expand Down Expand Up @@ -2763,3 +2754,19 @@ func captureHostObj(h *Hostobj) {
fmt.Fprintf(os.Stderr, "link: info: captured host object %s to %s\n",
h.file, opath)
}

// findExtLinkTool invokes the external linker CC with --print-prog-name
// passing the name of the tool we're interested in, such as "strip",
// "ar", or "dsymutil", and returns the path passed back from the command.
func (ctxt *Link) findExtLinkTool(toolname string) string {
var cc []string
cc = append(cc, ctxt.extld()...)
cc = append(cc, hostlinkArchArgs(ctxt.Arch)...)
cc = append(cc, "--print-prog-name", toolname)
out, err := exec.Command(cc[0], cc[1:]...).CombinedOutput()
if err != nil {
Exitf("%s: finding %s failed: %v\n%s", os.Args[0], toolname, err, out)
}
cmdpath := strings.TrimSuffix(string(out), "\n")
return cmdpath
}

0 comments on commit 422f448

Please sign in to comment.