Files
OrcaSlicer/deps/OpenSSL/OpenSSL.cmake
Ryan Hartman 6b5c8af1c8 Pin OpenSSL libdir so the bundled Python finds it (#15047)
On Linux the bundled CPython silently links the system OpenSSL instead of
the one built in deps/, and the dependency build then fails:

  install: cannot stat 'Modules/_ssl.cpython-312-x86_64-linux-gnu.so':
           No such file or directory

The chain:

  * OpenSSL's linux-x86_64 target sets multilib=64, so 'make install_sw'
    installs the static libs to <prefix>/lib64 while every other dependency
    in the prefix uses <prefix>/lib.
  * CPython's --with-openssl=<dir> only ever emits -L<dir>/lib. It does not
    look in lib64, so -lssl resolves to the system OpenSSL.
  * gcc -shared does not error on unresolved symbols, so the link appears to
    succeed. _ssl.c was compiled against the bundled 1.1.1w headers, which
    map SSL_get1_peer_certificate onto the pre-3.0 SSL_get_peer_certificate
    -- a symbol OpenSSL 3.x removed. The module then fails to import:

      _ssl failed to import: undefined symbol: SSL_get_peer_certificate
      Could not build the ssl module!

  * With no _ssl built, 'make install' cannot stat it and the build stops.

Passing --libdir=lib keeps the prefix single-layout, so CPython's -L<dir>/lib
finds the bundled static libraries and links against the headers it was
compiled with.

CMake-based dependencies were unaffected throughout, because CMake's
FindOpenSSL searches lib64 on its own; only CPython's autoconf path is
sensitive to this.

Affects any distribution where OpenSSL selects the lib64 layout, which is the
Fedora, openSUSE and Arch families. Debian and Ubuntu are unaffected, which is
why CI has not seen it.

Verified on Arch (GCC 16.1.1, CMake 4.4.2): the dependency build completes and
the bundled interpreter reports the bundled OpenSSL rather than the system one:

  $ deps/build/OrcaSlicer_dep/usr/local/libpython/bin/python3.12 \
      -c 'import ssl; print(ssl.OPENSSL_VERSION)'
  OpenSSL 1.1.1w  11 Sep 2023

Not verified on macOS or Windows. The flag is accepted by OpenSSL's Configure
on all platforms and Darwin targets do not set multilib, so it should be a
no-op there, but CI is the check.
2026-08-03 11:03:59 +08:00

79 lines
2.9 KiB
CMake

include(ProcessorCount)
ProcessorCount(NPROC)
if(DEFINED OPENSSL_ARCH)
set(_cross_arch ${OPENSSL_ARCH})
else()
if(WIN32)
if("${CMAKE_GENERATOR_PLATFORM}" STREQUAL "ARM64")
set(_cross_arch "VC-WIN64-ARM")
else()
set(_cross_arch "VC-WIN64A")
endif()
elseif(APPLE)
set(_cross_arch "darwin64-${CMAKE_OSX_ARCHITECTURES}-cc")
endif()
endif()
if(WIN32)
set(_conf_cmd perl Configure )
set(_cross_comp_prefix_line "")
set(_make_cmd nmake)
set(_install_cmd nmake install_sw )
else()
if(APPLE)
set(_conf_cmd export MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} && ./Configure -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET})
else()
set(_conf_cmd env "CC=${CMAKE_C_COMPILER}" "LDFLAGS=${CMAKE_EXE_LINKER_FLAGS}" "./config")
endif()
set(_cross_comp_prefix_line "")
set(_make_cmd make -j${NPROC})
set(_install_cmd make -j${NPROC} install_sw)
if (CMAKE_CROSSCOMPILING)
set(_cross_comp_prefix_line "--cross-compile-prefix=${TOOLCHAIN_PREFIX}-")
if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64" OR ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm64")
set(_cross_arch "linux-aarch64")
elseif (${CMAKE_SYSTEM_PROCESSOR} STREQUAL "armhf") # For raspbian
# TODO: verify
set(_cross_arch "linux-armv4")
endif ()
endif ()
endif()
ExternalProject_Add(dep_OpenSSL
#EXCLUDE_FROM_ALL ON
URL "https://github.com/openssl/openssl/archive/OpenSSL_1_1_1w.tar.gz"
URL_HASH SHA256=2130E8C2FB3B79D1086186F78E59E8BC8D1A6AEDF17AB3907F4CB9AE20918C41
# URL "https://github.com/openssl/openssl/archive/refs/tags/openssl-3.1.2.tar.gz"
# URL_HASH SHA256=8c776993154652d0bb393f506d850b811517c8bd8d24b1008aef57fbe55d3f31
DOWNLOAD_DIR ${DEP_DOWNLOAD_DIR}/OpenSSL
CONFIGURE_COMMAND ${_conf_cmd} ${_cross_arch}
"--openssldir=${DESTDIR}"
"--prefix=${DESTDIR}"
# OpenSSL's linux-x86_64 target sets multilib=64, so it installs to
# <prefix>/lib64 while every other dep uses <prefix>/lib. CPython's
# --with-openssl only ever emits -L<dir>/lib, so it misses the bundled
# static libs and silently links the system OpenSSL instead -- which,
# against 1.1.1w headers, leaves _ssl.so with an undefined
# SSL_get_peer_certificate (removed in OpenSSL 3.x). Pin libdir so the
# prefix stays single-layout.
"--libdir=lib"
${_cross_comp_prefix_line}
no-shared
no-asm
no-ssl3-method
no-dynamic-engine
BUILD_IN_SOURCE ON
BUILD_COMMAND ${_make_cmd}
INSTALL_COMMAND ${_install_cmd}
)
ExternalProject_Add_Step(dep_OpenSSL install_cmake_files
DEPENDEES install
COMMAND ${CMAKE_COMMAND} -E copy_directory openssl "${DESTDIR}${CMAKE_INSTALL_LIBDIR}/cmake/openssl"
WORKING_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}"
)