Golang在交叉编译ARM架构时无法链接net库的问题

Golang在交叉编译ARM架构时无法链接net库的问题 大家好,

在为ARM架构交叉编译我的应用程序时遇到了障碍,但在MIPS和x86架构上编译完全正常。 问题实际上不在于编译,而在于链接。我收到了以下错误:

command-line-arguments

loadelf: /home/build/iopsyswrt/tmp/go-build/da/da457e3b0405a90730032b92d7e3a72e3f753a3bf6736d198e49a434f7283add-d(_x001.o): 117022: sym#29: ignoring symbol in section 1 (type 0) loadelf: /home/build/iopsyswrt/tmp/go-build/da/da457e3b0405a90730032b92d7e3a72e3f753a3bf6736d198e49a434f7283add-d(_x002.o): 117026: sym#39: ignoring symbol in section 1 (type 0) loadelf: /home/build/iopsyswrt/tmp/go-build/da/da457e3b0405a90730032b92d7e3a72e3f753a3bf6736d198e49a434f7283add-d(_x003.o): 117030: sym#51: ignoring symbol in section 1 (type 0) loadelf: /home/build/iopsyswrt/tmp/go-build/da/da457e3b0405a90730032b92d7e3a72e3f753a3bf6736d198e49a434f7283add-d(_x004.o): 117034: sym#47: ignoring symbol in section 1 (type 0) loadelf: /home/build/iopsyswrt/tmp/go-build/da/da457e3b0405a90730032b92d7e3a72e3f753a3bf6736d198e49a434f7283add-d(_x005.o): 117038: sym#57: ignoring symbol in section 1 (type 0) loadelf: /home/build/iopsyswrt/tmp/go-build/43/4379d79a211b4d22d6aa20ce7478f83cf7e6aa5eae89a3e33fe91d2e12589829-d(_x001.o): 117042: sym#29: ignoring symbol in section 1 (type 0) loadelf: /home/build/iopsyswrt/tmp/go-build/43/4379d79a211b4d22d6aa20ce7478f83cf7e6aa5eae89a3e33fe91d2e12589829-d(_x002.o): 117046: sym#27: ignoring symbol in section 1 (type 0) loadelf: /home/build/iopsyswrt/tmp/go-build/43/4379d79a211b4d22d6aa20ce7478f83cf7e6aa5eae89a3e33fe91d2e12589829-d(_x003.o): 117050: sym#39: ignoring symbol in section 1 (type 0) loadelf: /home/build/iopsyswrt/tmp/go-build/43/4379d79a211b4d22d6aa20ce7478f83cf7e6aa5eae89a3e33fe91d2e12589829-d(_x004.o): 117056: sym#44: ignoring symbol in section 1 (type 0) loadelf: /home/build/iopsyswrt/tmp/go-build/43/4379d79a211b4d22d6aa20ce7478f83cf7e6aa5eae89a3e33fe91d2e12589829-d(_x005.o): 117066: sym#71: ignoring symbol in section 1 (type 0) loadelf: /home/build/iopsyswrt/tmp/go-build/43/4379d79a211b4d22d6aa20ce7478f83cf7e6aa5eae89a3e33fe91d2e12589829-d(_x006.o): 117074: sym#68: ignoring symbol in section 1 (type 0) loadelf: /home/build/iopsyswrt/tmp/go-build/43/4379d79a211b4d22d6aa20ce7478f83cf7e6aa5eae89a3e33fe91d2e12589829-d(_x007.o): 117078: sym#39: ignoring symbol in section 1 (type 0) loadelf: /home/build/iopsyswrt/tmp/go-build/43/4379d79a211b4d22d6aa20ce7478f83cf7e6aa5eae89a3e33fe91d2e12589829-d(_x008.o): 117082: sym#39: ignoring symbol in section 1 (type 0) loadelf: /home/build/iopsyswrt/tmp/go-build/43/4379d79a211b4d22d6aa20ce7478f83cf7e6aa5eae89a3e33fe91d2e12589829-d(_x009.o): 117089: sym#44: ignoring symbol in section 1 (type 0) _cgo_init: relocation target x_cgo_init not defined _cgo_notify_runtime_init_done: relocation target x_cgo_notify_runtime_init_done not defined _cgo_thread_start: relocation target x_cgo_thread_start not defined net._cgo_26061493d47f_C2func_getaddrinfo: relocation target _cgo_26061493d47f_C2func_getaddrinfo not defined net._cgo_26061493d47f_Cfunc_freeaddrinfo: relocation target _cgo_26061493d47f_Cfunc_freeaddrinfo not defined net._cgo_26061493d47f_Cfunc_gai_strerror: relocation target _cgo_26061493d47f_Cfunc_gai_strerror not defined runtime._cgo_setenv: relocation target x_cgo_setenv not defined /home/build/iopsyswrt/staging_dir/hostpkg/lib/go-cross/pkg/tool/linux_amd64/link: too many errors

所以,在我向代码中引入WebSocket代码片段之前,应用程序在ARM架构上一直运行良好:

package communicator

import (
    "bufio"
    "fmt"
    "log"
    "net"
    "os"
    "time"
)

const (
    gwDeviceHandle = "gateway"
    rxBufferSize   = 10240 // 接收套接字连接消息的缓冲区大小(字节)
    minPollCycle   = 100 * time.Millisecond
    socket_address = "/hc/data/var/scg/ipc.sock"
    connHost       = "localhost"
    connPort       = "8080"
    connType       = "tcp"
    connServAddr   = "192.168.2.167"
)

var Wizard_chan = make(chan string)

func Report_communicator() {
    fmt.Println("communicator module reporting in !")
}

func StartNodeSocketHandler() {
    fmt.Println("Starting " + connType + " server on " + connHost + ":" + connPort)
    l, err := net.Listen(connType, connHost+":"+connPort)
    if err != nil {
        fmt.Println("Error listening:", err.Error())
        os.Exit(1)
    }
    defer l.Close()

    for {

        c, err := l.Accept()
        if err != nil {
            fmt.Println("Error connecting:", err.Error())
            return
        }
        fmt.Println("Client connected.")

        fmt.Println("Client " + c.RemoteAddr().String() + " connected.")

        go handleConnection(c)
    }
}

请帮帮我! 非常感谢并致以最诚挚的问候!


更多关于Golang在交叉编译ARM架构时无法链接net库的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang在交叉编译ARM架构时无法链接net库的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这个问题是由于交叉编译ARM架构时CGO未正确配置导致的。net包在某些情况下需要CGO支持,特别是在使用DNS解析功能时。以下是解决方案:

// 在编译前设置环境变量
// 对于ARM架构(如ARMv7):
// GOOS=linux GOARCH=arm GOARM=7 CGO_ENABLED=1 CC=arm-linux-gnueabihf-gcc go build -o app main.go

// 如果使用musl libc:
// GOOS=linux GOARCH=arm GOARM=7 CGO_ENABLED=1 CC=arm-linux-musleabihf-gcc go build -o app main.go

// 纯Go替代方案(避免CGO依赖):
package main

import (
    "context"
    "fmt"
    "net"
    "time"
)

func main() {
    // 使用纯Go的DNS解析器
    resolver := &net.Resolver{
        PreferGo: true,
        Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
            d := net.Dialer{
                Timeout: time.Millisecond * time.Duration(10000),
            }
            return d.DialContext(ctx, "udp", "8.8.8.8:53")
        },
    }
    
    // 使用自定义解析器
    addrs, err := resolver.LookupHost(context.Background(), "localhost")
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    fmt.Println("Addresses:", addrs)
}

如果必须使用CGO,确保交叉编译工具链正确安装:

# 安装ARM交叉编译工具链
# Ubuntu/Debian:
sudo apt-get install gcc-arm-linux-gnueabihf

# 编译命令示例:
export GOOS=linux
export GOARCH=arm
export GOARM=7
export CGO_ENABLED=1
export CC=arm-linux-gnueabihf-gcc
go build -ldflags="-extldflags=-static" -o arm-app main.go

对于静态链接:

# 静态链接所有依赖
CGO_ENABLED=1 GOOS=linux GOARCH=arm GOARM=7 CC=arm-linux-gnueabihf-gcc \
go build -a -ldflags '-extldflags "-static"' -o app main.go

如果问题仍然存在,可以尝试禁用CGO:

# 完全禁用CGO(某些网络功能可能受限)
CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=7 go build -o app main.go

检查net包是否使用了cgo:

// 在代码中添加构建约束
// +build !cgo

package communicator

import (
    "net"
    // 其他导入
)

// 这样可以在没有CGO时使用纯Go实现
回到顶部