pg gem 在 M1 mac 上安装失败:“错误:‘PQconnectdb’的类型冲突”

Nat*_*han 0 homebrew libpq bundler pg apple-m1

pg我正在M1 macbook pro 上的 mac osx 12.5 上安装gem。Ruby 打包程序在运行时找不到 libpq gem install pg

current directory: /Users/me/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/pg-1.4.4/ext
/Users/me/.rbenv/versions/3.1.2/bin/ruby -I /Users/me/.rbenv/versions/3.1.2/lib/ruby/site_ruby/3.1.0 extconf.rb
Calling libpq with GVL unlocked
checking for pg_config... yes
Using config values from /opt/homebrew/opt/libpq/bin/pg_config
checking for whether -Wl,-rpath,/opt/homebrew/opt/libpq/lib is accepted as LDFLAGS... yes
Using libpq from /opt/homebrew/opt/libpq/lib
checking for libpq-fe.h... yes
checking for libpq/libpq-fs.h... yes
checking for pg_config_manual.h... yes
checking for PQconnectdb() in -lpq... no
checking for PQconnectdb() in -llibpq... no
checking for PQconnectdb() in -lms/libpq... no
Can't find the PostgreSQL client library (libpq)
*****************************************************************************

Unable to find PostgreSQL client library.

Please install libpq or postgresql client package like so:
  brew install libpq

or try again with:
  gem install pg -- --with-pg-config=/path/to/pg_config

or set library paths manually with:
  gem install pg -- --with-pg-include=/path/to/libpq-fe.h/ --with-pg-lib=/path/to/libpq.so/

...

To see why this extension failed to compile, please check the mkmf.log which can be found here:

  /Users/me/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/extensions/x86_64-darwin-21/3.1.0/pg-1.4.4/mkmf.log
Run Code Online (Sandbox Code Playgroud)

mkmf.log 显示的内容如下:

conftest.c:16:13: error: conflicting types for 'PQconnectdb'
extern void PQconnectdb();
            ^
/opt/homebrew/include/postgresql@14/libpq-fe.h:285:16: note: previous declaration is here
extern PGconn *PQconnectdb(const char *conninfo);
               ^
conftest.c:17:27: error: too few arguments to function call, single argument 'conninfo' was not specified
int t(void) { PQconnectdb(); return 0; }
              ~~~~~~~~~~~ ^
/opt/homebrew/include/postgresql@14/libpq-fe.h:285:16: note: 'PQconnectdb' declared here
extern PGconn *PQconnectdb(const char *conninfo);
Run Code Online (Sandbox Code Playgroud)

我已经按照建议使用 homebrew 安装了 libpq:

Warning: libpq 15.1 is already installed and up-to-date.
Run Code Online (Sandbox Code Playgroud)

有趣的是,我也尝试过gem install pg -- --with-pg-include=/opt/homebrew/opt/libpq/include/libpq-fe.h/,但我找不到libpq.so关于自制程序安装的信息。

有什么建议么?自制程序安装 libpq 是否可能遗漏了所需的.so文件?x86_64-darwin-21当我在M1 mac上运行时,是否怀疑日志文件位于某个目录下?是否error: conflicting types for 'PQconnectdb'暗示我的 libpq 版本与 pg gem 不兼容?

小智 5

gempg用于pg_config配置自身。如果gem发现错误的版本pg_config,它会配置错误,导致你提到的错误。

/opt/homebrew在 ARM Mac 上,Homebrew 将自身安装到与在 Intel Mac 上不同的位置 ( ) /usr/local。但是,如果您使用 Apple 的迁移助手,则最终可能会出现两个 Homebrew 实例,这可能会在编译 gem 时造成混乱。

首先,确保您的 Ruby 是 arm64:

$ ruby -v
ruby 3.1.3p185 (2022-11-24 revision 1a6b16756e) [arm64-darwin22]
Run Code Online (Sandbox Code Playgroud)

它应该显示arm64在接近尾声的地方。

接下来,查看 pg_config 来自哪里:

$ which pg_config
/usr/local/bin/pg_config      <- Intel version
/opt/homebrew/bin/pg_config   <- ARM version
Run Code Online (Sandbox Code Playgroud)

它将显示这两个之一(或不显示)。我们正在寻找第二条线(ARM)。

如果没有,则postgresql可能未安装(或未找到)。

如果它显示第一个,则编译正在查找pg_config. 这是我从 Intel Mac 迁移到 ARM Mac 后的情况。

这种混淆部分是可能的,因为pg_config它来自postgresql包,而不是libpq. 因此,您还需要安装arm64版本postgresql

如果您安装无版本控制(即:最新)的 postgresql,这可能就是您所需要的:

$ brew install postgresql
Run Code Online (Sandbox Code Playgroud)

如果您总是安装特定版本(就像我一样),那么您还需要“链接”以便pg_config正确可用。

$ brew install postgresql@15
$ brew link postgresql@15
Run Code Online (Sandbox Code Playgroud)

只要这是您安装的 postgresql 的唯一版本(在 Homebrew 的 ARM 副本中),使用 link 命令通常是安全的。

提示1:将来升级Postgres版本时,您可能需要先取消旧版本的链接,然后再链接新版本。

提示 2:如果您的 Postgres 的 Intel 版本仍在旧版 Homebrew 上运行,则您可能必须在两者之间迁移数据或解决其他一些冲突。这超出了这里的范围,所以请注意。

此时您将有望看到正确的pg_config

$ which pg_config
/opt/homebrew/bin/pg_config   <- ARM version
Run Code Online (Sandbox Code Playgroud)

如果没有,还要检查您的PATH外壳程序设置。重要的是/opt/homebrew/bin之前的事情/usr/local/bin

$ echo $PATH
Run Code Online (Sandbox Code Playgroud)

修复它取决于您选择的 shell,因此我将在这里跳过它。

希望如此。

请注意,我没有使用--with-pg-config. 虽然使用它可能允许跳过上面的一两个步骤,但pg_config正确检测也有助于提高其他 gem 将来正确编译并且不需要持续解决方法的可能性。