From 0232e66d5bc5b01a25a447c657e51747626488ab Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Thu, 20 Jun 2024 18:12:22 +0300 Subject: [PATCH] CMake: Add XZ_EXTERNAL_SHA256 --- CMakeLists.txt | 121 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 116 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 437b3ae6..c57deb07 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,9 +22,6 @@ # processors with CLMUL support, the C code should be faster than # the assembly code while on old processors the assembly code wins. # -# - External SHA-256 code isn't supported but it's disabled by -# default in the Autotools build too (--enable-external-sha256). -# # About CMAKE_BUILD_TYPE: # # - CMake's standard choices are fine to use for production builds, @@ -269,7 +266,7 @@ tuklib_large_file_support(ALL) # This is needed by liblzma and xz. tuklib_integer(ALL) -# This is used for liblzma.pc generation to add -lrt if needed. +# This is used for liblzma.pc generation to add -lrt and -lmd if needed. set(LIBS) # Check for clock_gettime(). Do this before checking for threading so @@ -732,9 +729,123 @@ if("crc64" IN_LIST XZ_CHECKS) endif() endif() +# External SHA-256 +# +# At least the following implementations are supported: +# +# OS Headers Library Type Function +# FreeBSD sys/types.h + sha256.h libmd SHA256_CTX SHA256_Init +# NetBSD sys/types.h + sha2.h SHA256_CTX SHA256_Init +# OpenBSD sys/types.h + sha2.h SHA2_CTX SHA256Init +# Solaris sys/types.h + sha2.h libmd SHA256_CTX SHA256Init +# MINIX 3 sys/types.h + sha2.h SHA256_CTX SHA256_Init +# Darwin CommonCrypto/CommonDigest.h CC_SHA256_CTX CC_SHA256_Init +# +# Note that Darwin's CC_SHA256_Update takes buffer size as uint32_t instead +# of size_t. +# +# This is disabled by default because it used to conflict with OpenSSL +# on some platforms and in some cases the builtin code in liblzma was faster. +# See INSTALL and the commit message ac398c3bafa6e4c80e20571373a96947db863b3d. +option(XZ_EXTERNAL_SHA256 "Use SHA-256 code from the operating system \ +if possible. See INSTALL for possible subtle problems." OFF) + if("sha256" IN_LIST XZ_CHECKS) add_compile_definitions("HAVE_CHECK_SHA256") - target_sources(liblzma PRIVATE src/liblzma/check/sha256.c) + + # Assume that external code won't be used. We need this to know + # if the internal sha256.c should be built. + set(USE_INTERNAL_SHA256 ON) + + if(XZ_EXTERNAL_SHA256) + # Find the header. + set(SHA256_HEADER OFF) + + foreach(X CommonCrypto/CommonDigest.h sha256.h sha2.h) + string(TOUPPER "HAVE_${X}" HAVE_X) + string(REGEX REPLACE "[/.]" "_" HAVE_X "${HAVE_X}") + check_include_file("${X}" "${HAVE_X}") + if(${HAVE_X}) + target_compile_definitions(liblzma PRIVATE "${HAVE_X}") + set(SHA256_HEADER "${X}") + break() + endif() + endforeach() + + if(SHA256_HEADER) + # Find the type to hold the SHA-256 state. + set(SHA256_TYPE OFF) + + foreach(X CC_SHA256_CTX SHA256_CTX SHA2_CTX) + string(TOUPPER "HAVE_${X}" HAVE_X) + + # configure.ac uses conditionally but it's + # required on all cases except Darwin where it exists too. + # So just use it unconditionally here. + set(SOURCE + "#include + #include <${SHA256_HEADER}> + int main(void) + { + ${X} ctx; + return 0; + }") + check_c_source_compiles("${SOURCE}" "${HAVE_X}") + if(${HAVE_X}) + target_compile_definitions(liblzma PRIVATE "${HAVE_X}") + set(SHA256_TYPE "${X}") + break() + endif() + endforeach() + + if(SHA256_TYPE) + # Find the initialization function. It might required libmd. + foreach(X CC_SHA256_Init SHA256Init SHA256_Init) + string(TOUPPER "HAVE_${X}" HAVE_X) + + # On FreeBSD, defines the SHA-256 functions as + # macros to rename them for namespace reasons. Avoid + # check_symbol_exists as that would accept macros without + # checking if the program links. + set(SOURCE + "#include + #include <${SHA256_HEADER}> + int main(void) + { + ${SHA256_TYPE} ctx; + ${X}(&ctx); + return 0; + }") + + check_c_source_compiles("${SOURCE}" "${HAVE_X}") + if(${HAVE_X}) + target_compile_definitions(liblzma PRIVATE "${HAVE_X}") + set(USE_INTERNAL_SHA256 OFF) + break() + else() + # Try with libmd. Other checks don't need it so we + # don't need to leave it into CMAKE_REQUIRED_LIBRARIES. + list(INSERT CMAKE_REQUIRED_LIBRARIES 0 md) + check_c_source_compiles("${SOURCE}" "${HAVE_X}_LIBMD") + list(REMOVE_AT CMAKE_REQUIRED_LIBRARIES 0) + if(${HAVE_X}_LIBMD) + # NOTE: Just "${HAVE_X}", not "${HAVE_X}_LIBMD": + target_compile_definitions(liblzma PRIVATE + "${HAVE_X}") + target_link_libraries(liblzma PRIVATE md) + set(LIBS "-lmd ${LIBS}") # For liblzma.pc + set(USE_INTERNAL_SHA256 OFF) + break() + endif() + endif() + endforeach() + endif() + endif() + endif() + + if(USE_INTERNAL_SHA256) + target_sources(liblzma PRIVATE src/liblzma/check/sha256.c) + endif() endif()