一、背景
本文演示了使用AWS SDK构建一个C++语言的测试应用,应用程序执行listBucket
的操作列出存储桶目录。(前提是AKSK对应的用户有权限)
二、安装SDK(动态链接库)
1、创建操作系统
海外区域创建一个Cloud9系统,选择Amazon Linux 2系统。连接类型选择System Manager
或者SSH
均可。
创建完毕,进入Cloud9的Shell。
2、安装开发工具
安装依存包:
sudo yum install -y gcc cmake3 git libcurl-devel openssl-devel libuuid-devel pulseaudio-libs-devel
修改cmake从默认的2.8改为3.2
sudo mv /bin/cmake /bin/cmake2
sudo ln -s /bin/cmake3 /bin/cmake
3、构建SDK(动态链接库)
git clone --recurse-submodules https://github.com/aws/aws-sdk-cpp
在当前目录下获得aws-sdk-cpp
目录。
mkdir sdk_build
cd sdk_build
cmake ../aws-sdk-cpp -DCMAKE_BUILD_TYPE=Debug -DCMAKE_PREFIX_PATH=/usr/local/ -DCMAKE_INSTALL_PREFIX=/usr/local/ -DBUILD_ONLY="s3"
make
sudo make install
SDK会被安装到如下目录:(节选部分目录)
/usr/local/include/aws/
/usr/local/include/aws/s3
/usr/local/include/aws/core/
构建SDK完成。
三、构建测试程序
1、准备源代码
在当前目录下,创建一个src
目录,里边包含两个文件分别是main.cpp
和CMakeLists.txt
。
其中main.cpp
内容如下:
#include <aws/core/Aws.h>
#include <aws/core/utils/logging/LogLevel.h>
#include <aws/s3/S3Client.h>
#include <iostream>
using namespace Aws;
int main()
{
//The Aws::SDKOptions struct contains SDK configuration options.
//An instance of Aws::SDKOptions is passed to the Aws::InitAPI and
//Aws::ShutdownAPI methods. The same instance should be sent to both methods.
SDKOptions options;
options.loggingOptions.logLevel = Utils::Logging::LogLevel::Debug;
//The AWS SDK for C++ must be initialized by calling Aws::InitAPI.
InitAPI(options);
{
S3::S3Client client;
auto outcome = client.ListBuckets();
if (outcome.IsSuccess()) {
std::cout << "Found " << outcome.GetResult().GetBuckets().size() << " buckets\n";
for (auto&& b : outcome.GetResult().GetBuckets()) {
std::cout << b.GetName() << std::endl;
}
}
else {
std::cout << "Failed with error: " << outcome.GetError() << std::endl;
}
}
//Before the application terminates, the SDK must be shut down.
ShutdownAPI(options);
return 0;
}
文件CMakeLists.txt
的内容如下:
# Minimal CMakeLists.txt for the AWS SDK for C++.
cmake_minimum_required(VERSION 3.3)
set(CMAKE_CXX_STANDARD 11)
project(app LANGUAGES CXX)
# Use shared libraries
set(BUILD_SHARED_LIBS ON CACHE STRING "Link to shared libraries by default.")
#Include in any AWS service packages your code will be using by service name
find_package(AWSSDK REQUIRED COMPONENTS s3)
add_executable(${PROJECT_NAME} "main.cpp") #add app's main sourcefile
set_compiler_flags(${PROJECT_NAME})
set_compiler_warnings(${PROJECT_NAME})
target_link_libraries(${PROJECT_NAME} ${AWSSDK_LINK_LIBRARIES})
创建完毕,可看到src
目录下有如下两个文件:
-rw-r--r-- 1 ec2-user ec2-user 2245 Jul 25 14:33 CMakeLists.txt
-rw-r--r-- 1 ec2-user ec2-user 1154 Jul 25 14:32 main.cpp
2、准备构建目录
进入src
目录,在其中创建编译目录。
cd src/
ls -l .
mkdir my_project_build/
cd my_project_build/
执行如下命令,编译构建可执行文件。
cmake ../
make
执行完毕后,输出结果如下:
Scanning dependencies of target app
[ 50%] Building CXX object CMakeFiles/app.dir/main.cpp.o
[100%] Linking CXX executable app
[100%] Built target app
3、执行程序
编译完毕,在当前目录下获得可执行文件,文件名为app
。使用ls -l
可查看如下。
total 164
-rwxrwxr-x 1 ec2-user ec2-user 131424 Jul 25 14:43 app
-rw-rw-r-- 1 ec2-user ec2-user 17873 Jul 25 14:43 CMakeCache.txt
drwxrwxr-x 6 ec2-user ec2-user 319 Jul 25 14:43 CMakeFiles
-rw-rw-r-- 1 ec2-user ec2-user 1541 Jul 25 14:43 cmake_install.cmake
-rw-rw-r-- 1 ec2-user ec2-user 4793 Jul 25 14:43 Makefile
可看到这个编译后的可执行文件体积约129KB。这是由于采用的动态编译,因此主程序很小。执行app
程序测试。
./app
即可看到整个程序列出本账号下所有S3存储桶。(前提是本机配置了AWSCLI的Access Key和Secret Key)
4、查看其依赖的动态链接库:
执行如下命令:
ldd ./app
返回结果如下:
linux-vdso.so.1 (0x00007ffe38b0b000)
libaws-cpp-sdk-s3.so => /usr/local/lib64/libaws-cpp-sdk-s3.so (0x00007f797968c000)
libaws-cpp-sdk-core.so => /usr/local/lib64/libaws-cpp-sdk-core.so (0x00007f7978bf0000)
libcrypto.so.10 => /lib64/libcrypto.so.10 (0x00007f7978799000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f7978595000)
librt.so.1 => /lib64/librt.so.1 (0x00007f797838d000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f797800b000)
libm.so.6 => /lib64/libm.so.6 (0x00007f7977ccb000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f7977ab5000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f7977897000)
libc.so.6 => /lib64/libc.so.6 (0x00007f79774ea000)
/lib64/ld-linux-x86-64.so.2 (0x00007f7979c6a000)
libcurl.so.4 => /lib64/libcurl.so.4 (0x00007f7977248000)
libz.so.1 => /lib64/libz.so.1 (0x00007f7977033000)
libnghttp2.so.14 => /lib64/libnghttp2.so.14 (0x00007f7976e0c000)
libidn2.so.0 => /lib64/libidn2.so.0 (0x00007f7976bbd000)
libssh2.so.1 => /lib64/libssh2.so.1 (0x00007f7976994000)
libssl.so.10 => /lib64/libssl.so.10 (0x00007f7976725000)
libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007f79764d9000)
libldap-2.4.so.2 => /lib64/libldap-2.4.so.2 (0x00007f7976287000)
liblber-2.4.so.2 => /lib64/liblber-2.4.so.2 (0x00007f7976078000)
libunistring.so.0 => /lib64/libunistring.so.0 (0x00007f7975d60000)
libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007f7975a7c000)
libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007f7975878000)
libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007f7975647000)
libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007f7975438000)
libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007f7975234000)
libresolv.so.2 => /lib64/libresolv.so.2 (0x00007f797501e000)
libsasl2.so.3 => /lib64/libsasl2.so.3 (0x00007f7974e02000)
libssl3.so => /lib64/libssl3.so (0x00007f7974ba1000)
libsmime3.so => /lib64/libsmime3.so (0x00007f797497b000)
libnss3.so => /lib64/libnss3.so (0x00007f797464e000)
libnssutil3.so => /lib64/libnssutil3.so (0x00007f797441f000)
libplds4.so => /lib64/libplds4.so (0x00007f797421b000)
libplc4.so => /lib64/libplc4.so (0x00007f7974016000)
libnspr4.so => /lib64/libnspr4.so (0x00007f7973dd9000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f7973bb2000)
libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f797397b000)
libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f7973719000)
查看其中的关键文件,其中一部分文件体积如下:
-rwxr-xr-x 1 root root 30M Jul 25 14:19 /usr/local/lib64/libaws-cpp-sdk-core.so
-rwxr-xr-x 1 root root 12M Jul 25 14:19 /usr/local/lib64/libaws-cpp-sdk-s3.so
lrwxrwxrwx 1 root root 19 Jun 21 04:48 /lib64/libcrypto.so.10 -> libcrypto.so.1.0.2k
-rwxr-xr-x 1 root root 2471392 Jun 1 17:09 /lib64/libcrypto.so.1.0.2k
这个动态链接库体积约为12MB+30MB+2MB。在其他EC2部署环境上,如果也是Amazon Linux 2系统给,只需要这几个动态链接库文件,即可支持程序运行(前提是AKSK配置正确)
为了让代码在任何一个没有以上动态链接库的环境上运行,可考虑采用静态编译。但缺点是文件体积会较大,并且更新程序时候不方便单独更新库文件。因此建议使用动态编译。
四、参考文档
AWS SDK for C++语言:
https://github.com/aws/aws-sdk-cpp
如何构建AWS SDK for C++(仅S3模块)
https://docs.aws.amazon.com/zh_cn/sdk-for-cpp/v1/developer-guide/setup-linux.html
如何构建C++的S3测试程序(功能为列出所有Bucket)
https://docs.aws.amazon.com/zh_cn/sdk-for-cpp/v1/developer-guide/build-cmake.html
更多S3操作的C++代码例子:
https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/s3