mirror of
https://github.com/yaobinwen/CMake.git
synced 2026-01-12 15:45:49 +00:00
Alternative symlink-creating mode for file(INSTALL ...)
An new environment variable 'CMAKE_INSTALL_MODE' is introduced, which can be used to ask CMake to create symbolic links instead of copying files during a file(INSTALL ...). The operation is at the file level only, directory trees are still created using actual directories, not links. Signed-off-by: Felix Lelchuk <felix.lelchuk@gmx.de>
This commit is contained in:
@ -843,6 +843,11 @@ and ``NO_SOURCE_PERMISSIONS`` is default.
|
||||
Installation scripts generated by the :command:`install` command
|
||||
use this signature (with some undocumented options for internal use).
|
||||
|
||||
.. versionchanged:: 3.22
|
||||
|
||||
The environment variable :envvar:`CMAKE_INSTALL_MODE` can override the
|
||||
default copying behavior of :command:`file(INSTALL)`.
|
||||
|
||||
.. _SIZE:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
@ -30,6 +30,10 @@ are executed in order during installation.
|
||||
with those in the parent directory to run in the order declared (see
|
||||
policy :policy:`CMP0082`).
|
||||
|
||||
.. versionchanged:: 3.22
|
||||
The environment variable :envvar:`CMAKE_INSTALL_MODE` can override the
|
||||
default copying behavior of :command:`install()`.
|
||||
|
||||
There are multiple signatures for this command. Some of them define
|
||||
installation options for files and targets. Options common to
|
||||
multiple signatures are covered here but they are valid only for
|
||||
|
||||
37
Help/envvar/CMAKE_INSTALL_MODE.rst
Normal file
37
Help/envvar/CMAKE_INSTALL_MODE.rst
Normal file
@ -0,0 +1,37 @@
|
||||
CMAKE_INSTALL_MODE
|
||||
------------------
|
||||
|
||||
.. versionadded:: 3.22
|
||||
|
||||
.. include:: ENV_VAR.txt
|
||||
|
||||
The ``CMAKE_INSTALL_MODE`` environment variable allows users to operate
|
||||
CMake in an alternate mode of :command:`file(INSTALL)` and :command:`install()`.
|
||||
|
||||
The default behavior for an installation is to copy a source file from a
|
||||
source directory into a destination directory. This environment variable
|
||||
however allows the user to override this behavior, causing CMake to create
|
||||
symbolic links instead.
|
||||
|
||||
.. note::
|
||||
A symbolic link consists of a reference file path rather than contents of its own,
|
||||
hence there are two ways to express the relation, either by a relative or an absolute path.
|
||||
|
||||
The following values are allowed for ``CMAKE_INSTALL_MODE``:
|
||||
|
||||
* empty, unset or ``COPY``: default behavior, duplicate the file at its destination
|
||||
* ``ABS_SYMLINK``: create an *absolute* symbolic link to the source file at the destination *or fail*
|
||||
* ``ABS_SYMLINK_OR_COPY``: like ``ABS_SYMLINK`` but silently copy on error
|
||||
* ``REL_SYMLINK``: create an *relative* symbolic link to the source file at the destination *or fail*
|
||||
* ``REL_SYMLINK_OR_COPY``: like ``REL_SYMLINK`` but silently copy on error
|
||||
* ``SYMLINK``: try as if through ``REL_SYMLINK`` and fall back to ``ABS_SYMLINK`` if the referenced
|
||||
file cannot be expressed using a relative path. Fail on error.
|
||||
* ``SYMLINK_OR_COPY``: like ``SYMLINK`` but silently copy on error
|
||||
|
||||
Installing symbolic links rather than copying files can help conserve storage space because files do
|
||||
not have to be duplicated on disk. However, modifications applied to the source immediately affects
|
||||
the symbolic link and vice versa. *Use with caution*.
|
||||
|
||||
.. note:: ``CMAKE_INSTALL_MODE`` only affects files, *not* directories.
|
||||
|
||||
.. note:: Symbolic links are not available on all platforms.
|
||||
@ -38,6 +38,7 @@ Environment Variables that Control the Build
|
||||
/envvar/CMAKE_GENERATOR_INSTANCE
|
||||
/envvar/CMAKE_GENERATOR_PLATFORM
|
||||
/envvar/CMAKE_GENERATOR_TOOLSET
|
||||
/envvar/CMAKE_INSTALL_MODE
|
||||
/envvar/CMAKE_LANG_COMPILER_LAUNCHER
|
||||
/envvar/CMAKE_LANG_LINKER_LAUNCHER
|
||||
/envvar/CMAKE_MSVCIDE_RUN_PATH
|
||||
|
||||
16
Help/release/dev/cmake-install-mode-symlink.rst
Normal file
16
Help/release/dev/cmake-install-mode-symlink.rst
Normal file
@ -0,0 +1,16 @@
|
||||
cmake-install-mode-symlink
|
||||
--------------------------
|
||||
|
||||
* The :envvar:`CMAKE_INSTALL_MODE` environment variable was added to
|
||||
allow users to override the default file-copying behavior of
|
||||
:command:`install` and :command:`file(INSTALL)` into creating
|
||||
symbolic links. This can aid in lowering storage space requirements
|
||||
and avoiding redundancy.
|
||||
|
||||
* The :command:`file(INSTALL)` can now be affected / modified by the
|
||||
:envvar:`CMAKE_INSTALL_MODE` environment variable causing installation
|
||||
of symbolic links instead of copying of files.
|
||||
|
||||
* The :command:`install` can now be affected / modified by the
|
||||
:envvar:`CMAKE_INSTALL_MODE` environment variable causing installation
|
||||
of symbolic links instead of copying of files.
|
||||
@ -67,8 +67,9 @@ protected:
|
||||
|
||||
bool InstallSymlinkChain(std::string& fromFile, std::string& toFile);
|
||||
bool InstallSymlink(const std::string& fromFile, const std::string& toFile);
|
||||
bool InstallFile(const std::string& fromFile, const std::string& toFile,
|
||||
MatchProperties match_properties);
|
||||
virtual bool InstallFile(const std::string& fromFile,
|
||||
const std::string& toFile,
|
||||
MatchProperties match_properties);
|
||||
bool InstallDirectory(const std::string& source,
|
||||
const std::string& destination,
|
||||
MatchProperties match_properties);
|
||||
|
||||
@ -3,7 +3,12 @@
|
||||
|
||||
#include "cmFileInstaller.h"
|
||||
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
|
||||
#include <cm/string_view>
|
||||
#include <cmext/string_view>
|
||||
|
||||
#include "cm_sys_stat.h"
|
||||
|
||||
@ -18,6 +23,7 @@ using namespace cmFSPermissions;
|
||||
cmFileInstaller::cmFileInstaller(cmExecutionStatus& status)
|
||||
: cmFileCopier(status, "INSTALL")
|
||||
, InstallType(cmInstallType_FILES)
|
||||
, InstallMode(cmInstallMode::COPY)
|
||||
, Optional(false)
|
||||
, MessageAlways(false)
|
||||
, MessageLazy(false)
|
||||
@ -82,6 +88,93 @@ bool cmFileInstaller::Install(const std::string& fromFile,
|
||||
return this->cmFileCopier::Install(fromFile, toFile);
|
||||
}
|
||||
|
||||
bool cmFileInstaller::InstallFile(const std::string& fromFile,
|
||||
const std::string& toFile,
|
||||
MatchProperties match_properties)
|
||||
{
|
||||
if (this->InstallMode == cmInstallMode::COPY) {
|
||||
return this->cmFileCopier::InstallFile(fromFile, toFile, match_properties);
|
||||
}
|
||||
|
||||
std::string newFromFile;
|
||||
|
||||
if (this->InstallMode == cmInstallMode::REL_SYMLINK ||
|
||||
this->InstallMode == cmInstallMode::REL_SYMLINK_OR_COPY ||
|
||||
this->InstallMode == cmInstallMode::SYMLINK ||
|
||||
this->InstallMode == cmInstallMode::SYMLINK_OR_COPY) {
|
||||
// Try to get a relative path.
|
||||
std::string toDir = cmSystemTools::GetParentDirectory(toFile);
|
||||
newFromFile = cmSystemTools::ForceToRelativePath(toDir, fromFile);
|
||||
|
||||
// Double check that we can restore the original path.
|
||||
std::string reassembled =
|
||||
cmSystemTools::CollapseFullPath(newFromFile, toDir);
|
||||
if (!cmSystemTools::ComparePath(reassembled, fromFile)) {
|
||||
if (this->InstallMode == cmInstallMode::SYMLINK ||
|
||||
this->InstallMode == cmInstallMode::SYMLINK_OR_COPY) {
|
||||
// User does not mind, silently proceed with absolute path.
|
||||
newFromFile = fromFile;
|
||||
} else if (this->InstallMode == cmInstallMode::REL_SYMLINK_OR_COPY) {
|
||||
// User expects a relative symbolic link or a copy.
|
||||
// Since an absolute symlink won't do, copy instead.
|
||||
return this->cmFileCopier::InstallFile(fromFile, toFile,
|
||||
match_properties);
|
||||
} else {
|
||||
// We cannot meet user's expectation (REL_SYMLINK)
|
||||
auto e = cmStrCat(this->Name,
|
||||
" cannot determine relative path for symlink to \"",
|
||||
newFromFile, "\" at \"", toFile, "\".");
|
||||
this->Status.SetError(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
newFromFile = fromFile; // stick with absolute path
|
||||
}
|
||||
|
||||
// Compare the symlink value to that at the destination if not
|
||||
// always installing.
|
||||
bool copy = true;
|
||||
if (!this->Always) {
|
||||
std::string oldSymlinkTarget;
|
||||
if (cmSystemTools::ReadSymlink(toFile, oldSymlinkTarget)) {
|
||||
if (newFromFile == oldSymlinkTarget) {
|
||||
copy = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Inform the user about this file installation.
|
||||
this->ReportCopy(toFile, TypeLink, copy);
|
||||
|
||||
if (copy) {
|
||||
// Remove the destination file so we can always create the symlink.
|
||||
cmSystemTools::RemoveFile(toFile);
|
||||
|
||||
// Create destination directory if it doesn't exist
|
||||
cmSystemTools::MakeDirectory(cmSystemTools::GetFilenamePath(toFile));
|
||||
|
||||
// Create the symlink.
|
||||
if (!cmSystemTools::CreateSymlink(newFromFile, toFile)) {
|
||||
if (this->InstallMode == cmInstallMode::ABS_SYMLINK_OR_COPY ||
|
||||
this->InstallMode == cmInstallMode::REL_SYMLINK_OR_COPY ||
|
||||
this->InstallMode == cmInstallMode::SYMLINK_OR_COPY) {
|
||||
// Failed to create a symbolic link, fall back to copying.
|
||||
return this->cmFileCopier::InstallFile(newFromFile, toFile,
|
||||
match_properties);
|
||||
}
|
||||
|
||||
auto e = cmStrCat(this->Name, " cannot create symlink to \"",
|
||||
newFromFile, "\" at \"", toFile,
|
||||
"\": ", cmSystemTools::GetLastSystemError(), "\".");
|
||||
this->Status.SetError(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void cmFileInstaller::DefaultFilePermissions()
|
||||
{
|
||||
this->cmFileCopier::DefaultFilePermissions();
|
||||
@ -141,6 +234,31 @@ bool cmFileInstaller::Parse(std::vector<std::string> const& args)
|
||||
return false;
|
||||
}
|
||||
|
||||
static const std::map<cm::string_view, cmInstallMode> install_mode_dict{
|
||||
{ "ABS_SYMLINK"_s, cmInstallMode::ABS_SYMLINK },
|
||||
{ "ABS_SYMLINK_OR_COPY"_s, cmInstallMode::ABS_SYMLINK_OR_COPY },
|
||||
{ "REL_SYMLINK"_s, cmInstallMode::REL_SYMLINK },
|
||||
{ "REL_SYMLINK_OR_COPY"_s, cmInstallMode::REL_SYMLINK_OR_COPY },
|
||||
{ "SYMLINK"_s, cmInstallMode::SYMLINK },
|
||||
{ "SYMLINK_OR_COPY"_s, cmInstallMode::SYMLINK_OR_COPY }
|
||||
};
|
||||
|
||||
std::string install_mode;
|
||||
cmSystemTools::GetEnv("CMAKE_INSTALL_MODE", install_mode);
|
||||
if (install_mode.empty() || install_mode == "COPY"_s) {
|
||||
this->InstallMode = cmInstallMode::COPY;
|
||||
} else {
|
||||
auto it = install_mode_dict.find(install_mode);
|
||||
if (it != install_mode_dict.end()) {
|
||||
this->InstallMode = it->second;
|
||||
} else {
|
||||
auto e = cmStrCat("Unrecognized value '", install_mode,
|
||||
"' for environment variable CMAKE_INSTALL_MODE");
|
||||
this->Status.SetError(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "cmFileCopier.h"
|
||||
#include "cmInstallMode.h"
|
||||
#include "cmInstallType.h"
|
||||
|
||||
class cmExecutionStatus;
|
||||
@ -19,6 +20,7 @@ struct cmFileInstaller : public cmFileCopier
|
||||
|
||||
protected:
|
||||
cmInstallType InstallType;
|
||||
cmInstallMode InstallMode;
|
||||
bool Optional;
|
||||
bool MessageAlways;
|
||||
bool MessageLazy;
|
||||
@ -35,7 +37,8 @@ protected:
|
||||
bool ReportMissing(const std::string& fromFile) override;
|
||||
bool Install(const std::string& fromFile,
|
||||
const std::string& toFile) override;
|
||||
|
||||
bool InstallFile(const std::string& fromFile, const std::string& toFile,
|
||||
MatchProperties match_properties) override;
|
||||
bool Parse(std::vector<std::string> const& args) override;
|
||||
enum
|
||||
{
|
||||
|
||||
17
Source/cmInstallMode.h
Normal file
17
Source/cmInstallMode.h
Normal file
@ -0,0 +1,17 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* Enumerate types known to file(INSTALL).
|
||||
*/
|
||||
enum class cmInstallMode
|
||||
{
|
||||
COPY,
|
||||
ABS_SYMLINK,
|
||||
ABS_SYMLINK_OR_COPY,
|
||||
REL_SYMLINK,
|
||||
REL_SYMLINK_OR_COPY,
|
||||
SYMLINK,
|
||||
SYMLINK_OR_COPY
|
||||
};
|
||||
@ -1641,6 +1641,54 @@ if(BUILD_TESTING)
|
||||
WORKING_DIRECTORY ${CMake_SOURCE_DIR}/Tests/ExternalProjectUpdate
|
||||
DEPENDS ExternalProjectUpdateSetup )
|
||||
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_CMAKE_COMMAND}
|
||||
"-E" create_symlink
|
||||
"${CMake_SOURCE_DIR}/Tests/CMakeLists.txt" # random source file that exists
|
||||
"${CMake_BINARY_DIR}/Tests/try_to_create_symlink" # random target file in existing directory
|
||||
RESULT_VARIABLE _failed
|
||||
)
|
||||
if(_failed)
|
||||
message("Failed to create a simple symlink on this machine. Skipping InstallMode tests.")
|
||||
else()
|
||||
function(add_installmode_test _mode)
|
||||
set(ENV{CMAKE_INSTALL_MODE} _mode)
|
||||
set(_maybe_InstallMode_CTEST_OPTIONS)
|
||||
set(_maybe_BUILD_OPTIONS)
|
||||
if(_isMultiConfig)
|
||||
set(_maybe_CTEST_OPTIONS -C $<CONFIGURATION>)
|
||||
else()
|
||||
set(_maybe_BUILD_OPTIONS "-DCMAKE_BUILD_TYPE=$<CONFIGURATION>")
|
||||
endif()
|
||||
add_test(
|
||||
NAME "InstallMode-${_mode}"
|
||||
COMMAND
|
||||
${CMAKE_CTEST_COMMAND} -V ${_maybe_CTEST_OPTIONS}
|
||||
--build-and-test
|
||||
"${CMake_SOURCE_DIR}/Tests/InstallMode"
|
||||
"${CMake_BINARY_DIR}/Tests/InstallMode-${_mode}"
|
||||
${build_generator_args}
|
||||
--build-project superpro
|
||||
--build-exe-dir "${CMake_BINARY_DIR}/Tests/InstallMode-${_mode}"
|
||||
--force-new-ctest-process
|
||||
--build-options
|
||||
${_maybe_BUILD_OPTIONS}
|
||||
"-DCMAKE_INSTALL_PREFIX:PATH=${CMake_BINARY_DIR}/Tests/InstallMode-${_mode}/install"
|
||||
)
|
||||
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/InstallMode-${_mode}")
|
||||
unset(ENV{CMAKE_INSTALL_MODE})
|
||||
endfunction()
|
||||
|
||||
add_installmode_test(COPY)
|
||||
add_installmode_test(REL_SYMLINK)
|
||||
add_installmode_test(REL_SYMLINK_OR_COPY)
|
||||
add_installmode_test(ABS_SYMLINK)
|
||||
add_installmode_test(ABS_SYMLINK_OR_COPY)
|
||||
add_installmode_test(SYMLINK)
|
||||
add_installmode_test(SYMLINK_OR_COPY)
|
||||
endif()
|
||||
|
||||
|
||||
# do each of the tutorial steps
|
||||
function(add_tutorial_test step_name use_mymath tutorial_arg pass_regex)
|
||||
set(tutorial_test_name Tutorial${step_name})
|
||||
|
||||
124
Tests/InstallMode/CMakeLists.txt
Normal file
124
Tests/InstallMode/CMakeLists.txt
Normal file
@ -0,0 +1,124 @@
|
||||
cmake_minimum_required(VERSION 3.20.0)
|
||||
|
||||
project(superpro LANGUAGES NONE)
|
||||
|
||||
add_subdirectory(superpro)
|
||||
|
||||
include(Subproject.cmake)
|
||||
add_subproject(static_lib DIR subpro_a_static_lib)
|
||||
add_subproject(shared_lib DIR subpro_b_shared_lib)
|
||||
add_subproject(nested_lib DIR subpro_c_nested_lib NO_INSTALL)
|
||||
add_subproject(executable DIR subpro_d_executable
|
||||
DEPENDS
|
||||
static_lib
|
||||
shared_lib
|
||||
nested_lib
|
||||
)
|
||||
|
||||
include(CTest)
|
||||
if(BUILD_TESTING)
|
||||
enable_language(CXX) # required by GNUInstallDirs
|
||||
include(GNUInstallDirs)
|
||||
|
||||
macro(testme _name _path _symlink)
|
||||
add_test(
|
||||
NAME "${_name}"
|
||||
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||
COMMAND
|
||||
"${CMAKE_COMMAND}"
|
||||
"-DFILE_PATH=${CMAKE_INSTALL_PREFIX}/${_path}"
|
||||
"-DEXPECT_SYMLINK:BOOL=${_symlink}"
|
||||
"-DEXPECT_ABSOLUTE:BOOL=${ARGN}"
|
||||
"-P" "${CMAKE_SOURCE_DIR}/Test.cmake"
|
||||
)
|
||||
endmacro()
|
||||
|
||||
set(_mode $ENV{CMAKE_INSTALL_MODE})
|
||||
if(NOT "${_mode}" OR "${_mode}" STREQUAL "COPY")
|
||||
set(expect_symlink NO)
|
||||
elseif("${_mode}" MATCHES "(REL_)?SYMLINK(_OR_COPY)?")
|
||||
set(expect_symlink YES)
|
||||
set(expect_absolute NO)
|
||||
elseif("${_mode}" MATCHES "ABS_SYMLINK(_OR_COPY)?")
|
||||
set(expect_symlink YES)
|
||||
set(expect_absolute YES)
|
||||
endif()
|
||||
|
||||
# toplevel project should respect CMAKE_INSTALL_MODE
|
||||
|
||||
testme(superproj_file_copy
|
||||
"file_copy.txt" NO)
|
||||
testme(superproj_file_copy_file
|
||||
"file_copy_file.txt" NO)
|
||||
testme(superproj_file_install
|
||||
"file_install.txt"
|
||||
${expect_symlink}
|
||||
${expect_absolute})
|
||||
testme(superproj_file_create_link_symbolic
|
||||
"file_create_link_symbolic.txt" YES YES)
|
||||
|
||||
# subprojects should receive and respect CMAKE_INSTALL_MODE too
|
||||
|
||||
testme(subpro_a_static_lib_header
|
||||
"${CMAKE_INSTALL_INCLUDEDIR}/static_lib.h"
|
||||
${expect_symlink}
|
||||
${expect_absolute}
|
||||
)
|
||||
testme(subpro_a_static_lib_libfile
|
||||
"${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}the_static_lib${CMAKE_STATIC_LIBRARY_SUFFIX}"
|
||||
${expect_symlink}
|
||||
${expect_absolute}
|
||||
)
|
||||
|
||||
testme(subpro_b_shared_lib_header
|
||||
"${CMAKE_INSTALL_INCLUDEDIR}/shared_lib.h"
|
||||
${expect_symlink}
|
||||
${expect_absolute}
|
||||
)
|
||||
|
||||
if(CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG AND
|
||||
"${CMAKE_CXX_CREATE_SHARED_MODULE}" MATCHES "SONAME_FLAG")
|
||||
# due to semver, this is always a link
|
||||
testme(subpro_b_shared_lib_libfile
|
||||
"${CMAKE_INSTALL_LIBDIR}/${CMAKE_SHARED_LIBRARY_PREFIX}the_shared_lib${CMAKE_SHARED_LIBRARY_SUFFIX}"
|
||||
YES
|
||||
${expect_absolute}
|
||||
)
|
||||
# this is the actual shared lib, so should follow CMAKE_INSTALL_MODE rules
|
||||
testme(subpro_b_shared_lib_libfile_versuffix
|
||||
"${CMAKE_INSTALL_LIBDIR}/${CMAKE_SHARED_LIBRARY_PREFIX}the_shared_lib${CMAKE_SHARED_LIBRARY_SUFFIX}.2.3.4"
|
||||
${expect_symlink}
|
||||
${expect_absolute}
|
||||
)
|
||||
endif()
|
||||
|
||||
testme(subpro_d_executable_exefile
|
||||
"${CMAKE_INSTALL_BINDIR}/the_executable${CMAKE_EXECUTABLE_SUFFIX}"
|
||||
${expect_symlink}
|
||||
${expect_absolute}
|
||||
)
|
||||
|
||||
# nested subprojects should receive and respect CMAKE_INSTALL_MODE too
|
||||
|
||||
testme(subsubpro_c1_header
|
||||
"${CMAKE_INSTALL_INCLUDEDIR}/c1_lib.h"
|
||||
${expect_symlink}
|
||||
${expect_absolute}
|
||||
)
|
||||
testme(subsubpro_c1_libfile
|
||||
"${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}the_c1_lib${CMAKE_STATIC_LIBRARY_SUFFIX}"
|
||||
${expect_symlink}
|
||||
${expect_absolute}
|
||||
)
|
||||
|
||||
testme(subsubpro_c2_header
|
||||
"${CMAKE_INSTALL_INCLUDEDIR}/c2_lib.h"
|
||||
${expect_symlink}
|
||||
${expect_absolute}
|
||||
)
|
||||
testme(subsubpro_c2_libfile
|
||||
"${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}the_c2_lib${CMAKE_STATIC_LIBRARY_SUFFIX}"
|
||||
${expect_symlink}
|
||||
${expect_absolute}
|
||||
)
|
||||
endif()
|
||||
43
Tests/InstallMode/README.txt
Normal file
43
Tests/InstallMode/README.txt
Normal file
@ -0,0 +1,43 @@
|
||||
This is an example superbuild project to demonstrate the use of the
|
||||
CMAKE_INSTALL_MODE environment variable on.
|
||||
|
||||
The project hierarchy is like (B = Builds / D = Link Dependency):
|
||||
|
||||
+---------------------------------------------------------------------+
|
||||
| Superbuild (Top) |
|
||||
+---------------------------------------------------------------------+
|
||||
| | | |
|
||||
| | | |
|
||||
(B) (B) (B) (B)
|
||||
| | | |
|
||||
v v v v
|
||||
+---------------+ +---------------+ +---------------+ +---------------+
|
||||
| A: Static Lib | | B: Shared Lib | | C: Nested | | D: Executable |
|
||||
| Project | | Project | | Superbuild | | Project |
|
||||
+---------------+ +---------------+ +---------------+ +---------------+
|
||||
^ ^ | | | | |
|
||||
| | (B) (B) | | |
|
||||
| | | | | | |
|
||||
| | v | | | |
|
||||
| | +----------------+ | | | |
|
||||
| | | C1: Static Lib | | | | |
|
||||
| | | Project | | (D) (D) (D)
|
||||
| | +----------------+ | | | |
|
||||
| | ^ | | | |
|
||||
| | | v | | |
|
||||
| | (D) +----------------+ | | |
|
||||
| | | | C2: Static Lib |<---+ | |
|
||||
| | +--| Project | | |
|
||||
| | +----------------+ | |
|
||||
| | | |
|
||||
| +------------------------------------+ |
|
||||
| |
|
||||
+--------------------------------------------------------+
|
||||
|
||||
The superbuild system is built on top of ExternalProject_Add().
|
||||
|
||||
NOTE that the subprojects will configure, build and install
|
||||
during the build phase ('make') of the top-level project.
|
||||
There is no install target in the top-level project!
|
||||
The CMAKE_INSTALL_PREFIX is therefore populated during the build
|
||||
phase already.
|
||||
76
Tests/InstallMode/Subproject.cmake
Normal file
76
Tests/InstallMode/Subproject.cmake
Normal file
@ -0,0 +1,76 @@
|
||||
include(ExternalProject)
|
||||
|
||||
# add_subproject(<name> [NO_INSTALL] [DIR <dirname>] [DEPENDS [subpro_dep ...]])
|
||||
function(add_subproject _name)
|
||||
cmake_parse_arguments(_arg "NO_INSTALL" "DIR" "DEPENDS" ${ARGN})
|
||||
|
||||
if(_arg_UNPARSED_ARGUMENTS)
|
||||
message(FATAL_ERROR "There are unparsed arguments")
|
||||
endif()
|
||||
|
||||
set(_maybe_NO_INSTALL)
|
||||
if(_arg_NO_INSTALL)
|
||||
set(_maybe_NO_INSTALL "INSTALL_COMMAND")
|
||||
else()
|
||||
# This is a trick to get a valid call.
|
||||
# Since we set UPDATE_COMMAND to ""
|
||||
# explicitly below, this won't harm.
|
||||
set(_maybe_NO_INSTALL "UPDATE_COMMAND")
|
||||
endif()
|
||||
|
||||
if(CMAKE_GENERATOR MATCHES "Ninja Multi-Config")
|
||||
# Replace list separator before passing on to ExternalProject_Add
|
||||
string(REPLACE ";" "|" _CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}")
|
||||
string(REPLACE ";" "|" _CROSS_CONFIGS "${CMAKE_CROSS_CONFIGS}")
|
||||
string(REPLACE ";" "|" _DEFAULT_CONFIGS "${CMAKE_DEFAULT_CONFIGS}")
|
||||
|
||||
set(_maybe_NINJA_MULTICONFIG_ARGS
|
||||
"-DCMAKE_CONFIGURATION_TYPES:STRINGS=${_CONFIGURATION_TYPES}"
|
||||
"-DCMAKE_CROSS_CONFIGS:STRINGS=${_CROSS_CONFIGS}"
|
||||
"-DCMAKE_DEFAULT_BUILD_TYPE:STRING=${CMAKE_DEFAULT_BUILD_TYPE}"
|
||||
"-DCMAKE_DEFAULT_CONFIGS:STRINGS=${_DEFAULT_CONFIGS}"
|
||||
)
|
||||
endif()
|
||||
|
||||
ExternalProject_Add("${_name}"
|
||||
DOWNLOAD_COMMAND ""
|
||||
UPDATE_COMMAND ""
|
||||
${_maybe_NO_INSTALL} ""
|
||||
|
||||
BUILD_ALWAYS ON
|
||||
|
||||
LOG_DOWNLOAD OFF
|
||||
LOG_UPDATE OFF
|
||||
LOG_PATCH OFF
|
||||
LOG_CONFIGURE OFF
|
||||
LOG_BUILD OFF
|
||||
LOG_INSTALL OFF
|
||||
|
||||
SOURCE_DIR "${PROJECT_SOURCE_DIR}/${_arg_DIR}"
|
||||
|
||||
# Private build directory per subproject
|
||||
BINARY_DIR "${PROJECT_BINARY_DIR}/subproject/${_arg_DIR}"
|
||||
|
||||
# Common install directory, populated immediately
|
||||
# during build (during build - not install - of superproject)
|
||||
INSTALL_DIR "${CMAKE_INSTALL_PREFIX}"
|
||||
|
||||
DEPENDS
|
||||
${_arg_DEPENDS}
|
||||
|
||||
LIST_SEPARATOR "|"
|
||||
CMAKE_ARGS
|
||||
"-DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>"
|
||||
|
||||
# We can rely on ExternalProject to pick the right
|
||||
# generator (and architecture/toolset where applicable),
|
||||
# however, we need to explicitly inherit other parent
|
||||
# project's build settings.
|
||||
"-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}"
|
||||
${_maybe_NINJA_MULTICONFIG_ARGS}
|
||||
|
||||
# Subproject progress reports clutter up the output, disable
|
||||
"-DCMAKE_TARGET_MESSAGES:BOOL=OFF"
|
||||
"-DCMAKE_RULE_MESSAGES:BOOL=OFF"
|
||||
)
|
||||
endfunction()
|
||||
38
Tests/InstallMode/Test.cmake
Normal file
38
Tests/InstallMode/Test.cmake
Normal file
@ -0,0 +1,38 @@
|
||||
message("Testing...")
|
||||
message("FILE_PATH = ${FILE_PATH}")
|
||||
message("EXPECT_SYMLINK = ${EXPECT_SYMLINK}")
|
||||
message("EXPECT_ABSOLUTE = ${EXPECT_ABSOLUTE}")
|
||||
|
||||
if(NOT DEFINED FILE_PATH)
|
||||
message(FATAL_ERROR "FILE_PATH variable must be defined")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${FILE_PATH}")
|
||||
message(FATAL_ERROR "File ${FILE_PATH} does not exist")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED EXPECT_SYMLINK)
|
||||
message(FATAL_ERROR "EXPECT_SYMLINK must be defined")
|
||||
endif()
|
||||
|
||||
if(EXPECT_SYMLINK)
|
||||
if(NOT DEFINED EXPECT_ABSOLUTE)
|
||||
message(FATAL_ERROR "EXPECT_ABSOLUTE variable must be defined")
|
||||
endif()
|
||||
|
||||
if(NOT IS_SYMLINK "${FILE_PATH}")
|
||||
message(FATAL_ERROR "${FILE_PATH} must be a symlink")
|
||||
endif()
|
||||
|
||||
file(READ_SYMLINK "${FILE_PATH}" TARGET_PATH)
|
||||
|
||||
if(EXPECT_ABSOLUTE AND NOT IS_ABSOLUTE "${TARGET_PATH}")
|
||||
message(FATAL_ERROR "${FILE_PATH} must be an absolute symlink")
|
||||
elseif(NOT EXPECT_ABSOLUTE AND IS_ABSOLUTE "${TARGET_PATH}")
|
||||
message(FATAL_ERROR "${FILE_PATH} must be a relative symlink")
|
||||
endif()
|
||||
else()
|
||||
if(IS_SYMLINK "${FILE_PATH}")
|
||||
message(FATAL_ERROR "${FILE_PATH} must NOT be a symlink")
|
||||
endif()
|
||||
endif()
|
||||
60
Tests/InstallMode/subpro_a_static_lib/CMakeLists.txt
Normal file
60
Tests/InstallMode/subpro_a_static_lib/CMakeLists.txt
Normal file
@ -0,0 +1,60 @@
|
||||
# This CMakeLists.txt is part of the subproject A (ExternalProject_Add).
|
||||
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
project(static_lib_project VERSION 1.2.3 LANGUAGES CXX)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
add_library(the_static_lib STATIC
|
||||
"include/static_lib.h"
|
||||
"src/static_lib.cpp"
|
||||
)
|
||||
|
||||
target_include_directories(the_static_lib PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/"
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
the_static_lib
|
||||
EXPORT main
|
||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
)
|
||||
|
||||
set(INSTALL_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
configure_package_config_file(
|
||||
"cmake/PackageConfig.cmake.in"
|
||||
"${PROJECT_NAME}Config.cmake"
|
||||
INSTALL_DESTINATION "${INSTALL_CMAKE_DIR}"
|
||||
PATH_VARS
|
||||
CMAKE_INSTALL_INCLUDEDIR
|
||||
CMAKE_INSTALL_LIBDIR
|
||||
)
|
||||
|
||||
write_basic_package_version_file("${PROJECT_NAME}Version.cmake"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
COMPATIBILITY SameMajorVersion
|
||||
)
|
||||
|
||||
install(
|
||||
EXPORT main
|
||||
FILE "${PROJECT_NAME}Targets.cmake"
|
||||
DESTINATION "${INSTALL_CMAKE_DIR}"
|
||||
)
|
||||
|
||||
install(
|
||||
FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Version.cmake"
|
||||
DESTINATION "${INSTALL_CMAKE_DIR}"
|
||||
)
|
||||
@ -0,0 +1,8 @@
|
||||
set(@PROJECT_NAME@_VERSION @PROJECT_VERSION@)
|
||||
|
||||
@PACKAGE_INIT@
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
|
||||
|
||||
set_and_check(@PROJECT_NAME@_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@")
|
||||
set_and_check(@PROJECT_NAME@_LIB_DIR "@PACKAGE_CMAKE_INSTALL_LIBDIR@")
|
||||
@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void static_hello();
|
||||
10
Tests/InstallMode/subpro_a_static_lib/src/static_lib.cpp
Normal file
10
Tests/InstallMode/subpro_a_static_lib/src/static_lib.cpp
Normal file
@ -0,0 +1,10 @@
|
||||
#include <iostream>
|
||||
|
||||
#include <static_lib.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void static_hello()
|
||||
{
|
||||
cout << "Hello from static_lib" << endl;
|
||||
}
|
||||
66
Tests/InstallMode/subpro_b_shared_lib/CMakeLists.txt
Normal file
66
Tests/InstallMode/subpro_b_shared_lib/CMakeLists.txt
Normal file
@ -0,0 +1,66 @@
|
||||
# This CMakeLists.txt is part of the subproject B (ExternalProject_Add).
|
||||
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
project(shared_lib_project VERSION 2.3.4 LANGUAGES CXX)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
add_library(the_shared_lib SHARED
|
||||
"include/shared_lib.h"
|
||||
"src/shared_lib.cpp"
|
||||
)
|
||||
|
||||
set_target_properties(the_shared_lib
|
||||
PROPERTIES
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
SOVERSION "${PROJECT_VERSION}"
|
||||
)
|
||||
|
||||
target_include_directories(the_shared_lib PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/"
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
the_shared_lib
|
||||
EXPORT main
|
||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
)
|
||||
|
||||
set(INSTALL_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
configure_package_config_file(
|
||||
"cmake/PackageConfig.cmake.in"
|
||||
"${PROJECT_NAME}Config.cmake"
|
||||
INSTALL_DESTINATION "${INSTALL_CMAKE_DIR}"
|
||||
PATH_VARS
|
||||
CMAKE_INSTALL_INCLUDEDIR
|
||||
CMAKE_INSTALL_LIBDIR
|
||||
)
|
||||
|
||||
write_basic_package_version_file("${PROJECT_NAME}Version.cmake"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
COMPATIBILITY SameMajorVersion
|
||||
)
|
||||
|
||||
install(
|
||||
EXPORT main
|
||||
FILE "${PROJECT_NAME}Targets.cmake"
|
||||
DESTINATION "${INSTALL_CMAKE_DIR}"
|
||||
)
|
||||
|
||||
install(
|
||||
FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Version.cmake"
|
||||
DESTINATION "${INSTALL_CMAKE_DIR}"
|
||||
)
|
||||
@ -0,0 +1,8 @@
|
||||
set(@PROJECT_NAME@_VERSION @PROJECT_VERSION@)
|
||||
|
||||
@PACKAGE_INIT@
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
|
||||
|
||||
set_and_check(@PROJECT_NAME@_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@")
|
||||
set_and_check(@PROJECT_NAME@_LIB_DIR "@PACKAGE_CMAKE_INSTALL_LIBDIR@")
|
||||
@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void shared_hello();
|
||||
10
Tests/InstallMode/subpro_b_shared_lib/src/shared_lib.cpp
Normal file
10
Tests/InstallMode/subpro_b_shared_lib/src/shared_lib.cpp
Normal file
@ -0,0 +1,10 @@
|
||||
#include <iostream>
|
||||
|
||||
#include <shared_lib.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void shared_hello()
|
||||
{
|
||||
cout << "Hello from shared_lib" << endl;
|
||||
}
|
||||
10
Tests/InstallMode/subpro_c_nested_lib/CMakeLists.txt
Normal file
10
Tests/InstallMode/subpro_c_nested_lib/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
cmake_minimum_required(VERSION 3.20.0)
|
||||
|
||||
project(subpro_c_nested_lib LANGUAGES NONE)
|
||||
|
||||
include(../Subproject.cmake)
|
||||
add_subproject(c1_lib DIR subsubpro_c1_lib)
|
||||
add_subproject(c2_lib DIR subsubpro_c2_lib
|
||||
DEPENDS
|
||||
c1_lib
|
||||
)
|
||||
@ -0,0 +1,61 @@
|
||||
# This CMakeLists.txt is a nested subproject of the
|
||||
# subproject C (ExternalProject_Add).
|
||||
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
project(c1_lib_project VERSION 1.2.3 LANGUAGES CXX)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
add_library(the_c1_lib STATIC
|
||||
"include/c1_lib.h"
|
||||
"src/c1_lib.cpp"
|
||||
)
|
||||
|
||||
target_include_directories(the_c1_lib PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/"
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
the_c1_lib
|
||||
EXPORT main
|
||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
)
|
||||
|
||||
set(INSTALL_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
configure_package_config_file(
|
||||
"cmake/PackageConfig.cmake.in"
|
||||
"${PROJECT_NAME}Config.cmake"
|
||||
INSTALL_DESTINATION "${INSTALL_CMAKE_DIR}"
|
||||
PATH_VARS
|
||||
CMAKE_INSTALL_INCLUDEDIR
|
||||
CMAKE_INSTALL_LIBDIR
|
||||
)
|
||||
|
||||
write_basic_package_version_file("${PROJECT_NAME}Version.cmake"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
COMPATIBILITY SameMajorVersion
|
||||
)
|
||||
|
||||
install(
|
||||
EXPORT main
|
||||
FILE "${PROJECT_NAME}Targets.cmake"
|
||||
DESTINATION "${INSTALL_CMAKE_DIR}"
|
||||
)
|
||||
|
||||
install(
|
||||
FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Version.cmake"
|
||||
DESTINATION "${INSTALL_CMAKE_DIR}"
|
||||
)
|
||||
@ -0,0 +1,8 @@
|
||||
set(@PROJECT_NAME@_VERSION @PROJECT_VERSION@)
|
||||
|
||||
@PACKAGE_INIT@
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
|
||||
|
||||
set_and_check(@PROJECT_NAME@_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@")
|
||||
set_and_check(@PROJECT_NAME@_LIB_DIR "@PACKAGE_CMAKE_INSTALL_LIBDIR@")
|
||||
@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void c1_hello();
|
||||
@ -0,0 +1,10 @@
|
||||
#include <iostream>
|
||||
|
||||
#include <c1_lib.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void c1_hello()
|
||||
{
|
||||
cout << "Hello from c1_lib" << endl;
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
# This CMakeLists.txt is a nested subproject of the
|
||||
# subproject C (ExternalProject_Add).
|
||||
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
project(c2_lib_project VERSION 1.2.3 LANGUAGES CXX)
|
||||
|
||||
find_package(c1_lib_project REQUIRED)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
add_library(the_c2_lib STATIC
|
||||
"include/c2_lib.h"
|
||||
"src/c2_lib.cpp"
|
||||
)
|
||||
|
||||
target_link_libraries(the_c2_lib
|
||||
PUBLIC
|
||||
the_c1_lib
|
||||
)
|
||||
|
||||
target_include_directories(the_c2_lib PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
)
|
||||
|
||||
install(
|
||||
DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/"
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
the_c2_lib
|
||||
EXPORT main
|
||||
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
)
|
||||
|
||||
set(INSTALL_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
configure_package_config_file(
|
||||
"cmake/PackageConfig.cmake.in"
|
||||
"${PROJECT_NAME}Config.cmake"
|
||||
INSTALL_DESTINATION "${INSTALL_CMAKE_DIR}"
|
||||
PATH_VARS
|
||||
CMAKE_INSTALL_INCLUDEDIR
|
||||
CMAKE_INSTALL_LIBDIR
|
||||
)
|
||||
|
||||
write_basic_package_version_file("${PROJECT_NAME}Version.cmake"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
COMPATIBILITY SameMajorVersion
|
||||
)
|
||||
|
||||
install(
|
||||
EXPORT main
|
||||
FILE "${PROJECT_NAME}Targets.cmake"
|
||||
DESTINATION "${INSTALL_CMAKE_DIR}"
|
||||
)
|
||||
|
||||
install(
|
||||
FILES
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Version.cmake"
|
||||
DESTINATION "${INSTALL_CMAKE_DIR}"
|
||||
)
|
||||
@ -0,0 +1,11 @@
|
||||
set(@PROJECT_NAME@_VERSION @PROJECT_VERSION@)
|
||||
|
||||
@PACKAGE_INIT@
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
|
||||
|
||||
set_and_check(@PROJECT_NAME@_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@")
|
||||
set_and_check(@PROJECT_NAME@_LIB_DIR "@PACKAGE_CMAKE_INSTALL_LIBDIR@")
|
||||
|
||||
include(CMakeFindDependencyMacro)
|
||||
find_dependency(c1_lib_project REQUIRED)
|
||||
@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void c2_hello();
|
||||
@ -0,0 +1,12 @@
|
||||
#include <iostream>
|
||||
|
||||
#include <c1_lib.h>
|
||||
#include <c2_lib.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void c2_hello()
|
||||
{
|
||||
cout << "Hello from c2_lib and also..." << endl;
|
||||
c1_hello();
|
||||
}
|
||||
24
Tests/InstallMode/subpro_d_executable/CMakeLists.txt
Normal file
24
Tests/InstallMode/subpro_d_executable/CMakeLists.txt
Normal file
@ -0,0 +1,24 @@
|
||||
# This CMakeLists.txt is part of the subproject B (ExternalProject_Add).
|
||||
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
project(subpro_d_executable LANGUAGES CXX)
|
||||
|
||||
find_package(static_lib_project REQUIRED)
|
||||
find_package(shared_lib_project REQUIRED)
|
||||
find_package(c2_lib_project REQUIRED)
|
||||
|
||||
add_executable(the_executable
|
||||
"src/main.cpp"
|
||||
)
|
||||
|
||||
target_link_libraries(the_executable PRIVATE
|
||||
the_static_lib
|
||||
the_shared_lib
|
||||
the_c2_lib
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS
|
||||
the_executable
|
||||
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||
)
|
||||
13
Tests/InstallMode/subpro_d_executable/src/main.cpp
Normal file
13
Tests/InstallMode/subpro_d_executable/src/main.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
#include <cstdlib>
|
||||
|
||||
#include <c2_lib.h>
|
||||
#include <shared_lib.h>
|
||||
#include <static_lib.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
static_hello();
|
||||
shared_hello();
|
||||
c2_hello();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
29
Tests/InstallMode/superpro/CMakeLists.txt
Normal file
29
Tests/InstallMode/superpro/CMakeLists.txt
Normal file
@ -0,0 +1,29 @@
|
||||
# This CMakeLists.txt is part of the superproject (add_subdirectory).
|
||||
|
||||
# Below file transfers are executed at configuration time!
|
||||
|
||||
file(
|
||||
COPY
|
||||
"file_copy.txt"
|
||||
DESTINATION
|
||||
"${CMAKE_INSTALL_PREFIX}"
|
||||
)
|
||||
|
||||
file(COPY_FILE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/file_copy_file.txt"
|
||||
"${CMAKE_INSTALL_PREFIX}/file_copy_file.txt"
|
||||
)
|
||||
|
||||
file(
|
||||
INSTALL
|
||||
"file_install.txt"
|
||||
DESTINATION
|
||||
"${CMAKE_INSTALL_PREFIX}"
|
||||
)
|
||||
|
||||
file(
|
||||
CREATE_LINK
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/file_create_link_symbolic.txt"
|
||||
"${CMAKE_INSTALL_PREFIX}/file_create_link_symbolic.txt"
|
||||
SYMBOLIC
|
||||
)
|
||||
1
Tests/InstallMode/superpro/file_copy.txt
Normal file
1
Tests/InstallMode/superpro/file_copy.txt
Normal file
@ -0,0 +1 @@
|
||||
This file should always be copied into CMAKE_INSTALL_PREFIX.
|
||||
1
Tests/InstallMode/superpro/file_copy_file.txt
Normal file
1
Tests/InstallMode/superpro/file_copy_file.txt
Normal file
@ -0,0 +1 @@
|
||||
This file should always be copied into CMAKE_INSTALL_PREFIX.
|
||||
2
Tests/InstallMode/superpro/file_create_link_symbolic.txt
Normal file
2
Tests/InstallMode/superpro/file_create_link_symbolic.txt
Normal file
@ -0,0 +1,2 @@
|
||||
This file should always be installed into CMAKE_INSTALL_PREFIX
|
||||
as a symbolic link to the original file.
|
||||
6
Tests/InstallMode/superpro/file_install.txt
Normal file
6
Tests/InstallMode/superpro/file_install.txt
Normal file
@ -0,0 +1,6 @@
|
||||
This file should be placed in CMAKE_INSTALL_PREFIX
|
||||
as a copy if the CMAKE_INSTALL_MODE environment variable
|
||||
is unset or equals "COPY".
|
||||
If the variable's value is "SYMLINK" or "SYMLINK_OR_COPY",
|
||||
the CMAKE_INSTALL_PREFIX should rather receive a symbolic
|
||||
link to this file.
|
||||
Reference in New Issue
Block a user