Libmagicxx v10.0.3
A modern C++23 wrapper for libmagic β€” the library that powers the Unix file command.
Loading...
Searching...
No Matches
Libmagicxx

✨ Libmagicxx ✨

A Modern C++23 Wrapper for libmagic

Bringing the power of the Unix file command to modern C++

Latest Release License: LGPL v3 C++ Standard: C++23 Downloads

Linux GCC Linux Clang Windows MinGW64 Windows Clang

Codacy Badge Quality Gate Status


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");
// Returns: "application/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)

  1. Download libmagicxx-<version>-windows-x86_64.exe
  2. Run the installer
  3. Follow the on-screen instructions
  4. 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>
#include <magic.hpp>
int main()
{
using namespace Recognition;
// Create a Magic instance with MIME type detection
// Identify a file's type
auto result = magic.IdentifyFile("mystery_file");
std::println(std::cout, "File type: {}", result);
// Example output: "application/pdf; charset=binary"
}
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 <magic.hpp>
#include <future>
#include <thread>
using namespace Recognition;
using namespace std::chrono_literals;
// Combine multiple flags for detailed output
Magic detailed{
};
// Use custom database
custom.LoadDatabaseFile("/path/to/custom.mgc");
// Track progress for batch file identification
// Start identification in background thread
auto future = std::async([&magic, tracker] {
return magic.IdentifyFiles("/large/directory", tracker);
});
// Monitor progress in main thread
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

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.

Contributing Guide


πŸ”’ Security

Found a security vulnerability? Please report it responsibly.

Security Policy


πŸ“ƒ 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

Component License
file/libmagic BSD-2-Clause
GoogleTest BSD-3-Clause
libgnurx LGPL-2.1-or-later


πŸ“œ 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

Star on GitHub