Key Concept: Allow other CMake projects to use your library without installing it system-wide.
Mechanism: Use export()
to generate a
file for dependency resolution.
Code Example:
add_library(MyLib STATIC mylib.cpp)
target_include_directories(MyLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
# Export targets to a file
export(
TARGETS MyLib
FILE "${CMAKE_CURRENT_BINARY_DIR}/MyLibTargets.cmake"
NAMESPACE MyNamespace::
)
This generates MyLibTargets.cmake
, allowing other projects to include it via include()
and link with MyNamespace::MyLib
.
Key Concept: Install built artifacts (executables, libraries, headers) to standard system paths.
Critical Commands:
install(TARGETS)
: Install build targets.install(FILES|DIRECTORY)
: Install headers/docs.Code Example:
install(
TARGETS MyLib
EXPORT MyLibTargets
ARCHIVE DESTINATION lib # Static libs (.a/.lib)
LIBRARY DESTINATION lib # Shared libs (.so/.dll)
RUNTIME DESTINATION bin # Executables/DLLs on Windows
INCLUDES DESTINATION include
)
install(
DIRECTORY include/ DESTINATION include
FILES LICENSE DESTINATION doc
)
# Install exported targets for downstream projects
install(
EXPORT MyLibTargets
FILE MyLibConfig.cmake
DESTINATION lib/cmake/MyLib
)
Platform-Specific Paths:
/usr/local/
(default CMAKE_INSTALL_PREFIX
)C:/Program Files/
Goal: Generate
for find_package()
compatibility.
Tools:
configure_package_config_file()
: Generates config file with correct paths.write_basic_package_version_file()
: Handles version compatibility.Code Example:
include(CMakePackageConfigHelpers)
configure_package_config_file(
MyLibConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/MyLibConfig.cmake
INSTALL_DESTINATION lib/cmake/MyLib
)
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/MyLibConfigVersion.cmake
VERSION 1.2.3
COMPATIBILITY SameMajorVersion # Accepts 1.x.x
)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/MyLibConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/MyLibConfigVersion.cmake
DESTINATION lib/cmake/MyLib
)
Template File MyLibConfig.cmake.in
:
@PACKAGE_INIT@ # CMake-provided initialization macro
include("${CMAKE_CURRENT_LIST_DIR}/MyLibTargets.cmake")
check_required_components(MyLib)
Use Case: Split installation into logical components (e.g., runtime
, development
, docs
).
Implementation: Add COMPONENT
to install()
commands.
Code Example:
install(TARGETS MyLib
EXPORT MyLibTargets
ARCHIVE DESTINATION lib COMPONENT development
LIBRARY DESTINATION lib COMPONENT runtime
INCLUDES DESTINATION include COMPONENT development
)
install(DIRECTORY include/
DESTINATION include
COMPONENT development
)
install(FILES LICENSE
DESTINATION doc
COMPONENT docs
)
Component-Specific Packaging (with CPack):
cpack_add_component(runtime DISPLAY_NAME "Runtime")
cpack_add_component(development DISPLAY_NAME "Development")
cpack_add_component(docs DISPLAY_NAME "Documentation")
Unix-Specific: Handle library versioning via symlinks (e.g., libfoo.so.1 → libfoo.so.1.2.3
).
CMake Support: Use SOVERSION
and VERSION
target properties.
Code Example:
set_target_properties(MyLib PROPERTIES
VERSION 1.2.3 # Full version
SOVERSION 1 # API compatibility version
)
This generates:
libMyLib.so.1.2.3
(real binary)libMyLib.so.1
→ libMyLib.so.1.2.3
libMyLib.so
→ libMyLib.so.1
Goal: Generate platform-specific packages (DEB, RPM, ZIP, etc.).
Configuration:
set(CPACK_PACKAGE_NAME "MyLib")
set(CPACK_PACKAGE_VERSION "1.2.3")
set(CPACK_PACKAGE_DESCRIPTION "A sample library")
# Component-aware packaging
set(CPACK_DEB_COMPONENT_INSTALL YES) # For Debian
include(CPack)
Generate Packages:
cmake --build build_dir --target install # Install artifacts first
cpack -G DEB # Generate Debian package
Component-Specific Variables:
cpack_add_component(runtime
DISPLAY_NAME "Runtime"
DESCRIPTION "Runtime components"
REQUIRED
)
cpack_add_component(development
DISPLAY_NAME "Development"
DEPENDS runtime
)
Config.cmake
) make your library discoverable via find_package()
.MyNamespace::
) in exported targets to avoid conflicts.CMAKE_INSTALL_PREFIX
, not absolute paths, for portability.VERSION
properties match between targets and ConfigVersion.cmake
.VERSION
/SOVERSION
for Unix.1. Which statements about exporting CMake targets without installation are correct?
A. export(TARGETS ...)
writes target properties to a file for external projects.
B. install(TARGETS ... EXPORT)
generates a
file.
C. Exported targets automatically resolve transitive dependencies.
D. The EXPORT
keyword in install()
requires a separate install(EXPORT ...)
call.
2. Which variables define default installation paths for public headers on Unix-like systems?
A. CMAKE_INSTALL_INCLUDEDIR
B. CMAKE_INSTALL_PREFIX
C. CMAKE_INSTALL_BINDIR
D. CMAKE_INSTALL_LIBDIR
3. What are valid methods for installing public headers?
A. Use target_include_directories()
with the PUBLIC
keyword.
B. Use install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
.
C. Use set_target_properties(... PUBLIC_HEADER ...)
.
D. Use file(COPY include/ DESTINATION ...)
followed by install(FILES ...)
.
4. Which are required steps to create a relocatable package with CMake?
A. Use absolute paths in target_include_directories()
.
B. Use configure_package_config_file()
with @PACKAGE_INIT@
.
C. Avoid CMAKE_INSTALL_PREFIX
in find_dependency()
calls.
D. Generate a
file.
5. What correctly describes component-based packaging in CMake?
A. Components are defined using cpack_add_component()
.
B. install(TARGETS ... COMPONENT runtime)
assigns targets to a component.
C. find_package(... COMPONENTS runtime)
filters installed components.
D. CPACK_DEB_COMPONENT_INSTALL
enables component-aware DEB packages.
6. Which CPack generators support component-based packaging?
A. ZIP
B. DEB
C. NSIS
D. RPM
7. How to manage versioned shared library symbolic links during installation?
A. Use install(CODE "execute_process(...)")
to create symlinks manually.
B. Use set_target_properties(... VERSION ... SOVERSION ...)
.
C. Use install(TARGETS ... LIBRARY DESTINATION ... NAMELINK_SKIP)
.
D. Use CMAKE_INSTALL_SO_NO_EXE
to disable symlink creation.
8. Which statements about runtime dependencies installation are correct?
A. install(TARGETS ... RUNTIME_DEPENDENCIES)
bundles all DLLs on Windows.
B. CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS
specifies additional runtime libraries.
C. BundleUtilities
is required for macOS .app
bundles.
D. WIX
CPack generator automatically resolves runtime dependencies.
9. Which are valid use cases for write_basic_package_version_file()
?
A. Enforce package version compatibility using ExactVersion
.
B. Generate a
file.
C. Compare versions using COMPATIBLE_VERSION_INTERNAL
.
D. Define custom version-check logic with macros.
10. What ensures correct behavior when using find_package()
for a custom package?
A. The package’s Config.cmake
file must be in CMAKE_PREFIX_PATH
.
B. find_dependency()
must be used for transitive dependencies.
C. The VERSION
field in project()
defines package compatibility.
D. CMAKE_MODULE_PATH
must include the package’s CMake/
directory.
A, B, D
export(TARGETS)
writes targets to a file (A). install(TARGETS ... EXPORT)
triggers export file generation (B). The EXPORT
keyword requires install(EXPORT)
(D). Exported targets do not auto-resolve dependencies (C is false).A
CMAKE_INSTALL_INCLUDEDIR
defaults to include/
(A). CMAKE_INSTALL_PREFIX
is the root (B). BINDIR
and LIBDIR
are for binaries/libraries (C/D incorrect).B, C
install(DIRECTORY ...)
copies headers (B). PUBLIC_HEADER
property installs headers via install(TARGETS)
©. target_include_directories()
doesn’t install files (A). file(COPY)
lacks integration with install()
(D is manual, not idiomatic).B, C, D
configure_package_config_file()
handles relative paths (B). Avoid absolute paths ©. Version files ensure compatibility (D). Absolute paths break relocatability (A is wrong).B, D
COMPONENT
in install()
assigns targets (B). CPACK_DEB_COMPONENT_INSTALL
enables DEB components (D). Components are defined via install(... COMPONENT)
(A is false). find_package(... COMPONENTS)
checks availability (C is correct but not a step in creation).B, D
B, C
VERSION/SOVERSION
controls symlink names (B). NAMELINK_SKIP
skips symlinks ©. Manual symlinks (A) are error-prone. CMAKE_INSTALL_SO_NO_EXE
is unrelated (D).A, C
RUNTIME_DEPENDENCIES
bundles dependencies (A). BundleUtilities
is for macOS ©. CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS
is not a standard variable (B). WIX doesn’t auto-resolve (D).B, D
write_basic_package_version_file()
generates version files (B). Custom logic requires macros (D). ExactVersion
is not a valid argument (A). COMPATIBLE_VERSION_INTERNAL
is internal ©.A, B
Config.cmake
must be in CMAKE_PREFIX_PATH
(A). find_dependency()
handles transitive deps (B). VERSION
in project()
doesn’t enforce compatibility ©. CMAKE_MODULE_PATH
is for Find*.cmake
, not Config.cmake
(D).Scenario:
You’re developing a C++ library MathLib
with the following structure:
MathLib/
├── include/MathLib.h
├── src/Calculator.cpp
└── apps/Main.cpp
Create CMake installation rules to:
include/MathLib
bin
find_package()
usageMathLibConfig.cmake
and MathLibConfigVersion.cmake
Answer:
include(GNUInstallDirs)
# Install targets
install(TARGETS MathLib
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/MathLib
)
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/MathLib)
install(TARGETS MathApp DESTINATION ${CMAKE_INSTALL_BINDIR})
# Export targets
install(EXPORT MathLibTargets
FILE MathLibTargets.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MathLib
NAMESPACE MathLib::
)
# Config files
include(CMakePackageConfigHelpers)
configure_package_config_file(
MathLibConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/MathLibConfig.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MathLib
)
write_basic_package_version_file(
MathLibConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion
)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/MathLibConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/MathLibConfigVersion.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MathLib
)
Explanation:
ARCHIVE/LIBRARY/RUNTIME
destinations handle different target typesINCLUDES
propagates include directories to dependent targetsinstall(EXPORT)
creates target export files with proper namespacingScenario:
Configure CPack to generate DEB packages with:
mathlib-.deb
ldconfig
Answer:
set(CPACK_GENERATOR "DEB")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Dev Team ")
set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libboost-all-dev (>= 1.65)")
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/mathlib.service
DESTINATION /lib/systemd/system
)
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
"${CMAKE_CURRENT_BINARY_DIR}/postinst"
)
# Create postinst script
file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/postinst CONTENT "#!/bin/sh\nldconfig\n")
include(CPack)
Explanation:
CPACK_GENERATOR
selects DEB package formatCPACK_DEBIAN_FILE_NAME
uses default naming conventionCPACK_DEBIAN_PACKAGE_DEPENDS
specifies runtime dependenciesCPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
adds post-install scriptinclude(CPack)
activates packaging supportScenario:
Create an installation with:
runtime
and development
componentslibmath.so.1.2.3
(real)libmath.so.1
(major version)libmath.so
(latest)MathLibConfigVersion.cmake
that:
development
requires runtime
docs
optional componentAnswer:
# Versioned library setup
set_target_properties(MathLib PROPERTIES
VERSION 1.2.3
SOVERSION 1
OUTPUT_NAME "math"
)
# Component definitions
cpack_add_component(runtime DISPLAY_NAME "Runtime")
cpack_add_component(development
DISPLAY_NAME "Development"
DEPENDS runtime
)
cpack_add_component(docs
DISPLAY_NAME "Documentation"
DISABLED
)
# Installation rules
install(TARGETS MathLib
EXPORT MathLibTargets
RUNTIME DESTINATION bin COMPONENT runtime
LIBRARY DESTINATION lib COMPONENT runtime
ARCHIVE DESTINATION lib COMPONENT development
INCLUDES DESTINATION include/MathLib
)
install(EXPORT MathLibTargets
FILE MathLibTargets.cmake
DESTINATION lib/cmake/MathLib
COMPONENT development
NAMESPACE MathLib::
)
# Version config
write_basic_package_version_file(
MathLibConfigVersion.cmake
VERSION 2.0.0
COMPATIBILITY SameMajorVersion
)
# Compatibility check
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/MathLibConfig.cmake.in
"if(NOT MathLib_FIND_VERSION VERSION_GREATER_EQUAL 2.0.0)\n"
" message(FATAL_ERROR \"Requires at least version 2.0.0\")\n"
"endif()\n"
"include(\${CMAKE_CURRENT_LIST_DIR}/MathLibTargets.cmake)"
)
configure_package_config_file(
MathLibConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/MathLibConfig.cmake
INSTALL_DESTINATION lib/cmake/MathLib
)
include(CPack)
Explanation:
COMPONENT
argumentsKey Concepts Reinforcement: