cmake: resolve libraries found by pkg-config Libraries found by CMake modules are usually handled with their full path. This makes linking against those libraries a lot more robust when it comes to libraries in non-standard locations, as otherwise we might mix up libraries from different locations when link directories are given. One excemption are libraries found by PKG_CHECK_MODULES. Instead of returning libraries with their complete path, it will return the variable names as well as a set of link directories. In case where multiple sets of the same library are installed in different locations, this can lead the compiler to link against the wrong libraries in the end, when link directories of other dependencies are added. To fix this shortcoming, we need to manually resolve library paths returned by CMake against their respective library directories. This is an easy task to do with `FIND_LIBRARY`.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9176eee..d411751 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -29,7 +29,7 @@ INCLUDE(CheckFunctionExists)
INCLUDE(CheckSymbolExists)
INCLUDE(CheckStructHasMember)
INCLUDE(AddCFlagIfSupported)
-INCLUDE(FindPkgConfig)
+INCLUDE(FindPkgLibraries)
INCLUDE(FindThreads)
INCLUDE(FindStatNsec)
INCLUDE(IdeSplitSources)
diff --git a/cmake/Modules/FindPkgLibraries.cmake b/cmake/Modules/FindPkgLibraries.cmake
new file mode 100644
index 0000000..49311c3
--- /dev/null
+++ b/cmake/Modules/FindPkgLibraries.cmake
@@ -0,0 +1,28 @@
+INCLUDE(FindPkgConfig)
+
+# This function will find and set up a pkg-config based module.
+# If a pc-file was found, it will resolve library paths to
+# absolute paths. Furthermore, the function will automatically
+# fall back to use static libraries in case no dynamic libraries
+# were found.
+FUNCTION(FIND_PKGLIBRARIES prefix package)
+ PKG_CHECK_MODULES(${prefix} ${package})
+ IF(NOT ${prefix}_FOUND)
+ RETURN()
+ ENDIF()
+
+ FOREACH(LIBRARY ${${prefix}_LIBRARIES})
+ FIND_LIBRARY(${LIBRARY}_RESOLVED ${LIBRARY} PATHS ${${prefix}_LIBRARY_DIRS})
+ IF(${${LIBRARY}_RESOLVED} STREQUAL "${LIBRARY}_RESOLVED-NOTFOUND")
+ MESSAGE(FATAL_ERROR "could not resolve ${LIBRARY}")
+ ENDIF()
+ LIST(APPEND RESOLVED_LIBRARIES ${${LIBRARY}_RESOLVED})
+ ENDFOREACH(LIBRARY)
+
+ SET(${prefix}_FOUND 1 PARENT_SCOPE)
+ SET(${prefix}_LIBRARIES ${RESOLVED_LIBRARIES} PARENT_SCOPE)
+ SET(${prefix}_INCLUDE_DIRS ${${prefix}_INCLUDE_DIRS} PARENT_SCOPE)
+ SET(${prefix}_LDFLAGS ${${prefix}_LDFLAGS} PARENT_SCOPE)
+
+ MESSAGE(STATUS " Resolved libraries: ${RESOLVED_LIBRARIES}")
+ENDFUNCTION()
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 0f5d785..0d101f6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -119,9 +119,8 @@ IF (WIN32 AND WINHTTP)
LIST(APPEND LIBGIT2_PC_LIBS "-lrpcrt4" "-lcrypt32" "-lole32")
ELSE ()
IF (CURL)
- PKG_CHECK_MODULES(CURL libcurl)
+ FIND_PKGLIBRARIES(CURL libcurl)
ENDIF ()
-
IF (CURL_FOUND)
SET(GIT_CURL 1)
LIST(APPEND LIBGIT2_INCLUDES ${CURL_INCLUDE_DIRS})
@@ -340,7 +339,7 @@ ENDIF()
# Optional external dependency: libssh2
IF (USE_SSH)
- PKG_CHECK_MODULES(LIBSSH2 libssh2)
+ FIND_PKGLIBRARIES(LIBSSH2 libssh2)
ENDIF()
IF (LIBSSH2_FOUND)
SET(GIT_SSH 1)
@@ -348,7 +347,6 @@ IF (LIBSSH2_FOUND)
LIST(APPEND LIBGIT2_LIBS ${LIBSSH2_LIBRARIES})
LIST(APPEND LIBGIT2_LIBDIRS ${LIBSSH2_LIBRARY_DIRS})
LIST(APPEND LIBGIT2_PC_LIBS ${LIBSSH2_LDFLAGS})
- #SET(LIBGIT2_PC_LIBS "${LIBGIT2_PC_LIBS} ${LIBSSH2_LDFLAGS}")
CHECK_LIBRARY_EXISTS("${LIBSSH2_LIBRARIES}" libssh2_userauth_publickey_frommemory "${LIBSSH2_LIBRARY_DIRS}" HAVE_LIBSSH2_MEMORY_CREDENTIALS)
IF (HAVE_LIBSSH2_MEMORY_CREDENTIALS)