diff --git a/.github/workflows/ci_c.yml b/.github/workflows/ci_c.yml new file mode 100644 index 00000000000..73144ebbf62 --- /dev/null +++ b/.github/workflows/ci_c.yml @@ -0,0 +1,84 @@ +--- +name: C Code + +on: + push: + branches: [main] + pull_request: + branches: [main] + merge_group: + types: [checks_requested] + branches: [main] + workflow_dispatch: + +jobs: + libcrypto-with-dependency: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + + - name: Cache OpenSSL + id: cache-openssl + uses: actions/cache@v4 + with: + path: ./openssl-3.5.4/openssl-install + key: ${{ runner.os }}-openssl-3.5.4 + + - name: Install OpenSSL + if: ${{ steps.cache-openssl.outputs.cache-hit != 'true' }} + run: | + wget https://github.com/openssl/openssl/releases/download/openssl-3.5.4/openssl-3.5.4.tar.gz + tar -xzvf openssl-3.5.4.tar.gz + + pushd openssl-3.5.4 + install_dir="$(pwd)"/openssl-install + mkdir "${install_dir}" + + # Build OpenSSL with a dependency on zlib. + ./config \ + --prefix="${install_dir}" \ + --openssldir="${install_dir}/openssl" \ + --libdir=lib \ + zlib + make + make install + + ls + + # Ensure the built libcrypto has a dependency on zlib. + ldd "${install_dir}"/lib/libcrypto.so | grep libz.so + + popd + + - name: Build static + run: | + libcrypto_dir="$(pwd)/openssl-3.5.4/openssl-install" + cmake . -Bbuild \ + -DCMAKE_PREFIX_PATH="${libcrypto_dir}" \ + -DBUILD_SHARED_LIBS=0 + + jobs=$(nproc) + cmake --build build -j $jobs + CTEST_PARALLEL_LEVEL=$jobs ctest --test-dir build + + - name: Build shared + run: | + libcrypto_dir="$(pwd)/openssl-3.5.4/openssl-install" + cmake . -Bbuild \ + -DCMAKE_PREFIX_PATH="${libcrypto_dir}" \ + -DBUILD_SHARED_LIBS=1 + + jobs=$(nproc) + cmake --build build -j $jobs + CTEST_PARALLEL_LEVEL=$jobs ctest --test-dir build + + - name: Build with interning + run: | + libcrypto_dir="$(pwd)/openssl-3.5.4/openssl-install" + cmake . -Bbuild \ + -DCMAKE_PREFIX_PATH="${libcrypto_dir}" \ + -DS2N_INTERN_LIBCRYPTO=1 + + jobs=$(nproc) + cmake --build build -j $jobs + CTEST_PARALLEL_LEVEL=$jobs ctest --test-dir build diff --git a/CMakeLists.txt b/CMakeLists.txt index 0e976d0c115..318f1f57f7b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -432,6 +432,15 @@ if (S2N_INTERN_LIBCRYPTO) add_dependencies(${PROJECT_NAME} s2n_libcrypto) add_definitions(-DS2N_INTERN_LIBCRYPTO=1) + # Now that the libcrypto lives inside libs2n, any dependencies of the libcrypto must become + # dependencies of libs2n. + get_target_property(crypto_LINK_LIBRARIES AWS::crypto INTERFACE_LINK_LIBRARIES) + if (crypto_LINK_LIBRARIES) + foreach (link_library ${crypto_LINK_LIBRARIES}) + target_link_libraries(${PROJECT_NAME} PUBLIC ${link_library}) + endforeach() + endif() + if ((BUILD_SHARED_LIBS AND BUILD_TESTING) OR NOT BUILD_SHARED_LIBS) # if libcrypto needs to be interned, rewrite libcrypto references so use of internal functions will link correctly add_custom_command( diff --git a/cmake/modules/Findcrypto.cmake b/cmake/modules/Findcrypto.cmake index 1ac4d9a619b..21e989fd3b5 100644 --- a/cmake/modules/Findcrypto.cmake +++ b/cmake/modules/Findcrypto.cmake @@ -31,29 +31,49 @@ if (TARGET crypto OR TARGET AWS::crypto) set(CRYPTO_FOUND true) set(crypto_FOUND true) else() - find_path(crypto_INCLUDE_DIR - NAMES openssl/crypto.h - HINTS - "${CMAKE_PREFIX_PATH}" - "${CMAKE_INSTALL_PREFIX}" - PATH_SUFFIXES include - ) + if(NOT BUILD_SHARED_LIBS AND NOT S2N_USE_CRYPTO_SHARED_LIBS) + set(OPENSSL_USE_STATIC_LIBS TRUE) + endif() + find_package(OpenSSL COMPONENTS Crypto QUIET) + if (OpenSSL_FOUND) + set(crypto_INCLUDE_DIR ${OPENSSL_INCLUDE_DIR}) + set(crypto_LIBRARY ${OPENSSL_CRYPTO_LIBRARY}) - find_library(crypto_SHARED_LIBRARY - NAMES libcrypto.so libcrypto.dylib - HINTS - "${CMAKE_PREFIX_PATH}" - "${CMAKE_INSTALL_PREFIX}" - PATH_SUFFIXES build/crypto build lib64 lib - ) + # CMakeLists.txt expects the crypto_SHARED_LIBRARY/crypto_STATIC_LIBRARY variables to be + # set. However, the FindOpenSSL module doesn't set separate variables depending on whether + # the artifact is shared or static. And, the TYPE property isn't set on the OpenSSL::Crypto + # target, so we can't use `get_target_property()` to determine this. Instead, we check for + # a ".a" suffix in the artifact path. + if ("${crypto_LIBRARY}" MATCHES "\\.a$") + set(crypto_STATIC_LIBRARY "${crypto_LIBRARY}") + else() + set(crypto_SHARED_LIBRARY "${crypto_LIBRARY}") + endif() + else() + find_path(crypto_INCLUDE_DIR + NAMES openssl/crypto.h + HINTS + "${CMAKE_PREFIX_PATH}" + "${CMAKE_INSTALL_PREFIX}" + PATH_SUFFIXES include + ) - find_library(crypto_STATIC_LIBRARY - NAMES libcrypto.a - HINTS - "${CMAKE_PREFIX_PATH}" - "${CMAKE_INSTALL_PREFIX}" - PATH_SUFFIXES build/crypto build lib64 lib - ) + find_library(crypto_SHARED_LIBRARY + NAMES libcrypto.so libcrypto.dylib + HINTS + "${CMAKE_PREFIX_PATH}" + "${CMAKE_INSTALL_PREFIX}" + PATH_SUFFIXES build/crypto build lib64 lib + ) + + find_library(crypto_STATIC_LIBRARY + NAMES libcrypto.a + HINTS + "${CMAKE_PREFIX_PATH}" + "${CMAKE_INSTALL_PREFIX}" + PATH_SUFFIXES build/crypto build lib64 lib + ) + endif() if (NOT crypto_LIBRARY) if (BUILD_SHARED_LIBS OR S2N_USE_CRYPTO_SHARED_LIBS) @@ -92,6 +112,12 @@ else() set(CRYPTO_FOUND true) set(crypto_FOUND true) + if (TARGET OpenSSL::Crypto) + message(STATUS "libcrypto discovered by the FindOpenSSL module") + else() + message(STATUS "libcrypto discovered by the s2n-tls Findcrypto module") + endif() + message(STATUS "LibCrypto Include Dir: ${crypto_INCLUDE_DIR}") message(STATUS "LibCrypto Shared Lib: ${crypto_SHARED_LIBRARY}") message(STATUS "LibCrypto Static Lib: ${crypto_STATIC_LIBRARY}") @@ -107,6 +133,19 @@ else() IMPORTED_LINK_INTERFACE_LANGUAGES "C" IMPORTED_LOCATION "${crypto_LIBRARY}") add_dependencies(AWS::crypto Threads::Threads) + + if (TARGET OpenSSL::Crypto) + # The discovered libcrypto may have been configured with additional dependencies + # such as zlib. If any dependencies were discovered by the FindOpenSSL module, add + # them to the AWS::crypto target. + get_target_property(OpenSSL_LINK_LIBRARIES OpenSSL::Crypto + INTERFACE_LINK_LIBRARIES) + if (OpenSSL_LINK_LIBRARIES) + foreach (link_library ${OpenSSL_LINK_LIBRARIES}) + target_link_libraries(AWS::crypto INTERFACE ${link_library}) + endforeach() + endif() + endif() endif() endif() diff --git a/codebuild/spec/buildspec_32bit_cross_compile.yml b/codebuild/spec/buildspec_32bit_cross_compile.yml index 67eb9450fac..dcdf2c5feb3 100644 --- a/codebuild/spec/buildspec_32bit_cross_compile.yml +++ b/codebuild/spec/buildspec_32bit_cross_compile.yml @@ -23,7 +23,10 @@ phases: build: on-failure: ABORT commands: - - cmake . -Bbuild -DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/32-bit.toolchain + - | + cmake . -Bbuild \ + -DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/32-bit.toolchain \ + -DCMAKE_PREFIX_PATH=/usr/lib/i386-linux-gnu - cmake --build ./build -j $(nproc) post_build: on-failure: ABORT