Windows:安装 pg gem 失败 "Can't find the PostgreSQL client library (libpq)" 和 "undefined reference to `PQconnectdb'"

Windows: Installing pg gem fail with "Can't find the PostgreSQL client library (libpq)" and "undefined reference to `PQconnectdb'"

我在 Windows 10 上安装 pg gem 时遇到问题。

我环顾四周并能够解决第一组错误,但现在我遇到了如下所示的错误。

我找到的大多数答案都是针对 Linux 和 OSX,并且通常围绕安装 libpq-dev,我找不到 Windows。鉴于我已经克服了最初丢失的 libpq-fe.h 错误,我假设所需的开发文件已经包含在 Windows 安装程序中。

我已经尝试通过多种方式指定 folder/lib 位置,包括:

gem install pg -v '1.1' -- --with-pg-dir="C:\Program Files\PostgreSQL" --with-pq-dir="C:\Program Files\PostgreSQL"

gem install pg -v '1.1' -- --with-pg-config="C:\Program Files\PostgreSQL\bin\pg_config.exe"

但似乎都不起作用。有什么建议吗?

附加信息:

控制台输出

Temporarily enhancing PATH for MSYS/MINGW...
Building native extensions with: '--with-pg-config=C:\Program Files\PostgreSQL\bin\pg_config.exe'
This could take a while...
ERROR:  Error installing pg:
        ERROR: Failed to build gem native extension.

    current directory: C:/Ruby30/lib/ruby/gems/3.0.0/gems/pg-1.1.0/ext
C:/Ruby30/bin/ruby.exe -I C:/Ruby30/lib/ruby/3.0.0 -r ./siteconf20210424-18200-bi9e9l.rb extconf.rb --with-pg-config\=C:\Program\ Files\PostgreSQL\13\bin\pg_config.exe
Using config values from C:\Program Files\PostgreSQL\bin\pg_config.exe
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)
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

mkmf.log

"i686-w64-mingw32-gcc -o conftest.exe -IC:/Ruby30/include/ruby-3.0.0/i386-mingw32 -IC:/Ruby30/include/ruby-3.0.0/ruby/backward -IC:/Ruby30/include/ruby-3.0.0 -I. -IC:/PROGRA~1/POSTGR~1/13/include -D__USE_MINGW_ANSI_STDIO=1 -DFD_SETSIZE=2048 -D_WIN32_WINNT=0x0600 -D__MINGW_USE_VC2005_COMPAT -D_FILE_OFFSET_BITS=64  -O3 -fno-fast-math -fstack-protector-strong conftest.c  -L. -LC:/Ruby30/lib -LC:/PROGRA~1/POSTGR~1/13/lib -L. -pipe -s -fstack-protector-strong     -lmsvcrt-ruby300  -lshell32 -lws2_32 -liphlpapi -limagehlp -lshlwapi  "
checked program was:
/* begin */
1: #include "ruby.h"
2: 
3: #include <winsock2.h>
4: #include <windows.h>
5: int main(int argc, char **argv)
6: {
7:   return !!argv[argc];
8: }
/* end */

"i686-w64-mingw32-gcc -o conftest.exe -IC:/Ruby30/include/ruby-3.0.0/i386-mingw32 -IC:/Ruby30/include/ruby-3.0.0/ruby/backward -IC:/Ruby30/include/ruby-3.0.0 -I. -IC:/PROGRA~1/POSTGR~1/13/include -D__USE_MINGW_ANSI_STDIO=1 -DFD_SETSIZE=2048 -D_WIN32_WINNT=0x0600 -D__MINGW_USE_VC2005_COMPAT -D_FILE_OFFSET_BITS=64  -O3 -fno-fast-math -fstack-protector-strong conftest.c  -L. -LC:/Ruby30/lib -LC:/PROGRA~1/POSTGR~1/13/lib -L. -pipe -s -fstack-protector-strong     -lmsvcrt-ruby300  -Wl,-rpath,C:/PROGRA~1/POSTGR~1/13/lib -lshell32 -lws2_32 -liphlpapi -limagehlp -lshlwapi  "
checked program was:
/* begin */
1: #include "ruby.h"
2: 
3: #include <winsock2.h>
4: #include <windows.h>
5: int main() {return 0;}
/* end */

find_header: checking for libpq-fe.h... -------------------- yes

"i686-w64-mingw32-gcc -E -IC:/Ruby30/include/ruby-3.0.0/i386-mingw32 -IC:/Ruby30/include/ruby-3.0.0/ruby/backward -IC:/Ruby30/include/ruby-3.0.0 -I. -IC:/PROGRA~1/POSTGR~1/13/include -D__USE_MINGW_ANSI_STDIO=1 -DFD_SETSIZE=2048 -D_WIN32_WINNT=0x0600 -D__MINGW_USE_VC2005_COMPAT -D_FILE_OFFSET_BITS=64  -O3 -fno-fast-math -fstack-protector-strong  conftest.c -o conftest.i"
checked program was:
/* begin */
1: #include "ruby.h"
2: 
3: #include <winsock2.h>
4: #include <windows.h>
5: #include <libpq-fe.h>
/* end */

--------------------

find_header: checking for libpq/libpq-fs.h... -------------------- yes

"i686-w64-mingw32-gcc -E -IC:/Ruby30/include/ruby-3.0.0/i386-mingw32 -IC:/Ruby30/include/ruby-3.0.0/ruby/backward -IC:/Ruby30/include/ruby-3.0.0 -I. -IC:/PROGRA~1/POSTGR~1/13/include -D__USE_MINGW_ANSI_STDIO=1 -DFD_SETSIZE=2048 -D_WIN32_WINNT=0x0600 -D__MINGW_USE_VC2005_COMPAT -D_FILE_OFFSET_BITS=64  -O3 -fno-fast-math -fstack-protector-strong  conftest.c -o conftest.i"
checked program was:
/* begin */
1: #include "ruby.h"
2: 
3: #include <winsock2.h>
4: #include <windows.h>
5: #include <libpq/libpq-fs.h>
/* end */

--------------------

find_header: checking for pg_config_manual.h... -------------------- yes

"i686-w64-mingw32-gcc -E -IC:/Ruby30/include/ruby-3.0.0/i386-mingw32 -IC:/Ruby30/include/ruby-3.0.0/ruby/backward -IC:/Ruby30/include/ruby-3.0.0 -I. -IC:/PROGRA~1/POSTGR~1/13/include -D__USE_MINGW_ANSI_STDIO=1 -DFD_SETSIZE=2048 -D_WIN32_WINNT=0x0600 -D__MINGW_USE_VC2005_COMPAT -D_FILE_OFFSET_BITS=64  -O3 -fno-fast-math -fstack-protector-strong  conftest.c -o conftest.i"
checked program was:
/* begin */
1: #include "ruby.h"
2: 
3: #include <winsock2.h>
4: #include <windows.h>
5: #include <pg_config_manual.h>
/* end */

--------------------

have_library: checking for PQconnectdb() in -lpq... -------------------- no

"i686-w64-mingw32-gcc -o conftest.exe -IC:/Ruby30/include/ruby-3.0.0/i386-mingw32 -IC:/Ruby30/include/ruby-3.0.0/ruby/backward -IC:/Ruby30/include/ruby-3.0.0 -I. -IC:/PROGRA~1/POSTGR~1/13/include -D__USE_MINGW_ANSI_STDIO=1 -DFD_SETSIZE=2048 -D_WIN32_WINNT=0x0600 -D__MINGW_USE_VC2005_COMPAT -D_FILE_OFFSET_BITS=64  -O3 -fno-fast-math -fstack-protector-strong conftest.c  -L. -LC:/Ruby30/lib -LC:/PROGRA~1/POSTGR~1/13/lib -L. -pipe -s -fstack-protector-strong -Wl,-rpath,C:/PROGRA~1/POSTGR~1/13/lib     -lmsvcrt-ruby300 -lpq  -lshell32 -lws2_32 -liphlpapi -limagehlp -lshlwapi  "
C:/Ruby30/msys32/mingw32/bin/../lib/gcc/i686-w64-mingw32/10.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:\Users\crist\AppData\Local\Temp\cch5p7v1.o:conftest.c:(.text+0x7): undefined reference to `PQconnectdb'
collect2.exe: error: ld returned 1 exit status
checked program was:
/* begin */
 1: #include "ruby.h"
 2: 
 3: #include <winsock2.h>
 4: #include <windows.h>
 5: #include <libpq-fe.h>
 6: 
 7: /*top*/
 8: extern int t(void);
 9: int main(int argc, char **argv)
10: {
11:   if (argc > 1000000) {
12:     int (* volatile tp)(void)=(int (*)(void))&t;
13:     printf("%d", (*tp)());
14:   }
15: 
16:   return !!argv[argc];
17: }
18: int t(void) { void ((*volatile p)()); p = (void ((*)()))PQconnectdb; return !p; }
/* end */

"i686-w64-mingw32-gcc -o conftest.exe -IC:/Ruby30/include/ruby-3.0.0/i386-mingw32 -IC:/Ruby30/include/ruby-3.0.0/ruby/backward -IC:/Ruby30/include/ruby-3.0.0 -I. -IC:/PROGRA~1/POSTGR~1/13/include -D__USE_MINGW_ANSI_STDIO=1 -DFD_SETSIZE=2048 -D_WIN32_WINNT=0x0600 -D__MINGW_USE_VC2005_COMPAT -D_FILE_OFFSET_BITS=64  -O3 -fno-fast-math -fstack-protector-strong conftest.c  -L. -LC:/Ruby30/lib -LC:/PROGRA~1/POSTGR~1/13/lib -L. -pipe -s -fstack-protector-strong -Wl,-rpath,C:/PROGRA~1/POSTGR~1/13/lib     -lmsvcrt-ruby300 -lpq  -lshell32 -lws2_32 -liphlpapi -limagehlp -lshlwapi  "
conftest.c:18:13: error: conflicting types for 'PQconnectdb'
   18 | extern void PQconnectdb();
      |             ^~~~~~~~~~~
In file included from conftest.c:5:
C:/PROGRA~1/POSTGR~1/13/include/libpq-fe.h:264:16: note: previous declaration of 'PQconnectdb' was here
  264 | extern PGconn *PQconnectdb(const char *conninfo);
      |                ^~~~~~~~~~~
checked program was:
/* begin */
 1: #include "ruby.h"
 2: 
 3: #include <winsock2.h>
 4: #include <windows.h>
 5: #include <libpq-fe.h>
 6: 
 7: /*top*/
 8: extern int t(void);
 9: int main(int argc, char **argv)
10: {
11:   if (argc > 1000000) {
12:     int (* volatile tp)(void)=(int (*)(void))&t;
13:     printf("%d", (*tp)());
14:   }
15: 
16:   return !!argv[argc];
17: }
18: extern void PQconnectdb();
19: int t(void) { PQconnectdb(); return 0; }
/* end */

--------------------

have_library: checking for PQconnectdb() in -llibpq... -------------------- no

"i686-w64-mingw32-gcc -o conftest.exe -IC:/Ruby30/include/ruby-3.0.0/i386-mingw32 -IC:/Ruby30/include/ruby-3.0.0/ruby/backward -IC:/Ruby30/include/ruby-3.0.0 -I. -IC:/PROGRA~1/POSTGR~1/13/include -D__USE_MINGW_ANSI_STDIO=1 -DFD_SETSIZE=2048 -D_WIN32_WINNT=0x0600 -D__MINGW_USE_VC2005_COMPAT -D_FILE_OFFSET_BITS=64  -O3 -fno-fast-math -fstack-protector-strong conftest.c  -L. -LC:/Ruby30/lib -LC:/PROGRA~1/POSTGR~1/13/lib -L. -pipe -s -fstack-protector-strong -Wl,-rpath,C:/PROGRA~1/POSTGR~1/13/lib     -lmsvcrt-ruby300 -llibpq  -lshell32 -lws2_32 -liphlpapi -limagehlp -lshlwapi  "
C:/Ruby30/msys32/mingw32/bin/../lib/gcc/i686-w64-mingw32/10.2.0/../../../../i686-w64-mingw32/bin/ld.exe: C:\Users\crist\AppData\Local\Temp\cc4PD9EV.o:conftest.c:(.text+0x7): undefined reference to `PQconnectdb'
collect2.exe: error: ld returned 1 exit status
checked program was:
/* begin */
 1: #include "ruby.h"
 2: 
 3: #include <winsock2.h>
 4: #include <windows.h>
 5: #include <libpq-fe.h>
 6: 
 7: /*top*/
 8: extern int t(void);
 9: int main(int argc, char **argv)
10: {
11:   if (argc > 1000000) {
12:     int (* volatile tp)(void)=(int (*)(void))&t;
13:     printf("%d", (*tp)());
14:   }
15: 
16:   return !!argv[argc];
17: }
18: int t(void) { void ((*volatile p)()); p = (void ((*)()))PQconnectdb; return !p; }
/* end */

"i686-w64-mingw32-gcc -o conftest.exe -IC:/Ruby30/include/ruby-3.0.0/i386-mingw32 -IC:/Ruby30/include/ruby-3.0.0/ruby/backward -IC:/Ruby30/include/ruby-3.0.0 -I. -IC:/PROGRA~1/POSTGR~1/13/include -D__USE_MINGW_ANSI_STDIO=1 -DFD_SETSIZE=2048 -D_WIN32_WINNT=0x0600 -D__MINGW_USE_VC2005_COMPAT -D_FILE_OFFSET_BITS=64  -O3 -fno-fast-math -fstack-protector-strong conftest.c  -L. -LC:/Ruby30/lib -LC:/PROGRA~1/POSTGR~1/13/lib -L. -pipe -s -fstack-protector-strong -Wl,-rpath,C:/PROGRA~1/POSTGR~1/13/lib     -lmsvcrt-ruby300 -llibpq  -lshell32 -lws2_32 -liphlpapi -limagehlp -lshlwapi  "
conftest.c:18:13: error: conflicting types for 'PQconnectdb'
   18 | extern void PQconnectdb();
      |             ^~~~~~~~~~~
In file included from conftest.c:5:
C:/PROGRA~1/POSTGR~1/13/include/libpq-fe.h:264:16: note: previous declaration of 'PQconnectdb' was here
  264 | extern PGconn *PQconnectdb(const char *conninfo);
      |                ^~~~~~~~~~~
checked program was:
/* begin */
 1: #include "ruby.h"
 2: 
 3: #include <winsock2.h>
 4: #include <windows.h>
 5: #include <libpq-fe.h>
 6: 
 7: /*top*/
 8: extern int t(void);
 9: int main(int argc, char **argv)
10: {
11:   if (argc > 1000000) {
12:     int (* volatile tp)(void)=(int (*)(void))&t;
13:     printf("%d", (*tp)());
14:   }
15: 
16:   return !!argv[argc];
17: }
18: extern void PQconnectdb();
19: int t(void) { PQconnectdb(); return 0; }
/* end */

--------------------

have_library: checking for PQconnectdb() in -lms/libpq... -------------------- no

"i686-w64-mingw32-gcc -o conftest.exe -IC:/Ruby30/include/ruby-3.0.0/i386-mingw32 -IC:/Ruby30/include/ruby-3.0.0/ruby/backward -IC:/Ruby30/include/ruby-3.0.0 -I. -IC:/PROGRA~1/POSTGR~1/13/include -D__USE_MINGW_ANSI_STDIO=1 -DFD_SETSIZE=2048 -D_WIN32_WINNT=0x0600 -D__MINGW_USE_VC2005_COMPAT -D_FILE_OFFSET_BITS=64  -O3 -fno-fast-math -fstack-protector-strong conftest.c  -L. -LC:/Ruby30/lib -LC:/PROGRA~1/POSTGR~1/13/lib -L. -pipe -s -fstack-protector-strong -Wl,-rpath,C:/PROGRA~1/POSTGR~1/13/lib     -lmsvcrt-ruby300 -lms/libpq  -lshell32 -lws2_32 -liphlpapi -limagehlp -lshlwapi  "
C:/Ruby30/msys32/mingw32/bin/../lib/gcc/i686-w64-mingw32/10.2.0/../../../../i686-w64-mingw32/bin/ld.exe: cannot find -lms/libpq
collect2.exe: error: ld returned 1 exit status
checked program was:
/* begin */
 1: #include "ruby.h"
 2: 
 3: #include <winsock2.h>
 4: #include <windows.h>
 5: #include <libpq-fe.h>
 6: 
 7: /*top*/
 8: extern int t(void);
 9: int main(int argc, char **argv)
10: {
11:   if (argc > 1000000) {
12:     int (* volatile tp)(void)=(int (*)(void))&t;
13:     printf("%d", (*tp)());
14:   }
15: 
16:   return !!argv[argc];
17: }
18: int t(void) { void ((*volatile p)()); p = (void ((*)()))PQconnectdb; return !p; }
/* end */

"i686-w64-mingw32-gcc -o conftest.exe -IC:/Ruby30/include/ruby-3.0.0/i386-mingw32 -IC:/Ruby30/include/ruby-3.0.0/ruby/backward -IC:/Ruby30/include/ruby-3.0.0 -I. -IC:/PROGRA~1/POSTGR~1/13/include -D__USE_MINGW_ANSI_STDIO=1 -DFD_SETSIZE=2048 -D_WIN32_WINNT=0x0600 -D__MINGW_USE_VC2005_COMPAT -D_FILE_OFFSET_BITS=64  -O3 -fno-fast-math -fstack-protector-strong conftest.c  -L. -LC:/Ruby30/lib -LC:/PROGRA~1/POSTGR~1/13/lib -L. -pipe -s -fstack-protector-strong -Wl,-rpath,C:/PROGRA~1/POSTGR~1/13/lib     -lmsvcrt-ruby300 -lms/libpq  -lshell32 -lws2_32 -liphlpapi -limagehlp -lshlwapi  "
conftest.c:18:13: error: conflicting types for 'PQconnectdb'
   18 | extern void PQconnectdb();
      |             ^~~~~~~~~~~
In file included from conftest.c:5:
C:/PROGRA~1/POSTGR~1/13/include/libpq-fe.h:264:16: note: previous declaration of 'PQconnectdb' was here
  264 | extern PGconn *PQconnectdb(const char *conninfo);
      |                ^~~~~~~~~~~
checked program was:
/* begin */
 1: #include "ruby.h"
 2: 
 3: #include <winsock2.h>
 4: #include <windows.h>
 5: #include <libpq-fe.h>
 6: 
 7: /*top*/
 8: extern int t(void);
 9: int main(int argc, char **argv)
10: {
11:   if (argc > 1000000) {
12:     int (* volatile tp)(void)=(int (*)(void))&t;
13:     printf("%d", (*tp)());
14:   }
15: 
16:   return !!argv[argc];
17: }
18: extern void PQconnectdb();
19: int t(void) { PQconnectdb(); return 0; }
/* end */

--------------------

这个问题显然是因为我使用的是 Ruby 的 32 位版本。安装了 64 位,问题解决了。