Skip to content

Commit 0e6c594

Browse files
committed
Add option to control installation via NAMESPACE_INSTALL
Introduces a CMake option `${NAMESPACE}_INSTALL` (defaulting to `PROJECT_IS_TOP_LEVEL`) to explicitly enable or disable installation of the library. Updates documentation and refactors install logic to use this option, allowing more flexible control for both top-level and subproject builds.
1 parent c77917f commit 0e6c594

3 files changed

Lines changed: 30 additions & 19 deletions

File tree

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,11 @@ cmake --install build/install --prefix /opt/mylib
171171
```
172172
The `install` preset enables `CPM_USE_LOCAL_PACKAGES`, which verifies your generated Config.cmake works correctly. See the [CPM.cmake documentation](https://github.com/cpm-cmake/CPM.cmake#cpm_use_local_packages) for more about using installed packages.
173173

174-
By default, installation is enabled only when building as a top-level project. To enable installation in non-top-level projects (e.g., when using CPM with package managers), set `${NAMESPACE}_INSTALL=ON`:
174+
**Controlling installation**: The `${NAMESPACE}_INSTALL` option controls whether installation is enabled (defaults to `PROJECT_IS_TOP_LEVEL`). Use `-D${NAMESPACE}_INSTALL=ON/OFF` to override:
175175

176176
```bash
177-
cmake -DSTLAB_INSTALL=ON -B build # For a library with NAMESPACE stlab
177+
cmake -DSTLAB_INSTALL=OFF -B build # Disable install for top-level project
178+
cmake -DSTLAB_INSTALL=ON -B build # Enable install for non-top-level (e.g., via CPM)
178179
```
179180

180181
**Re-exporting CPM dependencies:** When re-exporting dependencies from `CPMAddPackage`, wrap them in `BUILD_INTERFACE` to avoid export errors (CPM creates non-IMPORTED targets that can't be exported):
@@ -339,7 +340,7 @@ cpp_library_setup(
339340
- The project name is automatically taken from `PROJECT_NAME` (set by the `project()` command). You must call `project(your-library)` before `cpp_library_setup()`.
340341
- **If you specify `TESTS` or `EXAMPLES`**, call `include(CTest)` after `project()` and before `cpp_library_setup()`.
341342
- Version is automatically detected from git tags (see [Version Management](#version-management) for overrides).
342-
- Installation is enabled by default when `PROJECT_IS_TOP_LEVEL=TRUE`. Set `${NAMESPACE}_INSTALL=ON` to enable installation in non-top-level projects.
343+
- Installation is controlled by the `${NAMESPACE}_INSTALL` option, which defaults to `PROJECT_IS_TOP_LEVEL`.
343344

344345
### Target Naming
345346

cmake/cpp-library-install.cmake

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,7 @@ endfunction()
409409
# - Precondition: NAME, PACKAGE_NAME, VERSION, and NAMESPACE specified; target NAME exists
410410
# - Postcondition: install rules created for target, config files, and export with NAMESPACE:: prefix
411411
# - Supports header-only (INTERFACE) and compiled libraries, uses SameMajorVersion compatibility
412+
# - Installation can be controlled via ${NAMESPACE}_INSTALL option (defaults to PROJECT_IS_TOP_LEVEL)
412413
function(_cpp_library_setup_install)
413414
set(oneValueArgs
414415
NAME # Target name (e.g., "stlab-enum-ops")
@@ -422,10 +423,6 @@ function(_cpp_library_setup_install)
422423

423424
cmake_parse_arguments(ARG "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
424425

425-
# Include required CMake modules (deferred from top-level to avoid requiring project() before include)
426-
include(GNUInstallDirs)
427-
include(CMakePackageConfigHelpers)
428-
429426
# Validate required arguments
430427
if(NOT ARG_NAME)
431428
message(FATAL_ERROR "_cpp_library_setup_install: NAME is required")
@@ -440,6 +437,22 @@ function(_cpp_library_setup_install)
440437
message(FATAL_ERROR "_cpp_library_setup_install: NAMESPACE is required")
441438
endif()
442439

440+
# Define installation option with PROJECT_IS_TOP_LEVEL as default
441+
# This allows explicit control: -D${NAMESPACE}_INSTALL=ON/OFF
442+
# Upper-case the namespace for the option name
443+
string(TOUPPER "${ARG_NAMESPACE}" NAMESPACE_UPPER)
444+
option(${NAMESPACE_UPPER}_INSTALL "Enable installation of ${ARG_PACKAGE_NAME}" ${PROJECT_IS_TOP_LEVEL})
445+
446+
# Check if installation is enabled
447+
if(NOT ${NAMESPACE_UPPER}_INSTALL)
448+
message(STATUS "cpp-library: Installation disabled for ${ARG_PACKAGE_NAME} (${NAMESPACE_UPPER}_INSTALL=OFF)")
449+
return()
450+
endif()
451+
452+
# Include required CMake modules (deferred from top-level to avoid requiring project() before include)
453+
include(GNUInstallDirs)
454+
include(CMakePackageConfigHelpers)
455+
443456
# Install the library target
444457
# For header-only libraries (INTERFACE), this installs the target metadata
445458
# For compiled libraries, this installs the library files and headers

cmake/cpp-library-setup.cmake

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -119,18 +119,15 @@ function(_cpp_library_setup_core)
119119
endif()
120120
endif()
121121

122-
# Setup installation when building as top-level project OR explicitly requested
123-
# This allows package managers (vcpkg, CPM with install intent) to enable installation
124-
# even when PROJECT_IS_TOP_LEVEL is FALSE
125-
if(ARG_TOP_LEVEL OR ${ARG_NAMESPACE}_INSTALL)
126-
_cpp_library_setup_install(
127-
NAME "${ARG_NAME}"
128-
PACKAGE_NAME "${ARG_PACKAGE_NAME}"
129-
VERSION "${ARG_VERSION}"
130-
NAMESPACE "${ARG_NAMESPACE}"
131-
HEADERS "${ARG_HEADERS}"
132-
)
133-
endif()
122+
# Setup installation (controlled by ${NAMESPACE}_INSTALL option, defaults to PROJECT_IS_TOP_LEVEL)
123+
# The option is defined and checked inside _cpp_library_setup_install()
124+
_cpp_library_setup_install(
125+
NAME "${ARG_NAME}"
126+
PACKAGE_NAME "${ARG_PACKAGE_NAME}"
127+
VERSION "${ARG_VERSION}"
128+
NAMESPACE "${ARG_NAMESPACE}"
129+
HEADERS "${ARG_HEADERS}"
130+
)
134131

135132
endfunction()
136133

0 commit comments

Comments
 (0)