mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-02 03:39:43 -06:00
include_guard: implement new command
This commit is contained in:
@@ -469,6 +469,8 @@ set(SRCS
|
||||
cmIncludeDirectoryCommand.h
|
||||
cmIncludeExternalMSProjectCommand.cxx
|
||||
cmIncludeExternalMSProjectCommand.h
|
||||
cmIncludeGuardCommand.cxx
|
||||
cmIncludeGuardCommand.h
|
||||
cmIncludeRegularExpressionCommand.cxx
|
||||
cmIncludeRegularExpressionCommand.h
|
||||
cmInstallCommand.cxx
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "cmIfCommand.h"
|
||||
#include "cmIncludeCommand.h"
|
||||
#include "cmIncludeDirectoryCommand.h"
|
||||
#include "cmIncludeGuardCommand.h"
|
||||
#include "cmIncludeRegularExpressionCommand.h"
|
||||
#include "cmInstallCommand.h"
|
||||
#include "cmInstallFilesCommand.h"
|
||||
@@ -132,6 +133,7 @@ void GetScriptingCommands(cmState* state)
|
||||
state->AddBuiltinCommand("get_property", new cmGetPropertyCommand);
|
||||
state->AddBuiltinCommand("if", new cmIfCommand);
|
||||
state->AddBuiltinCommand("include", new cmIncludeCommand);
|
||||
state->AddBuiltinCommand("include_guard", new cmIncludeGuardCommand);
|
||||
state->AddBuiltinCommand("list", new cmListCommand);
|
||||
state->AddBuiltinCommand("macro", new cmMacroCommand);
|
||||
state->AddBuiltinCommand("make_directory", new cmMakeDirectoryCommand);
|
||||
|
||||
108
Source/cmIncludeGuardCommand.cxx
Normal file
108
Source/cmIncludeGuardCommand.cxx
Normal file
@@ -0,0 +1,108 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#include "cmIncludeGuardCommand.h"
|
||||
|
||||
#include "cmExecutionStatus.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmStateDirectory.h"
|
||||
#include "cmStateSnapshot.h"
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmake.h"
|
||||
|
||||
namespace {
|
||||
|
||||
enum IncludeGuardScope
|
||||
{
|
||||
VARIABLE,
|
||||
DIRECTORY,
|
||||
GLOBAL
|
||||
};
|
||||
|
||||
std::string GetIncludeGuardVariableName(std::string const& filePath)
|
||||
{
|
||||
std::string result = "__INCGUARD_";
|
||||
#ifdef CMAKE_BUILD_WITH_CMAKE
|
||||
result += cmSystemTools::ComputeStringMD5(filePath);
|
||||
#else
|
||||
result += cmSystemTools::MakeCidentifier(filePath);
|
||||
#endif
|
||||
result += "__";
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CheckIncludeGuardIsSet(cmMakefile* mf, std::string const& includeGuardVar)
|
||||
{
|
||||
if (mf->GetProperty(includeGuardVar)) {
|
||||
return true;
|
||||
}
|
||||
cmStateSnapshot dirSnapshot =
|
||||
mf->GetStateSnapshot().GetBuildsystemDirectoryParent();
|
||||
while (dirSnapshot.GetState()) {
|
||||
cmStateDirectory stateDir = dirSnapshot.GetDirectory();
|
||||
if (stateDir.GetProperty(includeGuardVar)) {
|
||||
return true;
|
||||
}
|
||||
dirSnapshot = dirSnapshot.GetBuildsystemDirectoryParent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// cmIncludeGuardCommand
|
||||
bool cmIncludeGuardCommand::InitialPass(std::vector<std::string> const& args,
|
||||
cmExecutionStatus& status)
|
||||
{
|
||||
if (args.size() > 1) {
|
||||
this->SetError(
|
||||
"given an invalid number of arguments. The command takes at "
|
||||
"most 1 argument.");
|
||||
return false;
|
||||
}
|
||||
|
||||
IncludeGuardScope scope = VARIABLE;
|
||||
|
||||
if (!args.empty()) {
|
||||
std::string const& arg = args[0];
|
||||
if (arg == "DIRECTORY") {
|
||||
scope = DIRECTORY;
|
||||
} else if (arg == "GLOBAL") {
|
||||
scope = GLOBAL;
|
||||
} else {
|
||||
this->SetError("given an invalid scope: " + arg);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string includeGuardVar = GetIncludeGuardVariableName(
|
||||
this->Makefile->GetDefinition("CMAKE_CURRENT_LIST_FILE"));
|
||||
|
||||
cmMakefile* const mf = this->Makefile;
|
||||
|
||||
switch (scope) {
|
||||
case VARIABLE:
|
||||
if (mf->IsDefinitionSet(includeGuardVar)) {
|
||||
status.SetReturnInvoked();
|
||||
return true;
|
||||
}
|
||||
mf->AddDefinition(includeGuardVar, true);
|
||||
break;
|
||||
case DIRECTORY:
|
||||
if (CheckIncludeGuardIsSet(mf, includeGuardVar)) {
|
||||
status.SetReturnInvoked();
|
||||
return true;
|
||||
}
|
||||
mf->SetProperty(includeGuardVar, "TRUE");
|
||||
break;
|
||||
case GLOBAL:
|
||||
cmake* const cm = mf->GetCMakeInstance();
|
||||
if (cm->GetProperty(includeGuardVar)) {
|
||||
status.SetReturnInvoked();
|
||||
return true;
|
||||
}
|
||||
cm->SetProperty(includeGuardVar, "TRUE");
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
37
Source/cmIncludeGuardCommand.h
Normal file
37
Source/cmIncludeGuardCommand.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||
#ifndef cmIncludeGuardCommand_h
|
||||
#define cmIncludeGuardCommand_h
|
||||
|
||||
#include "cmConfigure.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "cmCommand.h"
|
||||
|
||||
class cmExecutionStatus;
|
||||
|
||||
/** \class cmIncludeGuardCommand
|
||||
* \brief cmIncludeGuardCommand identical to C++ #pragma_once command
|
||||
* Can work in 3 modes: GLOBAL (works on global properties),
|
||||
* DIRECTORY(use directory property), VARIABLE(unnamed overload without
|
||||
* arguments) define an ordinary variable to be used as include guard checker
|
||||
*/
|
||||
class cmIncludeGuardCommand : public cmCommand
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* This is a virtual constructor for the command.
|
||||
*/
|
||||
cmCommand* Clone() CM_OVERRIDE { return new cmIncludeGuardCommand; }
|
||||
|
||||
/**
|
||||
* This is called when the command is first encountered in
|
||||
* the CMakeLists.txt file.
|
||||
*/
|
||||
bool InitialPass(std::vector<std::string> const& args,
|
||||
cmExecutionStatus& status) CM_OVERRIDE;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user