简体   繁体   中英

undefined reference to `PQclear' compiling simple 'C' program with Postgres 10 calls

Simple C prog that compiles and runs on Debian Linux. I need to get it running on Windows, but get the following when I compile it. It seems to be a common problem but I haven't yet found a solution.

If I use

#include <libpq-fe.h>

I get

C:\Users\Martin\Desktop\cl>gcc -o test2 test2.c
test2.c:3:22: fatal error: libpq-fe.h: No such file or directory
 #include <libpq-fe.h>

If I use

#include "C:\Program Files\PostgreSQL\10\include\libpq-fe.h"

I get

C:\Users\Martin\Desktop\cl>gcc -o test2 test2.c
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0xd): undefined reference to `PQclear'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0x18): undefined reference to `PQfinish'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0x46): undefined reference to `PQconnectdb'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0x56): undefined reference to `PQstatus'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0x66): undefined reference to `PQerrorMessage'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0x8e): undefined reference to `PQfinish'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0xae): undefined reference to `PQexec'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0xbe): undefined reference to `PQresultStatus'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0xcf): undefined reference to `PQerrorMessage'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0x10b): undefined reference to `PQclear'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0x11f): undefined reference to `PQexec'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0x12f): undefined reference to `PQresultStatus'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0x140): undefined reference to `PQerrorMessage'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0x17c): undefined reference to `PQclear'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0x190): undefined reference to `PQexec'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0x1a0): undefined reference to `PQresultStatus'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0x1b1): undefined reference to `PQerrorMessage'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0x1ed): undefined reference to `PQnfields'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0x20f): undefined reference to `PQfname'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0x26a): undefined reference to `PQgetvalue'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0x2a6): undefined reference to `PQntuples'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0x2b8): undefined reference to `PQclear'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0x2cc): undefined reference to `PQexec'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0x2dc): undefined reference to `PQclear'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0x2f0): undefined reference to `PQexec'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0x300): undefined reference to `PQclear'
C:\Users\Martin\AppData\Local\Temp\cclMue3l.o:test2.c:(.text+0x30c): undefined reference to `PQfinish'
collect2.exe: error: ld returned 1 exit status

Here a simple program that additionally to including the header file also queries a table test in a schema test which has two fields firstname and lastname . This makes sure that not only the include file is found but also the linker finds the additional libraries:

Simple test program

#include <libpq-fe.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
    int lib_ver = PQlibVersion();
    printf("PQlibVersion: %d\n", lib_ver);

    PGconn *conn = PQconnectdb("user=stephan password=mypwd dbname=postgres");
    if (PQstatus(conn) == CONNECTION_BAD) {        
        fprintf(stderr, "Can't connect to Postgres: %s\n", PQerrorMessage(conn));
        PQfinish(conn);
        exit(-1);
    }

    PGresult *res = PQexec(conn, "SELECT * FROM test.test");    
    if (PQresultStatus(res) == PGRES_TUPLES_OK) {
        printf("\n     %-10s %-10s\n", PQfname(res, 0), PQfname(res, 1));
        printf("-------------------------\n");
        int rows = PQntuples(res);    
        for(int i=0; i<rows; i++) {       
            printf("[%d]: %-10s %-10s\n", i, PQgetvalue(res, i, 0), PQgetvalue(res, i, 1));
        }   
    }       
    PQclear(res);
    PQfinish(conn);
    return 0;
}

Build

This can be build by the following command line:

gcc -Wall -Wextra -I "C:\PostgreSQL\pg10\include" -L "C:\PostgreSQL\pg10\lib" query.c -lpq -o query

Output of test run

测试运行的输出

Explanation of compiler arguments

+--------------+----------------------------------------------------------------------+
|    argumet   |                meaning                                               |
+--------------+----------------------------------------------------------------------+
|   -Wall      |  switches on many warnigs                                            |
|   -Wextra    |  switches on additional warnings like unused parameters              |
|   -I _xxx_   |  searches for additional include files in the directory _xxx_                   |
|   -L _yyy_   |  looks in directory _yyy_ for additional libraries                   |
|   -l_zz_     |  links library _zz_                                                  |
|   -o _name_  |  the resulting program is called _name_.exe instead of a.exe         |
+--------------+----------------------------------------------------------------------+

Order of libraries

The order is important when linking against libraries. To avoid undefined reference errors, the -lpq argument should come after the .c source files.

How to find include and lib directories?

The following commands are printing out the include and lib directory for Postgres:

pg_config --includedir
pg_config --libdir

Alternatively use Window File Explorer, navigate to the installation directory of Postgres and search for the include and lib directories.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM