Merge topic 'error_on_absolute_install_paths'

39a56136a3 Diagnostic: Add warn or error on absolute install paths
fd76089631 cmInstallFileSetGenerator: Only support per config Destination.

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !11882
This commit is contained in:
Brad King
2026-04-30 09:17:13 -04:00
committed by Kitware Robot
54 changed files with 281 additions and 43 deletions
+5
View File
@@ -60,6 +60,11 @@ signatures that specify them. The common options are:
``<dir>`` should be a relative path. An absolute path is allowed,
but not recommended.
.. versionadded:: 4.4
The :ref:`CMD_INSTALL_ABSOLUTE_DESTINATION <CMD_INSTALL_ABSOLUTE_DESTINATION>`
diagnostic can be enabled to warn or error out when an absolute destination
is provided.
When a relative path is given, it is interpreted relative to the value
of the :variable:`CMAKE_INSTALL_PREFIX` variable.
The prefix can be relocated at install time using the ``DESTDIR``
+12
View File
@@ -88,3 +88,15 @@ Warn about variables that are declared on the command line, but not used.
Although the action of this warning category can be queried as usual, changes
made using the :command:`cmake_diagnostic` command have no effect.
.. _CMD_INSTALL_ABSOLUTE_DESTINATION:
``CMD_INSTALL_ABSOLUTE_DESTINATION`` (``-Winstall-absolute-destination``)
-------------------------------------------------------------------------
:Default: Ignore
Warn when an :command:`install` command specifies an absolute
``DESTINATION`` path. Absolute destinations are typically undesirable
because they prevent the installation prefix from being overridden at
install time.
+3
View File
@@ -474,6 +474,9 @@ they were added and a summary of the new features and changes is given below.
* The ``uninitialized`` and ``unusedCli`` fields were added to
:preset:`configurePresets.errors`.
* The ``installAbsoluteDestination`` field was added to
:preset:`configurePresets.warnings` and :preset:`configurePresets.errors`.
* Changes to `Macro Expansion`_
* The `${fileDir} <CMakePresets fileDir_>`_ macro now always expands to
@@ -32,6 +32,15 @@
This may not be set to ``true``
if ``warnings.dev`` is set to ``false``.
.. _`CMakePresets.configurePresets.errors.installAbsoluteDestination`:
``installAbsoluteDestination``
.. presets-versionadded:: 12
An optional boolean. Equivalent to passing :cmake-option:`-Werror=install-absolute-destination` or
:cmake-option:`-Wno-error=install-absolute-destination` on the command line.
This may not be set to ``true`` if ``warnings.installAbsoluteDestination`` is set to ``false``.
.. _`CMakePresets.configurePresets.errors.uninitialized`:
``uninitialized``
+14
View File
@@ -1286,6 +1286,9 @@
"deprecated": {
"$ref": "#/definitions/configurePresets.warnings.deprecated@v1.."
},
"installAbsoluteDestination": {
"$ref": "#/definitions/configurePresets.warnings.installAbsoluteDestination@v12"
},
"uninitialized": {
"$ref": "#/definitions/configurePresets.warnings.uninitialized@v1.."
},
@@ -1312,6 +1315,10 @@
"type": "boolean",
"description": "An optional boolean. Equivalent to passing -Wdev or -Wno-dev on the command line. This may not be set to false if errors.dev is set to true."
},
"configurePresets.warnings.installAbsoluteDestination@v12": {
"type": "boolean",
"description": "An optional boolean. Equivalent to passing -Winstall-absolute-destination or -Wno-install-absolute-destination on the command line. This may not be set to false if errors.installAbsoluteDestination is set to true."
},
"configurePresets.warnings.uninitialized@v1..": {
"type": "boolean",
"description": "An optional boolean. Equivalent to passing -Wuninitialized or -Wno-uninitialized on the command line. This may not be set to false if errors.uninitialized is set to true."
@@ -1364,6 +1371,9 @@
"deprecated": {
"$ref": "#/definitions/configurePresets.errors.deprecated@v1.."
},
"installAbsoluteDestination": {
"$ref": "#/definitions/configurePresets.errors.installAbsoluteDestination@v12"
},
"uninitialized": {
"$ref": "#/definitions/configurePresets.errors.uninitialized@v12"
},
@@ -1387,6 +1397,10 @@
"type": "boolean",
"description": "An optional boolean. Equivalent to passing -Werror=dev or -Wno-error=dev on the command line. This may not be set to true if warnings.dev is set to false."
},
"configurePresets.errors.installAbsoluteDestination@v12": {
"type": "boolean",
"description": "An optional boolean. Equivalent to passing -Werror=install-absolute-destination or -Wno-error=install-absolute-destination on the command line. This may not be set to true if warnings.installAbsoluteDestination is set to false."
},
"configurePresets.errors.uninitialized@v12": {
"type": "boolean",
"description": "An optional boolean. Equivalent to passing -Werror=uninitialized or -Wno-error=uninitialized on the command line. This may not be set to true if warnings.uninitialized is set to false."
@@ -32,6 +32,15 @@
This may not be set to ``false``
if ``errors.dev`` is set to ``true``.
.. _`CMakePresets.configurePresets.warnings.installAbsoluteDestination`:
``installAbsoluteDestination``
.. presets-versionadded:: 12
An optional boolean. Equivalent to passing :option:`-Winstall-absolute-destination <cmake -W>` or
:option:`-Wno-install-absolute-destination <cmake -Wno->` on the command line.
This may not be set to ``false`` if ``errors.installAbsoluteDestination`` is set to ``true``.
.. _`CMakePresets.configurePresets.warnings.uninitialized`:
``uninitialized``
@@ -0,0 +1,10 @@
install-absolute-dest-configure-time
-------------------------------------
* CMake gained the ability to diagnose :command:`install` commands that
specify an absolute ``DESTINATION`` path via the
:ref:`CMD_INSTALL_ABSOLUTE_DESTINATION <CMD_INSTALL_ABSOLUTE_DESTINATION>`
diagnostic category. This diagnostic may be controlled with the
:option:`-Winstall-absolute-destination <cmake -W>` command-line option, the
``installAbsoluteDestination`` field in a :manual:`cmake-presets(7)`
``warnings`` object, or the :command:`cmake_diagnostic` command.
@@ -8,3 +8,11 @@ The fatal error is emitted before the installation of the offending
file takes place. This variable is used by CMake-generated
``cmake_install.cmake`` scripts. If one sets this variable to ``ON`` while
running the script, it may get fatal error messages from the script.
.. versionadded:: 4.4
The :ref:`CMD_INSTALL_ABSOLUTE_DESTINATION <CMD_INSTALL_ABSOLUTE_DESTINATION>`
diagnostic can be used to to generate errors for absolute install destinations
at generate time.
See also :variable:`CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION`.
@@ -7,3 +7,11 @@ Ask ``cmake_install.cmake`` script to warn each time a file with absolute
This variable is used by CMake-generated ``cmake_install.cmake`` scripts.
If one sets this variable to ``ON`` while running the script, it may get
warning messages from the script.
.. versionadded:: 4.4
The :ref:`CMD_INSTALL_ABSOLUTE_DESTINATION <CMD_INSTALL_ABSOLUTE_DESTINATION>`
diagnostic can be used to to generate warnings for absolute install destinations
at generate time.
See also :variable:`CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION`.
+1
View File
@@ -28,6 +28,7 @@
#define CM_FOR_EACH_DIAGNOSTIC_TABLE(ACTION, SELECT) \
SELECT(ACTION, Warn, CMD_NONE, CMD_AUTHOR, 12) \
SELECT(ACTION, Warn, CMD_AUTHOR, CMD_DEPRECATED, 1) \
SELECT(ACTION, Ignore, CMD_AUTHOR, CMD_INSTALL_ABSOLUTE_DESTINATION, 12) \
SELECT(ACTION, Ignore, CMD_NONE, CMD_UNINITIALIZED, 1) \
SELECT(ACTION, Warn, CMD_NONE, CMD_UNUSED_CLI, 1)
+9 -10
View File
@@ -284,22 +284,21 @@ std::string cmExportInstallCMakeConfigGenerator::GetFileSetDirectories(
auto configs =
gte->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
cmGeneratorExpression ge(*gte->Makefile->GetCMakeInstance());
auto cge =
ge.Parse(te->FileSetGenerators.at(fileSet->GetName())->GetDestination());
for (auto const& config : configs) {
auto unescapedDest = cge->Evaluate(gte->LocalGenerator, config, gte);
auto dest = cmOutputConverter::EscapeForCMake(
unescapedDest, cmOutputConverter::WrapQuotes::NoWrap);
if (!cmSystemTools::FileIsFullPath(unescapedDest)) {
cmInstallFileSetGenerator::DestinationContext result =
te->FileSetGenerators.at(fileSet->GetName())
->GetDestination(gte, config);
std::string dest = cmOutputConverter::EscapeForCMake(
result.UnescapedDestination, cmOutputConverter::WrapQuotes::NoWrap);
if (!cmSystemTools::FileIsFullPath(result.UnescapedDestination)) {
dest = cmStrCat("${_IMPORT_PREFIX}/", dest);
}
auto const& type = fileSet->GetType();
// C++ modules do not support interface file sets which are dependent upon
// the configuration.
if (cge->GetHadContextSensitiveCondition() &&
if (result.HadContextSensitiveCondition &&
type == cm::FileSetMetadata::CXX_MODULES) {
auto* mf = this->IEGen->GetLocalGenerator()->GetMakefile();
std::ostringstream e;
@@ -311,7 +310,7 @@ std::string cmExportInstallCMakeConfigGenerator::GetFileSetDirectories(
return std::string{};
}
if (cge->GetHadContextSensitiveCondition() && configs.size() != 1) {
if (result.HadContextSensitiveCondition && configs.size() != 1) {
resultVector.push_back(
cmStrCat("\"$<$<CONFIG:", config, ">:", dest, ">\""));
} else {
+7 -11
View File
@@ -224,18 +224,14 @@ cmExportInstallPackageInfoGenerator::GetFileSetDirectory(
cmGeneratorTarget* gte, cmTargetExport const* te,
cmGeneratorFileSet const* fileSet, cm::optional<std::string> const& config)
{
cmGeneratorExpression ge(*gte->Makefile->GetCMakeInstance());
auto cge =
ge.Parse(te->FileSetGenerators.at(fileSet->GetName())->GetDestination());
cmInstallFileSetGenerator::DestinationContext result =
te->FileSetGenerators.at(fileSet->GetName())
->GetDestination(gte, config.value_or(""));
std::string const unescapedDest =
cge->Evaluate(gte->LocalGenerator, config.value_or(""), gte);
bool const isConfigDependent = cge->GetHadContextSensitiveCondition();
if (config && !isConfigDependent) {
if (config && !result.HadContextSensitiveCondition) {
return {};
}
if (!config && isConfigDependent) {
if (!config && result.HadContextSensitiveCondition) {
this->RequiresConfigFiles = true;
return {};
}
@@ -255,9 +251,9 @@ cmExportInstallPackageInfoGenerator::GetFileSetDirectory(
}
cm::optional<std::string> dest = cmOutputConverter::EscapeForCMake(
unescapedDest, cmOutputConverter::WrapQuotes::NoWrap);
result.UnescapedDestination, cmOutputConverter::WrapQuotes::NoWrap);
if (!cmSystemTools::FileIsFullPath(unescapedDest)) {
if (!cmSystemTools::FileIsFullPath(result.UnescapedDestination)) {
dest = cmStrCat("@prefix@/"_s, *dest);
}
+6 -10
View File
@@ -216,15 +216,11 @@ cm::optional<std::string> cmExportInstallSbomGenerator::GetFileSetDirectory(
cmGeneratorTarget* gte, cmTargetExport const* te,
cmGeneratorFileSet const* fileSet, cm::optional<std::string> const& config)
{
cmGeneratorExpression ge(*gte->Makefile->GetCMakeInstance());
auto cge =
ge.Parse(te->FileSetGenerators.at(fileSet->GetName())->GetDestination());
cmInstallFileSetGenerator::DestinationContext result =
te->FileSetGenerators.at(fileSet->GetName())
->GetDestination(gte, config.value_or(""));
std::string const unescapedDest =
cge->Evaluate(gte->LocalGenerator, config.value_or(""), gte);
bool const isConfigDependent = cge->GetHadContextSensitiveCondition();
if (config && !isConfigDependent) {
if (config && !result.HadContextSensitiveCondition) {
return {};
}
@@ -241,9 +237,9 @@ cm::optional<std::string> cmExportInstallSbomGenerator::GetFileSetDirectory(
}
cm::optional<std::string> dest = cmOutputConverter::EscapeForCMake(
unescapedDest, cmOutputConverter::WrapQuotes::NoWrap);
result.UnescapedDestination, cmOutputConverter::WrapQuotes::NoWrap);
if (!cmSystemTools::FileIsFullPath(unescapedDest)) {
if (!cmSystemTools::FileIsFullPath(result.UnescapedDestination)) {
dest = cmStrCat("@prefix@/"_s, *dest);
}
+9
View File
@@ -1912,6 +1912,15 @@ bool HandleDirectoryMode(std::vector<std::string> const& args,
cmInstallGenerator::MessageLevel message =
cmInstallGenerator::SelectMessageLevel(helper.Makefile, message_never);
// Check for an absolute destination.
if (cmGeneratorExpression::Find(*destination) == std::string::npos &&
cmSystemTools::FileIsFullPath(*destination)) {
helper.Makefile->IssueDiagnostic(
cmDiagnostics::CMD_INSTALL_ABSOLUTE_DESTINATION,
cmStrCat("INSTALL command given absolute DESTINATION path (",
*destination, ").\n"));
}
// Create the directory install generator.
helper.Makefile->AddInstallGenerator(
cm::make_unique<cmInstallDirectoryGenerator>(
+1 -1
View File
@@ -22,7 +22,7 @@ public:
this->GenericArguments = args;
}
// Compute destination path.and check permissions
// Compute destination path and check permissions.
bool Finalize();
std::string const& GetDestination() const;
+5 -2
View File
@@ -118,6 +118,9 @@ void cmInstallDirectoryGenerator::AddDirectoryInstallRule(
std::string cmInstallDirectoryGenerator::GetDestination(
std::string const& config) const
{
return cmGeneratorExpression::Evaluate(this->Destination,
this->LocalGenerator, config);
std::string dest = cmGeneratorExpression::Evaluate(
this->Destination, this->LocalGenerator, config);
cmInstallGenerator::CheckAbsoluteDestination(dest, this->LocalGenerator,
this->Backtrace);
return dest;
}
+25 -2
View File
@@ -4,6 +4,7 @@
#include <algorithm>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
@@ -21,6 +22,7 @@
#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmStringAlgorithms.h"
#include "cmTarget.h"
@@ -91,11 +93,32 @@ bool cmInstallFileSetGenerator::Compute(cmLocalGenerator* lg)
return true;
}
std::string cmInstallFileSetGenerator::GetDestination() const
{
cmInstallGenerator::CheckAbsoluteDestination(
this->Destination, this->LocalGenerator, this->Backtrace);
return this->Destination;
}
std::string cmInstallFileSetGenerator::GetDestination(
std::string const& config) const
{
return cmGeneratorExpression::Evaluate(this->Destination,
this->LocalGenerator, config);
return this->GetDestination(this->Target, config).UnescapedDestination;
}
cmInstallFileSetGenerator::DestinationContext
cmInstallFileSetGenerator::GetDestination(cmGeneratorTarget* gte,
std::string const& config) const
{
cmGeneratorExpression ge(*gte->Makefile->GetCMakeInstance());
std::unique_ptr<cmCompiledGeneratorExpression> cge =
ge.Parse(this->Destination);
std::string const dest = cge->Evaluate(gte->LocalGenerator, config, gte);
cmInstallGenerator::CheckAbsoluteDestination(dest, gte->LocalGenerator,
this->Backtrace);
return { dest, cge->GetHadContextSensitiveCondition() };
}
void cmInstallFileSetGenerator::GenerateScriptForConfig(
+12 -2
View File
@@ -9,8 +9,9 @@
#include "cmInstallGenerator.h"
class cmGeneratorTarget;
class cmExportInstallCMakeConfigGenerator;
class cmGeneratorFileSet;
class cmGeneratorTarget;
class cmListFileBacktrace;
class cmLocalGenerator;
@@ -28,14 +29,23 @@ public:
bool Compute(cmLocalGenerator* lg) override;
struct DestinationContext
{
std::string UnescapedDestination;
bool HadContextSensitiveCondition;
};
std::string GetDestination(std::string const& config) const;
std::string GetDestination() const { return this->Destination; }
DestinationContext GetDestination(cmGeneratorTarget* gt,
std::string const& config) const;
bool GetOptional() const { return this->Optional; }
std::string GetFileSetName() const { return this->FileSetName; }
cmGeneratorFileSet const* GetFileSet() const { return this->FileSet; };
cmGeneratorTarget* GetTarget() const { return this->Target; }
protected:
friend cmExportInstallCMakeConfigGenerator;
std::string GetDestination() const;
void GenerateScriptForConfig(std::ostream& os, std::string const& config,
Indent indent) override;
+5 -2
View File
@@ -54,8 +54,11 @@ bool cmInstallFilesGenerator::Compute(cmLocalGenerator* lg)
std::string cmInstallFilesGenerator::GetDestination(
std::string const& config) const
{
return cmGeneratorExpression::Evaluate(this->Destination,
this->LocalGenerator, config);
std::string dest = cmGeneratorExpression::Evaluate(
this->Destination, this->LocalGenerator, config);
cmInstallGenerator::CheckAbsoluteDestination(dest, this->LocalGenerator,
this->Backtrace);
return dest;
}
std::string cmInstallFilesGenerator::GetRename(std::string const& config) const
+16
View File
@@ -7,6 +7,9 @@
#include <cm/string_view>
#include "cmDiagnostics.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -229,6 +232,19 @@ std::string cmInstallGenerator::ConvertToAbsoluteDestination(
return result;
}
void cmInstallGenerator::CheckAbsoluteDestination(
std::string const& dest, cmLocalGenerator* lg, cmListFileBacktrace const& bt)
{
if (!cmSystemTools::FileIsFullPath(dest)) {
return;
}
lg->IssueDiagnostic(
cmDiagnostics::CMD_INSTALL_ABSOLUTE_DESTINATION,
cmStrCat("INSTALL command given absolute DESTINATION path (", dest,
").\n"),
bt);
}
cmInstallGenerator::MessageLevel cmInstallGenerator::SelectMessageLevel(
cmMakefile* mf, bool never)
{
+3
View File
@@ -56,6 +56,9 @@ public:
/** Get the install destination as it should appear in the
installation script. */
static std::string ConvertToAbsoluteDestination(std::string const& dest);
static void CheckAbsoluteDestination(std::string const& dest,
cmLocalGenerator* lg,
cmListFileBacktrace const& bt);
/** Test if this generator installs something for a given configuration. */
bool InstallsForConfig(std::string const& config);
+5 -2
View File
@@ -479,8 +479,11 @@ void cmInstallTargetGenerator::GetInstallObjectNames(
std::string cmInstallTargetGenerator::GetDestination(
std::string const& config) const
{
return cmGeneratorExpression::Evaluate(
this->Destination, this->Target->GetLocalGenerator(), config);
cmLocalGenerator* lg = this->Target->GetLocalGenerator();
std::string dest =
cmGeneratorExpression::Evaluate(this->Destination, lg, config);
cmInstallGenerator::CheckAbsoluteDestination(dest, lg, this->Backtrace);
return dest;
}
std::string cmInstallTargetGenerator::GetInstallFilename(
@@ -0,0 +1,5 @@
CMake Warning \(unused-cli\):
Manually-specified variables were not used by the project:
RunCMake_GENERATOR
UNUSED_VARIABLE$
@@ -0,0 +1,6 @@
cmake_diagnostic(GET CMD_INSTALL_ABSOLUTE_DESTINATION action)
if(NOT "${action}" STREQUAL SEND_ERROR)
message(SEND_ERROR
"wrong action for diagnostic CMD_INSTALL_ABSOLUTE_DESTINATION"
" (expected 'SEND_ERROR', actual '${action}')")
endif()
@@ -363,7 +363,9 @@ run_cmake_presets(ErrorDeprecated)
set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/Warnings12.json.in")
run_cmake_presets(NoWarningFlags)
run_cmake_presets(WarningFlags)
run_cmake_presets(WarningAbsInstallPath)
run_cmake_presets(DisableWarningFlags)
run_cmake_presets(ErrorAbsInstallPath)
run_cmake_presets(ErrorDev)
run_cmake_presets(ErrorUninitialized)
run_cmake_presets(ErrorUnusedCli)
@@ -0,0 +1,5 @@
CMake Warning \(unused-cli\):
Manually-specified variables were not used by the project:
RunCMake_GENERATOR
UNUSED_VARIABLE$
@@ -0,0 +1,6 @@
cmake_diagnostic(GET CMD_INSTALL_ABSOLUTE_DESTINATION action)
if(NOT "${action}" STREQUAL WARN)
message(SEND_ERROR
"wrong action for diagnostic CMD_INSTALL_ABSOLUTE_DESTINATION"
" (expected 'WARN', actual '${action}')")
endif()
@@ -29,6 +29,20 @@
"unusedCli": false
}
},
{
"name": "WarningAbsInstallPath",
"inherits": "NoWarningFlags",
"warnings": {
"installAbsoluteDestination": true
}
},
{
"name": "ErrorAbsInstallPath",
"inherits": "NoWarningFlags",
"errors": {
"installAbsoluteDestination": true
}
},
{
"name": "ErrorDev",
"inherits": "NoWarningFlags",
@@ -1,4 +1,5 @@
include(Assertions.cmake)
expect(CMD_AUTHOR IGNORE)
expect(CMD_INSTALL_ABSOLUTE_DESTINATION IGNORE)
expect(CMD_DEPRECATED SEND_ERROR)
@@ -1,3 +1,5 @@
include(Assertions.cmake)
expect_cached(CMD_UNINITIALIZED IGNORE)
expect_cached(CMD_INSTALL_ABSOLUTE_DESTINATION WARN)
@@ -12,4 +12,4 @@ run_cmake_with_options(CommandLine1 -Werror=author)
run_cmake_with_options(CommandLine1 -Werror=author -Wdeprecated)
run_cmake_with_options(CommandLine1 -Wno-deprecated -Werror=author)
run_cmake_with_options(CommandLine2 -Werror=author -Wno-deprecated)
run_cmake_with_options(CommandLine3 -Wno-error=uninitialized)
run_cmake_with_options(CommandLine3 -Wno-error=uninitialized -Winstall-absolute-destination)
@@ -0,0 +1 @@
1
@@ -0,0 +1,2 @@
CMake Error \(install-absolute-destination\) at DIRECTORY-AbsoluteDest-error\.cmake:[0-9]+ \(install\):
INSTALL command given absolute DESTINATION path \(/absolute/path\)\.
@@ -0,0 +1 @@
install(DIRECTORY DESTINATION /absolute/path)
@@ -0,0 +1 @@
1
@@ -0,0 +1,2 @@
CMake Error \(install-absolute-destination\) at FILES-AbsoluteDest-error\.cmake:[0-9]+ \(install\):
INSTALL command given absolute DESTINATION path \(/absolute/path\)\.
@@ -0,0 +1 @@
install(FILES empty.c DESTINATION /absolute/path)
@@ -0,0 +1,2 @@
CMake Warning \(install-absolute-destination\) at FILES-AbsoluteDest-warn\.cmake:[0-9]+ \(install\):
INSTALL command given absolute DESTINATION path \(/absolute/path\)\.
@@ -0,0 +1 @@
install(FILES empty.c DESTINATION /absolute/path)
@@ -82,6 +82,14 @@ run_cmake(DIRECTORY-DESTINATION-bad)
run_cmake(FILES-DESTINATION-bad)
run_cmake(FILES-RENAME-bad)
run_cmake(TARGETS-DESTINATION-bad)
run_cmake_with_options(DIRECTORY-AbsoluteDest-error -Werror=install-absolute-destination)
run_cmake_with_options(FILES-AbsoluteDest-error -Werror=install-absolute-destination)
run_cmake_with_options(FILES-AbsoluteDest-warn -Winstall-absolute-destination)
run_cmake_with_options(TARGETS-AbsoluteDest-error -Werror=install-absolute-destination)
run_cmake_with_options(TARGETS-AbsoluteDest-warn -Winstall-absolute-destination)
run_cmake_with_options(TARGETS-AbsoluteDest-archive-error -Werror=install-absolute-destination)
run_cmake_with_options(TARGETS-AbsoluteDest-library-error -Werror=install-absolute-destination)
run_cmake_with_options(TARGETS-AbsoluteDest-runtime-error -Werror=install-absolute-destination)
run_cmake(EXPORT-Component)
run_cmake(EXPORT-FindDependencyExportGate)
run_cmake(EXPORT-OldIFace)
@@ -0,0 +1,2 @@
CMake Error \(install-absolute-destination\) at TARGETS-AbsoluteDest-archive-error\.cmake:[0-9]+ \(install\):
INSTALL command given absolute DESTINATION path \(/absolute/archive\)\.
@@ -0,0 +1,3 @@
enable_language(C)
add_library(mylib STATIC empty.c)
install(TARGETS mylib ARCHIVE DESTINATION /absolute/archive)
@@ -0,0 +1 @@
1
@@ -0,0 +1,2 @@
CMake Error \(install-absolute-destination\) at TARGETS-AbsoluteDest-error\.cmake:[0-9]+ \(install\):
INSTALL command given absolute DESTINATION path \(/absolute/path\)\.
@@ -0,0 +1,12 @@
enable_language(C)
add_library(mylib STATIC empty.c)
# FIXME(#27770): This diagnostic is issued at generate time. Currently, the
# install generator doesn't capture the immediate diagnostic state, only the
# top-most state of the current subdirectory, which we cannot affect (because
# this test was include()d. When we fix that, we should test by changing the
# diagnostic action here rather than by -W... in the test CLI arguments.
# cmake_diagnostic(SET CMD_INSTALL_ABSOLUTE_DESTINATION SEND_ERROR)
cmake_diagnostic(PROMOTE CMD_INSTALL_ABSOLUTE_DESTINATION WARN)
install(TARGETS mylib DESTINATION /absolute/path)
@@ -0,0 +1,2 @@
CMake Error \(install-absolute-destination\) at TARGETS-AbsoluteDest-library-error\.cmake:[0-9]+ \(install\):
INSTALL command given absolute DESTINATION path \(/absolute/lib\)\.
@@ -0,0 +1,3 @@
enable_language(C)
add_library(mylib MODULE empty.c)
install(TARGETS mylib LIBRARY DESTINATION /absolute/lib)
@@ -0,0 +1,2 @@
CMake Error \(install-absolute-destination\) at TARGETS-AbsoluteDest-runtime-error\.cmake:[0-9]+ \(install\):
INSTALL command given absolute DESTINATION path \(/absolute/bin\)\.
@@ -0,0 +1,3 @@
enable_language(C)
add_executable(myexe empty.c)
install(TARGETS myexe RUNTIME DESTINATION /absolute/bin)
@@ -0,0 +1,2 @@
CMake Warning \(install-absolute-destination\) at TARGETS-AbsoluteDest-warn\.cmake:[0-9]+ \(install\):
INSTALL command given absolute DESTINATION path \(/absolute/path\)\.
@@ -0,0 +1,3 @@
enable_language(C)
add_library(mylib STATIC empty.c)
install(TARGETS mylib DESTINATION /absolute/path)