ENH: Add global property ALLOW_DUPLICATE_CUSTOM_TARGETS to help existing projects that depend on having duplicate custom targets. It is allowed only for Makefile generators. See bug#6348.
This commit is contained in:
parent
67f8c0fd10
commit
1c0595c73f
@ -161,7 +161,7 @@ bool cmAddCustomTargetCommand
|
|||||||
// Enforce name uniqueness.
|
// Enforce name uniqueness.
|
||||||
{
|
{
|
||||||
std::string msg;
|
std::string msg;
|
||||||
if(!this->Makefile->EnforceUniqueName(args[0], msg))
|
if(!this->Makefile->EnforceUniqueName(args[0], msg, true))
|
||||||
{
|
{
|
||||||
this->SetError(msg.c_str());
|
this->SetError(msg.c_str());
|
||||||
return false;
|
return false;
|
||||||
|
@ -733,12 +733,39 @@ void cmGlobalGenerator::Configure()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cmGlobalGenerator::CheckALLOW_DUPLICATE_CUSTOM_TARGETS()
|
||||||
|
{
|
||||||
|
// If the property is not enabled then okay.
|
||||||
|
if(!this->CMakeInstance
|
||||||
|
->GetPropertyAsBool("ALLOW_DUPLICATE_CUSTOM_TARGETS"))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This generator does not support duplicate custom targets.
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "This project has enabled the ALLOW_DUPLICATE_CUSTOM_TARGETS "
|
||||||
|
<< "global property. "
|
||||||
|
<< "The \"" << this->GetName() << "\" generator does not support "
|
||||||
|
<< "duplicate custom targets. "
|
||||||
|
<< "Consider using a Makefiles generator or fix the project to not "
|
||||||
|
<< "use duplicat target names.";
|
||||||
|
cmSystemTools::Error(e.str().c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void cmGlobalGenerator::Generate()
|
void cmGlobalGenerator::Generate()
|
||||||
{
|
{
|
||||||
// Some generators track files replaced during the Generate.
|
// Some generators track files replaced during the Generate.
|
||||||
// Start with an empty vector:
|
// Start with an empty vector:
|
||||||
this->FilesReplacedDuringGenerate.clear();
|
this->FilesReplacedDuringGenerate.clear();
|
||||||
|
|
||||||
|
// Check whether this generator is allowed to run.
|
||||||
|
if(!this->CheckALLOW_DUPLICATE_CUSTOM_TARGETS())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// For each existing cmLocalGenerator
|
// For each existing cmLocalGenerator
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
@ -258,6 +258,8 @@ protected:
|
|||||||
void SetLanguageEnabledFlag(const char* l, cmMakefile* mf);
|
void SetLanguageEnabledFlag(const char* l, cmMakefile* mf);
|
||||||
void SetLanguageEnabledMaps(const char* l, cmMakefile* mf);
|
void SetLanguageEnabledMaps(const char* l, cmMakefile* mf);
|
||||||
|
|
||||||
|
virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS();
|
||||||
|
|
||||||
// Fill the ProjectMap, this must be called after LocalGenerators
|
// Fill the ProjectMap, this must be called after LocalGenerators
|
||||||
// has been populated.
|
// has been populated.
|
||||||
void FillProjectMap();
|
void FillProjectMap();
|
||||||
|
@ -162,6 +162,8 @@ protected:
|
|||||||
virtual const char* GetRebuildCacheTargetName() { return "rebuild_cache"; }
|
virtual const char* GetRebuildCacheTargetName() { return "rebuild_cache"; }
|
||||||
virtual const char* GetCleanTargetName() { return "clean"; }
|
virtual const char* GetCleanTargetName() { return "clean"; }
|
||||||
|
|
||||||
|
virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS() { return true; }
|
||||||
|
|
||||||
// Some make programs (Borland) do not keep a rule if there are no
|
// Some make programs (Borland) do not keep a rule if there are no
|
||||||
// dependencies or commands. This is a problem for creating rules
|
// dependencies or commands. This is a problem for creating rules
|
||||||
// that might not do anything but might have other dependencies
|
// that might not do anything but might have other dependencies
|
||||||
|
@ -3140,7 +3140,8 @@ cmTarget* cmMakefile::FindTargetToUse(const char* name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg)
|
bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg,
|
||||||
|
bool isCustom)
|
||||||
{
|
{
|
||||||
if(cmTarget* existing = this->FindTargetToUse(name.c_str()))
|
if(cmTarget* existing = this->FindTargetToUse(name.c_str()))
|
||||||
{
|
{
|
||||||
@ -3158,21 +3159,76 @@ bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg)
|
|||||||
}
|
}
|
||||||
else if(!this->NeedBackwardsCompatibility(2, 4))
|
else if(!this->NeedBackwardsCompatibility(2, 4))
|
||||||
{
|
{
|
||||||
// The conflict is with a non-imported target. Produce an error
|
// The conflict is with a non-imported target.
|
||||||
// that tells the user how to work around the problem.
|
// Allow this if the user has requested support.
|
||||||
|
cmake* cm =
|
||||||
|
this->LocalGenerator->GetGlobalGenerator()->GetCMakeInstance();
|
||||||
|
if(isCustom && existing->GetType() == cmTarget::UTILITY &&
|
||||||
|
this != existing->GetMakefile() &&
|
||||||
|
cm->GetPropertyAsBool("ALLOW_DUPLICATE_CUSTOM_TARGETS"))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Produce an error that tells the user how to work around the
|
||||||
|
// problem.
|
||||||
cmOStringStream e;
|
cmOStringStream e;
|
||||||
e << "cannot create target \"" << name
|
e << "cannot create target \"" << name
|
||||||
<< "\" because another target with the same name already exists. "
|
<< "\" because another target with the same name already exists. "
|
||||||
<< "Logical target names must be globally unique. "
|
<< "The existing target is ";
|
||||||
<< "For executables and libraries, consider using the OUTPUT_NAME "
|
switch(existing->GetType())
|
||||||
<< "target property to create two targets with the same physical "
|
{
|
||||||
<< "name while keeping logical names distinct. "
|
case cmTarget::EXECUTABLE:
|
||||||
<< "Custom targets must simply have globally unique names.\n"
|
e << "an executable ";
|
||||||
<< "If you are building an older project it is possible that "
|
break;
|
||||||
<< "it violated this rule but was working accidentally. "
|
case cmTarget::STATIC_LIBRARY:
|
||||||
<< "Set CMAKE_BACKWARDS_COMPATIBILITY to 2.4 or lower to disable "
|
e << "a static library ";
|
||||||
<< "this error.";
|
break;
|
||||||
msg = e.str();
|
case cmTarget::SHARED_LIBRARY:
|
||||||
|
e << "a shared library ";
|
||||||
|
break;
|
||||||
|
case cmTarget::MODULE_LIBRARY:
|
||||||
|
e << "a module library ";
|
||||||
|
break;
|
||||||
|
case cmTarget::UTILITY:
|
||||||
|
e << "a custom target ";
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
e << "created in source directory \""
|
||||||
|
<< existing->GetMakefile()->GetCurrentDirectory() << "\".\n"
|
||||||
|
<< "\n";
|
||||||
|
e <<
|
||||||
|
"Logical target names must be globally unique because:\n"
|
||||||
|
" - Unique names may be referenced unambiguously both in CMake\n"
|
||||||
|
" code and on make tool command lines.\n"
|
||||||
|
" - Logical names are used by Xcode and VS IDE generators\n"
|
||||||
|
" to produce meaningful project names for the targets.\n"
|
||||||
|
"The logical name of executable and library targets does not "
|
||||||
|
"have to correspond to the physical file names built. "
|
||||||
|
"Consider using the OUTPUT_NAME target property to create two "
|
||||||
|
"targets with the same physical name while keeping logical "
|
||||||
|
"names distinct. "
|
||||||
|
"Custom targets must simply have globally unique names.\n"
|
||||||
|
"\n"
|
||||||
|
"If you are building an older project it is possible that "
|
||||||
|
"it violated this rule but was working accidentally because "
|
||||||
|
"CMake did not previously diagnose this problem. "
|
||||||
|
"Set CMAKE_BACKWARDS_COMPATIBILITY to 2.4 or lower to disable "
|
||||||
|
"this error.\n";
|
||||||
|
if(isCustom && existing->GetType() == cmTarget::UTILITY)
|
||||||
|
{
|
||||||
|
e <<
|
||||||
|
"\n"
|
||||||
|
"For projects that care only about Makefile generators and do "
|
||||||
|
"not wish to support Xcode or VS IDE generators, one may add\n"
|
||||||
|
" set_property(GLOBAL PROPERTY ALLOW_DUPLICATE_CUSTOM_TARGETS 1)\n"
|
||||||
|
"to the top of the project to allow duplicate custom targets "
|
||||||
|
"(target names must still be unique within each directory). "
|
||||||
|
"However, setting this property will cause non-Makefile generators "
|
||||||
|
"to produce an error and refuse to generate the project.";
|
||||||
|
}
|
||||||
|
msg = e.str();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,8 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Help enforce global target name uniqueness.
|
* Help enforce global target name uniqueness.
|
||||||
*/
|
*/
|
||||||
bool EnforceUniqueName(std::string const& name, std::string& msg);
|
bool EnforceUniqueName(std::string const& name, std::string& msg,
|
||||||
|
bool isCustom = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform FinalPass, Library dependency analysis etc before output of the
|
* Perform FinalPass, Library dependency analysis etc before output of the
|
||||||
|
@ -3322,6 +3322,25 @@ void cmake::DefineProperties(cmake *cm)
|
|||||||
"at the beginning of native build system generation. "
|
"at the beginning of native build system generation. "
|
||||||
"This property causes it to display details of its analysis to stderr.");
|
"This property causes it to display details of its analysis to stderr.");
|
||||||
|
|
||||||
|
cm->DefineProperty(
|
||||||
|
"ALLOW_DUPLICATE_CUSTOM_TARGETS", cmProperty::GLOBAL,
|
||||||
|
"Allow duplicate custom targets to be created.",
|
||||||
|
"Normally CMake requires that all targets built in a project have "
|
||||||
|
"globally unique names. "
|
||||||
|
"This is necessary to generate meaningful project file names in "
|
||||||
|
"Xcode and VS IDE generators. "
|
||||||
|
"It also allows the target names to be referenced unambiguously.\n"
|
||||||
|
"Makefile generators are capable of supporting duplicate custom target "
|
||||||
|
"names. "
|
||||||
|
"For projects that care only about Makefile generators and do "
|
||||||
|
"not wish to support Xcode or VS IDE generators, one may set this "
|
||||||
|
"property to true to allow duplicate custom targets. "
|
||||||
|
"The property allows multiple add_custom_target command calls in "
|
||||||
|
"*different directories* to specify the same target name. "
|
||||||
|
"However, setting this property will cause non-Makefile generators "
|
||||||
|
"to produce an error and refuse to generate the project."
|
||||||
|
);
|
||||||
|
|
||||||
cm->DefineProperty
|
cm->DefineProperty
|
||||||
("IN_TRY_COMPILE", cmProperty::GLOBAL,
|
("IN_TRY_COMPILE", cmProperty::GLOBAL,
|
||||||
"Read-only property that is true during a try-compile configuration.",
|
"Read-only property that is true during a try-compile configuration.",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user