Search code examples
cmakeopensslcross-compilingmingw-w64vcpkg

Why can't CMake's OpenSSL with mingw-w64-g++ recognize libdl? ("cannot find -ldl")


I am trying to cross-compile on Linux for Windows. I am doing this through CMake and x86_64-mingw-w64-g++.

I have installed dlfcn (also vcpkg) to link libdl, and I realized that mingw-w64 has NO ISSUE whatsoever linking the two WHEN THEY ARE ALONE.

DL only:

cmake_minimum_required(VERSION 3.10)
project(main)

set(CMAKE_C_COMPILER /usr/bin/x86_64-w64-mingw32-gcc)
set(CMAKE_CXX_COMPILER /usr/bin/x86_64-w64-mingw32-g++)

set(CMAKE_PREFIX_PATH /home/undulating/Manual_Programs/vcpkg/installed/x64-mingw-static)

add_executable(main main.cpp)


find_package(dlfcn-win32 CONFIG REQUIRED)
target_link_libraries(main PUBLIC dlfcn-win32::dl)

This works FINE, no "missing -ldl"; nothing like that at all. It works perfect.

However, for some reason; mingw-w64 cannot recognize this with DL + OpenSSL. This is not the case with standard g++. There is no "missing -ldl" when I combine DL and OPENSSL with g++ but that is not the case with mingw.

DL + OPENSSL:

cmake_minimum_required(VERSION 3.10)
project(main)
 
set(CMAKE_C_COMPILER /usr/bin/x86_64-w64-mingw32-gcc)
set(CMAKE_CXX_COMPILER /usr/bin/x86_64-w64-mingw32-g++)
  
set(CMAKE_PREFIX_PATH /home/undulating/Manual_Programs/vcpkg/installed/x64-mingw-static)
 
add_executable(main main.cpp) 
find_package(dlfcn-win32 CONFIG REQUIRED)
target_link_libraries(main PUBLIC dlfcn-win32::dl)

find_package(OpenSSL REQUIRED)
target_link_libraries(main PUBLIC OpenSSL:SSL OpenSSL::Crypto)

I get the following error(s)

[ 50%] Linking CXX executable main
/usr/bin/x86_64-w64-mingw32-ld: cannot find -ldl
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/main.dir/build.make:106: main] Error 1
make[1]: *** [CMakeFiles/Makefile2:95: CMakeFiles/main.dir/all] Error 2
make: *** [Makefile:103: all] Error 2

I can tell that linking dl is no issue, but for some reason OpenSSL cannot find bind it to it and I have no idea why. How do I get OpenSSL to recognize libdl?

I have tried linking libdl.a/so directly by setting OpenSSL's CMake's variable to point directly to libdl via

OPENSSL_LIBRARIES

https://cmake.org/cmake/help/latest/module/FindOpenSSL.html

This is very puzzling, if it helps I am using vcpkg and using entirely static libs.

All the vcpkg were installed with the following triplet:

set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_ENV_PASSTHROUGH PATH)

set(VCPKG_CMAKE_SYSTEM_NAME MinGW)

Solution

  • There was no issue finding the library or anything like that. I was simply linking the libraries incorrectly:

    find_library(crypt REQUIRED NAMES crypt32)
    
    
    target_link_libraries(main ${crypt})
    

    unrelated package but I realized that it didn't matter if it was OpenSSL or not; you need to set the proper lib folder if you're cross compiling and make sure CMake is referring to the correct one via

    message(${crypt})
    

    this will help verify you are referring to the correct libs and you must link it (if the order is incorrect and you get undefined reference errors you may be helped by repeating it in target_link_libraries

    Also for mingw, it's helpful to have vcpkg's installed directory but absolutely necessary to add files in the /usr/ dir for mingw. Such as this:

    set(CMAKE_LIBRARY_PATH ${CMAKE_PREFIX_PATH}/lib /usr/x86_64-w64-mingw32/lib)
    

    so that you may mix them with libraries for other architectures.

    And also preferably have CMAKE_PREFIX_PATH primarily be /usr/x86_64-w64-mingw32 as that makes more sense as a primary prefix rather than vcpkg.