Martin Moore
Martin Moore

Reputation: 733

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

Upvotes: 1

Views: 3449

Answers (1)

Stephan Schlecht
Stephan Schlecht

Reputation: 27106

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

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.

Upvotes: 2

Related Questions