Skip to content

Building the SDK from source on EC2

Andrew Tang edited this page Sep 7, 2018 · 3 revisions

Step by step how to build and install the AWS C++ SDK on an Ubuntu server image on EC2

For this guide we'll use "Ubuntu Server 16.04 LTS" EC2 image.

  • Launch the instance and SSH into it.

The first thing we need to do is install GCC (g++) and CMake

$ sudo apt install g++ cmake -y

On this server edition, the development headers for zlib, OpenSSL and CURL are not installed out of the box, so we need to install them

$ sudo apt install zlib1g-dev libssl-dev libcurl4-openssl-dev -y

Git comes already installed with this image, so let's clone the SDK and create a build directory inside of it.

$ git clone https://github.com/aws/aws-sdk-cpp.git
$ mkdir build
$ cd build

Next we need to run the CMake scripts to configure and create the final Makefile. There're a few options that can be passed to CMake in this step, so refer to the README for a complete list of options. For this guide, we'll build only S3, as a shared library in Release mode.
We won't specify an installation prefix, so CMake will use the default installation path /usr/local/lib.

$ cmake .. -DBUILD_ONLY=s3 -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_SHARED_LIBS=ON

Here is my output (yours might be slightly different)

-- Found Git: /usr/bin/git (found version "2.7.4")
-- TARGET_ARCH not specified; inferring host OS to be platform compilation target
-- Building AWS libraries as shared objects
-- Generating linux build config
-- Building project version: 1.4.65
-- The CXX compiler identification is GNU 5.4.0
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found ZLIB: /usr/lib/x86_64-linux-gnu/libz.so (found version "1.2.8")
--   Zlib include directory: /usr/include
--   Zlib library: /usr/lib/x86_64-linux-gnu/libz.so
-- Encryption: Openssl
-- Found OpenSSL: /usr/lib/x86_64-linux-gnu/libssl.so;/usr/lib/x86_64-linux-gnu/libcrypto.so (found version "1.0.2g")
--   Openssl include directory: /usr/include
--   Openssl library: /usr/lib/x86_64-linux-gnu/libssl.so;/usr/lib/x86_64-linux-gnu/libcrypto.so
-- Http client: Curl
-- Found CURL: /usr/lib/x86_64-linux-gnu/libcurl.so (found version "7.47.0")
--   Curl include directory: /usr/include
--   Curl library: /usr/lib/x86_64-linux-gnu/libcurl.so
-- Performing Test HAVE_ATOMICS_WITHOUT_LIBATOMIC
-- Performing Test HAVE_ATOMICS_WITHOUT_LIBATOMIC - Success
-- Considering s3
-- The C compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Updating version info to 1.4.65
-- Custom memory management enabled; stl objects now using custom allocators
-- Configuring done
-- Generating done
-- Build files have been written to: /home/ubuntu/aws-sdk-cpp/build

The last step is to compile, link and install the library. This step might take a few minutes depending on how many AWS services you are building and the type of EC2 machine you're running on, so probably grab some coffee:

$ make
$ sudo make install

That's it.

Finally, here's a sample program to test that everything is working, the program simply downloads a file from S3 to your local machine:

// program.cpp
#include <aws/core/Aws.h>
#include <aws/core/client/ClientConfiguration.h>
#include <aws/core/auth/AWSCredentialsProviderChain.h>
#include <aws/core/utils/logging/LogLevel.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/GetObjectRequest.h>
#include <iostream>
#include <fstream>
#include <memory>

using namespace Aws;

int main(int argc, char *argv[])
{
    if (argc < 5) {
        std::cout << " Usage: s3sample <region-endpoint> <s3 bucket> <s3 key> <local destination path>\n"
                  << "Example: s3sample s3.us-west-2.amazonaws.com MyBucket MyKey MyLocalFile.pdf" << std::endl;
        return 0;
    }

    SDKOptions options;
    options.loggingOptions.logLevel = Utils::Logging::LogLevel::Error;
    InitAPI(options);
    {
        Client::ClientConfiguration config;
        config.endpointOverride = argv[1];
        config.scheme = Http::Scheme::HTTPS;

        S3::S3Client client(config);

        S3::Model::GetObjectRequest request;
        request.WithBucket(argv[2]).WithKey(argv[3]);
        request.SetResponseStreamFactory([argv] { return new std::fstream(argv[4], std::ios_base::out); });

        auto outcome = client.GetObject(request);
        if (outcome.IsSuccess()) {
            std::cout << "Completed!" << std::endl;
        } else {
            std::cout << "Failed with error: " << outcome.GetError() << std::endl;
        }
    }

    ShutdownAPI(options);
    return 0;
}

And its script CMakeLists.txt:

cmake_minimum_required(VERSION 3.5)
project(s3sample)
find_package(AWSSDK REQUIRED COMPONENTS s3)
set(CMAKE_CXX_STANDARD 11)
add_executable(s3sample "program.cpp")
# list all deps for static linking
target_link_libraries(s3sample ${AWSSDK_LINK_LIBRARIES})
target_compile_options(s3sample PRIVATE "-Wall" "-Werror")

Create a directory in your preferred location for the sample program and build and run the sample program:

$ cd ~
$ mkdir s3sample
$ vim program.cpp
$ vim CMakeLists.txt
$ mkdir build; cd build; cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo
$ make
$ export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
$ ./s3sample s3.us-west-2.amazonaws.com SomeBucket SomeKey ALocalFile

The LD_LIBRARY_PATH step is necessary because /usr/local/lib is not included by default in this distro (for security reasons)