diff --git a/README.md b/README.md index 2c5f01e..6c15678 100644 --- a/README.md +++ b/README.md @@ -171,6 +171,13 @@ cmake --install build/install --prefix /opt/mylib ``` 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. +**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: + +```bash +cmake -DSTLAB_INSTALL=OFF -B build # Disable install for top-level project +cmake -DSTLAB_INSTALL=ON -B build # Enable install for non-top-level (e.g., via CPM) +``` + **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): ```cmake @@ -333,6 +340,7 @@ cpp_library_setup( - The project name is automatically taken from `PROJECT_NAME` (set by the `project()` command). You must call `project(your-library)` before `cpp_library_setup()`. - **If you specify `TESTS` or `EXAMPLES`**, call `include(CTest)` after `project()` and before `cpp_library_setup()`. - Version is automatically detected from git tags (see [Version Management](#version-management) for overrides). +- Installation is controlled by the `${NAMESPACE}_INSTALL` option, which defaults to `PROJECT_IS_TOP_LEVEL`. ### Target Naming diff --git a/cmake/cpp-library-install.cmake b/cmake/cpp-library-install.cmake index dd78ad5..374635a 100644 --- a/cmake/cpp-library-install.cmake +++ b/cmake/cpp-library-install.cmake @@ -409,6 +409,7 @@ endfunction() # - Precondition: NAME, PACKAGE_NAME, VERSION, and NAMESPACE specified; target NAME exists # - Postcondition: install rules created for target, config files, and export with NAMESPACE:: prefix # - Supports header-only (INTERFACE) and compiled libraries, uses SameMajorVersion compatibility +# - Installation can be controlled via ${NAMESPACE}_INSTALL option (defaults to PROJECT_IS_TOP_LEVEL) function(_cpp_library_setup_install) set(oneValueArgs NAME # Target name (e.g., "stlab-enum-ops") @@ -422,10 +423,6 @@ function(_cpp_library_setup_install) cmake_parse_arguments(ARG "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - # Include required CMake modules (deferred from top-level to avoid requiring project() before include) - include(GNUInstallDirs) - include(CMakePackageConfigHelpers) - # Validate required arguments if(NOT ARG_NAME) message(FATAL_ERROR "_cpp_library_setup_install: NAME is required") @@ -440,6 +437,22 @@ function(_cpp_library_setup_install) message(FATAL_ERROR "_cpp_library_setup_install: NAMESPACE is required") endif() + # Define installation option with PROJECT_IS_TOP_LEVEL as default + # This allows explicit control: -D${NAMESPACE}_INSTALL=ON/OFF + # Upper-case the namespace for the option name + string(TOUPPER "${ARG_NAMESPACE}" NAMESPACE_UPPER) + option(${NAMESPACE_UPPER}_INSTALL "Enable installation of ${ARG_PACKAGE_NAME}" ${PROJECT_IS_TOP_LEVEL}) + + # Check if installation is enabled + if(NOT ${NAMESPACE_UPPER}_INSTALL) + message(STATUS "cpp-library: Installation disabled for ${ARG_PACKAGE_NAME} (${NAMESPACE_UPPER}_INSTALL=OFF)") + return() + endif() + + # Include required CMake modules (deferred from top-level to avoid requiring project() before include) + include(GNUInstallDirs) + include(CMakePackageConfigHelpers) + # Install the library target # For header-only libraries (INTERFACE), this installs the target metadata # For compiled libraries, this installs the library files and headers diff --git a/cmake/cpp-library-setup.cmake b/cmake/cpp-library-setup.cmake index ebecfd6..651db62 100644 --- a/cmake/cpp-library-setup.cmake +++ b/cmake/cpp-library-setup.cmake @@ -119,16 +119,15 @@ function(_cpp_library_setup_core) endif() endif() - # Setup installation when building as top-level project - if(ARG_TOP_LEVEL) - _cpp_library_setup_install( - NAME "${ARG_NAME}" - PACKAGE_NAME "${ARG_PACKAGE_NAME}" - VERSION "${ARG_VERSION}" - NAMESPACE "${ARG_NAMESPACE}" - HEADERS "${ARG_HEADERS}" - ) - endif() + # Setup installation (controlled by ${NAMESPACE}_INSTALL option, defaults to PROJECT_IS_TOP_LEVEL) + # The option is defined and checked inside _cpp_library_setup_install() + _cpp_library_setup_install( + NAME "${ARG_NAME}" + PACKAGE_NAME "${ARG_PACKAGE_NAME}" + VERSION "${ARG_VERSION}" + NAMESPACE "${ARG_NAMESPACE}" + HEADERS "${ARG_HEADERS}" + ) endfunction()