This is a C++ implementation/port of s3stor (my other project which was intially coded in golang) - a command-line tool for backing up files to S3-compatible storage (e.g., AWS S3, Wasabi) with block-based deduplication, point-in-time snapshots, and efficient file management. This is a POC/tester - you may want to use restic in production.
- Block-Based Deduplication: Splits files into blocks, stores unique blocks by SHA-256 hash
- Point-in-Time Snapshots: Creates consistent backups with independent file maps
- Multi-Writer Safety: Uses S3-based locking to prevent conflicts
- S3 Compatibility: Works with AWS S3, Wasabi, and other S3-compatible providers
- Full Feature Parity: Implements all functions from the Go version
- Compiler: C++17 compatible compiler
- Windows: Visual Studio 2017 or later (tested with VS 2022)
- Linux: GCC 7+ or Clang 5+
- macOS: Clang 5+ (Xcode 9.3+)
- Build System:
- Windows: MSBuild (included with Visual Studio)
- Linux/macOS: CMake 3.15 or higher
- Package Manager: vcpkg for dependency management
- AWS SDK for C++ (S3 and Transfer Manager components)
- nlohmann-json (JSON library)
- OpenSSL (for SHA-256 hashing)
The project includes Visual Studio solution files for easy building on Windows.
Option 1: Using Visual Studio IDE (Recommended)
-
Install vcpkg (if not already installed):
git clone https://github.com/Microsoft/vcpkg.git C:\vcpkg cd C:\vcpkg .\bootstrap-vcpkg.bat .\vcpkg integrate install
-
Install dependencies via vcpkg:
.\vcpkg install aws-sdk-cpp[s3,transfer]:x64-windows .\vcpkg install nlohmann-json:x64-windows .\vcpkg install openssl:x64-windows
-
Open the solution:
- Open
s3stor_cpp.slnin Visual Studio - The solution contains two projects:
s3stor_lib- Static librarys3stor_test- Test executable
- Open
-
Configure project settings (if needed):
- Right-click
s3stor_testproject → Properties - Ensure C++ Language Standard is set to ISO C++17 (
/std:c++17) - Verify vcpkg integration is enabled in project properties
- Right-click
-
Build the solution:
- Select configuration:
DebugorRelease - Select platform:
x64(recommended) orx86 - Build → Build Solution (or press
Ctrl+Shift+B)
- Select configuration:
-
Output files will be in:
x64\Debug\s3stor_lib.lib- Static libraryx64\Debug\s3stor_test.exe- Test executable
Option 2: Using MSBuild Command Line
# From the project directory
MSBuild s3stor_cpp.sln /p:Configuration=Release /p:Platform=x64# Install vcpkg if not already installed
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
# Install dependencies
./vcpkg install aws-sdk-cpp[s3,transfer]
./vcpkg install nlohmann-json
./vcpkg install openssl
# Build the project
cd /path/to/s3stor_cpp
mkdir build && cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake
cmake --build .
# Output files in build/
# - libs3stor_lib.a
# - s3stor_tests3stor_cpp/
├── s3stor_cpp.sln # Visual Studio solution
├── s3stor_lib.vcxproj # Library project
├── s3stor_test.vcxproj # Test executable project
├── vcpkg.json # vcpkg manifest (dependencies)
├── vcpkg-configuration.json # vcpkg configuration
├── s3stor_lib.h # Library header
├── s3stor_lib.cpp # Library implementation
├── s3stor_test.cpp # Test executable source
├── CMakeLists.txt # CMake build file (Linux/macOS)
├── x64/ # Build output (Windows)
│ ├── Debug/
│ └── Release/
└── vcpkg_installed/ # Installed packages (auto-generated)
Configure using environment variables (same as Go version):
export S3_PROVIDER=wasabi
export S3_BUCKET=your-bucket-name
export S3_REGION=us-east-1
export S3_ENDPOINT=https://s3.us-east-1.wasabisys.com
export AWS_ACCESS_KEY_ID=your-wasabi-access-key
export AWS_SECRET_ACCESS_KEY=your-wasabi-secret-keyOn Windows run below comman in Powershell :
# Set S3 provider
[Environment]::SetEnvironmentVariable("S3_PROVIDER", "<S3_PROVIDER_VALUE>", "User")
# Set S3 bucket
[Environment]::SetEnvironmentVariable("S3_BUCKET", "<S3_BUCKET_NAME>", "User")
# Set S3 region - if not set then you'll performance issues when initializing AWS/S3 SDK client
# it will be slow / will timeout before finishing initialization
[Environment]::SetEnvironmentVariable("S3_REGION", "<S3_REGION>", "User")
# Set S3 endpoint
[Environment]::SetEnvironmentVariable("S3_ENDPOINT", "<S3_ENDPOINT_URL>", "User")
# Set AWS secret access key
[Environment]::SetEnvironmentVariable("AWS_SECRET_ACCESS_KEY", "<AWS_SECRET_ACCESS_KEY>", "User")
# Set AWS access key ID
[Environment]::SetEnvironmentVariable("AWS_ACCESS_KEY_ID", "<AWS_ACCESS_KEY_ID>", "User")
# Set AWS default region - if not set then you'll performance issues when initializing AWS/S3 SDK client
# it will be slow / will timeout before finishing initialization
[Environment]::SetEnvironmentVariable("AWS_DEFAULT_REGION", "<AWS_DEFAULT_REGION>", "User")The C++ version provides the same command-line interface as the Go version.
Run from the build output directory:
# Navigate to output directory
cd x64\Debug # or x64\Release
# Sync a file to S3
.\s3stor_test.exe sync ..\..\test_out\file1.txt
# Create a snapshot
.\s3stor_test.exe snapshot ..\..\test_out sn001 file1.txt
# List files in global catalog
.\s3stor_test.exe ls
# List files in snapshot
.\s3stor_test.exe ls sn001
# Restore a file from snapshot
.\s3stor_test.exe get sn001 file1.txt .\restore
# Display file block map
.\s3stor_test.exe map file1.txt
# Delete a file from global catalog
.\s3stor_test.exe delete file1.txt
# Delete a snapshot
.\s3stor_test.exe delete-snapshot sn001
# Cleanup unreferenced blocks
.\s3stor_test.exe cleanup-blocksRun from the build directory:
# Sync a file to S3
./s3stor_test sync test_out/file1.txt
# Create a snapshot
./s3stor_test snapshot test_out sn001 file1.txt
# List files in global catalog
./s3stor_test ls
# List files in snapshot
./s3stor_test ls sn001
# Restore a file from snapshot
./s3stor_test get sn001 file1.txt ./restore
# Display file block map
./s3stor_test map file1.txt
# Delete a file from global catalog
./s3stor_test delete file1.txt
# Delete a snapshot
./s3stor_test delete-snapshot sn001
# Cleanup unreferenced blocks
./s3stor_test cleanup-blocksYou can also use s3stor as a library in your C++ projects:
#include "s3stor_lib.h"
int main() {
// Setup configuration
s3stor::S3ProviderConfig config;
config.bucket_name = "my-bucket";
config.region = "us-east-1";
config.access_key_id = "...";
config.secret_access_key = "...";
// Initialize AWS SDK
Aws::SDKOptions options;
Aws::InitAPI(options);
{
// Create S3Stor instance
s3stor::S3Stor s3stor(config);
// Sync a file
s3stor.sync_file("/path/to/file.txt", "/path/to");
// Create snapshot
std::vector<std::string> files = {"file.txt"};
s3stor.create_snapshot("/path/to", "snapshot-001", "my-host", files);
// List files
s3stor.list_files();
}
Aws::ShutdownAPI(options);
return 0;
}s3stor_cpp.sln- Visual Studio solution files3stor_lib.vcxproj- Static library projects3stor_test.vcxproj- Test executable projectvcpkg.json- vcpkg dependency manifestvcpkg-configuration.json- vcpkg configuration
s3stor_lib.h- Library header with class and structure definitionss3stor_lib.cpp- Library implementation (~31KB, all Go functions ported)s3stor_test.cpp- Test executable with command-line interface
CMakeLists.txt- CMake build configuration (Linux/macOS)*.vcxproj- Visual Studio project files (Windows)
README.md- This fileBUILD_FIX_INSTRUCTIONS.md- Windows build troubleshootingCROSS_PLATFORM_CHANGES.md- Cross-platform compatibility notesCPP_PORT_SUMMARY.md- Detailed porting summaryREADME_CPP.md- Additional C++ documentation
- Windows:
x64/Debug/orx64/Release/ - Linux/macOS:
build/
All functions from the Go version are implemented:
sync_file()- Upload a file with deduplicationsync_dir()- Upload a directory recursivelylist_files()- List files in global cataloglist_snapshot_files()- List files in a snapshotget_file()- Restore a file from catalog or snapshotget_file_map()- Display block mappings for a filecreate_snapshot()- Create a point-in-time snapshotdelete_snapshot()- Delete a snapshotcleanup_blocks()- Remove unreferenced blocksdelete_file()- Remove file from global catalog
hash_block()- Compute SHA-256 hash of a blockupload_block()- Upload a block to S3put_object()- Upload an object to S3get_object()- Download an object from S3acquire_lock()- Acquire distributed lockrelease_lock()- Release distributed lockupdate_catalog()- Update global catalog- And more...
Cross-Platform Compatibility:
- The code uses
#ifdef _WIN32to handle Windows-specific code - Winsock2 is automatically initialized for hostname retrieval
- Thread-safe time functions (
gmtime_son Windows,gmtime_ron Unix) - Windows macros (
GetObject) are undefined to prevent conflicts with AWS SDK
Build Requirements:
- Visual Studio 2017 or later (tested with VS 2022)
- Platform Toolset: v143 or v142
- C++ Language Standard: ISO C++17 (
/std:c++17) - Windows SDK 10.0 or later
Project Settings:
- Character Set: Unicode
- Configuration Type: Application (s3stor_test), Static Library (s3stor_lib)
- vcpkg Integration: Enabled via
VcpkgEnableManifest - Preprocessor:
_CRT_SECURE_NO_WARNINGSto suppress safe CRT warnings
Known Issues:
- If you see
error C1083: Cannot open include file: 'nlohmann/json.hpp', ensure vcpkg is properly integrated - If you see
STL4038: <filesystem> requires C++17, update project to use C++17 standard - See
BUILD_FIX_INSTRUCTIONS.mdfor detailed troubleshooting
Build Requirements:
- GCC 7+ or Clang 5+
- CMake 3.15+
- Standard POSIX headers (unistd.h, etc.)
Platform Features:
- Direct
gethostname()call without Winsock initialization - Uses
gmtime_r()for thread-safe time conversion - Standard filesystem paths with forward slashes
Build Requirements:
- Xcode 9.3+ (includes Clang 5+)
- CMake 3.15+
- Similar to Linux build process
Platform Features:
- Same POSIX-compliant code as Linux
- Homebrew can be used instead of vcpkg if preferred
The C++ version maintains full functional parity with minor implementation differences:
- Uses AWS SDK for C++ instead of Go's AWS SDK v2
- Uses nlohmann-json for JSON handling instead of Go's encoding/json
- Uses OpenSSL for SHA-256 instead of Go's crypto/sha256
- Uses C++17 filesystem library instead of Go's filepath
- Error handling uses exceptions and return values instead of Go's error values
MIT License - Same as the original Go version
© 2025 Alexey Shvechkov. All rights reserved.