Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cross-compile to Windows (64-bit) is failing given that OpenSSL can't be found #3001

Open
TSC21 opened this issue Jul 11, 2023 · 1 comment

Comments

@TSC21
Copy link

TSC21 commented Jul 11, 2023

I am trying to cross-compile a C++ project to Windows using dockcross (more specifically, https://github.com/dockcross/dockcross/tree/master/windows-static-x64) in Ubuntu 20.04. This container image in specific uses MXE together with the x86_64-w64-mingw32 compiler.

OpenSSL is also built (statically) through this container using the following configuration and build command: (note this is being called from CMake, and so the usage of CMake variables)

# Config
perl <SOURCE_DIR>/Configure mingw64 no-shared no-tests --prefix=${CMAKE_INSTALL_PREFIX}
# build
RC=/usr/src/mxe/usr/bin/x86_64-w64-mingw32.static-windres
AR=/usr/src/mxe/usr/bin/x86_64-w64-mingw32.static-ar
RANLIB=/usr/src/mxe/usr/bin/x86_64-w64-mingw32.static-ranlib
CROSS_COMPILE=x86_64-w64-mingw32.static-
make -e RC=${RC} AR=${AR} RANLIB=${RANLIB} CROSS_COMPILE=${CROSS_COMPILE}

The command above runs properly and libcrypto.a and libssl.a are both installed in ${CMAKE_INSTALL_PREFIX}/lib, besides the headers on the ${CMAKE_INSTALL_PREFIX}/include folder. Here's the install tree structure:

.
├── bin
│   ├── ...
│   └── openssl.exe
├── include
│   ├── ...
│   └── openssl
│      ├── ...
│      └── ssl.h
├── lib
│   ├── ...
│   ├── libcrypto.a
│   └── libssl.a
...

But, for some reason, on the C++ project, and when calling find_package(OpenSSL REQUIRED), it fails to find OPENSSL_CRYPTO_LIBRARY as it can be seen above. Note that OPENSSL_INCLUDE_DIR had to also be passed as a CMAKE_ARG to the project because FindOpenSSL() is was also not able to find openssl/ssl.h, although it is installed in ${CMAKE_INSTALL_PREFIX}/include. OpenSSL is marked as a dependency of libdatachannel while building through CMake, so I don't necessarily understand why this fails. One thing to note is that MXE sets MSYS to 1, and also since we are using mingw32 to cross-compile,WIN32 and MINGW are also set to 1. If I try to manually set MINGW and WIN32 to 0, then find_package(OpenSSL) succeeds and the build process continues, until the linker fails because the architecture is of course wrong. Setting the OPENSSL_ROOT_DIR also doesn't help.

This is the error seen:

-- Compiler flags (CMAKE_C_FLAGS):  -std=c99 -pedantic -Wall -Wextra -Wfloat-equal -Wshadow -Wpointer-arith -Wunreachable-code -Winit-self -Wno-unused-function -Wno-unused-parameter -Wno-unreachable-code -Wstrict-prototypes -Werror
-- link library: ws2_32
-- Configuring done
CMake Error at /usr/src/mxe/usr/x86_64-pc-linux-gnu/share/cmake-3.20/Modules/FindPackageHandleStandardArgs.cmake:230 (message):
  Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the
  system variable OPENSSL_ROOT_DIR (missing: OPENSSL_CRYPTO_LIBRARY) (found
  version "1.1.1o")
Call Stack (most recent call first):
  /usr/src/mxe/usr/x86_64-pc-linux-gnu/share/cmake-3.20/Modules/FindPackageHandleStandardArgs.cmake:594 (_FPHSA_FAILURE_MESSAGE)
  /usr/src/mxe/usr/x86_64-pc-linux-gnu/share/cmake-3.20/Modules/FindOpenSSL.cmake:571 (find_package_handle_standard_args)
  deps/libsrtp/CMakeLists.txt:75 (find_package)

For whatever it can help with, here's the /usr/src/mxe/usr/x86_64-w64-mingw32.static/share/cmake/mxe-conf.cmake MXE configuration:

# This file is part of MXE. See LICENSE.md for licensing information.

# https://cmake.org/cmake/help/latest

# Can't set `cmake_minimum_required` or `cmake_policy` in toolchain
# since toolchain is read before CMakeLists.txt
# See `target-cmake.in` for CMAKE_POLICY_DEFAULT_CMPNNNN

# Check if we are using mxe supplied version
#   - toolchain is included multiple times so set a guard in
#     environment to suppress duplicate messages
if(NOT ${CMAKE_COMMAND} STREQUAL /usr/src/mxe/usr/x86_64-pc-linux-gnu/bin/cmake AND NOT DEFINED ENV{_MXE_CMAKE_TOOLCHAIN_INCLUDED})
    message(WARNING "
** Warning: direct use of toolchain file is deprecated
** Please use prefixed wrapper script instead:
     x86_64-w64-mingw32.static-cmake [options] <path-to-source>
       - uses mxe supplied cmake version 3.20.1
       - loads toolchain
       - loads common run results
       - sets various policy defaults
    ")
    set(ENV{_MXE_CMAKE_TOOLCHAIN_INCLUDED} TRUE)
endif()

# Use CACHE variables to allow user setting with `-D`
# Use CACHE FORCE in rare cases of misconfigured CMakeLists.txt
#   - e.g include(FindPkgConfig)
#     https://github.com/mxe/mxe/issues/1023
#   - projects may still set these in which case FORCE doesn't have
#     any advantage, just causes inconvenience
#     https://github.com/mxe/mxe/pull/1621#discussion_r106937505
# Use normal variables expected to be set by toolchain/system
#   - projects should test for these values and not try to override

## General configuration
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR x86_64 CACHE STRING "System Processor")
set(MSYS 1)
set(CMAKE_EXPORT_NO_PACKAGE_REGISTRY ON)
# Workaround for https://www.cmake.org/Bug/view.php?id=14075
set(CMAKE_CROSS_COMPILING ON)


## Library config
set(BUILD_SHARED_LIBS OFF CACHE BOOL "BUILD_SHARED_LIBS")
set(BUILD_STATIC_LIBS ON CACHE BOOL "BUILD_STATIC_LIBS")
set(BUILD_SHARED OFF CACHE BOOL "BUILD_SHARED")
set(BUILD_STATIC ON CACHE BOOL "BUILD_STATIC")
set(LIBTYPE STATIC)


## Paths etc.
# These MODEs shouldn't be changed by users, we only want headers/libs
# from cross-build and "never" want binaries. We do, however, want
# `*-config` scripts but there's no way to instruct cmake to do that.
#
# The best solution may be to whitelist utilities
#   https://github.com/mxe/mxe/issues/1667
# and symlink them to an additional root path, changing PROGRAM to ONLY

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

# Allow user to specify list of locations to search
set(CMAKE_FIND_ROOT_PATH /usr/src/mxe/usr/x86_64-w64-mingw32.static CACHE PATH "List of root paths to search on the filesystem")
set(CMAKE_PREFIX_PATH /usr/src/mxe/usr/x86_64-w64-mingw32.static CACHE PATH "List of directories specifying installation prefixes to be searched")
set(CMAKE_INSTALL_PREFIX /usr/src/mxe/usr/x86_64-w64-mingw32.static CACHE PATH "Installation Prefix")
# For custom mxe FindPackage scripts
set(CMAKE_MODULE_PATH "/usr/src/mxe/usr/share/cmake/modules" ${CMAKE_MODULE_PATH})

# projects (mis)use `-isystem` to silence warnings from 3rd-party
# source (among other things). gcc6 introduces changes to search
# order which breaks this usage.
#   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70129
#   https://gitlab.kitware.com/cmake/cmake/issues/16291
#   https://gitlab.kitware.com/cmake/cmake/issues/16919
set(CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES /usr/src/mxe/usr/x86_64-w64-mingw32.static/include)
set(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES /usr/src/mxe/usr/x86_64-w64-mingw32.static/include)


## Programs
set(CMAKE_C_COMPILER /usr/src/mxe/usr/bin/x86_64-w64-mingw32.static-gcc)
set(CMAKE_CXX_COMPILER /usr/src/mxe/usr/bin/x86_64-w64-mingw32.static-g++)
set(CMAKE_Fortran_COMPILER /usr/src/mxe/usr/bin/x86_64-w64-mingw32.static-gfortran)
set(CMAKE_RC_COMPILER /usr/src/mxe/usr/bin/x86_64-w64-mingw32.static-windres)
# CMAKE_RC_COMPILE_OBJECT is defined in:
#     <cmake root>/share/cmake-X.Y/Modules/Platform/Windows-windres.cmake
set(CPACK_NSIS_EXECUTABLE x86_64-w64-mingw32.static-makensis)

## Individual package configuration
file(GLOB mxe_cmake_files
    "/usr/src/mxe/usr/x86_64-w64-mingw32.static/share/cmake/mxe-conf.d/*.cmake"
)
foreach(mxe_cmake_file ${mxe_cmake_files})
    include(${mxe_cmake_file})
endforeach()
set(CMAKE_CROSSCOMPILING_EMULATOR "/usr/bin/wine")

Is this potentially a problem with the OpenSSL build or even with the default FindOpenSSL.cmake module? Or is this something that can be addressed on the C++ project CMakeLists.txt? Any help with this would be appreciated.

Thanks in advance!

@mabrand
Copy link
Member

mabrand commented Apr 19, 2024

There is a patch to FindWrapOpenSSL.cmake in https://github.com/mxe/mxe/blob/master/src/qt/qt6/qt6-qtbase-1-fixes.patch that might help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants