【问题标题】:Cross compiling golang with cgo for Windows target on macOS host在 macOS 主机上使用 cgo for Windows 目标交叉编译 golang
【发布时间】:2018-09-04 15:56:52
【问题描述】:

我在 macOS 上并尝试使用从 homebrew 安装的 mingw-w64 交叉编译适用于 Windows 的 golang (CGO 1.10) 可执行文件。

我有一个只有一个函数(SimpleQRDecode)的 golang 包,它从我的 c++ 源调用其他函数(FindAndDecodeQR,使用 zxing c++ 端口)。

  1. 编译 ZXing 源代码没问题 (x86_64-w64-mingw32-g++)
  2. 编译 qrcode.cpp 没问题 (x86_64-w64-mingw32-g++)
  3. 成功将所有对象(zxing + my)合并到静态库(x86_64-w64-mingw32-ar)中
  4. 在静态库 (x86_64-w64-mingw32-ranlib) 上成功调用 ranlib
  5. 失败呼叫CGO_ENABLED=1 CXX="x86_64-w64-mingw32-g++" CXX_FOR_TARGET="x86_64-w64-mingw32-g++" CC="x86_64-w64-mingw32-gcc" CC_FOR_TARGET="x86_64-w64-mingw32-gcc" GOOS=windows GOARCH=amd64 go build -x

go build 输出包含大量未解析的符号消息,例如

libmyqr.a(qrcode.o):qrcode.cpp:(.text+0x79): undefined reference to `operator new(unsigned long long)'
libmyqr.a(qrcode.o):qrcode.cpp:(.text+0x2cb): undefined reference to `std::string::length() const'
libmyqr.a(qrcode.o):qrcode.cpp:(.text+0x4a7): undefined reference to `__cxa_begin_catch'
libmyqr.a(BinaryBitmap.cpp.obj):BinaryBitmap.cpp:(.text+0x5c2): undefined reference to `std::ios_base::Init::~Init()'
libmyqr.a(BinaryBitmap.cpp.obj):BinaryBitmap.cpp:(.xdata+0xc): undefined reference to `__gxx_personality_seh0'

qrcode.go:

package qrcode

/*
#cgo CFLAGS: -I../../native/prefix/include -I../../libmyqr -fPIC
#cgo CXXFLAGS: -I../../native/prefix/include -I../../libmyqr -fPIC
#cgo LDFLAGS: -L../../libmyqr -lmyqr -lstdc++
#include <stdlib.h>
#include <qrcode.h>
*/
import "C"

import (
    "errors"
    "fmt"
    "unsafe"
)

func SimpleQRDecode(rasterData []byte, width, height int) (string, bool, error) {
    res := C.FindAndDecodeQR((*C.char)(unsafe.Pointer(&data[0])), C.int(len(data)), C.int(width), C.int(height))

qrcode.h:

#ifdef __cplusplus
extern "C" {
#endif

const char* FindAndDecodeQR(char *raster, int size, int width, int height);


#ifdef __cplusplus
}
#endif

qrcode.cpp:

#include "qrcode.h"

#include <sstream>

#include <zxing/ZXing.h>
#include <zxing/Binarizer.h>
#include <zxing/BinaryBitmap.h>
#include <zxing/Result.h>
#include <zxing/qrcode/QRCodeReader.h>
#include <zxing/common/GreyscaleRotatedLuminanceSource.h>
#include <zxing/common/GlobalHistogramBinarizer.h>

const char* FindAndDecodeQR(char *raster, int size, int width, int height) {
    // GreyscaleLuminanceSource

    std::ostringstream resStream;

    try {
        zxing::ArrayRef<char> image(raster, size);
        zxing::Ref<zxing::GreyscaleRotatedLuminanceSource> source(new zxing::GreyscaleRotatedLuminanceSource(image, width, height, 0, 0, width, height));

libmyqr.a - 由所有 zxing 编译对象组成的静态库 + qrcode.cpp.o

【问题讨论】:

    标签: c++ macos go cross-compiling cgo


    【解决方案1】:

    这可能不是您想听到的,但在 Mac 上交叉编译到 Windows 的最简单方法是从您的 c/c++ 代码构建一个 DLL 库,并从您的 go 代码处理这个 DLL 库。在这种情况下,你甚至不需要CGO_ENABLED=1

    go 代码可能如下所示(未经测试):

    // +build windows
    
    package qrcode
    
    import (
        "errors"
        "fmt"
        "syscalls"
        "unsafe"
    )
    
    var modYourPkg = syscall.NewLazyDLL("yourpkg.dll")
    
    var procFindAndDecodeQR = modYourPkg.NewProc("FindAndDecodeQR")
    
    func SimpleQRDecode(rasterData []byte, width, height int) (string, bool, error) {
        res, _, _ := procFindAndDecodeQR.Call(
            uintptr(unsafe.Pointer(&rasterData[0])),
            uintptr(len(data)),
            uintptr(width),
            uintptr(height),
        )
        ...
    }
    

    在 syscall 包的文档中查看更多信息。

    【讨论】:

    • 感谢您的建议,但我正在寻找构建可靠二进制文件的方法。
    猜你喜欢
    • 2017-05-24
    • 2023-02-01
    • 2015-04-24
    • 2016-03-09
    • 2015-11-25
    • 1970-01-01
    • 1970-01-01
    • 2021-10-22
    • 2021-03-04
    相关资源
    最近更新 更多