Golang在Windows上如何编译嵌入的Python代码

Golang在Windows上如何编译嵌入的Python代码 你好! 我有一个嵌入Go代码中的Python代码(参考:在GO代码中使用python) 但我遇到了一个相当重要的问题——我需要将我的应用程序部署到Windows平台,但我无法在该平台上构建它。

在Windows上

即使我添加了pkg-config和Python配置,我仍然收到“Python.h”文件未找到的错误。

在Linux上

我尝试使用以下脚本进行交叉编译:

#!/bin/bash
#
ecoh "build for windows"
LD_LIBRARY_PATH="/usr/x86_64-w64-mingw32/sys-root/mingw/lib" PKG_CONFIG_PATH="/usr/x86_64-w64-mingw32/sys-root/mingw/lib/pkgconfig/" GOOS=windows GOARCH=amd64 \
        CGO_ENABLED=1 \
        CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++ \
        go build \
        -ldflags "-s -w -extldflags=-static" \
        -o main.go .

无论如何,我遇到了以下链接器错误:

/usr/local/go/pkg/tool/linux_amd64/link: running x86_64-w64-mingw32-g++ failed: exit status 1
/usr/lib/gcc/x86_64-w64-mingw32/12.2.1/../../../../x86_64-w64-mingw32/bin/ld: cannot find -lpython3.10: No such file or directory
/usr/lib/gcc/x86_64-w64-mingw32/12.2.1/../../../../x86_64-w64-mingw32/bin/ld: skipping incompatible /usr/i686-w64-mingw32/sys-root/mingw/lib/libimm32.a when searching for -limm32
/usr/lib/gcc/x86_64-w64-mingw32/12.2.1/../../../../x86_64-w64-mingw32/bin/ld: skipping incompatible /usr/i686-w64-mingw32/sys-root/mingw/lib/libimm32.a when searching for -limm32
/usr/lib/gcc/x86_64-w64-mingw32/12.2.1/../../../../x86_64-w64-mingw32/bin/ld: cannot find -lpython3.10: No such file or directory
/usr/lib/gcc/x86_64-w64-mingw32/12.2.1/../../../../x86_64-w64-mingw32/bin/ld: skipping incompatible /usr/i686-w64-mingw32/sys-root/mingw/lib/libgdi32.a when searching for -lgdi32
/usr/lib/gcc/x86_64-w64-mingw32/12.2.1/../../../../x86_64-w64-mingw32/bin/ld: skipping incompatible /usr/i686-w64-mingw32/sys-root/mingw/lib/libgdi32.a when searching for -lgdi32
/usr/lib/gcc/x86_64-w64-mingw32/12.2.1/../../../../x86_64-w64-mingw32/bin/ld: skipping incompatible /usr/i686-w64-mingw32/sys-root/mingw/lib/libopengl32.a when searching for -lopengl32
/usr/lib/gcc/x86_64-w64-mingw32/12.2.1/../../../../x86_64-w64-mingw32/bin/ld: skipping incompatible /usr/i686-w64-mingw32/sys-root/mingw/lib/libopengl32.a when searching for -lopengl32
/usr/lib/gcc/x86_64-w64-mingw32/12.2.1/../../../../x86_64-w64-mingw32/bin/ld: skipping incompatible /usr/i686-w64-mingw32/sys-root/mingw/lib/libopengl32.a when searching for -lopengl32
/usr/lib/gcc/x86_64-w64-mingw32/12.2.1/../../../../x86_64-w64-mingw32/bin/ld: skipping incompatible /usr/i686-w64-mingw32/sys-root/mingw/lib/libopengl32.a when searching for -lopengl32
/usr/lib/gcc/x86_64-w64-mingw32/12.2.1/../../../../x86_64-w64-mingw32/bin/ld: skipping incompatible /usr/i686-w64-mingw32/sys-root/mingw/lib/libopengl32.a when searching for -lopengl32
/usr/lib/gcc/x86_64-w64-mingw32/12.2.1/../../../../x86_64-w64-mingw32/bin/ld: skipping incompatible /usr/i686-w64-mingw32/sys-root/mingw/lib/libopengl32.a when searching for -lopengl32
collect2: error: ld returned 1 exit status

我不知道哪个错误更容易解决 smile


更多关于Golang在Windows上如何编译嵌入的Python代码的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

你是否也为Windows编译了Python?

更多关于Golang在Windows上如何编译嵌入的Python代码的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我安装了 mingw32-python 包,我猜它提供了 Python 的 Windows 编译版本,不过说实话,我不太确定是否使用了这个编译版本。

也许你的 ldflags 需要一个 -L 标志来指定 python310.dll 所在的目录?另外,我认为在 Windows 上是 python310.dll,而在其他系统上则是 libpython3.10.so(这是根据我电脑上 C:\Program Files\Python310 文件夹的内容得出的结论)。

在Windows上编译嵌入Python的Go代码需要正确配置CGO和Python开发环境。以下是解决方案:

Windows本地编译

首先安装Windows版Python开发环境:

  1. 从Python官网下载Windows安装包,安装时勾选"Add Python to PATH"和"Install for all users"
  2. 安装完成后,确保Python.h位于C:\Program Files\Python310\include(版本号可能不同)

设置环境变量:

set CGO_ENABLED=1
set PKG_CONFIG_PATH=C:\Program Files\Python310\libs\pkgconfig
set CGO_CFLAGS=-IC:\Program Files\Python310\include
set CGO_LDFLAGS=-LC:\Program Files\Python310\libs -lpython310

然后编译:

go build -o app.exe main.go

Linux交叉编译到Windows

需要安装mingw-w64和Windows版Python库:

# Ubuntu/Debian
sudo apt-get install mingw-w64 gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64

# 下载Windows Python开发库
wget https://www.python.org/ftp/python/3.10.0/python-3.10.0-embed-amd64.zip
unzip python-3.10.0-embed-amd64.zip -d /opt/windows-python

创建pkg-config文件 /opt/windows-python/lib/pkgconfig/python-3.10.pc

prefix=/opt/windows-python
exec_prefix=${prefix}
libdir=${exec_prefix}/libs
includedir=${prefix}/include

Name: Python
Description: Python library
Version: 3.10
Libs: -L${libdir} -lpython310
Cflags: -I${includedir}

交叉编译命令:

export PKG_CONFIG_PATH=/opt/windows-python/lib/pkgconfig
export CGO_ENABLED=1
export CC=x86_64-w64-mingw32-gcc
export CXX=x86_64-w64-mingw32-g++

GOOS=windows GOARCH=amd64 go build \
    -ldflags "-s -w" \
    -o app.exe main.go

完整示例代码

package main

/*
#cgo pkg-config: python-3.10
#include <Python.h>
*/
import "C"
import (
    "fmt"
    "unsafe"
)

func main() {
    C.Py_Initialize()
    
    code := C.CString(`
import sys
print(f"Python {sys.version}")
print("Hello from embedded Python!")
`)
    
    defer C.free(unsafe.Pointer(code))
    
    result := C.PyRun_SimpleString(code)
    if result != 0 {
        fmt.Println("Python execution failed")
    }
    
    C.Py_Finalize()
}

静态链接方案

如果需要完全静态链接,使用以下编译选项:

GOOS=windows GOARCH=amd64 CGO_ENABLED=1 \
CC=x86_64-w64-mingw32-gcc \
CGO_CFLAGS="-I/opt/windows-python/include" \
CGO_LDFLAGS="-L/opt/windows-python/libs -lpython310 -static -lwinpthread -lssp" \
go build -ldflags "-s -w -extldflags=-static" \
-o app.exe main.go

关键点:

  1. Windows本地编译需要Python开发头文件和库文件
  2. 交叉编译需要Windows版的Python库,不能使用Linux库
  3. 确保pkg-config路径正确指向Windows Python库
  4. 静态链接需要额外的Windows系统库
回到顶部