c++postgresqlcmakelibpqlibpqxx

Linker fails when using libpqxx with CMake


I'm trying to build a simple C++ program with libpqxx using CMake. But the linker fails on both Linux and macOS. It cannot identify C++-related headers and libraries, whereas C files related to libpq are found with the provided find_package() and target_link_libraries(). As a proof of successful installation, main.cpp can be compiled and run with clang++ main.cpp -o main -lpqxx -lpq.

Ninja output on macOS:

[2/2] Linking CXX executable main
FAILED: main 
: && /Library/Developer/CommandLineTools/usr/bin/c++ -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk -mmacosx-version-min=12.6 -Wl,-search_paths_first -Wl,-headerpad_max_install_names  CMakeFiles/main.dir/src/main.cpp.o -o main  /usr/local/lib/libpq.dylib && :
Undefined symbols for architecture x86_64:
  "pqxx::connection::init(char const*)", referenced from:
      pqxx::connection::connection(char const*) in main.cpp.o
  "pqxx::connection::close()", referenced from:
      pqxx::connection::~connection() in main.cpp.o
  "pqxx::internal::demangle_type_name(char const*)", referenced from:
      ___cxx_global_var_init in main.cpp.o
      ___cxx_global_var_init.2 in main.cpp.o
      ___cxx_global_var_init.3 in main.cpp.o
      ___cxx_global_var_init.4 in main.cpp.o
  "pqxx::internal::check_pqxx_version_7_8()", referenced from:
      pqxx::check_version() in main.cpp.o
  "pqxx::connection::dbname() const", referenced from:
      _main in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.

CMakeLists.txt

cmake_minimum_required(VERSION 3.25)
project(main VERSION 0.1 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(PROJECT_SOURCES 
    src/main.cpp)

add_executable(main ${PROJECT_SOURCES})

find_package(PostgreSQL REQUIRED)

target_link_libraries(main PRIVATE PostgreSQL::PostgreSQL)

main.cpp

#include <iostream>
#include <pqxx/pqxx>

int main(int argc, const char *argv[])
{
    pqxx::connection c;

    std::cout << "Connected to " << c.dbname() << ".\n";

    return 0;
}

A similar CMakeLists.txt file for C works fine.

main.c

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

int main(int argc, const char *argv[])
{
    int lib_ver = PQlibVersion();

    printf("Version of libpq: %d\n", lib_ver);

    return 0;
}

Intel-based Mac
macOS 12.6.8
PostgreSQL, libpq, libpqxx from Homebrew

Ubuntu 22.04
PostgreSQL, libpq-dev from apt
libpqxx built from source and installed to /usr/local


Solution

  • libpqxx-dev provides libpqxx.pc for pkg-config that is well integrated with CMake. Add to your CMakeLists.txt:

    find_package(PkgConfig REQUIRED)
    
    pkg_check_modules(PQXX REQUIRED libpqxx)
    
    target_link_libraries(main PRIVATE ${PQXX_LINK_LIBRARIES} PostgreSQL::PostgreSQL)