
Security News
CISA’s 2025 SBOM Guidance Adds Hashes, Licenses, Tool Metadata, and Context
CISA’s 2025 draft SBOM guidance adds new fields like hashes, licenses, and tool metadata to make software inventories more actionable.
XmpToolkitRuby is a Ruby gem that provides fast, native bindings to the Adobe XMP Toolkit, enabling Ruby applications to read and write XMP metadata in various file formats (images, PDFs, etc.).
Recommended: Compile natively on your target system for best performance and compatibility.
A precompiled extension may be available for some platforms.
First, clone and prepare the Adobe XMP Toolkit SDK.
export XMP_TOOLKIT_SDK_VERSION=2025.03
# Prerequisites
sudo apt update && sudo apt install cmake build-essential curl
# Download and extract the SDK
mkdir XMP-Toolkit-SDK
cd XMP-Toolkit-SDK
curl -LO https://github.com/adobe/XMP-Toolkit-SDK/archive/refs/tags/v${XMP_TOOLKIT_SDK_VERSION}.tar.gz
tar -xzf v${XMP_TOOLKIT_SDK_VERSION}.tar.gz --strip-components=1
# Prepare required third-party libraries
cd third-party
# zlib
cd zlib
curl -O https://zlib.net/zlib.tar.gz
tar --strip-components=1 -xzf zlib.tar.gz
cd ..
# expat
cd expat
curl -LO https://github.com/libexpat/libexpat/releases/download/R_2_5_0/expat-2.5.0.tar.gz
tar --strip-components=1 -xzf expat-2.5.0.tar.gz
cd ../..
# Build instructions
cd build
# ⚠️ Patch required: Remove `${XMP_GCC_LIBPATH}/libssp.a` from `ProductConfig.cmake` (see [this issue](https://github.com/adobe/XMP-Toolkit-SDK/issues/8))
# Optionally, disable secure settings in `shared/ToolchainGCC.cmake`:
# -set(XMP_ENABLE_SECURE_SETTINGS "ON")
# +set(XMP_ENABLE_SECURE_SETTINGS "OFF")
make
When you copy and paste the following commands, make sure that during the paste nothing got escaped (e.g. {
becomes
\{
).
export XMP_TOOLKIT_SDK_VERSION=2025.03
xcode-select --install # Ensure Xcode command line tools are selected
# within a directory of your choice
mkdir XMP-Toolkit-SDK
cd XMP-Toolkit-SDK
curl -LO https://github.com/adobe/XMP-Toolkit-SDK/archive/refs/tags/v${XMP_TOOLKIT_SDK_VERSION}.tar.gz
tar -xzf v${XMP_TOOLKIT_SDK_VERSION}.tar.gz --strip-components=1
# Prepare required third-party libraries
cd third-party
# zlib
cd zlib
curl -O https://zlib.net/zlib.tar.gz
tar --strip-components=1 -xzf zlib.tar.gz
cd ..
# expat
cd expat
curl -LO https://github.com/libexpat/libexpat/releases/download/R_2_5_0/expat-2.5.0.tar.gz
tar --strip-components=1 -xzf expat-2.5.0.tar.gz
cd ../..
# cmake
cd tools/cmake
mkdir bin
cd bin
curl -LO https://cmake.org/files/v3.15/cmake-3.15.5-Darwin-x86_64.tar.gz
tar --strip-components=1 -xzf cmake-3.15.5-Darwin-x86_64.tar.gz
cd ../../..
cd build
./GenerateXMPToolkitSDK_mac.sh
# choose 3 => Generate XMPToolkitSDK Static 64
cd xcode/static/universal/
# I needed to patch SDKROOT from macOS 13.1 SDK to 15.1 SDK in two places inside the Xcode project file:
#
# From:
# SDKROOT = /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk;
#
# To:
# SDKROOT = /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.1.sdk;
#
# The following sed script replaces both occurrences in-place, backing up the original file with a .bak extension:
#
# Usage:
# sed -i.bak -E 's|(SDKROOT = /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX)13\.1(\.sdk;)|\115.1\2|g' ./XMPToolkitSDK64.xcodeproj/project.pbxproj
#
# Explanation:
# - The regex captures the prefix and suffix around "13.1" to ensure only the SDK version number is replaced.
# - The 'g' flag ensures all matching lines (both places) are updated.
# Build Debug configuration
xcodebuild -scheme ALL_BUILD -configuration Debug build
# Build Release configuration
xcodebuild -scheme ALL_BUILD -configuration Release build
See Adobe’s docs for details on other platforms.
Bundler:
# for linux
bundle config set --local build.xmp_toolkit_ruby "--with-xmp-lib=/path/to/XMP-Toolkit-SDK/public/libraries/i80386linux_x64/debug --with-xmp-include=/path/to/XMP-Toolkit-SDK/public/include"
# for macOS
bundle config set --local build.xmp_toolkit_ruby "--with-xmp-lib=/path/to/XMP-Toolkit-SDK/public/libraries/macintosh/universal/Debug --with-xmp-include=/path/to/XMP-Toolkit-SDK/public/include"
bundle add xmp_toolkit_ruby
Or, with plain RubyGems:
# for linux
gem install xmp_toolkit_ruby -- --with-xmp-lib /path/to/XMP-Toolkit-SDK/public/libraries/i80386linux_x64/debug --with-xmp-include /path/to/XMP-Toolkit-SDK/public/include
# for macOS
gem install xmp_toolkit_ruby -- --with-xmp-lib /path/to/XMP-Toolkit-SDK/public/libraries/macintosh/universal/Debug --with-xmp-include /path/to/XMP-Toolkit-SDK/public/include
Replace paths as needed for your environment.
This gem ships with precompiled binaries for the native libraries libxmpcore
and libxmpfile
for common
platforms.
⚠️ Note:
These precompiled binaries may not work on your system, especially if your OS, architecture, or C++ standard library differs from those used to build the binaries.
For maximum compatibility, it is strongly recommended to compile the native libraries yourself on your target machine.
If you encounter issues or want maximum portability, please build the SDK from source using the instructions above.
Tip:
Check out docker/Dockerfile
in this repository for a full working example of a native build
setup, including all dependencies and configuration flags.
require "xmp_toolkit_ruby"
xmp = XmpToolkitRuby.xmp_from_file("BlueSquare.png")
pp xmp.keys
puts xmp["xmp_data"]
new_xmp = <<~XMP
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 6.0.0">
<rdf:RDF xmlns:rdf="#{XmpToolkitRuby::Namespaces::XMP_NS_RDF}">
<rdf:Description xmlns:xmp="#{XmpToolkitRuby::Namespaces::XMP_NS_XMP}" rdf:about="">
<xmp:CreateDate>2025-06-04T20:20:40+02:00</xmp:CreateDate>
<xmp:ModifyDate>2025-06-04T20:20:40+02:00</xmp:ModifyDate>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
XMP
XmpToolkitRuby.xmp_to_file(
"BlueSquare.png",
new_xmp,
override: true # Set to false to upsert/merge instead of replacing
)
# fine-grained control
# if you want to take full control over the SDK lifecycle
# you can use the XmpToolkitRuby::XmpToolkit module directly:
XmpToolkitRuby::XmpToolkit.initialize_xmp(XmpToolkitRuby::PLUGINS_PATH)
# in this case you can call here
XmpToolkitRuby::XmpFile.register_namespace XmpToolkitRuby::Namespaces::XMP_NS_PDFUA_ID, "pdfua"
XmpToolkitRuby::XmpFile.with_xmp_file(filename, open_flags: XmpToolkitRuby::XmpFileOpenFlags.bitmask_for(:open_for_update, :open_use_smart_handler, auto_terminate_toolkit: false)) do |xmp_file|
# in case the lifecycle is managed by with_xmp_file
XmpToolkitRuby::XmpFile.register_namespace XmpToolkitRuby::Namespaces::XMP_NS_PDFUA_ID, "pdfua"
xmp_file.update_localized_property schema_ns: XmpToolkitRuby::Namespaces::XMP_NS_DC,
alt_text_name: "title",
generic_lang: "en",
specific_lang: "en-US",
item_value: "Hello world",
options: 0
xmp_file.update_property XmpToolkitRuby::Namespaces::XMP_NS_PDFUA_ID, "part", "1"
end
# if auto_terminate_toolkit is false, you must call
XmpToolkitRuby::XmpToolkit.terminate
# to clean up resources
If you built the XMP Toolkit yourself or store the plugins elsewhere,
set the XMP_TOOLKIT_PLUGINS_PATH
environment variable so the gem can
locate the PDF handler:
export XMP_TOOLKIT_PLUGINS_PATH=/path/to/XMP-Toolkit-SDK/XMPFilesPlugins/PDF_Handler/<platform>
Run your Ruby code or CLI commands in the same shell so this variable is visible.
XmpFile
The XmpToolkitRuby::XmpFile
class exposes low-level access to XMP metadata files, allowing you to:
In order to work properly you need to ensure the XMP Toolkit is initialized:
XmpToolkitRuby::XmpToolkit.initialize_xmp(XmpToolkitRuby::PLUGINS_PATH)
Alternatively, you can use the with_xmp_file
method which automatically initializes and terminates the toolkit.
Before working with properties in custom or less-common namespaces, you need to register them with a prefix:
XmpToolkitRuby::XmpFile.register_namespace XmpToolkitRuby::Namespaces::XMP_NS_PDFUA_ID, "pdfua"
This allows the SDK to recognize and correctly handle properties within that namespace.
You can open an XMP file with specific flags to control behavior:
open_for_update
: Open the file for modifying metadataopen_use_smart_handler
: Use smart handlers for better metadata processingFlags are combined via the bitmask_for
helper method:
flags = XmpToolkitRuby::XmpFileOpenFlags.bitmask_for(:open_for_update, :open_use_smart_handler)
Open the file in a block to ensure safe usage:
XmpToolkitRuby::XmpFile.with_xmp_file(filename, open_flags: flags) do |xmp_file|
# work with xmp_file inside this block
end
Localized properties support multiple language alternatives. Use update_localized_property
with options:
schema_ns
: Namespace URI for the schema (e.g., Dublin Core)alt_text_name
: The property name that holds alternative textsgeneric_lang
: Language tag for the generic language (e.g., "en"
)specific_lang
: Specific locale variant (e.g., "en-US"
)item_value
: The actual text value to setoptions
: Optional flags (typically 0)Example:
xmp_file.update_localized_property(
schema_ns: XmpToolkitRuby::Namespaces::XMP_NS_DC,
alt_text_name: "title",
generic_lang: "en",
specific_lang: "en-US",
item_value: "Hello world",
options: 0
)
This sets or updates the localized "title"
property in English (US).
For simpler property updates without localization, use update_property
:
xmp_file.update_property(
XmpToolkitRuby::Namespaces::XMP_NS_PDFUA_ID,
"part",
"1"
)
This updates the "part"
property within the PDF/UA ID namespace.
The fine-grained control API empowers you to work precisely with metadata:
Using these methods allows sophisticated metadata management, crucial for professional publishing, digital asset management, or compliance workflows.
The gem ships with a xmp_toolkit_ruby
command for basic operations:
# Print XMP metadata to stdout
xmp_toolkit_ruby print_xmp BlueSquare.png
# Print XMP metadata and save to a file
xmp_toolkit_ruby print_xmp BlueSquare.png xmp_metadata.xml
# Update XMP metadata (replace/merge)
xmp_toolkit_ruby override_xmp --override BlueSquare.png xmp_metadata.xml
You can run the CLI tool via Docker without installing any build tools:
docker run -it --rm -v $(pwd):/workspace dieters877565/xmp-toolkit-ruby:main xmp_toolkit_ruby print_xmp /workspace/BlueSquare.png
bin/setup
to install dependenciesrake spec
to run testsbin/console
for an interactive shellBuild & install locally with:
bundle exec rake install
Release process:
lib/xmp_toolkit_ruby/version.rb
bundle exec rake release
to tag, push, and publish to rubygems.orgBug reports and pull requests are welcome on GitHub.
This project is open source, licensed under the MIT License.
FAQs
Unknown package
We found that xmp_toolkit_ruby demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
CISA’s 2025 draft SBOM guidance adds new fields like hashes, licenses, and tool metadata to make software inventories more actionable.
Security News
A clarification on our recent research investigating 60 malicious Ruby gems.
Security News
ESLint now supports parallel linting with a new --concurrency flag, delivering major speed gains and closing a 10-year-old feature request.