ARMOR is a tool for checking backward source-level compatibility of C/C++ software libraries using Clang AST.
This tool analyzes two versions of a C/C++ header file and detects source-level API incompatibilities. It leverages Clang's AST to perform deep structural comparisons, helping maintainers ensure backward compatibility in evolving codebases.
sudo apt update
sudo apt install clang-14 make cmake
sudo apt install libclang-common-14-dev libclang-14-dev llvm-14-dev
- make
- cmake
- llvm-14
- clang-14
- Linux
Clone the repository and run the build_binary.sh script to build the armor tool:
bash build_binary.sh --buildThis will build armor.
Important: All header files and include paths must exist in both project_root1 and project_root2.
The tool is invoked directly using the armor binary:
./build/src/armor/armor [OPTIONS] projectroot1 projectroot2 [headers...]-
projectroot1 (REQUIRED)
Path to the project root directory of the older version -
projectroot2 (REQUIRED)
Path to the project root directory of the newer version -
headers (optional)
List of header files to compare between the two versions.
Note: Headers must exist in both project roots.Header path interpretation depends on whether
--header-diris provided:-
With
--header-dir:
Headers are treated as basenames (e.g.,foo.h) under the specified subdirectory.
Example:--header-dir include/api foo.h bar.hpp
This will compare:
projectroot1/include/api/foo.hwithprojectroot2/include/api/foo.hprojectroot1/include/api/bar.hppwithprojectroot2/include/api/bar.hpp
-
Without
--header-dir:
Headers must be relative paths from the project root.
Example:include/api/foo.h include/api/bar.hpp
This will compare:
projectroot1/include/api/foo.hwithprojectroot2/include/api/foo.hprojectroot1/include/api/bar.hppwithprojectroot2/include/api/bar.hpp
-
-
-h, --help
Print help message and exit -
--header-dir TEXT
Subdirectory under each project root containing headers -
-r, --report-format TEXT:{html,json}
Report format:html(default).
Ifjsonis provided, both HTML and JSON reports will be generated. -
--dump-ast-diff
Dump AST diff JSON files for debugging -
-v, --version
Display program version information and exit -
--log-level TEXT:{ERROR,LOG,INFO,DEBUG}
Set debug log level: ERROR, LOG, INFO (default), DEBUG -
-I, --include-paths TEXT ...
Include paths for header dependencies (relative to project roots).
Note: Include paths must exist in both project roots.
Example:-I path/to/include1 -I path/to/include2
This will add:
projectroot1/path/to/include1andprojectroot2/path/to/include1projectroot1/path/to/include2andprojectroot2/path/to/include2
-
-m, --macro-flags TEXT
Macro flags to be passed for headers
-
Basic comparison with header directory:
./build/src/armor/armor /path/to/old/project /path/to/new/project --header-dir include foo.h bar.h
-
Comparison with relative header paths:
./build/src/armor/armor /path/to/old/project /path/to/new/project include/api/foo.h include/api/bar.h
-
Generate JSON report with include paths:
./build/src/armor/armor /path/to/old/project /path/to/new/project \ --header-dir include \ --report-format json \ -I dependencies/include \ -I third_party/headers \ foo.h
This assumes both projects have
dependencies/includeandthird_party/headersdirectories. -
Debug mode with AST diff dump:
./build/src/armor/armor /path/to/old/project /path/to/new/project \ --header-dir include \ --dump-ast-diff \ --log-level DEBUG \ foo.h
All tests are located in the src/tests folder. The test suite uses pytest for test execution and validation.
To run all tests, use the following command from the project root:
pytestYou can also run specific test files:
pytest src/tests/test_example.pyEnsure pytest and deepdiff packages are installed before running tests:
pip install pytest==8.4.1 deepdiff==8.5.0If you encounter build errors, ensure the following environment setup:
-
You have C++ version 11 or higher (e.g., 23):
ls /usr/include/c++
-
The same C++ version is available under the platform-specific path:
ls /usr/include/x86_64-linux-gnu/c++
-
You have Clang version 14 and subversion 14.0.0:
ls /usr/include/clang
-
You only have LLVM version 14 installed (Clang 14 is only compatible with LLVM 14):
ls /usr/lib | grep llvm-
armor is licensed under the BSD-3-clause License. See LICENSE.txt for the full license text.