|
PackageBuilder
Tools to assist with CMake/C++ package development
|
Tired of writing hundreds of lines of CMake boilerplate just to create a properly installable library? Build sleek, professional C++ libraries and executables with a few simple function calls. Installation and package config generation all handled automatically.
If your project uses cmake-conan (the tnt-coders fork), this is the recommended way to consume PackageBuilder. Dependencies are resolved automatically with no manual installation.
Add the following to your conanfile.py:
Or in conanfile.txt:
The #recipe: tag tells cmake-conan where to find the source for the package. If the package is not already present in your local Conan cache or any configured remote, cmake-conan will automatically clone the tagged version from the provided git URL and run conan create to build it locally. No manual recipe hosting or remote setup needed.
Then in your CMakeLists.txt:
For full details on how cmake-conan and the recipe tag work, see the tnt-coders fork of the cmake-conan repository.
The simplest way to get started. No installation or package manager required.
This allows you to immediately hit the ground running with professional quality install/package creation logic for your own project.
Build and install PackageBuilder to your system, then find it like any other CMake package.
Install:
Consume:
Required. Must be called before any other PackageBuilder functions.
This function performs essential validation before any targets are defined:
PROJECT_VERSION is set and fails with a fatal error if it is not. PROJECT_VERSION is typically set by specifying the version in the project() command.PROJECT_DESCRIPTION is set and fails with a fatal error if it is not. Set via the DESCRIPTION argument in the project() command.LICENSE file exists at the project root. This is required for CPack packaging.Libraries created with package_add_library are automatically given a namespaced alias of <PROJECT_NAME>::<target>. This is the same alias that downstream consumers will use after find_package().
Targets created with package_add_library and package_add_executable automatically receive these private include directories:
${CMAKE_CURRENT_SOURCE_DIR}${CMAKE_CURRENT_SOURCE_DIR}/include${CMAKE_CURRENT_SOURCE_DIR}/srcFor libraries, only ${CMAKE_CURRENT_SOURCE_DIR}/include is exposed publicly. The project root is a build-time convenience only and is not exported to consumers.
package_add_executable accepts optional packaging arguments:
| Argument | Description |
|---|---|
ICON | Path to an icon file (.ico). On Windows, package_add_executable() embeds this into the executable and also uses it as the NSIS installer/uninstaller icon. Paths may be relative to the calling CMakeLists.txt. |
LINUX_DESKTOP_FILE | Path to an XDG .desktop file. Installed to share/applications on Linux for desktop launcher integration. Paths may be relative to the calling CMakeLists.txt. |
LINUX_ICON_THEME_DIR | Path to a directory containing a Linux icon theme subtree such as hicolor/256x256/apps/myapp.png. Installed to share/icons on Linux. Paths may be relative to the calling CMakeLists.txt. |
All other arguments after the target name are forwarded to add_executable() as source files.
If your target is created outside PackageBuilder, such as by add_executable or another CMake helper, register it for install, export, and CPack handling with package_register_target:
For externally created libraries, use PUBLIC_HEADER_DIRS to tell PackageBuilder which public header roots should be installed:
package_register_target accepts the same ICON, LINUX_DESKTOP_FILE, and LINUX_ICON_THEME_DIR arguments as package_add_executable. For externally created targets, ICON is packaging metadata only; it is used for the NSIS installer/uninstaller icon on Windows, but it does not modify the executable's own resources. package_register_target does not create the target, add sources, add include directories, or create a namespaced build-tree alias. Those details remain the responsibility of the project that created the target.
This single call handles everything:
package_add_library, package_add_executable, and package_register_targetinclude/ or any PUBLIC_HEADER_DIRS provided while registering external librariescmake/<ProjectName>Config.cmake and <ProjectName>ConfigVersion.cmakeDownstream projects can then consume your package:
package_install() configures CPack to generate platform-native installers:
| Platform | Generators |
|---|---|
| Windows | ZIP, NSIS |
| macOS | ZIP, DragNDrop |
| Linux | ZIP, DEB |
Multiple registered applications — including macOS app bundles created by external CMake helpers — are supported in a single package. Each registered runtime target gets its own runtime dependency set, so CPack can correctly resolve and bundle the dependencies for every app.
PackageBuilder assigns every install artifact to one of two CPack components:
| Component | Contents |
|---|---|
Runtime | Executables, macOS app bundles, shared libraries, and their runtime dependencies |
Development | Static libraries, public headers, CMake package metadata (exported targets, config/version files, custom modules) |
By default, generated installers include only the Runtime component: executables, app bundles, and shared libraries. Development-facing artifacts such as static libraries, public headers, exported CMake target definitions, and package config files are excluded because Conan is the preferred method for consuming packages as libraries during development.
By default, every registered executable gets a desktop shortcut (Windows) or an XDG .desktop launcher entry (Linux). To limit this to a specific subset, set PACKAGE_BUILDER_DESKTOP_LINKS to the list of target names that should receive shortcuts before calling package_install():
| Platform | Behavior |
|---|---|
| Windows | See Windows one-click installer below for desktop shortcut behavior. The NSIS installer icon is taken from the first registered executable that provides ICON. |
| Linux | Installs the .desktop file provided via LINUX_DESKTOP_FILE to share/applications, and installs the icon theme tree provided via LINUX_ICON_THEME_DIR to share/icons. If LINUX_DESKTOP_FILE is omitted, PackageBuilder falls back to looking for a <target>.desktop file in the same directory as the target's CMakeLists.txt. |
| macOS | No action needed — DragNDrop bundles are self-contained and Launchpad discovers them automatically when dragged to /Applications. |
By default (PACKAGE_BUILDER_WINDOWS_ONE_CLICK_INSTALLER ON), the generated NSIS installer is zero-interaction: the user double-clicks the installer, it installs the application, creates a desktop shortcut, and closes automatically. No wizard pages, no "Next" buttons, no path or directory choices.
When set to OFF, the installer reverts to the classic NSIS wizard with Welcome, License, Directory, Start Menu, and Install pages, plus an opt-in desktop shortcut checkbox.
| Mode | Desktop shortcut | PATH modification | Wizard pages |
|---|---|---|---|
ON (default) | Always created unconditionally | Never added to PATH | None — installs silently |
OFF | Opt-in checkbox during install | User-controlled via installer page | Welcome, License, Directory, Start Menu, Finish |
If your project needs a fully custom NSIS installer template, set PACKAGE_BUILDER_NSIS_TEMPLATE_DIR to the directory containing your NSIS.template.in before calling package_install(). This directory takes the highest priority over PackageBuilder's own template:
PackageBuilder's lookup order for NSIS.template.in (highest to lowest priority):
PACKAGE_BUILDER_NSIS_TEMPLATE_DIR — caller-provided overridecmake/NSIS/ directory (one-click template)If your project needs installers that also ship development files, set PACKAGE_BUILDER_CPACK_COMPONENTS before calling package_install():
PackageBuilder is designed to work best with the following project layout:
include/ are exposed publicly to consumers of your library.package_add_library and package_add_executable.src/ are private to your project and are not installed..cmake files in cmake/ are installed alongside the generated package config, making them available to consumers via CMAKE_MODULE_PATH.Projects with non-canonical layouts can still use PackageBuilder by creating targets themselves and then registering them with package_register_target(...).
JUCE creates GUI app targets via juce_add_gui_app rather than add_executable. Use package_register_target to hand the externally-created target off to PackageBuilder:
For Linux desktop icons, place PNG files under a standard icon theme layout rooted at the directory passed to LINUX_ICON_THEME_DIR, for example:
Then set Icon=my_app in your .desktop file, without a file extension.