Skip to content

Patch provided: Windows MSVC linker args not properly set (it is getting -L, -l) #1191

@ar-visions

Description

@ar-visions

generating with:
cmake -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DCRYPTO_BACKEND=mbedTLS -DCMAKE_INSTALL_PREFIX=/users/kalen/src/prefix/install/native ..

it errors in msvc's msbuild, because that sees a bunch of -L's and -l (these should not be given to add_library and MSVC does not recognize these only UNIX env)

since it runs on UNIX and not MSVC, I keep the -L and -l on UNIX and make them blank on MSVC. I also make the libs a proper list because it was separated by spaces prior to concatenation with ws2_32. Again I am not sure why we are using -l at all, because its a given because its going to add_library() .. It can be made a bit simpler but I wasnt sure if you needed to retain this info on UNIX.

here is a diff that makes it work (didnt replace ALL -l's but the pattern is simple): (main id: 67e3909)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 60fc07de..11595a39 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -38,6 +38,8 @@
 
 cmake_minimum_required(VERSION 3.7)
 
+include(cmake/lib-prefix.cmake)
+
 set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
 
 include(CheckFunctionExists)
@@ -299,14 +301,14 @@ if(CRYPTO_BACKEND STREQUAL "OpenSSL" OR NOT CRYPTO_BACKEND)
     set(CRYPTO_BACKEND_DEFINE "LIBSSH2_OPENSSL")
     set(CRYPTO_BACKEND_INCLUDE_DIR ${OPENSSL_INCLUDE_DIR})
     list(APPEND LIBRARIES ${OPENSSL_LIBRARIES})
-    list(APPEND LIBSSH2_PC_LIBS_PRIVATE "-lcrypto")
+    list(APPEND LIBSSH2_PC_LIBS_PRIVATE "${L}crypto")
     list(APPEND LIBSSH2_PC_REQUIRES_PRIVATE "libcrypto")
 
     if(WIN32)
       # Statically linking to OpenSSL requires crypt32 for some Windows APIs.
       # This should really be handled by FindOpenSSL.cmake.
       list(APPEND LIBRARIES "crypt32" "bcrypt")
-      list(APPEND LIBSSH2_PC_LIBS_PRIVATE "-lcrypt32" "-lbcrypt")
+      list(APPEND LIBSSH2_PC_LIBS_PRIVATE "${L}crypt32" "${L}bcrypt")
 
       #set(CMAKE_FIND_DEBUG_MODE ON)
 
@@ -330,7 +332,7 @@ if(CRYPTO_BACKEND STREQUAL "OpenSSL" OR NOT CRYPTO_BACKEND)
 
     if(ZLIB_FOUND)
       list(APPEND LIBRARIES ${ZLIB_LIBRARIES})
-      list(APPEND LIBSSH2_PC_LIBS_PRIVATE "-lz")
+      list(APPEND LIBSSH2_PC_LIBS_PRIVATE "${L}z")
     endif()
   endif()
 endif()
@@ -344,12 +346,12 @@ if(CRYPTO_BACKEND STREQUAL "wolfSSL" OR NOT CRYPTO_BACKEND)
     set(CRYPTO_BACKEND_DEFINE "LIBSSH2_WOLFSSL")
     set(CRYPTO_BACKEND_INCLUDE_DIR ${WOLFSSL_INCLUDE_DIR} "${WOLFSSL_INCLUDE_DIR}/wolfssl")
     list(APPEND LIBRARIES ${WOLFSSL_LIBRARIES})
-    list(APPEND LIBSSH2_PC_LIBS_PRIVATE "-lwolfssl")
+    list(APPEND LIBSSH2_PC_LIBS_PRIVATE "${L}wolfssl")
     list(APPEND LIBSSH2_PC_REQUIRES_PRIVATE "wolfssl")
 
     if(WIN32)
       list(APPEND LIBRARIES "crypt32")
-      list(APPEND LIBSSH2_PC_LIBS_PRIVATE "-lcrypt32")
+      list(APPEND LIBSSH2_PC_LIBS_PRIVATE "${L}crypt32")
     endif()
 
     find_package(ZLIB)
@@ -357,7 +359,7 @@ if(CRYPTO_BACKEND STREQUAL "wolfSSL" OR NOT CRYPTO_BACKEND)
     if(ZLIB_FOUND)
       list(APPEND CRYPTO_BACKEND_INCLUDE_DIR ${ZLIB_INCLUDE_DIR})  # Public wolfSSL headers require zlib headers
       list(APPEND LIBRARIES ${ZLIB_LIBRARIES})
-      list(APPEND LIBSSH2_PC_LIBS_PRIVATE "-lz")
+      list(APPEND LIBSSH2_PC_LIBS_PRIVATE "${L}z")
     endif()
   endif()
 endif()
@@ -371,7 +373,7 @@ if(CRYPTO_BACKEND STREQUAL "Libgcrypt" OR NOT CRYPTO_BACKEND)
     set(CRYPTO_BACKEND_DEFINE "LIBSSH2_LIBGCRYPT")
     set(CRYPTO_BACKEND_INCLUDE_DIR ${LIBGCRYPT_INCLUDE_DIRS})
     list(APPEND LIBRARIES ${LIBGCRYPT_LIBRARIES})
-    list(APPEND LIBSSH2_PC_LIBS_PRIVATE "-lgcrypt")
+    list(APPEND LIBSSH2_PC_LIBS_PRIVATE "${L}gcrypt")
     list(APPEND LIBSSH2_PC_REQUIRES_PRIVATE "libgcrypt")
   endif()
 endif()
@@ -385,7 +387,10 @@ if(CRYPTO_BACKEND STREQUAL "mbedTLS" OR NOT CRYPTO_BACKEND)
     set(CRYPTO_BACKEND_DEFINE "LIBSSH2_MBEDTLS")
     set(CRYPTO_BACKEND_INCLUDE_DIR ${MBEDTLS_INCLUDE_DIR})
     list(APPEND LIBRARIES ${MBEDTLS_LIBRARIES})
-    list(APPEND LIBSSH2_PC_LIBS_PRIVATE "-lmbedcrypto")
+
+    message(STATUS "mbed: ${MBEDTLS_LIBRARIES}")
+
+    list(APPEND LIBSSH2_PC_LIBS_PRIVATE "${L}mbedcrypto")
     link_directories(${MBEDTLS_LIBRARY_DIR})
   endif()
 endif()
@@ -398,7 +403,7 @@ if(CRYPTO_BACKEND STREQUAL "WinCNG" OR NOT CRYPTO_BACKEND)
     set(CRYPTO_BACKEND_DEFINE "LIBSSH2_WINCNG")
     set(CRYPTO_BACKEND_INCLUDE_DIR "")
     list(APPEND LIBRARIES "crypt32" "bcrypt")
-    list(APPEND LIBSSH2_PC_LIBS_PRIVATE "-lcrypt32" "-lbcrypt")
+    list(APPEND LIBSSH2_PC_LIBS_PRIVATE "${L}crypt32" "${L}bcrypt")
   elseif(SPECIFIC_CRYPTO_REQUIREMENT STREQUAL "REQUIRED")
     message(FATAL_ERROR "WinCNG not available")
   endif()
diff --git a/cmake/FindmbedTLS.cmake b/cmake/FindmbedTLS.cmake
index 3e3d2717..b7fa8b3d 100644
--- a/cmake/FindmbedTLS.cmake
+++ b/cmake/FindmbedTLS.cmake
@@ -13,6 +13,8 @@
 #  MBEDX509_LIBRARY - path to mbedTLS X.509 library
 #  MBEDCRYPTO_LIBRARY - path to mbedTLS Crypto library
 
+include(cmake/lib-prefix.cmake)
+
 find_path(MBEDTLS_INCLUDE_DIR mbedtls/version.h)
 
 if(MBEDTLS_INCLUDE_DIR AND MBEDTLS_LIBRARIES)
@@ -37,8 +39,13 @@ if(MBEDTLS_FOUND)
   string(REGEX REPLACE "^lib" "" MBEDTLS_LIBRARY_FILE ${MBEDTLS_LIBRARY_FILE})
   string(REGEX REPLACE "^lib" "" MBEDX509_LIBRARY_FILE ${MBEDX509_LIBRARY_FILE})
   string(REGEX REPLACE "^lib" "" MBEDCRYPTO_LIBRARY_FILE ${MBEDCRYPTO_LIBRARY_FILE})
-  set(MBEDTLS_LIBRARIES "-L${MBEDTLS_LIBRARY_DIR} -l${MBEDTLS_LIBRARY_FILE} -l${MBEDX509_LIBRARY_FILE} -l${MBEDCRYPTO_LIBRARY_FILE}")
 
+  # when you call target_link_libraries you dont give it -l's and -L's.  thats not portable!
+  set(MBEDTLS_LIBRARIES
+    ${L}${MBEDTLS_LIBRARY_FILE}
+    ${L}${MBEDX509_LIBRARY_FILE}
+    ${L}${MBEDCRYPTO_LIBRARY_FILE})
+  
   if(NOT MBEDTLS_FIND_QUIETLY)
     message(STATUS "Found mbedTLS:")
     file(READ ${MBEDTLS_INCLUDE_DIR}/mbedtls/version.h MBEDTLSCONTENT)
diff --git a/cmake/lib-prefix.cmake b/cmake/lib-prefix.cmake
new file mode 100644
index 00000000..d67c7501
--- /dev/null
+++ b/cmake/lib-prefix.cmake
@@ -0,0 +1,8 @@
+set(L "-l")
+set(LPath "-L")
+set(Lext "")
+if(MSVC)
+  set(L "")
+  set(LPath "")
+  set(Lext ".lib")
+endif()
\ No newline at end of file
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index d6ee077e..342569a1 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -39,6 +39,8 @@
 set(LIBSSH2_SOVERSION 1)
 set(LIBSSH2_LIBVERSION 1.0.1)
 
+include(../cmake/lib-prefix.cmake)
+
 if(CRYPTO_BACKEND)
   list(APPEND PRIVATE_COMPILE_DEFINITIONS ${CRYPTO_BACKEND_DEFINE})
   list(APPEND PRIVATE_INCLUDE_DIRECTORIES ${CRYPTO_BACKEND_INCLUDE_DIR})
@@ -61,7 +63,7 @@ if(ENABLE_ZLIB_COMPRESSION)
 
   list(APPEND libssh2_INCLUDE_DIRS ${ZLIB_INCLUDE_DIRS})
   list(APPEND LIBRARIES ${ZLIB_LIBRARIES})
-  list(APPEND LIBSSH2_PC_LIBS_PRIVATE "-lz")
+  list(APPEND LIBSSH2_PC_LIBS_PRIVATE "${L}z")
   list(APPEND LIBSSH2_PC_REQUIRES_PRIVATE "zlib")
   if(ZLIB_FOUND)
     list(APPEND libssh2_DEFINITIONS "LIBSSH2_HAVE_ZLIB")
@@ -71,7 +73,7 @@ endif()
 list(APPEND LIBRARIES ${SOCKET_LIBRARIES})
 
 if(WIN32)
-  list(APPEND LIBSSH2_PC_LIBS_PRIVATE "-lws2_32")
+  list(APPEND LIBSSH2_PC_LIBS_PRIVATE "${L}ws2_32")
 endif()
 
 # to find generated header
@@ -106,9 +108,15 @@ endif()
 if(BUILD_STATIC_LIBS)
   list(APPEND libssh2_export ${LIB_STATIC})
   add_library(${LIB_STATIC} STATIC ${SOURCES})
+  if(MSVC)
+    target_compile_options(${LIB_STATIC} /MT)
+  endif()
   add_library(${PROJECT_NAME}::${LIB_STATIC} ALIAS ${LIB_STATIC})
   target_compile_definitions(${LIB_STATIC} PRIVATE ${PRIVATE_COMPILE_DEFINITIONS} ${libssh2_DEFINITIONS})
-  target_link_libraries(${LIB_STATIC} PRIVATE ${LIBRARIES})
+  target_link_libraries(${LIB_STATIC} PRIVATE ${LIBRARIES}) # we need a LIBRARY_PATHS
+
+  #message(FATAL_ERROR "libraries = ${LIBRARIES}")
+
   set_target_properties(${LIB_STATIC} PROPERTIES
     PREFIX "" OUTPUT_NAME "libssh2" SOVERSION "${LIBSSH2_SOVERSION}" VERSION "${LIBSSH2_LIBVERSION}"
     SUFFIX "${STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}")

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions