From 1dbb5a6a14006330aa45afb848e5374b0ed08a57 Mon Sep 17 00:00:00 2001 From: Michael Graeb Date: Thu, 8 Sep 2022 12:41:21 -0700 Subject: [PATCH] allow static or shared libs to be used (#601) Currently, a static lib that uses AWS-LC must use a static build of AWS-LC, it cannot use a shared build. And vice-versa, a shared lib that uses AWS-LC must use a shared build of AWS-LC, it cannot use a static build. With this change, either a static or shared build of AWS-LC can be used. If both are installed, then BUILD_SHARED_LIBS serves as a tie-breaker between the two. --- crypto/cmake/crypto-config.cmake | 21 ++- ssl/cmake/ssl-config.cmake | 14 +- .../github_ci_linux_x86_omnibus.yaml | 8 ++ .../linux-x86/install_shared_and_static.yml | 9 ++ tests/ci/run_install_shared_and_static.sh | 133 ++++++++++++++++++ 5 files changed, 178 insertions(+), 7 deletions(-) create mode 100644 tests/ci/codebuild/linux-x86/install_shared_and_static.yml create mode 100755 tests/ci/run_install_shared_and_static.sh diff --git a/crypto/cmake/crypto-config.cmake b/crypto/cmake/crypto-config.cmake index 4854242162..722a2acae6 100644 --- a/crypto/cmake/crypto-config.cmake +++ b/crypto/cmake/crypto-config.cmake @@ -2,11 +2,22 @@ if(WIN32 OR UNIX OR APPLE) find_package(Threads REQUIRED) endif() +# Allow static or shared lib to be used. +# If both are installed, choose based on BUILD_SHARED_LIBS. if (BUILD_SHARED_LIBS) - message(STATUS "FOUND AWS-LC CRYPTO cmake config - shared") - include(${CMAKE_CURRENT_LIST_DIR}/shared/crypto-targets.cmake) + if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/shared/crypto-targets.cmake") + include(${CMAKE_CURRENT_LIST_DIR}/shared/crypto-targets.cmake) + message(STATUS "FOUND AWS-LC CRYPTO cmake config - shared") + else() + include(${CMAKE_CURRENT_LIST_DIR}/static/crypto-targets.cmake) + message(STATUS "FOUND AWS-LC CRYPTO cmake config - static") + endif() else() - message(STATUS "FOUND AWS-LC CRYPTO cmake config - static") - include(${CMAKE_CURRENT_LIST_DIR}/static/crypto-targets.cmake) + if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/static/crypto-targets.cmake") + include(${CMAKE_CURRENT_LIST_DIR}/static/crypto-targets.cmake) + message(STATUS "FOUND AWS-LC CRYPTO cmake config - static") + else() + include(${CMAKE_CURRENT_LIST_DIR}/shared/crypto-targets.cmake) + message(STATUS "FOUND AWS-LC CRYPTO cmake config - shared") + endif() endif() - diff --git a/ssl/cmake/ssl-config.cmake b/ssl/cmake/ssl-config.cmake index 49fb6cee5d..cb885b7c62 100644 --- a/ssl/cmake/ssl-config.cmake +++ b/ssl/cmake/ssl-config.cmake @@ -2,8 +2,18 @@ include(CMakeFindDependencyMacro) find_dependency(crypto) +# Allow static or shared lib to be used. +# If both are installed, choose based on BUILD_SHARED_LIBS. if (BUILD_SHARED_LIBS) - include(${CMAKE_CURRENT_LIST_DIR}/shared/ssl-targets.cmake) + if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/shared/ssl-targets.cmake") + include(${CMAKE_CURRENT_LIST_DIR}/shared/ssl-targets.cmake) + else() + include(${CMAKE_CURRENT_LIST_DIR}/static/ssl-targets.cmake) + endif() else() - include(${CMAKE_CURRENT_LIST_DIR}/static/ssl-targets.cmake) + if (EXISTS "${CMAKE_CURRENT_LIST_DIR}/static/ssl-targets.cmake") + include(${CMAKE_CURRENT_LIST_DIR}/static/ssl-targets.cmake) + else() + include(${CMAKE_CURRENT_LIST_DIR}/shared/ssl-targets.cmake) + endif() endif() diff --git a/tests/ci/cdk/cdk/codebuild/github_ci_linux_x86_omnibus.yaml b/tests/ci/cdk/cdk/codebuild/github_ci_linux_x86_omnibus.yaml index b17c842146..39e60c2771 100644 --- a/tests/ci/cdk/cdk/codebuild/github_ci_linux_x86_omnibus.yaml +++ b/tests/ci/cdk/cdk/codebuild/github_ci_linux_x86_omnibus.yaml @@ -232,6 +232,14 @@ batch: compute-type: BUILD_GENERAL1_LARGE image: 620771051181.dkr.ecr.us-west-2.amazonaws.com/aws-lc-docker-images-linux-x86:ubuntu-20.04_clang-9x_latest + - identifier: install_shared_and_static + buildspec: ./tests/ci/codebuild/linux-x86/install_shared_and_static.yml + env: + type: LINUX_CONTAINER + privileged-mode: false + compute-type: BUILD_GENERAL1_SMALL + image: 620771051181.dkr.ecr.us-west-2.amazonaws.com/aws-lc-docker-images-linux-x86:ubuntu-20.04_clang-9x_latest + - identifier: fedora31_clang9x_x86_64 buildspec: ./tests/ci/codebuild/linux-x86/fedora-31_clang-9x.yml env: diff --git a/tests/ci/codebuild/linux-x86/install_shared_and_static.yml b/tests/ci/codebuild/linux-x86/install_shared_and_static.yml new file mode 100644 index 0000000000..f2d67bc245 --- /dev/null +++ b/tests/ci/codebuild/linux-x86/install_shared_and_static.yml @@ -0,0 +1,9 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 + +version: 0.2 + +phases: + build: + commands: + - ./tests/ci/run_install_shared_and_static.sh diff --git a/tests/ci/run_install_shared_and_static.sh b/tests/ci/run_install_shared_and_static.sh new file mode 100755 index 0000000000..efb9776909 --- /dev/null +++ b/tests/ci/run_install_shared_and_static.sh @@ -0,0 +1,133 @@ +#!/bin/bash +set -exo pipefail +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 + +source tests/ci/common_posix_setup.sh +print_system_and_dependency_information + +export CMAKE_BUILD_PARALLEL_LEVEL=${NUM_CPU_THREADS} + +# Set up environment. + +# ROOT +# | +# - AWS_LC_DIR +# | +# - SCRATCH_FOLDER +# | +# - BUILD_DIR +# - install-shared +# - install-static +# - install-both +# - MYAPP_SRC + +# Assumes script is executed from the root of aws-lc directory +AWS_LC_DIR=$(pwd) +ROOT=$(realpath ${AWS_LC_DIR}/..) + +SCRATCH_DIR=${ROOT}/SCRATCH_AWSLC_INSTALL_SHARED_AND_STATIC +mkdir -p ${SCRATCH_DIR} +rm -rf ${SCRATCH_DIR}/* + +function fail() { + echo "test failure: $1" + exit 1 +} + +function install_aws_lc() { + local INSTALL_DIR=${SCRATCH_DIR}/$1 + local BUILD_SHARED_LIBS=$2 + + local BUILD_DIR=${SCRATCH_DIR}/build + rm -rf ${BUILD_DIR} + ${CMAKE_COMMAND} -H${AWS_LC_DIR} -B${BUILD_DIR} -GNinja -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} -DBUILD_TESTING=OFF -D${BUILD_SHARED_LIBS} + ${CMAKE_COMMAND} --build ${BUILD_DIR} --target install +} + +# create installation with shared libssl.so/libcrypto.so +install_aws_lc install-shared BUILD_SHARED_LIBS=ON + +# create installation with static libssl.a/libcrypto.a +install_aws_lc install-static BUILD_SHARED_LIBS=OFF + +# create installation with both shared libssl.so/libcrypto.so and static libssl.a/libcrypto.a +install_aws_lc install-both BUILD_SHARED_LIBS=OFF +install_aws_lc install-both BUILD_SHARED_LIBS=ON + +# write out source of a small cmake project, containing: +# - mylib: a library that uses AWS-LC +# - myapp: executable that uses mylib +MYAPP_SRC_DIR=${SCRATCH_DIR}/myapp-src +rm -rf ${MYAPP_SRC_DIR} +mkdir -p ${MYAPP_SRC_DIR} + +cat < ${MYAPP_SRC_DIR}/mylib.c +#include +void mylib_init(void) { + OPENSSL_init_ssl(0, NULL); +} +EOF + +cat < ${MYAPP_SRC_DIR}/myapp.c +extern void mylib_init(void); +int main() { + mylib_init(); +} +EOF + +cat < ${MYAPP_SRC_DIR}/CMakeLists.txt +cmake_minimum_required (VERSION 3.0) +project (myapp C) +add_library(mylib mylib.c) +find_package(ssl REQUIRED) +target_link_libraries(mylib PRIVATE AWS::ssl) +add_executable(myapp myapp.c) +target_link_libraries(myapp PRIVATE mylib) +EOF + +# build myapp and mylib, confirm that expected type of libssl and libcrypto are used +build_myapp() { + local BUILD_SHARED_LIBS=$1 # ("BUILD_SHARED_LIBS=ON" or "BUILD_SHARED_LIBS=OFF") + local AWS_LC_INSTALL_DIR=$2 # which install dir should be used + local EXPECT_USE_LIB_TYPE=$3 # (".so" or ".a") which types of libssl and libcrypto are expected to be used + + local BUILD_DIR=${SCRATCH_DIR}/build + rm -rf ${BUILD_DIR} + + cmake -H${MYAPP_SRC_DIR} -B${BUILD_DIR} -GNinja -D${BUILD_SHARED_LIBS} -DCMAKE_PREFIX_PATH=${SCRATCH_DIR}/${AWS_LC_INSTALL_DIR} + cmake --build ${BUILD_DIR} + ldd ${BUILD_DIR}/myapp + + test_lib_use ${BUILD_DIR}/myapp libssl ${EXPECT_USE_LIB_TYPE} + test_lib_use ${BUILD_DIR}/myapp libcrypto ${EXPECT_USE_LIB_TYPE} +} + +# test that app is using expected library +test_lib_use() { + local APP=$1 # app to examine + local LIB_NAME=$2 # name of lib that app should be using, without file extension + local EXPECT_USE_LIB_TYPE=$3 # (".so" or ".a") expected type of lib that app should be using + + if ldd ${APP} | grep -q ${LIB_NAME}.so; then + local ACTUAL_USE_LIB_TYPE=.so + else + local ACTUAL_USE_LIB_TYPE=.a + fi + + if [ ${ACTUAL_USE_LIB_TYPE} != ${EXPECT_USE_LIB_TYPE} ]; then + fail "used ${LIB_NAME}${ACTUAL_USE_LIB_TYPE}, but expected to use ${LIB_NAME}${EXPECT_USE_LIB_TYPE}" + fi +} + +# if only shared libssl.so/libcrypto.so are available, that's what should get used +build_myapp BUILD_SHARED_LIBS=ON install-shared .so +build_myapp BUILD_SHARED_LIBS=OFF install-shared .so + +# if only static libssl.a/libcrypto.a are available, that's what should get used +build_myapp BUILD_SHARED_LIBS=ON install-static .a +build_myapp BUILD_SHARED_LIBS=OFF install-static .a + +# if both shared libssl.so/libcrypto.so and static libssl.a/libcrypto.a are available... +build_myapp BUILD_SHARED_LIBS=ON install-both .so # myapp should use libssl.so/libcrypto.so +build_myapp BUILD_SHARED_LIBS=OFF install-both .a # myapp should use libssl.a/libcrypto.a