在执行所有步骤之前,请安装Visual Studio 2022,并配置相应的环境变量,保证系统中有pexports.exe、dumpbin.exe和lib.exe。
报错回放
1.No module named ‘gi’
2.msvc_recommended_pragmas.h 找不到文件。
C:\Users\临江词客>pip install pygobject
Looking in indexes: https://mirrors.ustc.edu.cn/pypi/web/simple/
Collecting pygobject
Using cached https://mirrors.bfsu.edu.cn/pypi/web/packages/ac/4a/f24ddf1d20cc4b56affc7921e29928559a06c922eb60077448392792b914/PyGObject-3.46.0.tar.gz (723 kB)
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing metadata (pyproject.toml) ... done
Requirement already satisfied: pycairo>=1.16.0 in c:\users\临江词客\appdata\roaming\python\python39\site-packages (from pygobject) (1.24.0)
Building wheels for collected packages: pygobject
Building wheel for pygobject (pyproject.toml) ... error
error: subprocess-exited-with-error
× Building wheel for pygobject (pyproject.toml) did not run successfully.
│ exit code: 1
╰─> [47 lines of output]
running bdist_wheel
running build
running build_py
creating build
creating build\lib.win-amd64-cpython-39
creating build\lib.win-amd64-cpython-39\pygtkcompat
copying pygtkcompat\generictreemodel.py -> build\lib.win-amd64-cpython-39\pygtkcompat
copying pygtkcompat\pygtkcompat.py -> build\lib.win-amd64-cpython-39\pygtkcompat
copying pygtkcompat\__init__.py -> build\lib.win-amd64-cpython-39\pygtkcompat
creating build\lib.win-amd64-cpython-39\gi
copying gi\docstring.py -> build\lib.win-amd64-cpython-39\gi
copying gi\importer.py -> build\lib.win-amd64-cpython-39\gi
copying gi\module.py -> build\lib.win-amd64-cpython-39\gi
copying gi\pygtkcompat.py -> build\lib.win-amd64-cpython-39\gi
copying gi\types.py -> build\lib.win-amd64-cpython-39\gi
copying gi\_constants.py -> build\lib.win-amd64-cpython-39\gi
copying gi\_error.py -> build\lib.win-amd64-cpython-39\gi
copying gi\_gtktemplate.py -> build\lib.win-amd64-cpython-39\gi
copying gi\_option.py -> build\lib.win-amd64-cpython-39\gi
copying gi\_ossighelper.py -> build\lib.win-amd64-cpython-39\gi
copying gi\_propertyhelper.py -> build\lib.win-amd64-cpython-39\gi
copying gi\_signalhelper.py -> build\lib.win-amd64-cpython-39\gi
copying gi\__init__.py -> build\lib.win-amd64-cpython-39\gi
creating build\lib.win-amd64-cpython-39\gi\repository
copying gi\repository\__init__.py -> build\lib.win-amd64-cpython-39\gi\repository
creating build\lib.win-amd64-cpython-39\gi\overrides
copying gi\overrides\Gdk.py -> build\lib.win-amd64-cpython-39\gi\overrides
copying gi\overrides\GdkPixbuf.py -> build\lib.win-amd64-cpython-39\gi\overrides
copying gi\overrides\GIMarshallingTests.py -> build\lib.win-amd64-cpython-39\gi\overrides
copying gi\overrides\Gio.py -> build\lib.win-amd64-cpython-39\gi\overrides
copying gi\overrides\GLib.py -> build\lib.win-amd64-cpython-39\gi\overrides
copying gi\overrides\GObject.py -> build\lib.win-amd64-cpython-39\gi\overrides
copying gi\overrides\Gtk.py -> build\lib.win-amd64-cpython-39\gi\overrides
copying gi\overrides\keysyms.py -> build\lib.win-amd64-cpython-39\gi\overrides
copying gi\overrides\Pango.py -> build\lib.win-amd64-cpython-39\gi\overrides
copying gi\overrides\__init__.py -> build\lib.win-amd64-cpython-39\gi\overrides
running build_ext
pycairo: trying include directory: 'C:\\Users\\临江词客\\AppData\\Local\\Temp\\pip-build-env-elf12_ev\\overlay\\Lib\\site-packages\\cairo\\include'
pycairo: found 'C:\\Users\\临江词客\\AppData\\Local\\Temp\\pip-build-env-elf12_ev\\overlay\\Lib\\site-packages\\cairo\\include\\py3cairo.h'
building 'gi._gi' extension
creating build\temp.win-amd64-cpython-39
creating build\temp.win-amd64-cpython-39\Release
creating build\temp.win-amd64-cpython-39\Release\gi
"D:\Program Files\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.38.33130\bin\HostX86\x64\cl.exe" /c /nologo /O2 /W3 /GL /DNDEBUG /MD -DPY_SSIZE_T_CLEAN -IC:\Users\临江词客\AppData\Local\Temp\pip-install-mfigxaxk\pygobject_256bb6a29a134136bf2f14d0a158351f -IC:\Users\临江词客\AppData\Local\Temp\pip-install-mfigxaxk\pygobject_256bb6a29a134136bf2f14d0a158351f\gi "-IC:\Program Files\Python39\include" "-IC:\Program Files\Python39\Include" "-ID:\Program Files\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.38.33130\include" "-ID:\Program Files\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\VS\include" "-IC:\Program Files (x86)\Windows Kits\10\include\10.0.22621.0\ucrt" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\um" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\shared" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\winrt" "-IC:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\cppwinrt" "-IC:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um" "-Id:\Program Files (x86)\vc6\atl\include" "-Id:\Program Files (x86)\vc6\mfc\include" "-Id:\Program Files (x86)\vc6\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\VC98\atl\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\VC98\mfc\include" "-IC:\Program Files (x86)\Microsoft Visual Studio\VC98\include" -ID:\Ruby33\msys64\mingw64\include /Tcgi\gimodule.c /Fobuild\temp.win-amd64-cpython-39\Release\gi\gimodule.obj -FImsvc_recommended_pragmas.h
gimodule.c
gi\gimodule.c: fatal error C1083: 无法打开包括文件: “msvc_recommended_pragmas.h”: No such file or directory
error: command 'D:\\Program Files\\Microsoft Visual Studio\\2022\\BuildTools\\VC\\Tools\\MSVC\\14.38.33130\\bin\\HostX86\\x64\\cl.exe' failed with exit code 2
[end of output]
note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed building wheel for pygobject
Failed to build pygobject
ERROR: Could not build wheels for pygobject, which is required to install pyproject.toml-based projects
分析问题
msvc_recommended_pragmas.h是glib里面的文件。
解决办法
1.从官网下载ruby33 RubyInstaller for Windows ,然后运行安装程序(建议安装到D盘),安装结束后,勾选后点击finish。
2.在弹出的命令行界面中输入1,然后回车,等待密钥更新结束后回车退出。
3.进入到D:\Ruby33\msys64目录中,以管理员身份运行mingw64,第一次安装等待其设置完毕后,关闭mingw64,进入到D:\Ruby33\msys64\etc\pacman.d目录下面,给每一个mirrorlist中的“##Primary”下面第一行添加如下内容并保存:
对应的Server地址如下:
mirrorlist.clang32:
Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/clang32/
mirrorlist.clang64:
Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/clang64/
mirrorlist.mingw32:
Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/i686/
mirrorlist.mingw64:
Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/mingw64/
mirrorlist.msys:
Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/msys/$arch/
mirrorlist.ucrt64
Server = https://mirrors.tuna.tsinghua.edu.cn/msys2/mingw/ucrt64/
4.再次管理员模式运行mingw64,输入 pacman -Sy 然后回车更新软件源,输入以下内容,安装依赖库。
pacman -S mingw-w64-x86_64-pkgconf
pacman -S gcc make mingw-w64-x86_64-glib2 mingw-w64-x86_64-glibmm mingw-w64-x86_64-python-gobject mingw-w64-x86_64-gtk2 mingw-w64-x86_64-gtk3 mingw-w64-x86_64-gtk4 mingw-w64-x86_64-gobject-introspection
5.之后进入到D:\Ruby33\msys64\mingw64\bin下面,新建一个名为“dlls”的文件夹,并将以下两段代码保存到“D:\Ruby33\msys64\mingw64\bin\dlls”里面
convert.py
import os
need_modify_list = [file for file in os.listdir(".") if file.endswith(".def")]
datas = {}
def get_header(filename):
# Generate File Header
return f"LIBRARY {filename[0:-4]}\n\nEXPORTS\n\n"
def modify(defname):
header = get_header(defname)
modify_filename = defname + '.write'
# If file exists, then remove it.
if os.path.exists(modify_filename):
os.remove(modify_filename)
with open(defname, "r") as original_def:
for line in original_def.readlines():
datas[line.split()[0]] = line.split()[-1]
original_def.close()
with open(modify_filename, "a+") as rechanged_def:
rechanged_def.write(header)
for ordinal in datas.keys():
data = f"{datas[ordinal]} @{ordinal}\n"
rechanged_def.write(data)
rechanged_def.close()
os.remove(defname)
os.rename(modify_filename, defname)
def install(defname, machine):
# Generate lib file with MSVC def file.
output = f"{defname[0:-4]}.lib"
os.system(f"lib /def:{defname} /machine:{machine} /out:{output}")
os.system(f"cp {output} ../../lib")
def main():
print('Convert dumpbin def to MSVC def.')
for file in need_modify_list:
input("Please ensure their def files is exists and removed headers and ends, \
and then press Enter to continue."
)
# If def files was generated by pexports, 'modify' will be needn't.
# modify(file)
install(file, "X64")
print("Complete!")
if __name__ == "__main__":
main()
extract.py
import os
dllfiles = [file for file in os.listdir(".") if file.endswith(".dll")]
deffile = {}
for file in dllfiles:
deffile[file] = file[0:-4][3:]+".def" if file.startswith('lib') else file[0:-4]+".def"
for dllfile in dllfiles:
os.system(f"pexports {dllfile} > {deffile[dllfile]}")
6.返回到上一级的“bin”目录,并将下图中所有的dll文件复制到dlls文件夹中。
并将它们重命名为下图所示(-和后面的数字删掉)。
7.在“D:\Ruby33\msys64\mingw64\bin\dlls”目录下打开cmd命令行窗口,输入 python extract.py 之后回车,等待所有的def文件提取完毕,之后运行 python convert.py 将def文件链接成lib文件并安装到“D:\Ruby33\msys64\mingw64\lib”中。
请注意,在你的环境变量中应该把“D:\Ruby33\msys64\mingw64\lib”添加进这个lib变量和把“D:\Ruby33\msys64\mingw64\include”添加进include变量。
8.进入到“D:\Ruby33\msys64\mingw64\include”目录中,把glib-2.0、cairo和gobject-introspection-1.0目录中的所有文件及文件夹复制出来,放到“D:\Ruby33\msys64\mingw64\include”里面,之后把“D:\Ruby33\msys64\mingw64\lib\glib-2.0\include”中的“glibconfig.h”也复制到“D:\Ruby33\msys64\mingw64\include”里面,之后运行 pip install pygobject ,你会得到一个报错。
D:\Ruby33\msys64\mingw64\include\glib/gatomic.h(1): error C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
D:\Ruby33\msys64\mingw64\include\glib/gtestutils.h(1): error C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
D:\Ruby33\msys64\mingw64\include\gobject/gtype.h(879): error C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
打开 Visual Studio 2022 Community Preview,修改glib/gatomic.h、glib/gtestutilis.h、gobject/gtype.h的编码为 Unicode (UTF-8 带签名) - 代码页 65001,然后保存(需要更改三个文件的权限,使Users用户组有全部控制的权限才能写入)。
9.在解决 error C4819 错误后,再次运行 pip install pygobject,成功安装。
参考文档
解决VS编译C++时,该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格 式以防止数据丢失 - 芈璐 - 博客园 (cnblogs.com)