使用 LibreSSL 替代 OpenSSL
虽然这不是 OpenSSL 1.1 版本,但如果您不熟悉 LibreSSL,它可以直接替换 OpenSSL 1.0.x,我认为从编译角度来看更易于使用,因为它依赖于 CMake。
构建 macOS 不一定需要工具链文件。
您需要执行三个步骤:
- 修改 CMakeLists.txt 以生成框架(如果需要)
- 为每个 SDK 提供工具链文件
- 将输出合并成 XCFramework - 可选
我已经将以下代码段作为 Pull Request 应用到源根目录的CMakeLists.txt
中。
if (BUILD_APPLE_FRAMEWORK)
set(EMPTY_C ${CMAKE_CURRENT_BINARY_DIR}/empty.c)
file(TOUCH ${EMPTY_C})
set(MODULE_MODULEMAP ${CMAKE_CURRENT_BINARY_DIR}/module.modulemap)
file(WRITE ${MODULE_MODULEMAP} "\
framework module LibreSSL {
umbrella header \"LibreSSL.h\"
export *
module * { export * }
}
")
set_source_files_properties(${MODULE_MODULEMAP} PROPERTIES
MACOSX_PACKAGE_LOCATION Modules)
set(LIBRESSL_H ${CMAKE_CURRENT_BINARY_DIR}/LibreSSL.h)
file(REMOVE ${LIBRESSL_H})
file(GLOB LIBRESSL_INCLUDES
${CMAKE_CURRENT_LIST_DIR}/include/*.h ${CMAKE_CURRENT_LIST_DIR}/include/openssl/*.h)
foreach(LIBRESSL_INCLUDE ${LIBRESSL_INCLUDES})
file(RELATIVE_PATH RELATIVE_INCLUDE ${CMAKE_CURRENT_LIST_DIR}/include ${LIBRESSL_INCLUDE})
get_filename_component(RELATIVE_INCLUDE_DIR ${RELATIVE_INCLUDE} DIRECTORY)
set_source_files_properties(${LIBRESSL_INCLUDE} PROPERTIES
MACOSX_PACKAGE_LOCATION Headers/${RELATIVE_INCLUDE_DIR})
file(APPEND ${LIBRESSL_H} "#include \"${RELATIVE_INCLUDE}\"\n")
endforeach()
add_library(LibreSSL_framework ${EMPTY_C}
$<TARGET_OBJECTS:crypto_obj> $<TARGET_OBJECTS:ssl_obj>
${LIBRESSL_H} ${LIBRESSL_INCLUDES}
${MODULE_MODULEMAP})
set_target_properties(LibreSSL_framework PROPERTIES
OUTPUT_NAME LibreSSL
PUBLIC_HEADER "${LIBRESSL_H}"
FRAMEWORK on)
install(TARGETS LibreSSL_framework
FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR})
endif(BUILD_APPLE_FRAMEWORK)
generate_xcframework.sh
#!/usr/bin/env bash
set -e
FRAMEWORKS=()
for SDK in macosx iphoneos iphonesimulator; do
BUILD_DIR=build-${SDK}
rm -rf ${BUILD_DIR}
mkdir -p ${BUILD_DIR}
pushd ${BUILD_DIR}
cmake -G Ninja -D CMAKE_TOOLCHAIN_FILE=cmake/${SDK}.toolchain.cmake ..
cmake --build . --target LibreSSL_framework
FRAMEWORKS+=(-framework ${BUILD_DIR}/LibreSSL.framework)
popd
done
XCFRAMEWORK_DIR=build-xcframework
rm -rf ${XCFRAMEWORK_DIR}
mkdir -p ${XCFRAMEWORK_DIR}
xcodebuild -create-xcframework \
"${FRAMEWORKS[@]}" \
-output ${XCFRAMEWORK_DIR}/LibreSSL.xcframework
macosx.toolchain.cmake
set( CMAKE_SYSTEM_NAME Darwin )
set( SDK macosx CACHE STRING "Xcode SDK" )
set( CMAKE_OSX_ARCHITECTURES x86_64 arm64 CACHE STRING "Architectures" )
iphoneos.toolchain.cmake
set( CMAKE_SYSTEM_NAME Darwin )
set( SDK iphoneos CACHE STRING "Xcode SDK" )
set( CMAKE_OSX_ARCHITECTURES armv7 armv7s arm64 CACHE STRING "Architectures" )
include(${CMAKE_CURRENT_LIST_DIR}/apple-common-toolchain.cmake)
iphonesimulator.toolchain.cmake
set( CMAKE_SYSTEM_NAME Darwin )
set( SDK iphonesimulator CACHE STRING "Xcode SDK" )
set( CMAKE_OSX_ARCHITECTURES x86_64 CACHE STRING "Architectures" )
include(${CMAKE_CURRENT_LIST_DIR}/apple-common-toolchain.cmake)
apple-common-toolchain.cmake
set(BUILD_APPLE_FRAMEWORK on)
if(SDK STREQUAL iphoneos OR SDK STREQUAL iphonesimulator)
set(IOS_DEPLOYMENT_TARGET "9.0")
set(CMAKE_OSX_DEPLOYMENT_TARGET ${IOS_DEPLOYMENT_TARGET} CACHE STRING "" FORCE)
elseif(SDK STREQUAL macosx)
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.10" CACHE STRING "" FORCE)
else()
message(FATAL_ERROR "Unknown sdk when setting deployment target: ${SDK}")
endif()
set(CMAKE_EXPORT_COMPILE_COMMANDS on)
execute_process(COMMAND xcrun --sdk ${SDK} --find clang
OUTPUT_VARIABLE CMAKE_C_COMPILER
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(CMAKE_C_COMPILER ${CMAKE_C_COMPILER} CACHE PATH "clang executable")
execute_process( COMMAND xcrun --sdk ${SDK} --find clang++
OUTPUT_VARIABLE CMAKE_CXX_COMPILER
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(CMAKE_CXX_COMPILER ${CMAKE_CXX_COMPILER} CACHE PATH "clang++ executable")
execute_process( COMMAND xcrun --sdk ${SDK} --find libtool
OUTPUT_VARIABLE CMAKE_LIBTOOL
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(CMAKE_LIBTOOL ${CMAKE_LIBTOOL} CACHE PATH "libtool executable")
execute_process( COMMAND xcrun --sdk ${SDK} --find strip
OUTPUT_VARIABLE CMAKE_STRIP
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(CMAKE_STRIP ${CMAKE_STRIP} CACHE PATH "strip executable")
execute_process( COMMAND xcrun --sdk ${SDK} --find dsymutil
OUTPUT_VARIABLE DSYMUTIL
OUTPUT_STRIP_TRAILING_WHITESPACE)
if( BUILD_TARGET_IOS AND NOT BUILD_TARGET_SIMULATOR)
if( XCODE_VERSION VERSION_LESS 11)
set(DSYMUTIL ${DSYMUTIL} -t 1)
endif()
endif()
set(DSYMUTIL ${DSYMUTIL} CACHE PATH "dsymutil executable")
execute_process( COMMAND xcrun --sdk ${SDK} --show-sdk-path
OUTPUT_VARIABLE CMAKE_OSX_SYSROOT
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(CMAKE_OSX_SYSROOT ${CMAKE_OSX_SYSROOT} CACHE PATH "sysroot")
set(CMAKE_CXX_COMPILER_WORKS TRUE)
set(CMAKE_C_COMPILER_WORKS TRUE)
set(CMAKE_Swift_COMPILER_WORKS TRUE)
set(CMAKE_FIND_FRAMEWORK FIRST)
set(CMAKE_SYSTEM_FRAMEWORK_PATH ${CMAKE_OSX_SYSROOT}/System/Library/Frameworks)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)