M1芯片的Mac,系统指令集构架为amd64。
最初使用电脑自带Python3(这里是与Mac系统指令集构架一致的)的 pip 安装了 psycopg2 ,连接 PostgreSQL 数据库正常。但是在后来项目中使用的是 conda 中的 python 环境,执行程序并连接数据库的时候,就会出现Symbol not found: _PQbackendPID的问题。
在网上找到GitHub的issue 似乎也没有找到好的解决办法。
2.问题进一步发现和解决最初并没有意识到这和系统的指令集构架相关。后来由于需要将C++的一些写好的程序编译成动态库文件,并在python中进行调用。python代码在运行到需要使用到C++中的函数时,就会出现如下问题:
Traceback (most recent call last): File "/Users/debris/documents/Job/HA/encryption-cpp/test_encrypt.py", line 6, inmy_func = CDLL(so_file) File "/Users/debris/miniconda3/lib/python3.9/ctypes/__init__.py", line 382, in __init__ self._handle = _dlopen(self._name, mode) OSError: dlopen(/Users/debris/documents/Job/HA/encryption-cpp/encrypt_for_python.so, 0x0006): tried: '/Users/debris/documents/Job/HA/encryption-cpp/encrypt_for_python.so' (mach-o file, but is an incompatible architecture (have 'arm64', need 'x86_64')), '/usr/local/lib/encrypt_for_python.so' (no such file), '/usr/lib/encrypt_for_python.so' (no such file)
报错看起来有点复杂,但是,不难发现有一句很奇怪:(mach-o file, but is an incompatible architecture (have 'arm64', need 'x86_64')),大致意思是构架不兼容的问题。Python代码中使用到的动态库是在我 Mac 本地编译的,使用的指令集构架为 amd64 ,但是这里报错信息为什么提示说已有 amd64 而需要 x86_64 ?动态库确定是 amd64 构架,那么可能就是 Python 的问题。
接下来就要查看一下使用的 Python 是不是真如我们所想。
首先,查看在使用的 conda 环境中 Python 的情况,如下:
file $(which python3) /Users/debris/miniconda3/bin/python3: Mach-O 64-bit executable x86_64
再查看一下本地的情况:
file $(which python3) /opt/homebrew/bin/python3: Mach-O 64-bit executable arm64
果然,情况,其使用的指令集构架是不一样的。使用的动态库文件和使用的 Python 版本达到兼容状态,也就是对应的指令集构架一致,工作就不会有这种问题。也就是说,有两种解决方案,一是使用 x86_64 指令集构架的工具编译动态库,另一种则是使用 amd64 指令集构架的 Python。
知道了 conda 环境中的指令集构架与 Mac 本地的不同,那么,很容易联想到,之前出现的 Symbol not found: _PQbackendPID ,可能与这里也有关系。
重新安装 conda ,这次选择使用 amd64 对应版本,成功解决上述两个问题!✌️
为什么自己安装的 conda 环境中会是对应 x86_64 指令集构架的呢?似乎之前版本的 Mac (还在使用 Intel 芯片的时候),使用的就是这种构架,但是在之后使用 M1 芯片之后,经历了处理器的变革,就改为 amd64 指令集构架了,因此好多软件,给 Mac 用户提供两个版本。在我安装 conda 环境的时候,我并没有注意到这种情况。
那么,后续,如果类似情形出现构架不兼容的问题,解决方案应当也类似。



