ENH: add framework for unified handling of arguments to cmake commands,
example see cmExportCommand.cxx Alex
This commit is contained in:
parent
7f29f8966d
commit
2e56fa4808
|
@ -29,6 +29,7 @@
|
||||||
#include "cmAddTestCommand.cxx"
|
#include "cmAddTestCommand.cxx"
|
||||||
#include "cmBuildCommand.cxx"
|
#include "cmBuildCommand.cxx"
|
||||||
#include "cmCMakeMinimumRequired.cxx"
|
#include "cmCMakeMinimumRequired.cxx"
|
||||||
|
#include "cmCommandArgumentsHelper.cxx"
|
||||||
#include "cmConfigureFileCommand.cxx"
|
#include "cmConfigureFileCommand.cxx"
|
||||||
#include "cmCoreTryCompile.cxx"
|
#include "cmCoreTryCompile.cxx"
|
||||||
#include "cmCreateTestSourceList.cxx"
|
#include "cmCreateTestSourceList.cxx"
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "cmObject.h"
|
#include "cmObject.h"
|
||||||
#include "cmListFileCache.h"
|
#include "cmListFileCache.h"
|
||||||
#include "cmMakefile.h"
|
#include "cmMakefile.h"
|
||||||
|
#include "cmCommandArgumentsHelper.h"
|
||||||
|
|
||||||
/** \class cmCommand
|
/** \class cmCommand
|
||||||
* \brief Superclass for all commands in CMake.
|
* \brief Superclass for all commands in CMake.
|
||||||
|
@ -174,6 +175,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
cmMakefile* Makefile;
|
cmMakefile* Makefile;
|
||||||
|
cmCommandArgumentsHelper Helper;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool Enabled;
|
bool Enabled;
|
||||||
|
|
|
@ -0,0 +1,308 @@
|
||||||
|
/*=========================================================================
|
||||||
|
|
||||||
|
Program: CMake - Cross-Platform Makefile Generator
|
||||||
|
Module: $RCSfile$
|
||||||
|
Language: C++
|
||||||
|
Date: $Date$
|
||||||
|
Version: $Revision$
|
||||||
|
|
||||||
|
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
|
||||||
|
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
|
||||||
|
|
||||||
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||||||
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. See the above copyright notices for more information.
|
||||||
|
|
||||||
|
=========================================================================*/
|
||||||
|
|
||||||
|
#include "cmCommandArgumentsHelper.h"
|
||||||
|
|
||||||
|
cmCommandArgument::cmCommandArgument(cmCommandArgumentsHelper* args,
|
||||||
|
const char* key,
|
||||||
|
cmCommandArgumentGroup* group)
|
||||||
|
:Key(key)
|
||||||
|
,Group(group)
|
||||||
|
,WasActive(false)
|
||||||
|
,CurrentIndex(0)
|
||||||
|
{
|
||||||
|
if (args!=0)
|
||||||
|
{
|
||||||
|
args->AddArgument(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->Group!=0)
|
||||||
|
{
|
||||||
|
this->Group->ContainedArguments.push_back(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmCommandArgument::Reset()
|
||||||
|
{
|
||||||
|
this->WasActive =false;
|
||||||
|
this->CurrentIndex = 0;
|
||||||
|
this->DoReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmCommandArgument::Follows(const cmCommandArgument* arg)
|
||||||
|
{
|
||||||
|
this->ArgumentsBefore.insert(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmCommandArgument::FollowsGroup(const cmCommandArgumentGroup* group)
|
||||||
|
{
|
||||||
|
if (group!=0)
|
||||||
|
{
|
||||||
|
for(std::vector<cmCommandArgument*>::const_iterator
|
||||||
|
argIt= group->ContainedArguments.begin();
|
||||||
|
argIt != group->ContainedArguments.end();
|
||||||
|
++argIt)
|
||||||
|
{
|
||||||
|
this->ArgumentsBefore.insert(*argIt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cmCommandArgument::MayFollow(const cmCommandArgument* current) const
|
||||||
|
{
|
||||||
|
if (this->ArgumentsBefore.empty())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<const cmCommandArgument*>::const_iterator argIt
|
||||||
|
= this->ArgumentsBefore.find(current);
|
||||||
|
if (argIt != this->ArgumentsBefore.end())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cmCommandArgument::KeyMatches(const std::string& key) const
|
||||||
|
{
|
||||||
|
if ((this->Key==0) || (this->Key[0]=='\0'))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return (key==this->Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmCommandArgument::ApplyOwnGroup()
|
||||||
|
{
|
||||||
|
if (this->Group!=0)
|
||||||
|
{
|
||||||
|
for (std::vector<cmCommandArgument*>::const_iterator
|
||||||
|
it = this->Group->ContainedArguments.begin();
|
||||||
|
it != this->Group->ContainedArguments.end();
|
||||||
|
++it)
|
||||||
|
{
|
||||||
|
if(*it != this)
|
||||||
|
{
|
||||||
|
this->ArgumentsBefore.insert(*it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmCommandArgument::Activate()
|
||||||
|
{
|
||||||
|
this->WasActive = true;
|
||||||
|
this->CurrentIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cmCommandArgument::Consume(const std::string& arg)
|
||||||
|
{
|
||||||
|
bool res=this->DoConsume(arg, this->CurrentIndex);
|
||||||
|
this->CurrentIndex++;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cmCAStringVector::cmCAStringVector(cmCommandArgumentsHelper* args,
|
||||||
|
const char* key,
|
||||||
|
cmCommandArgumentGroup* group)
|
||||||
|
:cmCommandArgument(args, key, group)
|
||||||
|
{
|
||||||
|
if ((key==0) || (*key==0))
|
||||||
|
{
|
||||||
|
this->DataStart = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->DataStart = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cmCAStringVector::DoConsume(const std::string& arg,unsigned int index)
|
||||||
|
{
|
||||||
|
if (index >= this->DataStart)
|
||||||
|
{
|
||||||
|
if ((this->Ignore==0) || (arg != this->Ignore))
|
||||||
|
{
|
||||||
|
this->Vector.push_back(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmCAStringVector::DoReset()
|
||||||
|
{
|
||||||
|
this->Vector.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
cmCAString::cmCAString(cmCommandArgumentsHelper* args,
|
||||||
|
const char* key,
|
||||||
|
cmCommandArgumentGroup* group)
|
||||||
|
:cmCommandArgument(args, key, group)
|
||||||
|
{
|
||||||
|
if ((key==0) || (*key==0))
|
||||||
|
{
|
||||||
|
this->DataStart = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->DataStart = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cmCAString::DoConsume(const std::string& arg, unsigned int index)
|
||||||
|
{
|
||||||
|
if (index == this->DataStart)
|
||||||
|
{
|
||||||
|
this->String = arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
return index >= this->DataStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmCAString::DoReset()
|
||||||
|
{
|
||||||
|
this->String = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
cmCAEnabler::cmCAEnabler(cmCommandArgumentsHelper* args,
|
||||||
|
const char* key,
|
||||||
|
cmCommandArgumentGroup* group)
|
||||||
|
:cmCommandArgument(args, key, group)
|
||||||
|
,Enabled(false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool cmCAEnabler::DoConsume(const std::string& arg, unsigned int index)
|
||||||
|
{
|
||||||
|
if (index==0)
|
||||||
|
{
|
||||||
|
this->Enabled = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmCAEnabler::DoReset()
|
||||||
|
{
|
||||||
|
this->Enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmCADisabler::cmCADisabler(cmCommandArgumentsHelper* args,
|
||||||
|
const char* key,
|
||||||
|
cmCommandArgumentGroup* group)
|
||||||
|
:cmCommandArgument(args, key, group)
|
||||||
|
,Enabled(true)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool cmCADisabler::DoConsume(const std::string& arg, unsigned int index)
|
||||||
|
{
|
||||||
|
if (index==0)
|
||||||
|
{
|
||||||
|
this->Enabled = false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmCADisabler::DoReset()
|
||||||
|
{
|
||||||
|
this->Enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmCommandArgumentGroup::Follows(const cmCommandArgument* arg)
|
||||||
|
{
|
||||||
|
for(std::vector<cmCommandArgument*>::iterator
|
||||||
|
it = this->ContainedArguments.begin();
|
||||||
|
it != this->ContainedArguments.end();
|
||||||
|
++it)
|
||||||
|
{
|
||||||
|
(*it)->Follows(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmCommandArgumentGroup::FollowsGroup(const cmCommandArgumentGroup* group)
|
||||||
|
{
|
||||||
|
for(std::vector<cmCommandArgument*>::iterator
|
||||||
|
it = this->ContainedArguments.begin();
|
||||||
|
it != this->ContainedArguments.end();
|
||||||
|
++it)
|
||||||
|
{
|
||||||
|
(*it)->FollowsGroup(group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmCommandArgumentsHelper::Parse(const std::vector<std::string>* args,
|
||||||
|
std::vector<std::string>* unconsumedArgs)
|
||||||
|
{
|
||||||
|
if(args==0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(std::vector<cmCommandArgument*>::iterator
|
||||||
|
argIt = this->Arguments.begin();
|
||||||
|
argIt != this->Arguments.end();
|
||||||
|
++argIt)
|
||||||
|
{
|
||||||
|
(*argIt)->ApplyOwnGroup();
|
||||||
|
(*argIt)->Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
cmCommandArgument* activeArgument = 0;
|
||||||
|
const cmCommandArgument* previousArgument = 0;
|
||||||
|
for(std::vector<std::string>::const_iterator it = args->begin();
|
||||||
|
it != args->end();
|
||||||
|
++it)
|
||||||
|
{
|
||||||
|
for(std::vector<cmCommandArgument*>::iterator
|
||||||
|
argIt = this->Arguments.begin();
|
||||||
|
argIt != this->Arguments.end();
|
||||||
|
++argIt)
|
||||||
|
{
|
||||||
|
if ((*argIt)->KeyMatches(*it) && ((*argIt)->MayFollow(previousArgument)))
|
||||||
|
{
|
||||||
|
activeArgument = *argIt;
|
||||||
|
activeArgument->Activate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (activeArgument)
|
||||||
|
{
|
||||||
|
bool argDone = activeArgument->Consume(*it);
|
||||||
|
previousArgument = activeArgument;
|
||||||
|
if (argDone)
|
||||||
|
{
|
||||||
|
activeArgument = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (unconsumedArgs!=0)
|
||||||
|
{
|
||||||
|
unconsumedArgs->push_back(*it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmCommandArgumentsHelper::AddArgument(cmCommandArgument* arg)
|
||||||
|
{
|
||||||
|
this->Arguments.push_back(arg);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,208 @@
|
||||||
|
/*=========================================================================
|
||||||
|
|
||||||
|
Program: CMake - Cross-Platform Makefile Generator
|
||||||
|
Module: $RCSfile$
|
||||||
|
Language: C++
|
||||||
|
Date: $Date$
|
||||||
|
Version: $Revision$
|
||||||
|
|
||||||
|
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
|
||||||
|
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
|
||||||
|
|
||||||
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||||||
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. See the above copyright notices for more information.
|
||||||
|
|
||||||
|
=========================================================================*/
|
||||||
|
#ifndef cmCommandArgumentsHelper_h
|
||||||
|
#define cmCommandArgumentsHelper_h
|
||||||
|
|
||||||
|
#include "cmStandardIncludes.h"
|
||||||
|
|
||||||
|
class cmCommandArgumentsHelper;
|
||||||
|
class cmCommandArgumentGroup;
|
||||||
|
|
||||||
|
/* cmCommandArgumentsHelper, cmCommandArgumentGroup and cmCommandArgument (i.e.
|
||||||
|
its derived classes cmCAXXX can be used to simplify the processing of
|
||||||
|
arguments to cmake commands. Maybe they can also be used to generate
|
||||||
|
documentation.
|
||||||
|
|
||||||
|
For every argument supported by a command one cmCommandArgument is created
|
||||||
|
and added to cmCommandArgumentsHelper. cmCommand has a cmCommandArgumentsHelper
|
||||||
|
as member variable so this should be used.
|
||||||
|
|
||||||
|
The order of the arguments is defined using the Follows(arg) method. It says
|
||||||
|
that this argument follows immediateley the given argument. It can be used
|
||||||
|
with multiple arguments if the argument can follow after different arguments.
|
||||||
|
|
||||||
|
Arguments can be arranged in groups using cmCommandArgumentGroup. Every
|
||||||
|
member of a group can follow any other member of the group. These groups
|
||||||
|
can also be used to define the order.
|
||||||
|
|
||||||
|
Once all arguments and groups are set up, cmCommandArgumentsHelper::Parse()
|
||||||
|
is called and afterwards the values of the arguments can be evaluated.
|
||||||
|
|
||||||
|
For an example see cmExportCommand.cxx.
|
||||||
|
*/
|
||||||
|
class cmCommandArgument
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
cmCommandArgument(cmCommandArgumentsHelper* args,
|
||||||
|
const char* key,
|
||||||
|
cmCommandArgumentGroup* group=0);
|
||||||
|
virtual ~cmCommandArgument() {}
|
||||||
|
|
||||||
|
/// this argument may follow after arg. 0 means it comes first.
|
||||||
|
void Follows(const cmCommandArgument* arg);
|
||||||
|
|
||||||
|
/// this argument may follow after any of the arguments in the given group
|
||||||
|
void FollowsGroup(const cmCommandArgumentGroup* group);
|
||||||
|
|
||||||
|
/// Returns true if the argument was found in the argument list
|
||||||
|
bool WasFound() const {return this->WasActive;}
|
||||||
|
|
||||||
|
// The following methods are only called from
|
||||||
|
// cmCommandArgumentsHelper::Parse(), but making this a friend would
|
||||||
|
// give it access to everything
|
||||||
|
|
||||||
|
/// Make the current argument the currently active argument
|
||||||
|
void Activate();
|
||||||
|
/// Consume the current string
|
||||||
|
bool Consume(const std::string& arg);
|
||||||
|
|
||||||
|
/// Return true if this argument may follow after the given argument.
|
||||||
|
bool MayFollow(const cmCommandArgument* current) const;
|
||||||
|
|
||||||
|
/** Returns true if the given key matches the key for this argument.
|
||||||
|
If this argument has an empty key everything matches. */
|
||||||
|
bool KeyMatches(const std::string& key) const;
|
||||||
|
|
||||||
|
/// Make this argument follow all members of the own group
|
||||||
|
void ApplyOwnGroup();
|
||||||
|
|
||||||
|
/// Reset argument, so it's back to its initial state
|
||||||
|
void Reset();
|
||||||
|
private:
|
||||||
|
const char* Key;
|
||||||
|
std::set<const cmCommandArgument*> ArgumentsBefore;
|
||||||
|
cmCommandArgumentGroup* Group;
|
||||||
|
bool WasActive;
|
||||||
|
unsigned int CurrentIndex;
|
||||||
|
|
||||||
|
virtual bool DoConsume(const std::string& arg, unsigned int index) = 0;
|
||||||
|
virtual void DoReset() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** cmCAStringVector is to be used for arguments which can consist of more
|
||||||
|
than one string, e.g. the FILES argument in INSTALL(FILES f1 f2 f3 ...). */
|
||||||
|
class cmCAStringVector : public cmCommandArgument
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
cmCAStringVector(cmCommandArgumentsHelper* args,
|
||||||
|
const char* key,
|
||||||
|
cmCommandArgumentGroup* group=0);
|
||||||
|
|
||||||
|
/// Return the vector of strings
|
||||||
|
const std::vector<std::string>& GetVector() const {return this->Vector;}
|
||||||
|
|
||||||
|
/** Is there a keyword which should be skipped in
|
||||||
|
the arguments (e.g. ARGS for ADD_CUSTOM_COMMAND) ? */
|
||||||
|
void SetIgnore(const char* ignore) {this->Ignore=ignore;}
|
||||||
|
private:
|
||||||
|
std::vector<std::string> Vector;
|
||||||
|
unsigned int DataStart;
|
||||||
|
const char* Ignore;
|
||||||
|
cmCAStringVector();
|
||||||
|
virtual bool DoConsume(const std::string& arg, unsigned int index);
|
||||||
|
virtual void DoReset();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** cmCAString is to be used for arguments which consist of one value,
|
||||||
|
e.g. the executable name in ADD_EXECUTABLE(). */
|
||||||
|
class cmCAString : public cmCommandArgument
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
cmCAString(cmCommandArgumentsHelper* args,
|
||||||
|
const char* key,
|
||||||
|
cmCommandArgumentGroup* group=0);
|
||||||
|
|
||||||
|
/// Return the string
|
||||||
|
const std::string& GetString() const {return this->String;}
|
||||||
|
private:
|
||||||
|
std::string String;
|
||||||
|
unsigned int DataStart;
|
||||||
|
virtual bool DoConsume(const std::string& arg, unsigned int index);
|
||||||
|
virtual void DoReset();
|
||||||
|
cmCAString();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** cmCAEnabler is to be used for options which are off by default and can be
|
||||||
|
enabled using a special argument, e.g. EXCLUDE_FROM_ALL in ADD_EXECUTABLE(). */
|
||||||
|
class cmCAEnabler : public cmCommandArgument
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
cmCAEnabler(cmCommandArgumentsHelper* args,
|
||||||
|
const char* key,
|
||||||
|
cmCommandArgumentGroup* group=0);
|
||||||
|
|
||||||
|
/// Has it been enabled ?
|
||||||
|
bool IsEnabled() const {return this->Enabled;}
|
||||||
|
private:
|
||||||
|
bool Enabled;
|
||||||
|
virtual bool DoConsume(const std::string& arg, unsigned int index);
|
||||||
|
virtual void DoReset();
|
||||||
|
cmCAEnabler();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** cmCADisable is to be used for options which are on by default and can be
|
||||||
|
disabled using a special argument.*/
|
||||||
|
class cmCADisabler : public cmCommandArgument
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
cmCADisabler(cmCommandArgumentsHelper* args,
|
||||||
|
const char* key,
|
||||||
|
cmCommandArgumentGroup* group=0);
|
||||||
|
|
||||||
|
/// Is it still enabled ?
|
||||||
|
bool IsEnabled() const {return this->Enabled;}
|
||||||
|
private:
|
||||||
|
bool Enabled;
|
||||||
|
virtual bool DoConsume(const std::string& arg, unsigned int index);
|
||||||
|
virtual void DoReset();
|
||||||
|
cmCADisabler();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** Group of arguments, needed for ordering. E.g. WIN32, EXCLUDE_FROM_ALL and
|
||||||
|
MACSOX_BUNDLE from ADD_EXECUTABLE() are a group.
|
||||||
|
*/
|
||||||
|
class cmCommandArgumentGroup
|
||||||
|
{
|
||||||
|
friend class cmCommandArgument;
|
||||||
|
public:
|
||||||
|
cmCommandArgumentGroup() {}
|
||||||
|
|
||||||
|
/// All members of this group may follow the given argument
|
||||||
|
void Follows(const cmCommandArgument* arg);
|
||||||
|
|
||||||
|
/// All members of this group may follow all members of the given group
|
||||||
|
void FollowsGroup(const cmCommandArgumentGroup* group);
|
||||||
|
private:
|
||||||
|
std::vector<cmCommandArgument*> ContainedArguments;
|
||||||
|
};
|
||||||
|
|
||||||
|
class cmCommandArgumentsHelper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// Parse the argument list
|
||||||
|
void Parse(const std::vector<std::string>* args,
|
||||||
|
std::vector<std::string>* unconsumedArgs);
|
||||||
|
|
||||||
|
/// Add an argument.
|
||||||
|
void AddArgument(cmCommandArgument* arg);
|
||||||
|
private:
|
||||||
|
std::vector<cmCommandArgument*> Arguments;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -22,6 +22,21 @@
|
||||||
|
|
||||||
#include <cmsys/auto_ptr.hxx>
|
#include <cmsys/auto_ptr.hxx>
|
||||||
|
|
||||||
|
cmExportCommand::cmExportCommand()
|
||||||
|
:cmCommand()
|
||||||
|
,ArgumentGroup()
|
||||||
|
,Targets(&this->Helper, "TARGETS")
|
||||||
|
,Append(&this->Helper, "APPEND", &ArgumentGroup)
|
||||||
|
,Prefix(&this->Helper, "PREFIX", &ArgumentGroup)
|
||||||
|
,Filename(&this->Helper, "FILE", &ArgumentGroup)
|
||||||
|
{
|
||||||
|
// at first TARGETS
|
||||||
|
this->Targets.Follows(0);
|
||||||
|
// and after that the other options in any order
|
||||||
|
this->ArgumentGroup.Follows(&this->Targets);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// cmExportCommand
|
// cmExportCommand
|
||||||
bool cmExportCommand
|
bool cmExportCommand
|
||||||
::InitialPass(std::vector<std::string> const& args)
|
::InitialPass(std::vector<std::string> const& args)
|
||||||
|
@ -32,42 +47,50 @@ bool cmExportCommand
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string filename;
|
std::vector<std::string> unknownArgs;
|
||||||
std::string prefix;
|
this->Helper.Parse(&args, &unknownArgs);
|
||||||
std::string exportName;
|
|
||||||
std::vector<std::string> targets;
|
if (!unknownArgs.empty())
|
||||||
bool append = false;
|
|
||||||
if (!this->ParseArgs(args, filename, prefix, exportName, targets, append))
|
|
||||||
{
|
{
|
||||||
|
this->SetError("Unknown arguments.");
|
||||||
|
cmSystemTools::SetFatalErrorOccured();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !this->Makefile->CanIWriteThisFile(filename.c_str()) )
|
if (this->Targets.WasFound() == false)
|
||||||
{
|
{
|
||||||
std::string e = "attempted to write a file: " + filename
|
this->SetError("TARGETS option missing.");
|
||||||
|
cmSystemTools::SetFatalErrorOccured();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ( !this->Makefile->CanIWriteThisFile(this->Filename.GetString().c_str()) )
|
||||||
|
{
|
||||||
|
std::string e = "attempted to write a file: " + this->Filename.GetString()
|
||||||
+ " into a source directory.";
|
+ " into a source directory.";
|
||||||
this->SetError(e.c_str());
|
this->SetError(e.c_str());
|
||||||
cmSystemTools::SetFatalErrorOccured();
|
cmSystemTools::SetFatalErrorOccured();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((targets.empty()) || (filename.empty()))
|
if((this->Targets.GetVector().empty())||(this->Filename.GetString().empty()))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use copy-if-different if not appending.
|
// Use copy-if-different if not appending.
|
||||||
cmsys::auto_ptr<std::ofstream> foutPtr;
|
cmsys::auto_ptr<std::ofstream> foutPtr;
|
||||||
if(append)
|
if(this->Append.IsEnabled())
|
||||||
{
|
{
|
||||||
cmsys::auto_ptr<std::ofstream> ap(
|
cmsys::auto_ptr<std::ofstream> ap(
|
||||||
new std::ofstream(filename.c_str(), std::ios::app));
|
new std::ofstream(this->Filename.GetString().c_str(), std::ios::app));
|
||||||
foutPtr = ap;
|
foutPtr = ap;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cmsys::auto_ptr<cmGeneratedFileStream> ap(
|
cmsys::auto_ptr<cmGeneratedFileStream> ap(
|
||||||
new cmGeneratedFileStream(filename.c_str(), true));
|
new cmGeneratedFileStream(this->Filename.GetString().c_str(), true));
|
||||||
ap->SetCopyIfDifferent(true);
|
ap->SetCopyIfDifferent(true);
|
||||||
foutPtr = ap;
|
foutPtr = ap;
|
||||||
}
|
}
|
||||||
|
@ -75,7 +98,7 @@ bool cmExportCommand
|
||||||
|
|
||||||
if (!fout)
|
if (!fout)
|
||||||
{
|
{
|
||||||
cmSystemTools::Error("Error Writing ", filename.c_str());
|
cmSystemTools::Error("Error Writing ", this->Filename.GetString().c_str());
|
||||||
cmSystemTools::ReportLastSystemError("");
|
cmSystemTools::ReportLastSystemError("");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -97,8 +120,9 @@ bool cmExportCommand
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(std::vector<std::string>::const_iterator currentTarget = targets.begin();
|
for(std::vector<std::string>::const_iterator
|
||||||
currentTarget != targets.end();
|
currentTarget = this->Targets.GetVector().begin();
|
||||||
|
currentTarget != this->Targets.GetVector().end();
|
||||||
++currentTarget)
|
++currentTarget)
|
||||||
{
|
{
|
||||||
cmTarget* target = this->Makefile->GetLocalGenerator()->
|
cmTarget* target = this->Makefile->GetLocalGenerator()->
|
||||||
|
@ -112,8 +136,9 @@ bool cmExportCommand
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(std::vector<std::string>::const_iterator currentTarget = targets.begin();
|
for(std::vector<std::string>::const_iterator
|
||||||
currentTarget != targets.end();
|
currentTarget = this->Targets.GetVector().begin();
|
||||||
|
currentTarget != this->Targets.GetVector().end();
|
||||||
++currentTarget)
|
++currentTarget)
|
||||||
{
|
{
|
||||||
// Look for a CMake target with the given name, which is an executable
|
// Look for a CMake target with the given name, which is an executable
|
||||||
|
@ -129,26 +154,30 @@ bool cmExportCommand
|
||||||
switch (target->GetType())
|
switch (target->GetType())
|
||||||
{
|
{
|
||||||
case cmTarget::EXECUTABLE:
|
case cmTarget::EXECUTABLE:
|
||||||
fout << "ADD_EXECUTABLE(" << prefix.c_str() << currentTarget->c_str()
|
fout << "ADD_EXECUTABLE("
|
||||||
<< " IMPORT )\n";
|
<< this->Prefix.GetString().c_str() << currentTarget->c_str()
|
||||||
|
<< " IMPORT )\n";
|
||||||
break;
|
break;
|
||||||
case cmTarget::STATIC_LIBRARY:
|
case cmTarget::STATIC_LIBRARY:
|
||||||
fout << "ADD_LIBRARY(" << prefix.c_str() << currentTarget->c_str()
|
fout << "ADD_LIBRARY("
|
||||||
<< " STATIC IMPORT )\n";
|
<< this->Prefix.GetString().c_str() << currentTarget->c_str()
|
||||||
|
<< " STATIC IMPORT )\n";
|
||||||
break;
|
break;
|
||||||
case cmTarget::SHARED_LIBRARY:
|
case cmTarget::SHARED_LIBRARY:
|
||||||
fout << "ADD_LIBRARY(" << prefix.c_str() << currentTarget->c_str()
|
fout << "ADD_LIBRARY("
|
||||||
<< " SHARED IMPORT )\n";
|
<< this->Prefix.GetString().c_str() << currentTarget->c_str()
|
||||||
|
<< " SHARED IMPORT )\n";
|
||||||
break;
|
break;
|
||||||
case cmTarget::MODULE_LIBRARY:
|
case cmTarget::MODULE_LIBRARY:
|
||||||
fout << "ADD_LIBRARY(" << prefix.c_str() << currentTarget->c_str()
|
fout << "ADD_LIBRARY("
|
||||||
<< " MODULE IMPORT )\n";
|
<< this->Prefix.GetString().c_str() << currentTarget->c_str()
|
||||||
|
<< " MODULE IMPORT )\n";
|
||||||
break;
|
break;
|
||||||
default: // should never happen
|
default: // should never happen
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
fout << "SET_TARGET_PROPERTIES(" << prefix.c_str()
|
fout << "SET_TARGET_PROPERTIES(" << this->Prefix.GetString().c_str()
|
||||||
<< currentTarget->c_str() << " PROPERTIES \n"
|
<< currentTarget->c_str() << " PROPERTIES \n"
|
||||||
<< " LOCATION " << target->GetLocation(0) << "\n";
|
<< " LOCATION " << target->GetLocation(0) << "\n";
|
||||||
for(std::vector<std::string>::const_iterator
|
for(std::vector<std::string>::const_iterator
|
||||||
|
@ -172,82 +201,3 @@ bool cmExportCommand
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cmExportCommand::ParseArgs(const std::vector<std::string>& args,
|
|
||||||
std::string& filename,
|
|
||||||
std::string& prefix,
|
|
||||||
std::string& exportName,
|
|
||||||
std::vector<std::string>& targets,
|
|
||||||
bool& append) const
|
|
||||||
{
|
|
||||||
bool doingFile = false;
|
|
||||||
bool doingPrefix = false;
|
|
||||||
bool doingTargets = false;
|
|
||||||
bool doingName = true;
|
|
||||||
for(std::vector<std::string>::const_iterator it = args.begin();
|
|
||||||
it != args.end();
|
|
||||||
++it)
|
|
||||||
{
|
|
||||||
if (*it == "FILE")
|
|
||||||
{
|
|
||||||
doingFile = true;
|
|
||||||
doingPrefix = false;
|
|
||||||
doingName = false;
|
|
||||||
doingTargets = false;
|
|
||||||
}
|
|
||||||
else if (*it == "PREFIX")
|
|
||||||
{
|
|
||||||
doingFile = false;
|
|
||||||
doingPrefix = true;
|
|
||||||
doingName = false;
|
|
||||||
doingTargets = false;
|
|
||||||
}
|
|
||||||
else if (*it == "TARGETS")
|
|
||||||
{
|
|
||||||
doingFile = false;
|
|
||||||
doingPrefix = false;
|
|
||||||
doingName = false;
|
|
||||||
doingTargets = true;
|
|
||||||
}
|
|
||||||
else if (*it == "APPEND")
|
|
||||||
{
|
|
||||||
append = true;
|
|
||||||
doingFile = false;
|
|
||||||
doingPrefix = false;
|
|
||||||
doingName = false;
|
|
||||||
doingTargets = false;
|
|
||||||
}
|
|
||||||
else if (doingFile)
|
|
||||||
{
|
|
||||||
filename = *it;
|
|
||||||
doingFile = false;
|
|
||||||
doingPrefix = false;
|
|
||||||
doingName = false;
|
|
||||||
doingTargets = false;
|
|
||||||
}
|
|
||||||
else if (doingPrefix)
|
|
||||||
{
|
|
||||||
prefix = *it;
|
|
||||||
doingFile = false;
|
|
||||||
doingPrefix = false;
|
|
||||||
doingName = false;
|
|
||||||
doingTargets = false;
|
|
||||||
}
|
|
||||||
else if (doingTargets)
|
|
||||||
{
|
|
||||||
targets.push_back(*it);
|
|
||||||
}
|
|
||||||
else if (doingName)
|
|
||||||
{
|
|
||||||
exportName = *it;
|
|
||||||
doingFile = false;
|
|
||||||
doingPrefix = false;
|
|
||||||
doingName = false;
|
|
||||||
doingTargets = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
class cmExportCommand : public cmCommand
|
class cmExportCommand : public cmCommand
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
cmExportCommand();
|
||||||
/**
|
/**
|
||||||
* This is a virtual constructor for the command.
|
* This is a virtual constructor for the command.
|
||||||
*/
|
*/
|
||||||
|
@ -75,10 +76,11 @@ public:
|
||||||
cmTypeMacro(cmExportCommand, cmCommand);
|
cmTypeMacro(cmExportCommand, cmCommand);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool ParseArgs(const std::vector<std::string>& args, std::string& filename,
|
cmCommandArgumentGroup ArgumentGroup;
|
||||||
std::string& prefix, std::string& exportName,
|
cmCAStringVector Targets;
|
||||||
std::vector<std::string>& targets, bool& append ) const;
|
cmCAEnabler Append;
|
||||||
|
cmCAString Prefix;
|
||||||
|
cmCAString Filename;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue