# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0. # # When using AWSSDK package, users need to tell the installation root dir # by setting up variable as set(AWSSDK_ROOT_DIR, "") # In Windows the dir is like C:/Progra~1/AWSSDK/ # In Unix like system the dir is like /usr/local/ # if AWSSDK_ROOT_DIR doesn't appear, this module will identify it automatically # By default: # The cmake files will all be in /lib/cmake dir # The headers will all be in /include dir # The libraries will all be in /lib/ dir # The binaries will all be in /bin/ dir # The archives will all be in /lib/ dir if target is shared, # otherwise will be in /bin/ dir. # Platform_prefix is determined on compile time nbu option SIMPLE_INSTALL # such as "" if(AWSSDK_FOUND) return() endif() include(${CMAKE_CURRENT_LIST_DIR}/sdksCommon.cmake) include(${CMAKE_CURRENT_LIST_DIR}/platformDeps.cmake) include(${CMAKE_CURRENT_LIST_DIR}/compiler_settings.cmake) if (NOT AWSSDK_INSTALL_LIBDIR) set(AWSSDK_INSTALL_LIBDIR "lib") endif() if (NOT AWSSDK_INSTALL_BINDIR) set(AWSSDK_INSTALL_BINDIR "bin") endif() if (NOT AWSSDK_INSTALL_INCLUDEDIR) set(AWSSDK_INSTALL_INCLUDEDIR "include") endif() if (DEFINED CMAKE_PREFIX_PATH) file(TO_CMAKE_PATH "${CMAKE_PREFIX_PATH}" CMAKE_PREFIX_PATH) endif() if (DEFINED CMAKE_INSTALL_PREFIX) file(TO_CMAKE_PATH "${CMAKE_INSTALL_PREFIX}" CMAKE_INSTALL_PREFIX) endif() set(AWS_MODULE_DIR "/${AWSSDK_INSTALL_LIBDIR}/cmake") string(REPLACE ";" "${AWS_MODULE_DIR};" AWS_MODULE_PATH "${CMAKE_PREFIX_PATH}${AWS_MODULE_DIR}") string(REPLACE ";" "${AWS_MODULE_DIR};" SYSTEM_MODULE_PATH "${CMAKE_SYSTEM_PREFIX_PATH}${AWS_MODULE_DIR}") list(APPEND CMAKE_MODULE_PATH ${AWS_MODULE_PATH} ${SYSTEM_MODULE_PATH}) # On Windows, dlls are treated as runtime target and installed in bindir if (WIN32 AND AWSSDK_INSTALL_AS_SHARED_LIBS) set(AWSSDK_INSTALL_LIBDIR "${AWSSDK_INSTALL_BINDIR}") # If installed CMake scripts are associated with dll library, define USE_IMPORT_EXPORT for customers add_definitions(-DUSE_IMPORT_EXPORT) endif() # Compute the default installation root relative to this file. # from prefix/lib/cmake/AWSSDK/xx.cmake to prefix get_filename_component(AWSSDK_DEFAULT_ROOT_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) get_filename_component(AWSSDK_DEFAULT_ROOT_DIR "${AWSSDK_DEFAULT_ROOT_DIR}" PATH) get_filename_component(AWSSDK_DEFAULT_ROOT_DIR "${AWSSDK_DEFAULT_ROOT_DIR}" PATH) get_filename_component(AWSSDK_DEFAULT_ROOT_DIR "${AWSSDK_DEFAULT_ROOT_DIR}" PATH) get_filename_component(AWS_NATIVE_SDK_ROOT "${CMAKE_CURRENT_SOURCE_DIR}" ABSOLUTE) set(CPP_STANDARD "11" CACHE STRING "Flag to upgrade the C++ standard used. The default is 11. The minimum is 11.") if(AWSSDK_DEFAULT_ROOT_DIR STREQUAL "/") set(AWSSDK_DEFAULT_ROOT_DIR "") endif() # currently AWSSDK_ROOT_DIR is either empty or user specified if (AWSSDK_ROOT_DIR) find_file(AWSSDK_CORE_HEADER_FILE Aws.h "${AWSSDK_ROOT_DIR}/${AWSSDK_INSTALL_INCLUDEDIR}/aws/core" "${AWSSDK_DEFAULT_ROOT_DIR}/${AWSSDK_INSTALL_INCLUDEDIR}/aws/core" ) else() find_file(AWSSDK_CORE_HEADER_FILE Aws.h "${AWSSDK_DEFAULT_ROOT_DIR}/${AWSSDK_INSTALL_INCLUDEDIR}/aws/core" "/usr/${AWSSDK_INSTALL_INCLUDEDIR}/aws/core" "/usr/local/${AWSSDK_INSTALL_INCLUDEDIR}/aws/core" "C:/Progra~1/AWSSDK/${AWSSDK_INSTALL_INCLUDEDIR}/aws/core" "C:/Program Files/AWSSDK/${AWSSDK_INSTALL_INCLUDEDIR}/aws/core" "C:/Program Files/aws-cpp-sdk-all/${AWSSDK_INSTALL_INCLUDEDIR}/aws/core" "C:/Program Files (x86)/aws-cpp-sdk-all/${AWSSDK_INSTALL_INCLUDEDIR}/aws/core" "C:/AWSSDK/${AWSSDK_INSTALL_INCLUDEDIR}/aws/core" ) endif() if (NOT AWSSDK_CORE_HEADER_FILE) message(FATAL_ERROR "AWS SDK for C++ is missing, please install it first") endif() if (IS_ABSOLUTE ${AWSSDK_INSTALL_LIBDIR}) set(AWSSDK_ROOT_DIR "") else() # based on core header file path, inspects the actual AWSSDK_ROOT_DIR get_filename_component(AWSSDK_ROOT_DIR "${AWSSDK_CORE_HEADER_FILE}" PATH) get_filename_component(AWSSDK_ROOT_DIR "${AWSSDK_ROOT_DIR}" PATH) get_filename_component(AWSSDK_ROOT_DIR "${AWSSDK_ROOT_DIR}" PATH) get_filename_component(AWSSDK_ROOT_DIR "${AWSSDK_ROOT_DIR}" PATH) if (NOT AWSSDK_ROOT_DIR) message(FATAL_ERROR "AWSSDK_ROOT_DIR is not set or can't be calculated from the path of core header file") endif() endif() find_library(AWSSDK_CORE_LIB_FILE aws-cpp-sdk-core "${AWSSDK_ROOT_DIR}/${AWSSDK_INSTALL_LIBDIR}/${AWSSDK_PLATFORM_PREFIX}" "${AWSSDK_ROOT_DIR}/${AWSSDK_INSTALL_LIBDIR}/${AWSSDK_PLATFORM_PREFIX}/Debug" "${AWSSDK_ROOT_DIR}/${AWSSDK_INSTALL_LIBDIR}/${AWSSDK_PLATFORM_PREFIX}/DebugOpt" "${AWSSDK_ROOT_DIR}/${AWSSDK_INSTALL_LIBDIR}/${AWSSDK_PLATFORM_PREFIX}/Release" "${AWSSDK_ROOT_DIR}/${AWSSDK_INSTALL_LIBDIR}/${AWSSDK_PLATFORM_PREFIX}/RelWithDebInfo" "${AWSSDK_ROOT_DIR}/${AWSSDK_INSTALL_LIBDIR}/${AWSSDK_PLATFORM_PREFIX}/MinSizeRel" NO_DEFAULT_PATH) if (NOT AWSSDK_CORE_LIB_FILE) message(FATAL_ERROR "AWS SDK for C++ headers found, but we were unable to locate the binaries. Have you deleted or moved it? Please make sure header files and binaries are located in INSTALL_ROOT_DIR/INCLUDE_DIR/ and INSTALL_ROOT_DIR/LIB_DIR/[PLATFORM_PREFIX]/[Debug|Config|OtherConfigs]") endif() # based on AWSSDK_CORE_LIB_FILE path, inspects the actual AWSSDK_PLATFORM_PREFIX get_filename_component(TEMP_PATH "${AWSSDK_CORE_LIB_FILE}" PATH) get_filename_component(TEMP_NAME "${TEMP_PATH}" NAME) if (LIB_SEARCH_PREFIX) while (NOT TEMP_NAME STREQUAL "${LIB_SEARCH_PREFIX}") set(TEMP_PLATFORM_PREFIX "${TEMP_NAME}/${TEMP_PLATFORM_PREFIX}") get_filename_component(TEMP_PATH "${TEMP_PATH}" PATH) get_filename_component(TEMP_NAME "${TEMP_PATH}" NAME) endwhile() endif() set(AWSSDK_PLATFORM_PREFIX "${TEMP_PLATFORM_PREFIX}") set(AWSSDK_FOUND TRUE) set(AWSSDK_INCLUDE_DIR "${AWSSDK_ROOT_DIR}/${AWSSDK_INSTALL_INCLUDEDIR}") set(AWSSDK_CMAKE_DIR "${AWSSDK_ROOT_DIR}/${AWSSDK_INSTALL_LIBDIR}/cmake") set(AWSSDK_LIB_DIR "${AWSSDK_ROOT_DIR}/${AWSSDK_INSTALL_LIBDIR}/${AWSSDK_PLATFORM_PREFIX}") set(AWSSDK_BIN_DIR "${AWSSDK_ROOT_DIR}/${AWSSDK_INSTALL_BINDIR}/${AWSSDK_PLATFORM_PREFIX}") if (AWSSDK_PLATFORM_DEPS_LIBS) set(AWSSDK_PLATFORM_DEPS "${AWSSDK_PLATFORM_DEPS_LIBS}") endif() if (AWSSDK_CRYPTO_LIBS) set(AWSSDK_PLATFORM_DEPS "${AWSSDK_PLATFORM_DEPS}" "${AWSSDK_CRYPTO_LIBS}") endif() if (AWSSDK_CLIENT_LIBS) set(AWSSDK_PLATFORM_DEPS "${AWSSDK_PLATFORM_DEPS}" "${AWSSDK_CLIENT_LIBS}") endif() if (AWSSDK_ADDITIONAL_LIBS) set(AWSSDK_PLATFORM_DEPS "${AWSSDK_PLATFORM_DEPS}" "${AWSSDK_ADDITIONAL_LIBS}") endif() message(STATUS "Found AWS SDK for C++, Version: ${AWSSDK_VERSION}, Install Root:${AWSSDK_ROOT_DIR}, Platform Prefix:${AWSSDK_PLATFORM_PREFIX}, Platform Dependent Libraries: ${AWSSDK_PLATFORM_DEPS}") # copy libs of services in SERVICE_LIST and all there dependent libs to DEST_DIR # CONFIG denote copy release or debug version macro(AWSSDK_CPY_DYN_LIBS SERVICE_LIST CONFIG DEST_DIR) set(ALL_SERVICES "core" ${AWSSDK_COMMON_RUNTIME_LIBS}) foreach(SVC IN LISTS ${SERVICE_LIST}) list(APPEND ALL_SERVICES ${SVC}) get_dependencies_for_sdk(${SVC} DEPENDENCY_LIST) if (DEPENDENCY_LIST) string(REPLACE "," ";" LIST_RESULT ${DEPENDENCY_LIST}) list(APPEND ALL_SERVICES ${LIST_RESULT}) endif() unset(DEPENDENCY_LIST CACHE) endforeach() list(REMOVE_DUPLICATES ALL_SERVICES) foreach(SVC IN LISTS ALL_SERVICES) if (WIN32) set(CMAKE_FIND_LIBRARY_SUFFIXES_TEMP ${CMAKE_FIND_LIBRARY_SUFFIXES}) set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll") endif() find_library(LIB_PATH "aws-cpp-sdk-${SVC}" "${AWSSDK_LIB_DIR}/${CONFIG}" NO_DEFAULT_PATH) if (NOT LIB_PATH) find_library(LIB_PATH "${SVC}" "${AWSSDK_LIB_DIR}/${CONFIG}" NO_DEFAULT_PATH) if (NOT LIB_PATH) message(FATAL_ERROR "Couldn't find library aws-cpp-sdk-${SVC} or ${SVC}") endif() endif() file(COPY ${LIB_PATH} DESTINATION ${DEST_DIR}) unset(LIB_PATH CACHE) if (WIN32) set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_TEMP}) endif() endforeach() endmacro(AWSSDK_CPY_DYN_LIBS) # output link libs command to OUTPUT_VAR which required by all services from SERVCE_LIST macro(AWSSDK_DETERMINE_LIBS_TO_LINK SERVICE_LIST OUTPUT_VAR) foreach(SVC IN LISTS ${SERVICE_LIST}) list(APPEND ALL_SERVICES ${SVC}) get_dependencies_for_sdk(${SVC} DEPENDENCY_LIST) if (DEPENDENCY_LIST) string(REPLACE "," ";" LIST_RESULT ${DEPENDENCY_LIST}) list(APPEND ALL_SERVICES ${LIST_RESULT}) endif() unset(DEPENDENCY_LIST CACHE) endforeach() list(REMOVE_DUPLICATES ALL_SERVICES) # Order the dependencies correctly # Change order from e.g. "core;transfer;s3;s3-encryption;kms" to "transfer;s3-encryption;kms;s3;core". # This is important for static linked user application. # They way of doing this is to keep checking libs after current lib till the end, if current lib is a dependency of checking lib, # then move current lib to the end of list, after moving, current index stay and start another round of checking. If no libs after # current lib is a dependency of current lib, move current index to next and start another round of checking. # Example: "s3;core;transfer" #-> s3(cur);core(checking);transfer s3 is not a dependency of core #-> s3(cur);core;transfer(checking) s3 is a dependency of transfer #-> core(cur);transfer(checking);s3 core is a dependency of transfer #-> transfer(cur);s3(checking);core transfer is not a dependency of s3 #-> transfer(cur);s3;core(checking) transfer is not a dependency of core #-> transfer;s3(cur);core(checking) s3 is not a dependency of core #-> transfer;s3;core(cur) end of checking list(LENGTH ALL_SERVICES length) math(EXPR length ${length}-1) # Get index of last element. if (length GREATER 0) # If more than 1 element. set(i 0) while (i LESS length) # No need to process last element list(GET ALL_SERVICES ${i} SVC) math(EXPR j ${i}+1) math(EXPR jEnd ${length}+1) while (j LESS jEnd) list(GET ALL_SERVICES ${j} NEXT_SVC) get_dependencies_for_sdk(${NEXT_SVC} DEPENDING_SDKS) if (DEPENDING_SDKS) string(REPLACE "," ";" DEPENDING_SDKS ${DEPENDING_SDKS}) endif() list(FIND DEPENDING_SDKS ${SVC} index) if (NOT ${index} EQUAL -1) # NEXT_SVC depend on SVC list(REMOVE_AT ALL_SERVICES ${i}) # Move SVC to end list(APPEND ALL_SERVICES ${SVC}) math(EXPR i ${i}-1) # make index point to new element but with the same index. break() # as long as we moved SVC to end, the inner loop can be broke. endif() math(EXPR j ${j}+1) endwhile() if (i LESS 0) #CMake with some older versions (at least 3.6.0) do not support negative numbers in math expr e.g.: math(EXPR i -1+1) set(i 0) else() math(EXPR i ${i}+1) endif() endwhile() endif() set(${OUTPUT_VAR} "") foreach(DEP IN LISTS ALL_SERVICES) list(APPEND ${OUTPUT_VAR} "aws-cpp-sdk-${DEP}") endforeach() if (NOT AWSSDK_INSTALL_AS_SHARED_LIBS) list(APPEND ${OUTPUT_VAR} ${AWSSDK_COMMON_RUNTIME_LIBS} ${AWSSDK_PLATFORM_DEPS}) endif() endmacro(AWSSDK_DETERMINE_LIBS_TO_LINK) # output high level lib dependencies such as for transfer; sqs; dynamodb etc. macro(AWSSDK_LIB_DEPS HIGH_LEVEL_LIB_NAME OUTPUT_VAR) get_dependencies_for_sdk(${HIGH_LEVEL_LIB_NAME} DEPENDENCY_LIST) if (DEPENDENCY_LIST) string(REPLACE "," ";" ${OUTPUT_VAR} ${DEPENDENCY_LIST}) list(APPEND ALL_SERVICES ${LIST_RESULT}) endif() list(APPEND ${OUTPUT_VAR} "core") list(REMOVE_DUPLICATES ${OUTPUT_VAR}) endmacro(AWSSDK_LIB_DEPS) if (AWSSDK_FIND_COMPONENTS) #AWSSDK_LINK_LIBRARIES includes all the libraries (including dependencies) used by SDK and needed by customer application when doing linking. #It only comes with COMPONENTS when doing find_package in customer application. e.g. find_package(AWSSDK REQUIRED COMPONENTS s3 ec2) #While SDK will resolve all the dependencies for customer application by doing find_package when COMPONENTS are specified, #there is no need to add those dependencies into AWSSDK_LINK_LIBRARIES. Dependencies in AWSSDK_LINK_LIBRARIES will also become a problem when #customer specified CMAKE_PREFIX_PATH and set it with non-default CMake search directories for dependencies when building SDK. In this case, when building customer #application, target_link_libraries(target ${AWSSDK_LINK_LIBRARIES}) will fail to find the dependencies even when you specify CMAKE_PREFIX_PATH to the same directories. #See https://github.com/aws/aws-sdk-cpp/issues/1279 #Because CMAKE_PREFIX_PATH is used for find_package, find_dependency, find_library, etc, but not target_link_libraries. #Well, you could still solve it by adding an additional target_link_directories call before target_link_libraries, whereas remove those dependencies from #AWSSDK_LINK_LIBRARIES will be more convenient and less confusing. AWSSDK_DETERMINE_LIBS_TO_LINK(AWSSDK_FIND_COMPONENTS AWSSDK_LINK_LIBRARIES) message(STATUS "Components specified for AWSSDK: ${AWSSDK_FIND_COMPONENTS}, application will be depending on libs: ${AWSSDK_LINK_LIBRARIES}") # platform dependencies will be resolved automatically when doing find_package(aws-cpp-sdk-core). list(REMOVE_ITEM AWSSDK_LINK_LIBRARIES ${AWSSDK_PLATFORM_DEPS}) # AWS common runtime dependencies will be resolved automatically when doing find_package(aws-cpp-sdk-core) as well. list(REMOVE_ITEM AWSSDK_LINK_LIBRARIES ${AWSSDK_COMMON_RUNTIME_LIBS}) set(AWSSDK_TARGETS ${AWSSDK_LINK_LIBRARIES}) list(REVERSE AWSSDK_TARGETS) foreach(TARGET IN LISTS AWSSDK_TARGETS) message(STATUS "Try finding ${TARGET}") find_package(${TARGET} REQUIRED) message(STATUS "Found ${TARGET}") endforeach() endif() set(AWSSDK_INCLUDE_DIRS ${AWSSDK_INCLUDE_DIR}) set(AWSSDK_LIBRARIES ${AWSSDK_LINK_LIBRARIES})