Cpack: Exclude Install Commands from Subdirectory (Googletest Directory)

CPack: Exclude INSTALL commands from subdirectory (googletest directory)

Updated: As noted in the other answer,
it seems that EXCLUDE_FROM_ALL option is the most direct and correct way for disable install in the subproject in the subdirectory:

add_subdirectory(googletest EXCLUDE_FROM_ALL)


Previous solutions

If you don't need tests in your project's release (which you want to deliver with CPack), then include googletest subdirectory conditionally, and set conditional to false when packaging:

...
if(NOT DISABLE_TESTS)
add_subdirectory(googletest)
endif()

packaging with

cmake -DDISABLE_TESTS=ON <source-dir>
cpack

Alternatively, if you want tests, but don't want to install testing infrastructure, you may disable install command via defining macro or function with same name:

# Replace install() to do-nothing macro.
macro(install)
endmacro()
# Include subproject (or any other CMake code) with "disabled" install().
add_subdirectory(googletest)
# Restore original install() behavior.
macro(install)
_install(${ARGN})
endmacro()

This approach has also been suggested in CMake mailing.

According to the comments, that way with replacing CMake command is very tricky one and may to not work in some cases: either parameters passed to the modified install are parsed incorrectly or restoring install is not work and even following installs are disabled.

add_subdirectory() without installing anything

You can use this to prevent Google Test from being installed:

add_directory(gtest EXCLUDE_FROM_ALL)

install a EXCLUDE_FROM_ALL subdirectory

You can install specific targets defined in subdirectory CMakeLists.txt after cmake 3.13.

Before 3.13, user may use

add_subdirectory(path/to/sub_dir EXCLUDE_FROM_ALL)
target_link_libraries(your_target PRIVATE your_sub_dir_target)
...
install(SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/path/to/sub_dir/cmake_install.cmake)

with EXCLUDE_FROM_ALL, the your_sub_dir_target will not be included in the ALL target, then the install command will not be called for your sub_dir, you'll need to manually do it.

CMake add_subdirectory causes CPack to build only source directory

Turns out, the problem was the location of include(CPack). Since the statement is in itself responsible for generating the CPack configurations, calling it as early as I did generated those configurations before I had defined everything necessary for them.

The template for setting up install targets has changed as follows:

set(CPACK_GENERATOR "ZIP")
include(GNUInstallDirs)
install(TARGETS ourlibrary EXPORT ourlibrary_export
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(EXPORT ourlibrary_export
FILE ourlibraryTargets.cmake
NAMESPACE productfamily
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ourlibrary
)
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/ourlibraryConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion
)
configure_package_config_file(
${CMAKE_CURRENT_LIST_DIR}/CMake/ourlibraryConfig.cmake.in # It's a package init and an inclusion to ourlibraryTargets.cmake
${CMAKE_CURRENT_BINARY_DIR}/ourlibraryConfig.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ourlibrary
)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/ourlibraryConfigVersion.cmake
${CMAKE_CURRENT_BINARY_DIR}/ourlibraryConfig.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/ourlibrary
)
install(DIRECTORY
${CMAKE_CURRENT_BINARY_DIR}/etc/ourlibrary
DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}
)
include(CPack)

By moving the include until after the install targets were defined, my problem was resolved.

How to check whether include(CPack) is already being called before or not in CMake?

To override 3rd-party misbehavior is never easy. This is why I personally do not favor add_subdirectory and prefer to use vcpkg or another build orchestration tool (like Conan) instead.

However, the following snippet should work:

function (add_third_party)
# Write an empty CPack module
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/override/CPack.cmake" "")
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_BINARY_DIR}/override;${CMAKE_MODULE_PATH}")
add_subdirectory(third-party-source)
endfunction ()

add_third_party()

This will create a blank CPack module and trick the third party code into including it rather than the standard module. The function exists to make sure this overriding behavior can't leak out into the rest of your build.


I had misread your question. I thought you were in control of the project that included CPack.

Yes, the variable is named CPack_CMake_INCLUDED. However, it is better to check whether you are the top-level project and conditionally include your packaging rules, like this:

string(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}" is_top_level)
option(MyProj_INCLUDE_PACKAGING "Include packaging rules for MyProj" "${is_top_level}")

if (MyProj_INCLUDE_PACKAGING)
# ...
include(CPack)
endif ()

How to exclude files/dirs from CPack binary using CMake

Try to use component install.

  1. Add component label for each install command:

    install(TARGET app DESTINATION ... COMPONENT applications)
    install(TARGET library DESTINATION ... COMPONENT libraries)
    install(FILES <headers> DESTINATION ... COMPONENT headers)
  2. Turn on component install in CPack and list components you want to install:

    set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
    set(CPACK_COMPONENTS_ALL applications)
    include(CPack)

More information : http://www.cmake.org/Wiki/CMake:Component_Install_With_CPack

How to enable cmake to exclude a subdirectory from install?

Actually, with a helpful person in the cmake mailing list, I am now able to rid of the %dir /usr/lib in the generated spec file. It's actually quite simple: just cd to $CMAKE_SOURCE_DIR/lib and edit the CMakeLists.txt there. Append ${LIB_SUFFIX} to the two install DESTINATIONs. Regenerate the Makefile in the build subdirectory, and then make && make package. All library files go into /usr/lib64 as desired.



Related Topics



Leave a reply



Submit