mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-09-25 04:09:36 +03:00
install: Parse SCRIPT and CODE arguments with cmArgumentParser
This commit is contained in:
+59
-64
@@ -316,89 +316,84 @@ void CheckAbsoluteDestination(Helper& helper, std::string const& destination)
|
||||
bool HandleScriptMode(std::vector<std::string> const& args,
|
||||
cmExecutionStatus& status)
|
||||
{
|
||||
Helper helper(status);
|
||||
struct Arguments : ArgumentParser::ParseResult
|
||||
{
|
||||
struct Script
|
||||
{
|
||||
std::string Value;
|
||||
bool IsCode;
|
||||
};
|
||||
|
||||
std::string component = helper.DefaultComponentName;
|
||||
int componentCount = 0;
|
||||
bool doingScript = false;
|
||||
bool doingCode = false;
|
||||
bool excludeFromAll = false;
|
||||
bool allComponents = false;
|
||||
ArgumentParser::Continue AddScript(cm::string_view keyword,
|
||||
cm::string_view value)
|
||||
{
|
||||
this->Scripts.push_back({ std::string(value), keyword == "CODE"_s });
|
||||
return ArgumentParser::Continue::No;
|
||||
}
|
||||
|
||||
// Scan the args once for COMPONENT. Only allow one.
|
||||
//
|
||||
for (size_t i = 0; i < args.size(); ++i) {
|
||||
if (args[i] == "COMPONENT" && i + 1 < args.size()) {
|
||||
++componentCount;
|
||||
++i;
|
||||
component = args[i];
|
||||
}
|
||||
if (args[i] == "EXCLUDE_FROM_ALL") {
|
||||
excludeFromAll = true;
|
||||
} else if (args[i] == "ALL_COMPONENTS") {
|
||||
allComponents = true;
|
||||
ArgumentParser::Continue AddComponent(cm::string_view value)
|
||||
{
|
||||
this->Components.emplace_back(value);
|
||||
return ArgumentParser::Continue::No;
|
||||
}
|
||||
|
||||
std::vector<Script> Scripts;
|
||||
std::vector<std::string> Components;
|
||||
bool ExcludeFromAll = false;
|
||||
bool AllComponents = false;
|
||||
};
|
||||
|
||||
static auto const parser =
|
||||
cmArgumentParser<Arguments>{}
|
||||
.Bind("SCRIPT"_s, &Arguments::AddScript)
|
||||
.Bind("CODE"_s, &Arguments::AddScript)
|
||||
.Bind("COMPONENT"_s, &Arguments::AddComponent)
|
||||
.Bind("EXCLUDE_FROM_ALL"_s, &Arguments::ExcludeFromAll)
|
||||
.Bind("ALL_COMPONENTS"_s, &Arguments::AllComponents);
|
||||
|
||||
std::vector<std::string> unknownArgs;
|
||||
Arguments arguments = parser.Parse(args, &unknownArgs);
|
||||
if (!arguments.Check(args[0], &unknownArgs, status)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (componentCount > 1) {
|
||||
if (arguments.Components.size() > 1) {
|
||||
status.SetError("given more than one COMPONENT for the SCRIPT or CODE "
|
||||
"signature of the INSTALL command. "
|
||||
"Use multiple INSTALL commands with one COMPONENT each.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (allComponents && componentCount == 1) {
|
||||
if (arguments.AllComponents && !arguments.Components.empty()) {
|
||||
status.SetError("ALL_COMPONENTS and COMPONENT are mutually exclusive");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Scan the args again, this time adding install generators each time we
|
||||
// encounter a SCRIPT or CODE arg:
|
||||
//
|
||||
for (std::string const& arg : args) {
|
||||
if (arg == "SCRIPT") {
|
||||
doingScript = true;
|
||||
doingCode = false;
|
||||
} else if (arg == "CODE") {
|
||||
doingScript = false;
|
||||
doingCode = true;
|
||||
} else if (arg == "COMPONENT") {
|
||||
doingScript = false;
|
||||
doingCode = false;
|
||||
} else if (doingScript) {
|
||||
doingScript = false;
|
||||
std::string script = arg;
|
||||
if (!cmHasLiteralPrefix(script, "$<INSTALL_PREFIX>")) {
|
||||
if (!cmSystemTools::FileIsFullPath(script)) {
|
||||
script =
|
||||
cmStrCat(helper.Makefile->GetCurrentSourceDirectory(), '/', arg);
|
||||
}
|
||||
if (cmSystemTools::FileIsDirectory(script)) {
|
||||
status.SetError("given a directory as value of SCRIPT argument.");
|
||||
return false;
|
||||
}
|
||||
Helper helper(status);
|
||||
std::string const component = arguments.Components.empty()
|
||||
? helper.DefaultComponentName
|
||||
: arguments.Components.front();
|
||||
|
||||
for (Arguments::Script& script : arguments.Scripts) {
|
||||
if (!script.IsCode &&
|
||||
!cmHasLiteralPrefix(script.Value, "$<INSTALL_PREFIX>")) {
|
||||
if (!cmSystemTools::FileIsFullPath(script.Value)) {
|
||||
script.Value = cmStrCat(helper.Makefile->GetCurrentSourceDirectory(),
|
||||
'/', script.Value);
|
||||
}
|
||||
if (cmSystemTools::FileIsDirectory(script.Value)) {
|
||||
status.SetError("given a directory as value of SCRIPT argument.");
|
||||
return false;
|
||||
}
|
||||
helper.Makefile->AddInstallGenerator(
|
||||
cm::make_unique<cmInstallScriptGenerator>(
|
||||
script, false, component, excludeFromAll, allComponents,
|
||||
helper.Makefile->GetBacktrace()));
|
||||
} else if (doingCode) {
|
||||
doingCode = false;
|
||||
std::string const& code = arg;
|
||||
helper.Makefile->AddInstallGenerator(
|
||||
cm::make_unique<cmInstallScriptGenerator>(
|
||||
code, true, component, excludeFromAll, allComponents,
|
||||
helper.Makefile->GetBacktrace()));
|
||||
}
|
||||
}
|
||||
|
||||
if (doingScript) {
|
||||
status.SetError("given no value for SCRIPT argument.");
|
||||
return false;
|
||||
}
|
||||
if (doingCode) {
|
||||
status.SetError("given no value for CODE argument.");
|
||||
return false;
|
||||
for (Arguments::Script& script : arguments.Scripts) {
|
||||
helper.Makefile->AddInstallGenerator(
|
||||
cm::make_unique<cmInstallScriptGenerator>(
|
||||
std::move(script.Value), script.IsCode, component,
|
||||
arguments.ExcludeFromAll, arguments.AllComponents,
|
||||
helper.Makefile->GetBacktrace()));
|
||||
}
|
||||
|
||||
// Tell the global generator about any installation component names
|
||||
|
||||
@@ -76,6 +76,7 @@ if (CMake_TEST_install_VARIANT STREQUAL "Files")
|
||||
run_cmake(SkipInstallRulesWarning)
|
||||
run_cmake(SkipInstallRulesNoWarning1)
|
||||
run_cmake(SkipInstallRulesNoWarning2)
|
||||
run_cmake(SCRIPT-CODE-arguments)
|
||||
run_cmake(DIRECTORY-DIRECTORY-bad)
|
||||
run_cmake(DIRECTORY-DESTINATION-bad)
|
||||
run_cmake(FILES-DESTINATION-bad)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
1
|
||||
@@ -0,0 +1,50 @@
|
||||
CMake Error at SCRIPT-CODE-arguments\.cmake:[0-9]+ \(install\):
|
||||
install SCRIPT given invalid argument:
|
||||
|
||||
SCRIPT: missing required value
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
|
||||
|
||||
CMake Error at SCRIPT-CODE-arguments\.cmake:[0-9]+ \(install\):
|
||||
install CODE given invalid argument:
|
||||
|
||||
CODE: missing required value
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
|
||||
|
||||
CMake Error at SCRIPT-CODE-arguments\.cmake:[0-9]+ \(install\):
|
||||
install CODE given invalid argument:
|
||||
|
||||
CODE: missing required value
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
|
||||
|
||||
CMake Error at SCRIPT-CODE-arguments\.cmake:[0-9]+ \(install\):
|
||||
install CODE given invalid argument:
|
||||
|
||||
COMPONENT: missing required value
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
|
||||
|
||||
CMake Error at SCRIPT-CODE-arguments\.cmake:[0-9]+ \(install\):
|
||||
install CODE given unknown argument: "UNKNOWN"\.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
|
||||
|
||||
CMake Error at SCRIPT-CODE-arguments\.cmake:[0-9]+ \(install\):
|
||||
install given more than one COMPONENT for the SCRIPT or CODE signature of
|
||||
the INSTALL command\. Use multiple INSTALL commands with one COMPONENT
|
||||
each\.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
|
||||
|
||||
CMake Error at SCRIPT-CODE-arguments\.cmake:[0-9]+ \(install\):
|
||||
install ALL_COMPONENTS and COMPONENT are mutually exclusive
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists\.txt:[0-9]+ \(include\)
|
||||
@@ -0,0 +1,7 @@
|
||||
install(SCRIPT)
|
||||
install(CODE)
|
||||
install(CODE SCRIPT install_script.cmake)
|
||||
install(CODE "" COMPONENT)
|
||||
install(CODE "" UNKNOWN)
|
||||
install(CODE "" COMPONENT "" COMPONENT "")
|
||||
install(CODE "" COMPONENT "" ALL_COMPONENTS)
|
||||
@@ -4,6 +4,7 @@ install(
|
||||
)
|
||||
install(
|
||||
SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/install_script.cmake"
|
||||
CODE ""
|
||||
CODE "write_empty_file(empty2.txt)"
|
||||
SCRIPT "$<INSTALL_PREFIX>/empty3.cmake"
|
||||
CODE [[include($<INSTALL_PREFIX>/empty4.cmake)]]
|
||||
|
||||
Reference in New Issue
Block a user