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 install
s 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.
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)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 DESTINATION
s. Regenerate the Makefile
in the build
subdirectory, and then make && make package
. All library files go into /usr/lib64
as desired.
Related Topics
How to Use Non-Default Delimiters When Reading a Text File with Std::Fstream
Profiler for Visual Studio 2008, C++
Address-Of Operator (&) VS Reference Operator(&)
Clang Doesn't See Basic Headers
Initializing Std::String from Char* Without Copy
Does a C/C++ Compiler Optimize Constant Divisions by Power-Of-Two Value into Shifts
Cmake: Failed to Run Msbuild Command: Msbuild.Exe
Reason for Using Non-Type Template Parameter Instead of Regular Parameter
Consistent Pseudo-Random Numbers Across Platforms
Difference Between 'Strcpy' and 'Strcpy_S'
How to Build Google's Protobuf in Windows Using Mingw
Why Does Wide File-Stream in C++ Narrow Written Data by Default
How to Enable Visual Styles Without a Manifest
Initializing a C++ Std::Istringstream from an in Memory Buffer
How to Declare an Array of Objects Whose Class Has No Default Constructor
C++ Priority_Queue with Lambda Comparator Error
How to Compare Two Time Stamp in Format "Month Date Hh:Mm:Ss" to Check +Ve or -Ve Value