jtv / libpqxx

The official C++ client API for PostgreSQL.
http://pqxx.org/libpqxx/
BSD 3-Clause "New" or "Revised" License
1.05k stars 243 forks source link

Link libpqxx in Cmake #383

Closed noctera closed 4 years ago

noctera commented 4 years ago

How can I link libpqxx in Cmake? I have installed it with sudo pacman -S libpqxx and want to use the lib in my code now. But i don't how to do this in cmake. Could someone provide me a little code snippet?

tt4g commented 4 years ago

CMake will automatically detect installed PostgreSQL, but most package managers such as pacman will not automatically detect the location of the installation.

The workaround is to specify the PostgreSQL installation path when you run CMake. Try setting the PostgreSQL_ROOT variable.

Example:

$ cmake -DPostgreSQL_ROOT:PATH="<PATH_TO_LIBPQ>" (other argments ...)

<PATH_TO_LIBPQ> is your libpq path, and it should have an include and bin directory directly underneath it.

noctera commented 4 years ago

Thanks for your response :) Do i only have to include Libpq or do I also have to include libpqxx?

tt4g commented 4 years ago

Oh, I made a mistake between libpq and libpqxx. Try setting LIBPQXX_ROOT along withPostgreSQL_ROOT. CMake should then be able to detect both libraries.

noctera commented 4 years ago

I tried linking them in my Cmakelist directly not over the terminal arguments

target_link_libraries(Vocascan-server LINK_PUBLIC postgresql)
target_link_libraries(Vocascan-server LINK_PUBLIC libpqxx)

But this gives me the error of not being able to find them. I don´t know how to define the path of them

tt4g commented 4 years ago

Are you using find_package? The find_package refers to the <PackageName>_ROOT variable to find the library: https://cmake.org/cmake/help/v3.18/command/find_package.html

find_package(PostgreSQL REQUIRED)
find_package(libpqxx REQUIRED)

target_link_libraries(Vocascan-server LINK_PUBLIC postgresql)
target_link_libraries(Vocascan-server LINK_PUBLIC libpqxx)
noctera commented 4 years ago

Unfortunately this didn´t resolve the problem, because it is now looking for a libpqxx-config.cmake

tt4g commented 4 years ago

If libpqxx has been installed by CMake, libpqxx-config.cmake will be installed as well. Does pacman exclude libpqxx-config.cmake from the installation?

noctera commented 4 years ago

I dont think so. You think i should build it myself?

tt4g commented 4 years ago

The libpqxx-config.cmake provides information for CMake to automatically add libpqxx and dependency libraries to the application. If there is no libpqxx-config.cmake, you will have to add the library path and dependent libraries to the link target by yourself.

You can specify libpqxx's library path and include path by hand without using find_pacakge().

Example:

set(LIBPQXX_LIBRARIES "/path/to/libpqxx/lib/libpqxx.so") # Change .so to your library extension.
set(LIBPQXX_INCLUDE_DIRS "/path/to/libpqxx/include")

find_package(PostgreSQL REQUIRED)

target_link_libraries(Vocascan-server LINK_PUBLIC postgresql)
target_link_libraries(Vocascan-server PUBLIC "${LIBPQXX_LIBRARIES }")
target_include_directories(Vocascan-server PUBLIC "${LIBPQXX_INCLUDE_DIRS }")

However, other libraries that were dependent on libpqxx when it was built must also be added to the dependencies. For other dependent libraries, ask questions on the pacman forums.

You think i should build it myself?

If you install libpqxx using CMake, libpqxx-config.cmake will solve all the dependent libraries.

noctera commented 4 years ago

Thanks for your effort, but somehow this didn´t work either. But I think I got a solution. I only added

target_link_libraries(Vocascan-server LINK_PUBLIC pqxx)

to my CMakeList and it seems to work. Ok it gives me an Error, because the database I´m calling doesn´t exist yet, but that is crucial that it works now. But thank you again for your help :)

tt4g commented 4 years ago

I don't know why, but I'm glad to hear the problem has been resolved.

srinathv2 commented 8 months ago

hi @tt4g,i am getting linking issues when trying to link libpq with my pg extension and i am using pg's libpq ,so libpq is built along with pg,so i did this in my extension's cmakelists.txt file (GLOB storage_SRC CONFIGURE_DEPENDS "*.cpp" ) add_library(storage OBJECT ${storage_SRC}) target_link_libraries(storage PRIVATE pq) btw included all required include dirs in my toplevel cmakelists.txt then i got undefined symbol: pqsecure_write

but dont know why if i give the pg_config --libdir/libpq.a path then it compiles but walreceiver process cant start and i get FATAL: could not connect to the primary server: libpq is incorrectly linked to backend functions

tt4g commented 8 months ago

@srinathv2 Open an issue to ask a new question. This is because comments on closed issues may go unnoticed.

undefined symbol: pqsecure_write

pqsecure_write is a symbol of libpq. I assume that there is a problem, such as a difference between the version of the libpq header file that the project includes and the version of the built .so file.

FATAL: could not connect to the primary server: libpq is incorrectly linked to backend functions

It appears that libpq reports this error when it detects an incorrect link. See: https://github.com/postgres/postgres/blob/REL_16_2/src/interfaces/libpq/fe-connect.c#L2345-L2356

Your question is not about libpqxx, but about libpq and CMake. You should ask on Stack Overflow or similar.

srinathv2 commented 8 months ago

@tt4g thanks for response,just wanted some help in linking libpq,so thought to check how libpqxx is linking libpq,so i was going throught the https://github.com/jtv/libpqxx/blob/master/BUILDING-configure.md#finding-libpq and thought here also we are including the required libpq header and giving the libpq binary location which i did in my pg extension using cmake

tt4g commented 8 months ago

@srinathv2 libpqxx requires libpq, but it is your responsibility to provide a built libpq.

srinathv2 commented 8 months ago

@tt4g yeah ,i was checking how libpqxx is actually linking libpq,as far as i saw the configure.ac first it relies on pkg-config to get the includes,binaries of libpq if not uses pg_config --includedir,--libdir which i am doing the same in my cmake

tt4g commented 8 months ago

@srinathv2 Using pg_config to get the libpq library and header file paths is not the crux of the problem. The problem is that the header file symbols retrieved from it are incompatible with the library file symbols. If the library file is corrupt, repair it.

And, the incompatibility of the libpq header files and libraries is not a problem caused by libpqxx. It is a problem caused by libpq management on your machine.

srinathv2 commented 8 months ago

@tt4g got it but i am building postgres from source code and i am using pg's libpq which is built along pg not installing packages like libpq-dev ,so i dont think its incompatibility of the libpq header files and libraries

srinathv2 commented 8 months ago

@tt4g and i am not at all saying as this is libpqxx issue :smile: ,just going through code and learning stuff.

tt4g commented 8 months ago

@srinathv2

just going through code and learning stuff.

Then open a new issue and ask a question. Since this issue deals with the problem of not being able to link libpq with libpqxx, it is assumed that you have the same problem when you comment here.

srinathv2 commented 8 months ago

I don't know why, but I'm glad to hear the problem has been resolved.

@tt4g cmake will take the given lib name and it changes to "-l{libname}" and linker will search using "-l{libname}"

tt4g commented 8 months ago

cmake will take the given lib name and it changes to "-l{libname}" and linker will search using "-l{libname}"

@srinathv2 No. CMake checks if a string and the matching CMake target are defined. If a CMake target is found, it adds the necessary linker flags to use that target. If the target is not found, the name is treated as a link target.

See:

tt4g commented 8 months ago

@srinathv2 I will not check this issue in the future. You should not comment on a closed issue, you should open a new one. And your question is related to CMake and make, not libpqxx.