jlakes85
jlakes85

Reputation: 57

Cmake C++ libpqxx library find_package() find_library() issues

I'm working through Swidzinzki's "Modern CMake for C++" book. These issues stem from the "04-find-package-custom" example in chapter 7. The github link is https://github.com/PacktPublishing/Modern-CMake-for-Cpp/tree/main/examples/chapter07/04-find-package-custom

here is my top level CMakeLists.txt file, with added messages for debugging:

    cmake_minimum_required(VERSION 3.20.0)
    project(FindPackageCustom CXX)
    set(CMAKE_CXX_STANDARD 20)

    list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/module/") 
    #list(APPEND CMAKE_MODULE_PATH "C:/Users/jsudo/Desktop/ModernCMake/chap07/04-find- 
    package-custom/cmake/module") works as well
    message("cmake source directory: ${CMAKE_SOURCE_DIR}")
    message("cmake module path: ${CMAKE_MODULE_PATH}")
    message("pqxx library path: ${PQXX_LIBRARY_PATH}")
    message("cmake install prefix: ${CMAKE_INSTALL_PREFIX}")
    message("cmake library architecture: ${CMAKE_LIBRARY_ARCHITECTURE}")
    message("pqxx dir: ${_PQXX_DIR}")
    #set(ENV{POSTGRES_LIBRARY_PATH} "C:/Vcpkg/install/vcpkg/packages/libpqxx_x64- 
    windows/lib/")
    #message("postgres library path: ${POSTGRES_LIBRARY_PATH}")
    #set(ENV{PKG_CONFIG_PATH} "C:/Vcpkg/install/vcpkg/packages/libpqxx_x64- 
    windows/lib/pkgconfig")
    message("pkgconfig path: ${PKG_CONFIG_PATH}")
    message("lipqxx_LIBRARIES=${lipqxx_LIBRARIES}")
    #set(ENV{PQXX_HEADER_PATH} "C:/Vcpkg/install/vcpkg/packages/libpqxx_x64- 
    windows/include/pqxx")
    #set(ENV{PQXX_LIBRARY_PATH} "C:/Vcpkg/install/vcpkg/packages/libpqxx_x64-windows/lib")
    message("pqxx header path: ${PQXX_HEADER_PATH}")
    message("pqxx library path: ${PQXX_LIBRARY_PATH}")
    find_package(PQXX REQUIRED)
    message("FOUND: " ${PQXX_FOUND})
    message("pqxx library path: ${PQXX_LIBRARY_PATH}")
    #set(ENV{POSTGRES_LIBRARY_PATH} "C:/Vcpkg/install/vcpkg/packages/libpqxx_x64- 
    windows/lib/")
    #message("postgres library path: ${POSTGRES_LIBRARY_PATH}")
    message("pqxx header path: ${PQXX_HEADER_PATH}")
    add_executable(main main.cpp)
    target_link_libraries(main PRIVATE PQXX::PQXX)
    #target_link_libraries(main PRIVATE "C:/Vcpkg/install/vcpkg/packages/libpqxx_x64- 
    windows/lib/pqxx.lib")
    #target_link_directories(main PRIVATE "C:/Vcpkg/install/vcpkg/packages/libpqxx_x64- 
    windows/include/pqxx")

Here is the original CMakeLists.txt from the book repository:

cmake_minimum_required(VERSION 3.20.0)
project(FindPackageCustom CXX)

list(APPEND CMAKE_MODULE_PATH
            "${CMAKE_SOURCE_DIR}/cmake/module/")
find_package(PQXX REQUIRED)
message("FOUND: " ${PQXX_FOUND})
add_executable(main main.cpp)
target_link_libraries(main PRIVATE PQXX::PQXX)

Shown below is the FindPQXX.cmake file located in the .../cmake/module path of my visual studio 2022 project directory:

    function(add_imported_library library headers)
    add_library(PQXX::PQXX UNKNOWN IMPORTED)
    set_target_properties(PQXX::PQXX PROPERTIES
    IMPORTED_LOCATION ${library}
    INTERFACE_INCLUDE_DIRECTORIES ${headers}
    )
    set(PQXX_FOUND 1 CACHE INTERNAL "PQXX found" FORCE)
    set(PQXX_LIBRARIES ${library}
      CACHE STRING "Path to pqxx library" FORCE)
    set(PQXX_INCLUDES ${headers}
      CACHE STRING "Path to pqxx headers" FORCE)
    mark_as_advanced(FORCE PQXX_LIBRARIES)
    mark_as_advanced(FORCE PQXX_INCLUDES)
    endfunction()

    if (PQXX_LIBRARIES AND PQXX_INCLUDES)
    add_imported_library(${PQXX_LIBRARIES} ${PQXX_INCLUDES})
    return()
    endif()

    # deliberately used in FindModule against the documentation
    include(CMakeFindDependencyMacro)
    find_dependency(PostgreSQL)

    file(TO_CMAKE_PATH "$ENV{PQXX_DIR}" _PQXX_DIR)
    message("calling find_library()...")
    find_library(PQXX_LIBRARY_PATH NAMES libpqxx pqxx
    PATHS
    ${_PQXX_DIR}/lib/${CMAKE_LIBRARY_ARCHITECTURE}
    ${CMAKE_INSTALL_PREFIX}/lib/${CMAKE_LIBRARY_ARCHITECTURE}
    /usr/local/pgsql/lib/${CMAKE_LIBRARY_ARCHITECTURE}
    /usr/local/lib/${CMAKE_LIBRARY_ARCHITECTURE}
    /usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}
    ${_PQXX_DIR}/lib
    ${_PQXX_DIR}
    ${CMAKE_INSTALL_PREFIX}/lib
    ${CMAKE_INSTALL_PREFIX}/bin
    /usr/local/pgsql/lib
    /usr/local/lib
    /usr/lib
    NO_DEFAULT_PATH
    )
    message("finished calling find_library()")

    find_path(PQXX_HEADER_PATH NAMES pqxx/pqxx
    PATHS
    ${_PQXX_DIR}/include
    ${_PQXX_DIR}
    ${CMAKE_INSTALL_PREFIX}/include
    /usr/local/pgsql/include
    /usr/local/include
    /usr/include
    NO_DEFAULT_PATH
    )

    include(FindPackageHandleStandardArgs)
    find_package_handle_standard_args(
    PQXX DEFAULT_MSG PQXX_LIBRARY_PATH PQXX_HEADER_PATH
    )
    if (PQXX_FOUND)
    add_imported_library(
    "${PQXX_LIBRARY_PATH};${POSTGRES_LIBRARIES}"
    "${PQXX_HEADER_PATH};${POSTGRES_INCLUDE_DIRECTORIES}"
     )
     endif()

Here is the main.cpp file located in the top level of the project directory:

    #include <pqxx/pqxx>
    int main()
    {
        // We're not actually connecting, but
        // just proving that pqxx is available.
        pqxx::nullconnection connection;
    }

When I run "Delete Cache and Reconfigure" I receive the following error:

Severity Code Description File Project Line Suppression State Details Error CMake Error at C:/Program Files/Microsoft Visual Studio/2022/Professional/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/FindPackageHandleStandardArgs.cmake:230 (message): Could NOT find PQXX (missing: PQXX_LIBRARY_PATH PQXX_HEADER_PATH) C:/Program Files/Microsoft Visual Studio/2022/Professional/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/FindPackageHandleStandardArgs.cmake 230

Here is the truncated CMake output:

1> [CMake] cmake source directory: C:/Users/.../Desktop/ModernCMake/chap07/04-find-package-custom
1> [CMake] cmake module path: C:/Users/.../Desktop/ModernCMake/chap07/04-find-package-custom/cmake/module/
1> [CMake] pqxx library path: 
1> [CMake] cmake install prefix: C:/.../jsudo/Desktop/ModernCMake/chap07/04-find-package-custom/out/install/x64-debug
1> [CMake] cmake library architecture: 
1> [CMake] pqxx dir: 
1> [CMake] pkgconfig path: 
1> [CMake] lipqxx_LIBRARIES=
1> [CMake] pqxx header path: 
1> [CMake] pqxx library path: 
1> [CMake] -- Found PostgreSQL: C:/Program Files/PostgreSQL/14/lib/libpq.lib (found version "14.3")  
1> [CMake] calling find_library()...
1> [CMake] finished calling find_library()
1> [CMake] CMake Error at C:/Program Files/Microsoft Visual Studio/2022/Professional/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
1> [CMake]   Could NOT find PQXX (missing: PQXX_LIBRARY_PATH PQXX_HEADER_PATH)
1> [CMake] Call Stack (most recent call first):
1> [CMake]   C:/Program Files/Microsoft Visual Studio/2022/Professional/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/FindPackageHandleStandardArgs.cmake:600 (_FPHSA_FAILURE_MESSAGE)
1> [CMake]   cmake/module/FindPQXX.cmake:57 (find_package_handle_standard_args)
1> [CMake]   CMakeLists.txt:22 (find_package)
1> [CMake] -- Configuring incomplete, errors occurred!
1> 'C:\WINDOWS\system32\cmd.exe' '/c "%SYSTEMROOT%\System32\chcp.com 65001 >NUL && "c:\program files\microsoft visual studio\2022\professional\common7\ide\commonextensions\microsoft\cmake\CMake\bin\cmake.exe"  -G "Ninja"  -DCMAKE_C_COMPILER:STRING="cl.exe" -DCMAKE_CXX_COMPILER:STRING="cl.exe" -DCMAKE_BUILD_TYPE:STRING="Debug" -DCMAKE_INSTALL_PREFIX:PATH="C:/Users/jsudo/Desktop/ModernCMake/chap07/04-find-package-custom/out/install/x64-debug"   -DCMAKE_MAKE_PROGRAM="c:\program files\microsoft visual studio\2022\professional\common7\ide\commonextensions\microsoft\cmake\Ninja\ninja.exe" "C:\Users\jsudo\Desktop\ModernCMake\chap07\04-find-package-custom" 2>&1"' execution failed with error: ''C:\WINDOWS\system32\cmd.exe' '/c "%SYSTEMROOT%\System32\chcp.com 65001 >NUL && "c:\program files\microsoft visual studio\2022\professional\common7\ide\commonextensions\microsoft\cmake\CMake\bin\cmake.exe"  -G "Ninja"  -DCMAKE_C_COMPILER:STRING="cl.exe" -DCMAKE_CXX_COMPILER:STRING="cl.exe" -DCMAKE_BUILD_TYPE:STRING="Debug" -DCMAKE_INSTALL_PREFIX:PATH="C:/Users/jsudo/Desktop/ModernCMake/chap07/04-find-package-custom/out/install/x64-debug"   -DCMAKE_MAKE_PROGRAM="c:\program files\microsoft visual studio\2022\professional\common7\ide\commonextensions\microsoft\cmake\Ninja\ninja.exe" "C:\Users\jsudo\Desktop\ModernCMake\chap07\04-find-package-custom" 2>&1"' returned with exit code: 1'.

I've stepped through the CMakeLists.txt file in debugging mode and am wondering if the find_library() function is being called.

Is there a way to print a debug message within the function call? I also deliberately misspelled some of the find_library arguments on different runs and these did not cause additional errors.

Upvotes: 0

Views: 158

Answers (1)

jlakes85
jlakes85

Reputation: 57

I was able to solve the problem with a modified FindPQXX.cmake file shown below. I had to add the explicit path to the libpqxx library and headers, which I previously installed using Vcpkg

function(add_imported_library library headers)
  add_library(PQXX::PQXX UNKNOWN IMPORTED)
  set_target_properties(PQXX::PQXX PROPERTIES
    IMPORTED_LOCATION ${library}
    INTERFACE_INCLUDE_DIRECTORIES ${headers}
  )
  set(PQXX_FOUND 1 CACHE INTERNAL "PQXX found" FORCE)
  set(PQXX_LIBRARIES ${library}
      CACHE STRING "Path to pqxx library" FORCE)
  set(PQXX_INCLUDES ${headers}
      CACHE STRING "Path to pqxx headers" FORCE)
  mark_as_advanced(FORCE PQXX_LIBRARIES)
  mark_as_advanced(FORCE PQXX_INCLUDES)
endfunction()

if (PQXX_LIBRARIES AND PQXX_INCLUDES)
  add_imported_library(${PQXX_LIBRARIES} ${PQXX_INCLUDES})
  return()
endif()

# deliberately used in FindModule against the documentation
include(CMakeFindDependencyMacro)
find_dependency(PostgreSQL)

file(TO_CMAKE_PATH "$ENV{PQXX_DIR}" _PQXX_DIR)
message("calling find_library()...")
find_library(PQXX_LIBRARY_PATH NAMES libpqxx pqxx
  PATHS
    C:/Vcpkg/install/vcpkg/packages/libpqxx_x64-windows/lib # needed to include this to remove CMAKE errors!!!!!
    ${_PQXX_DIR}/lib/${CMAKE_LIBRARY_ARCHITECTURE}
    ${CMAKE_INSTALL_PREFIX}/lib/${CMAKE_LIBRARY_ARCHITECTURE}
    /usr/local/pgsql/lib/${CMAKE_LIBRARY_ARCHITECTURE}
    /usr/local/lib/${CMAKE_LIBRARY_ARCHITECTURE}
    /usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}
    ${_PQXX_DIR}/lib
    ${_PQXX_DIR}
    ${CMAKE_INSTALL_PREFIX}/lib
    ${CMAKE_INSTALL_PREFIX}/bin
    /usr/local/pgsql/lib
    /usr/local/lib
    /usr/lib
  NO_DEFAULT_PATH
)
message("finished calling find_library()")

find_path(PQXX_HEADER_PATH NAMES pqxx/pqxx
  PATHS
    C:/Vcpkg/install/vcpkg/packages/libpqxx_x64-windows/include # needed to include this to remove CMAKE errors!!!!!
    ${_PQXX_DIR}/include
    ${_PQXX_DIR}
    ${CMAKE_INSTALL_PREFIX}/include
    /usr/local/pgsql/include
    /usr/local/include
    /usr/include
  NO_DEFAULT_PATH
)

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
  PQXX DEFAULT_MSG PQXX_LIBRARY_PATH PQXX_HEADER_PATH
)
if (PQXX_FOUND)
  add_imported_library(
    "${PQXX_LIBRARY_PATH};${POSTGRES_LIBRARIES}"
    "${PQXX_HEADER_PATH};${POSTGRES_INCLUDE_DIRECTORIES}"
  )
endif()

Upvotes: 0

Related Questions