Heimdall Multi-Standard C++ Support
Overview
Heimdall now supports multiple C++ standards (C++11, C++14, C++17, C++20, C++23) with a robust compatibility layer that ensures consistent behavior across different compiler versions and standard library implementations.
Supported Standards
C++ Standard | Status | Features | Requirements |
---|---|---|---|
C++11 | ✅ Working | Basic C++11 features | LLVM 7-18, Compatibility mode |
C++14 | ✅ Working | C++14 features + compatibility | LLVM 7-18, Compatibility mode |
C++17 | ✅ Working | Standard library features | LLVM 11+, Standard library |
C++20 | ✅ Working | C++20 features + {fmt} | LLVM 19+, {fmt} library |
C++23 | ✅ Working | C++23 features + std::format | LLVM 19+, Standard library |
Build Commands
Standard Build Commands
# C++11 (with compatibility mode)
./build.sh --cxx-standard 11 --tests --cpp11-14 --no-boost
# C++14 (with compatibility mode)
./build.sh --cxx-standard 14 --tests --cpp11-14 --no-boost
# C++17 (standard library)
./build.sh --cxx-standard 17 --tests
# C++20 (with {fmt} library)
./build.sh --cxx-standard 20 --tests
# C++23 (with std::format)
./build.sh --cxx-standard 23 --tests
Build Script Options
--cxx-standard VERSION
: Set C++ standard (11, 14, 17, 20, 23)--tests
: Enable tests--no-tests
: Disable tests--cpp11-14
: Enable C++11/14 compatibility mode--no-boost
: Disable Boost.Filesystem requirement--coverage
: Enable coverage reporting--build-type TYPE
: Set build type (Debug, Release, etc.)
Compatibility Layer
Architecture
The compatibility layer (src/compat/compatibility.hpp
) provides:
- Standard Library Includes: All standard library headers are included outside any namespace to prevent pollution
- Namespace Aliases: Provides
heimdall::compat::fs
for filesystem operations - Type Compatibility: Re-exports standard types or provides custom implementations
- Utility Functions: Common utilities in
heimdall::compat::utils
Key Features
C++11/14 Compatibility
- Custom
optional<T>
implementation - Custom
string_view
implementation - Custom
variant<T...>
implementation (limited) - Custom
span<T>
implementation - Boost.Filesystem support (optional)
C++17+ Compatibility
- Uses standard library types directly
std::optional
,std::string_view
,std::variant
std::filesystem
supportstd::span
(C++20+)
C++20/23 Compatibility
- Standard library types
- Concepts support
- Ranges support (C++20+)
- Format support (
{fmt}
for C++20,std::format
for C++23)
Test Suite
The test suite (tests/test_cyclonedx_all_versions_cpp.cpp
) validates:
C++11 Features
auto
keyword- Range-based for loops
- Lambda expressions
nullptr
- Uniform initialization
decltype
- Trailing return types
C++14 Features
- Auto return type deduction
- Generic lambdas
- Binary literals
- Digit separators
- Variable templates
Compatibility Features
heimdall::compat::optional
heimdall::compat::string_view
heimdall::compat::fs::path
heimdall::compat::variant
heimdall::compat::utils
functions
Build System
CMake Configuration
- Automatic C++ standard detection
- Conditional Boost.Filesystem linking
- LLVM version compatibility checks
- Test framework integration
Key CMake Variables
CMAKE_CXX_STANDARD
: Target C++ standardENABLE_CPP11_14
: Enable compatibility modeUSE_BOOST_FILESYSTEM
: Use Boost.FilesystemENABLE_TESTS
: Enable test suite
Issues Resolved
1. Namespace Pollution
Problem: Standard library was being included inside heimdall::compat::std
namespace
Solution: Moved all standard library includes outside any namespace
2. Boost.Filesystem Dependency
Problem: C++11/14 required Boost.Filesystem even when not needed
Solution: Added --no-boost
option and conditional Boost linking
3. CMake Configuration
Problem: CMake automatically required Boost for C++11/14 Solution: Modified CMakeLists.txt to respect explicit Boost settings
4. Test Compatibility
Problem: Tests used features not available in older standards Solution: Enhanced test suite with conditional compilation and compatibility types
Usage Examples
Using Compatibility Types
#include "compat/compatibility.hpp"
using namespace heimdall::compat;
// Works across all C++ standards
optional<int> opt(42);
string_view sv("hello");
fs::path p("file.txt");
variant<int, std::string> v(100);
Using Utility Functions
#include "compat/compatibility.hpp"
using namespace heimdall::compat;
// Utility functions work across standards
string_view sv = utils::to_string_view(42);
int val = utils::get_optional_value(opt, 0);
std::string result = utils::format_string("Value: {}", 42);
Future Enhancements
- Enhanced C++11/14 Support: More complete custom implementations
- Better Error Handling: Standardized error types across standards
- Performance Optimizations: Standard-specific optimizations
- Additional Utilities: More compatibility utilities
- Documentation: API documentation for compatibility layer
Troubleshooting
Common Issues
Boost.Filesystem Not Found
# Use --no-boost option ./build.sh --cxx-standard 14 --tests --cpp11-14 --no-boost
LLVM Version Warnings
- C++11/14: Consider using LLVM 7-18 for best compatibility
- C++17+: LLVM 11+ recommended
- C++20/23: LLVM 19+ required
Test Failures
- Ensure compatibility header is included
- Check C++ standard detection
- Verify LLVM version compatibility
Debugging
# Verbose build
make VERBOSE=1
# Debug configuration
./build.sh --build-type Debug --cxx-standard 17 --tests
# Check CMake configuration
cmake --build build --target help
Contributing
When adding new features:
- Test All Standards: Ensure compatibility across C++11-23
- Use Compatibility Types: Prefer
heimdall::compat
types - Add Tests: Include tests for new functionality
- Update Documentation: Document new features and APIs