I wanted to start using the AWS SDK from a native app with the least amount of friction to simplify porting it to other platforms and thought about sharing the approach in case it’s of use to others.
Rationale
Whilst Amazon provide a CMake find module to locate the AWS SDK’s libs and headers those libs and headers need to be installed on the system and platform-specific steps to do that are described (at the time of writing) in the AWS docs as a precursor to finding it using CMake. The process however could be simplified by instead performing the SDK build and installation within CMake itself as part of your app’s project using CMake’s ExternalProject support. By performing the initial SDK fetch and install in CMake you can trivialise the move to other platforms given the entire app build (app + SDK) is now managed by CMake. Potentially the Amazon provided CMake find module could also be discarded (as we control what we are building and where we are building it to – i.e. a project specific build directory that we control as part of our project’s CMake file vs. the entire system).
Integrating the AWS SDK (s3) with CMake
The snippet below will download, build and then link in the minimum required AWS SDK libraries to perform S3 access in C++ from an app using this approach. The CMake code below describes an app (example_AWS) that has a single source file (example.cpp) the source code of which is left as an exercise for the reader (there are plenty of s3 examples in Amazon’s SDK documentation linked to below).
Include(ExternalProject) # Build a minimal AWS SDK for s3 ExternalProject_Add(aws-sdk PREFIX ${CMAKE_BINARY_DIR}/aws-sdk GIT_REPOSITORY https://github.com/aws/aws-sdk-cpp.git UPDATE_COMMAND "" CMAKE_ARGS -DBUILD_ONLY=s3 -DBUILD_SHARED_LIBS=ON -DCMAKE_SOURCE_DIR:PATH=<SOURCE_DIR> -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON ) ExternalProject_Get_Property(aws-sdk INSTALL_DIR) add_library(aws-sdk::core SHARED IMPORTED) add_library(aws-sdk::s3 SHARED IMPORTED) set_target_properties(aws-sdk::core PROPERTIES IMPORTED_LOCATION ${INSTALL_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}aws-cpp-sdk-core${CMAKE_SHARED_LIBRARY_SUFFIX}) set_target_properties(aws-sdk::s3 PROPERTIES IMPORTED_LOCATION ${INSTALL_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}aws-cpp-sdk-s3${CMAKE_SHARED_LIBRARY_SUFFIX}) set(AWS_INCLUDE_DIRS ${INSTALL_DIR}/include) set(AWS_LIBS aws-sdk::s3 aws-sdk::core) include_directories(SYSTEM ${AWS_INCLUDE_DIRS}) # Build our project (that uses s3) SET(SOURCES example.cpp ) SET(HEADERS ) set(PROJECT_NAME example_AWS) add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS}) add_dependencies(${PROJECT_NAME} aws-sdk) target_link_libraries(${PROJECT_NAME} ${AWS_LIBS}) if(APPLE) set_target_properties(${PROJECT_NAME} PROPERTIES INSTALL_RPATH "@executable_path") endif()
NB. If you’re cross-compiling then you’ll need to provide the CMAKE_TOOLCHAIN_FILE and any toolchain specific arguments to the CONFIGURE_COMMAND above (i.e. CMAKE_TOOLCHAIN_FILE=path/to/my/tool_chain_file.cmake).
Accessing s3
From here you can now follow the S3 examples provided by Amazon:
Amazon S3 code examples and S3 – encrypting data prior to sending to S3