β¨ Libmagicxx β¨
A Modern C++23 Wrapper for libmagic
Bringing the power of the Unix file command to modern C++
Libmagicxx is a modern C++23 wrapper library for the battle-tested libmagic β the same library that powers the Unix file command used by millions of developers worldwide. Rather than reinventing the wheel, libmagicxx brings libmagic's decades of file type detection expertise into the modern C++ ecosystem with an elegant, type-safe interface.
What libmagicxx adds to libmagic:
| libmagic (C API) | libmagicxx (C++23 Wrapper) |
| Manual resource management | RAII with automatic cleanup |
| Error codes and global state | std::expected and exceptions |
| Raw C strings | std::string and std::string_view |
| Procedural API | Object-oriented Magic class |
| No type safety | Strong typing with concepts |
| Manual flag handling | Type-safe Flags and Parameters enums |
| Single file identification | Batch directory and container identification |
| No progress feedback | Built-in progress tracking for batch operations |
| Manual state checking | IsOpen(), IsDatabaseLoaded(), IsValid() queries |
| One parameter at a time | Bulk GetParameters() / SetParameters() |
π Why a wrapper? libmagic is the gold standard for content-based file detection, maintained for decades and used in countless production systems. Libmagicxx doesn't replace itβit makes it accessible to modern C++ developers with the safety and ergonomics they expect.
π Table of Contents
π― Why Use Libmagicxx?
You need libmagic's capabilities, but want modern C++:
| Your Need | Libmagicxx Solution |
| π Security | Use libmagic's proven detection to validate file uploads |
| π¨ Media Processing | Route files to correct handlers based on true content type |
| π File Management | Leverage decades of magic database refinements |
| β‘ Developer Experience | Write idiomatic C++23 instead of C-style code |
| π‘οΈ Safety | Automatic resource management prevents leaks and errors |
β¨ What Libmagicxx Adds
π Modern C++23 Interface
Wraps libmagic's C API with modern features:
- std::expected for elegant error handling
- Concepts and constraints for type safety
- RAII for automatic resource management
π― High-Level API
Clean, intuitive interface:
Magic magic{Magic::Flags::Mime};
auto type = magic.IdentifyFile("document.pdf");
π¦ CMake Integration
First-class CMake support:
find_package(Magicxx REQUIRED)
target_link_libraries(app Recognition::Magicxx)
π Cross-Platform
- β
Linux (x86_64) β GCC & Clang
- β
Windows (x86_64) β MinGW & Clang
- π¦ DEB, RPM, and NSIS installers
Why Use the Wrapper?
- π libmagic Power β Access libmagic features through a clean C++ interface
- π‘οΈ Memory Safe β No manual magic_open/magic_close calls to forget
- π§ͺ Extensively Tested β 600+ unit tests (shared and static libs tested independently)
- π§ Flexible Configuration β All 30 libmagic flags exposed as type-safe enums
- π Progress Tracking β Shared progress tracker for monitoring batch operations
- ποΈ Database Support β Easy loading of custom magic definition files
οΏ½οΏ½ Supported Platforms
| Platform | Architecture | Compilers | Package Formats |
| π§ Linux | x86_64 | GCC, Clang | .deb, .rpm |
| πͺ Windows | x86_64 | MinGW-w64, Clang | .exe (NSIS) |
π Quick Start
Get up and running in under a minute:
# 1. Download the latest release for your platform
# β https://github.com/oguztoraman/libmagicxx/releases/latest
# 2. Install (Linux example)
sudo apt install ./libmagicxx-*-linux-x86_64.deb # Debian/Ubuntu
sudo dnf install ./libmagicxx-*-linux-x86_64.rpm # Fedora/RHEL
# 3. Use in your project (see CMake integration below)
π₯ Installation
π§ Debian/Ubuntu (APT)
sudo apt install ./libmagicxx-<version>-linux-x86_64.deb
π§ Fedora/RHEL (DNF)
sudo dnf install ./libmagicxx-<version>-linux-x86_64.rpm
πͺ Windows (NSIS Installer)
- Download libmagicxx-<version>-windows-x86_64.exe
- Run the installer
- Follow the on-screen instructions
- Add the installation directory to your PATH if needed
π§ Build from Source
git clone https://github.com/oguztoraman/libmagicxx.git
cd libmagicxx
python ./scripts/launch_container.py
./scripts/initialize.sh
./scripts/workflows.sh -p linux-x86_64-clang -c
See CONTRIBUTING.md for detailed build instructions.
π¦ Download: Latest Release | All Releases
π§ Usage with CMake
Step 1: Link the Library
Add to your CMakeLists.txt:
find_package(Magicxx REQUIRED)
target_link_libraries(your_project
PRIVATE Recognition::Magicxx # Shared library
# or
PRIVATE Recognition::MagicxxStatic # Static library
)
Step 2: Identify Files
#include <print>
#include <iostream>
{
std::println(std::cout, "File type: {}", result);
}
A modern C++23 wrapper for libmagic β the library that powers the Unix file command.
Definition magic.hpp:216
FileTypeT IdentifyFile(const std::filesystem::path &path) const
Identify the type of a single file.
Definition magic.cpp:2530
@ Mime
Definition magic.hpp:328
Main header file for the libmagicxx library.
auto main() -> int
Main entry point for the examples program.
Definition magic_examples.cpp:402
Root namespace for the libmagicxx library.
Step 3: Advanced Usage
#include <future>
#include <thread>
using namespace std::chrono_literals;
};
auto future = std::async([&magic, tracker] {
});
while (!tracker->IsCompleted()) {
std::println("Progress: {}", tracker->GetCompletionPercentage().ToString());
std::this_thread::sleep_for(100ms);
}
auto results = future.get();
void LoadDatabaseFile(const std::filesystem::path &database_file=DEFAULT_DATABASE_FILE)
Load a magic database file.
Definition magic.cpp:2638
FileTypeMapT IdentifyFiles(const std::filesystem::path &directory, std::filesystem::directory_options option=std::filesystem::directory_options::follow_directory_symlink) const
Identify all files in a directory.
Definition magic.hpp:1037
@ ContinueSearch
Definition magic.hpp:322
@ MimeEncoding
Definition magic.hpp:327
@ None
Definition magic.hpp:316
@ MimeType
Definition magic.hpp:321
SharedProgressTrackerT MakeSharedProgressTracker(std::uint64_t total_steps=1u) noexcept
Factory function to create a shared ProgressTracker.
Definition progress_tracker.hpp:440
π Magic States
The Magic class follows a clear state machine model:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Magic State Diagram β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Constructor() Constructor(flags) β
β β β β
β βΌ βΌ β
β ββββββββββββββ Open(flags) ββββββββββββββ ββββββββββββββ β
β β CLOSED βββββββββββββββ>β OPENED β<βββββββββ VALID β β
β ββββ¬ββββββββββ ββββ¬βββββββ¬βββ Open βββββββββββ¬βββ β
β β β² β² β β² β (flags) β² β β
β ββββββ β β βββββ β β β
β Close() β β Open(flags) β β β
β β β β β β
β β βββββββββββββββββββββββββ β β
β β LoadDatabaseFile() β β
β β β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββ β
β Close() β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| State | IsOpen() | IsDatabaseLoaded() | IsValid() | Can Identify Files? |
| Closed | β false | β false | β false | β No |
| Opened | β
true | β false | β false | β No |
| Valid | β
true | β
true | β
true | β
Yes |
π‘ Tip: Use the convenience constructorsβthey automatically open and load the default database, putting you directly in the Valid state!
π CMake Package Variables
After find_package(Magicxx), these variables are available:
| Variable | Description |
| MAGICXX_FOUND | β
TRUE if Libmagicxx was found |
| MAGICXX_VERSION | Version string (e.g., "9.1.1") |
| MAGICXX_SHARED_LIB_AVAILABLE | Shared library availability |
| MAGICXX_STATIC_LIB_AVAILABLE | Static library availability |
| MAGICXX_INCLUDE_DIR | Path to headers |
| MAGICXX_LIB_DIR | Path to libraries |
| MAGICXX_LICENSE_DIR | Path to license files |
| MAGICXX_DOC_DIR | Path to documentation |
| MAGICXX_CMAKE_DIR | Path to CMake config |
| MAGICXX_DEFAULT_DATABASE_DIR | Path to magic database |
π Examples
Explore real-world usage patterns in the examples:
| Example | Description |
| Basic Identify | File identification with exception handling |
| Noexcept Identify | Non-throwing API with std::expected |
| Directory Identify | Batch identification of files in a directory |
| Custom Flags/Parameters | Configuring flags and tuning parameters |
| Check and Compile | Database validation and compilation |
| Progress Tracking | Monitoring batch operations with progress tracker |
| Container Identify | Identify specific files from a container |
| Lifecycle Management | Manual state transitions and queries |
| Version and All Parameters | Get version and bulk parameter operations |
π Documentation
The comprehensive documentation includes:
| Section | Description |
| Modules | Core API, Exceptions, Utility, String Conversions |
| Classes | Magic, MagicException, Percentage, ProgressTracker |
| Examples | 9 runnable examples with detailed explanations |
| Style Guides | C++ and CMake coding conventions |
| Project Docs | Contributing, Security, Code of Conduct, Changelog |
π€ Contributing
We welcome contributions of all kinds! Whether you're fixing bugs, adding features, improving documentation, or suggesting enhancementsβyour help makes Libmagicxx better for everyone.
π Security
Found a security vulnerability? Please report it responsibly.
π License
Libmagicxx is licensed under the GNU Lesser General Public License v3.0.
This means you can:
- β
Use it in commercial projects
- β
Link to it from proprietary software
- β
Modify and distribute it (under LGPL terms)
See COPYING.LESSER for the full license text.
Third-Party Licenses
π Disclaimer
This project is a personal hobby project developed independently. It is not affiliated with, endorsed by, or created on behalf of any employer, company, or organization. No proprietary or confidential information was used in its development.
Made with β€οΈ for the C++ community