cmExportCommand: Port away from cmCommand
This commit is contained in:
parent
ebb9346490
commit
fdc3ba4583
@ -275,7 +275,7 @@ void GetProjectCommands(cmState* state)
|
||||
state->AddBuiltinCommand("add_compile_options", cmAddCompileOptionsCommand);
|
||||
state->AddBuiltinCommand("aux_source_directory",
|
||||
cmAuxSourceDirectoryCommand);
|
||||
state->AddBuiltinCommand("export", cm::make_unique<cmExportCommand>());
|
||||
state->AddBuiltinCommand("export", cmExportCommand);
|
||||
state->AddBuiltinCommand("fltk_wrap_ui", cmFLTKWrapUICommand);
|
||||
state->AddBuiltinCommand("include_external_msproject",
|
||||
cmIncludeExternalMSProjectCommand);
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "cmAlgorithms.h"
|
||||
#include "cmArgumentParser.h"
|
||||
#include "cmExecutionStatus.h"
|
||||
#include "cmExportBuildAndroidMKGenerator.h"
|
||||
#include "cmExportBuildFileGenerator.h"
|
||||
#include "cmExportSet.h"
|
||||
@ -23,23 +24,31 @@
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmTarget.h"
|
||||
|
||||
class cmExecutionStatus;
|
||||
|
||||
#if defined(__HAIKU__)
|
||||
# include <FindDirectory.h>
|
||||
# include <StorageDefs.h>
|
||||
#endif
|
||||
|
||||
bool cmExportCommand::InitialPass(std::vector<std::string> const& args,
|
||||
cmExecutionStatus&)
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
static bool HandlePackage(std::vector<std::string> const& args,
|
||||
cmExecutionStatus& status);
|
||||
|
||||
static void StorePackageRegistry(cmMakefile& mf, std::string const& package,
|
||||
const char* content, const char* hash);
|
||||
|
||||
bool cmExportCommand(std::vector<std::string> const& args,
|
||||
cmExecutionStatus& status)
|
||||
{
|
||||
if (args.size() < 2) {
|
||||
this->SetError("called with too few arguments");
|
||||
status.SetError("called with too few arguments");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (args[0] == "PACKAGE") {
|
||||
return this->HandlePackage(args);
|
||||
return HandlePackage(args, status);
|
||||
}
|
||||
|
||||
struct Arguments
|
||||
@ -72,7 +81,7 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args,
|
||||
parser.Parse(args, &unknownArgs, &keywordsMissingValue);
|
||||
|
||||
if (!unknownArgs.empty()) {
|
||||
this->SetError("Unknown argument: \"" + unknownArgs.front() + "\".");
|
||||
status.SetError("Unknown argument: \"" + unknownArgs.front() + "\".");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -84,7 +93,7 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args,
|
||||
}
|
||||
if (arguments.Filename.empty() && fname.empty()) {
|
||||
if (args[0] != "EXPORT") {
|
||||
this->SetError("FILE <filename> option missing.");
|
||||
status.SetError("FILE <filename> option missing.");
|
||||
return false;
|
||||
}
|
||||
fname = arguments.ExportSetName + ".cmake";
|
||||
@ -95,30 +104,32 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args,
|
||||
std::ostringstream e;
|
||||
e << "FILE option given filename \"" << arguments.Filename
|
||||
<< "\" which does not have an extension of \".cmake\".\n";
|
||||
this->SetError(e.str());
|
||||
status.SetError(e.str());
|
||||
return false;
|
||||
}
|
||||
fname = arguments.Filename;
|
||||
}
|
||||
|
||||
cmMakefile& mf = status.GetMakefile();
|
||||
|
||||
// Get the file to write.
|
||||
if (cmSystemTools::FileIsFullPath(fname)) {
|
||||
if (!this->Makefile->CanIWriteThisFile(fname)) {
|
||||
if (!mf.CanIWriteThisFile(fname)) {
|
||||
std::ostringstream e;
|
||||
e << "FILE option given filename \"" << fname
|
||||
<< "\" which is in the source tree.\n";
|
||||
this->SetError(e.str());
|
||||
status.SetError(e.str());
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Interpret relative paths with respect to the current build dir.
|
||||
std::string dir = this->Makefile->GetCurrentBinaryDirectory();
|
||||
std::string const& dir = mf.GetCurrentBinaryDirectory();
|
||||
fname = dir + "/" + fname;
|
||||
}
|
||||
|
||||
std::vector<std::string> targets;
|
||||
|
||||
cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
|
||||
cmGlobalGenerator* gg = mf.GetGlobalGenerator();
|
||||
|
||||
cmExportSet* exportSet = nullptr;
|
||||
if (args[0] == "EXPORT") {
|
||||
@ -127,32 +138,32 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args,
|
||||
if (it == setMap.end()) {
|
||||
std::ostringstream e;
|
||||
e << "Export set \"" << arguments.ExportSetName << "\" not found.";
|
||||
this->SetError(e.str());
|
||||
status.SetError(e.str());
|
||||
return false;
|
||||
}
|
||||
exportSet = &it->second;
|
||||
} else if (!arguments.Targets.empty() ||
|
||||
cmContains(keywordsMissingValue, "TARGETS")) {
|
||||
for (std::string const& currentTarget : arguments.Targets) {
|
||||
if (this->Makefile->IsAlias(currentTarget)) {
|
||||
if (mf.IsAlias(currentTarget)) {
|
||||
std::ostringstream e;
|
||||
e << "given ALIAS target \"" << currentTarget
|
||||
<< "\" which may not be exported.";
|
||||
this->SetError(e.str());
|
||||
status.SetError(e.str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cmTarget* target = gg->FindTarget(currentTarget)) {
|
||||
if (target->GetType() == cmStateEnums::UTILITY) {
|
||||
this->SetError("given custom target \"" + currentTarget +
|
||||
"\" which may not be exported.");
|
||||
status.SetError("given custom target \"" + currentTarget +
|
||||
"\" which may not be exported.");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
std::ostringstream e;
|
||||
e << "given target \"" << currentTarget
|
||||
<< "\" which is not built by this project.";
|
||||
this->SetError(e.str());
|
||||
status.SetError(e.str());
|
||||
return false;
|
||||
}
|
||||
targets.push_back(currentTarget);
|
||||
@ -165,7 +176,7 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this->SetError("EXPORT or TARGETS specifier missing.");
|
||||
status.SetError("EXPORT or TARGETS specifier missing.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -184,12 +195,12 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args,
|
||||
} else {
|
||||
ebfg->SetTargets(targets);
|
||||
}
|
||||
this->Makefile->AddExportBuildFileGenerator(ebfg);
|
||||
mf.AddExportBuildFileGenerator(ebfg);
|
||||
ebfg->SetExportOld(arguments.ExportOld);
|
||||
|
||||
// Compute the set of configurations exported.
|
||||
std::vector<std::string> configurationTypes;
|
||||
this->Makefile->GetConfigurations(configurationTypes);
|
||||
mf.GetConfigurations(configurationTypes);
|
||||
if (configurationTypes.empty()) {
|
||||
configurationTypes.emplace_back();
|
||||
}
|
||||
@ -205,7 +216,8 @@ bool cmExportCommand::InitialPass(std::vector<std::string> const& args,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cmExportCommand::HandlePackage(std::vector<std::string> const& args)
|
||||
static bool HandlePackage(std::vector<std::string> const& args,
|
||||
cmExecutionStatus& status)
|
||||
{
|
||||
// Parse PACKAGE mode arguments.
|
||||
enum Doing
|
||||
@ -222,14 +234,14 @@ bool cmExportCommand::HandlePackage(std::vector<std::string> const& args)
|
||||
} else {
|
||||
std::ostringstream e;
|
||||
e << "PACKAGE given unknown argument: " << args[i];
|
||||
this->SetError(e.str());
|
||||
status.SetError(e.str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Verify the package name.
|
||||
if (package.empty()) {
|
||||
this->SetError("PACKAGE must be given a package name.");
|
||||
status.SetError("PACKAGE must be given a package name.");
|
||||
return false;
|
||||
}
|
||||
const char* packageExpr = "^[A-Za-z0-9_.-]+$";
|
||||
@ -238,16 +250,18 @@ bool cmExportCommand::HandlePackage(std::vector<std::string> const& args)
|
||||
std::ostringstream e;
|
||||
e << "PACKAGE given invalid package name \"" << package << "\". "
|
||||
<< "Package names must match \"" << packageExpr << "\".";
|
||||
this->SetError(e.str());
|
||||
status.SetError(e.str());
|
||||
return false;
|
||||
}
|
||||
|
||||
cmMakefile& mf = status.GetMakefile();
|
||||
|
||||
// CMP0090 decides both the default and what variable changes it.
|
||||
switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0090)) {
|
||||
switch (mf.GetPolicyStatus(cmPolicies::CMP0090)) {
|
||||
case cmPolicies::WARN:
|
||||
case cmPolicies::OLD:
|
||||
// Default is to export, but can be disabled.
|
||||
if (this->Makefile->IsOn("CMAKE_EXPORT_NO_PACKAGE_REGISTRY")) {
|
||||
if (mf.IsOn("CMAKE_EXPORT_NO_PACKAGE_REGISTRY")) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
@ -255,7 +269,7 @@ bool cmExportCommand::HandlePackage(std::vector<std::string> const& args)
|
||||
case cmPolicies::REQUIRED_ALWAYS:
|
||||
case cmPolicies::NEW:
|
||||
// Default is to not export, but can be enabled.
|
||||
if (!this->Makefile->IsOn("CMAKE_EXPORT_PACKAGE_REGISTRY")) {
|
||||
if (!mf.IsOn("CMAKE_EXPORT_PACKAGE_REGISTRY")) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
@ -264,22 +278,17 @@ bool cmExportCommand::HandlePackage(std::vector<std::string> const& args)
|
||||
// We store the current build directory in the registry as a value
|
||||
// named by a hash of its own content. This is deterministic and is
|
||||
// unique with high probability.
|
||||
const std::string& outDir = this->Makefile->GetCurrentBinaryDirectory();
|
||||
const std::string& outDir = mf.GetCurrentBinaryDirectory();
|
||||
std::string hash = cmSystemTools::ComputeStringMD5(outDir);
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
this->StorePackageRegistryWin(package, outDir.c_str(), hash.c_str());
|
||||
#else
|
||||
this->StorePackageRegistryDir(package, outDir.c_str(), hash.c_str());
|
||||
#endif
|
||||
StorePackageRegistry(mf, package, outDir.c_str(), hash.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
# include <windows.h>
|
||||
|
||||
void cmExportCommand::ReportRegistryError(std::string const& msg,
|
||||
std::string const& key, long err)
|
||||
static void ReportRegistryError(cmMakefile& mf, std::string const& msg,
|
||||
std::string const& key, long err)
|
||||
{
|
||||
std::ostringstream e;
|
||||
e << msg << "\n"
|
||||
@ -291,12 +300,11 @@ void cmExportCommand::ReportRegistryError(std::string const& msg,
|
||||
e << "Windows reported:\n"
|
||||
<< " " << cmsys::Encoding::ToNarrow(winmsg);
|
||||
}
|
||||
this->Makefile->IssueMessage(MessageType::WARNING, e.str());
|
||||
mf.IssueMessage(MessageType::WARNING, e.str());
|
||||
}
|
||||
|
||||
void cmExportCommand::StorePackageRegistryWin(std::string const& package,
|
||||
const char* content,
|
||||
const char* hash)
|
||||
static void StorePackageRegistry(cmMakefile& mf, std::string const& package,
|
||||
const char* content, const char* hash)
|
||||
{
|
||||
std::string key = cmStrCat("Software\\Kitware\\CMake\\Packages\\", package);
|
||||
HKEY hKey;
|
||||
@ -304,7 +312,7 @@ void cmExportCommand::StorePackageRegistryWin(std::string const& package,
|
||||
RegCreateKeyExW(HKEY_CURRENT_USER, cmsys::Encoding::ToWide(key).c_str(), 0,
|
||||
0, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, 0, &hKey, 0);
|
||||
if (err != ERROR_SUCCESS) {
|
||||
this->ReportRegistryError("Cannot create/open registry key", key, err);
|
||||
ReportRegistryError(mf, "Cannot create/open registry key", key, err);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -317,14 +325,13 @@ void cmExportCommand::StorePackageRegistryWin(std::string const& package,
|
||||
if (err != ERROR_SUCCESS) {
|
||||
std::ostringstream msg;
|
||||
msg << "Cannot set registry value \"" << hash << "\" under key";
|
||||
this->ReportRegistryError(msg.str(), key, err);
|
||||
ReportRegistryError(mf, msg.str(), key, err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
void cmExportCommand::StorePackageRegistryDir(std::string const& package,
|
||||
const char* content,
|
||||
const char* hash)
|
||||
static void StorePackageRegistry(cmMakefile& mf, std::string const& package,
|
||||
const char* content, const char* hash)
|
||||
{
|
||||
# if defined(__HAIKU__)
|
||||
char dir[B_PATH_NAME_LENGTH];
|
||||
@ -356,7 +363,7 @@ void cmExportCommand::StorePackageRegistryDir(std::string const& package,
|
||||
<< " " << fname << "\n"
|
||||
<< cmSystemTools::GetLastSystemError() << "\n";
|
||||
/* clang-format on */
|
||||
this->Makefile->IssueMessage(MessageType::WARNING, e.str());
|
||||
mf.IssueMessage(MessageType::WARNING, e.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,38 +8,9 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <cm/memory>
|
||||
|
||||
#include "cmCommand.h"
|
||||
|
||||
class cmExecutionStatus;
|
||||
|
||||
class cmExportCommand : public cmCommand
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This is a virtual constructor for the command.
|
||||
*/
|
||||
std::unique_ptr<cmCommand> Clone() override
|
||||
{
|
||||
return cm::make_unique<cmExportCommand>();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called when the command is first encountered in
|
||||
* the CMakeLists.txt file.
|
||||
*/
|
||||
bool InitialPass(std::vector<std::string> const& args,
|
||||
cmExecutionStatus& status) override;
|
||||
|
||||
private:
|
||||
bool HandlePackage(std::vector<std::string> const& args);
|
||||
void StorePackageRegistryWin(std::string const& package, const char* content,
|
||||
const char* hash);
|
||||
void StorePackageRegistryDir(std::string const& package, const char* content,
|
||||
const char* hash);
|
||||
void ReportRegistryError(std::string const& msg, std::string const& key,
|
||||
long err);
|
||||
};
|
||||
bool cmExportCommand(std::vector<std::string> const& args,
|
||||
cmExecutionStatus& status);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user