summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2008-02-14 21:42:29 (GMT)
committerBrad King <brad.king@kitware.com>2008-02-14 21:42:29 (GMT)
commit1c0595c73fe1fa88b67691794eef8ee10edfc257 (patch)
treefd453a6e799d7d5f4ee6e1f01096a40cb8aadb1d /Source
parent67f8c0fd104fe6ec1b6c1df2ebce6fdb9b2c811f (diff)
downloadCMake-1c0595c73fe1fa88b67691794eef8ee10edfc257.zip
CMake-1c0595c73fe1fa88b67691794eef8ee10edfc257.tar.gz
CMake-1c0595c73fe1fa88b67691794eef8ee10edfc257.tar.bz2
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.
Diffstat (limited to 'Source')
-rw-r--r--Source/cmAddCustomTargetCommand.cxx2
-rw-r--r--Source/cmGlobalGenerator.cxx27
-rw-r--r--Source/cmGlobalGenerator.h2
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h2
-rw-r--r--Source/cmMakefile.cxx82
-rw-r--r--Source/cmMakefile.h3
-rw-r--r--Source/cmake.cxx19
7 files changed, 122 insertions, 15 deletions
diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx
index d7e479a..06998c6 100644
--- a/Source/cmAddCustomTargetCommand.cxx
+++ b/Source/cmAddCustomTargetCommand.cxx
@@ -161,7 +161,7 @@ bool cmAddCustomTargetCommand
// Enforce name uniqueness.
{
std::string msg;
- if(!this->Makefile->EnforceUniqueName(args[0], msg))
+ if(!this->Makefile->EnforceUniqueName(args[0], msg, true))
{
this->SetError(msg.c_str());
return false;
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 25d1bef..003788e 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -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()
{
// Some generators track files replaced during the Generate.
// Start with an empty vector:
this->FilesReplacedDuringGenerate.clear();
+ // Check whether this generator is allowed to run.
+ if(!this->CheckALLOW_DUPLICATE_CUSTOM_TARGETS())
+ {
+ return;
+ }
+
// For each existing cmLocalGenerator
unsigned int i;
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 9c13a4e..8ea408e 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -258,6 +258,8 @@ protected:
void SetLanguageEnabledFlag(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
// has been populated.
void FillProjectMap();
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index 4a6421e..cf80599 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -162,6 +162,8 @@ protected:
virtual const char* GetRebuildCacheTargetName() { return "rebuild_cache"; }
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
// dependencies or commands. This is a problem for creating rules
// that might not do anything but might have other dependencies
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 35b0aea..429eae8 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -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()))
{
@@ -3158,21 +3159,76 @@ bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg)
}
else if(!this->NeedBackwardsCompatibility(2, 4))
{
- // The conflict is with a non-imported target. Produce an error
- // that tells the user how to work around the problem.
+ // The conflict is with a non-imported target.
+ // 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;
e << "cannot create target \"" << name
<< "\" because another target with the same name already exists. "
- << "Logical target names must be globally unique. "
- << "For executables and libraries, 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"
- << "If you are building an older project it is possible that "
- << "it violated this rule but was working accidentally. "
- << "Set CMAKE_BACKWARDS_COMPATIBILITY to 2.4 or lower to disable "
- << "this error.";
- msg = e.str();
+ << "The existing target is ";
+ switch(existing->GetType())
+ {
+ case cmTarget::EXECUTABLE:
+ e << "an executable ";
+ break;
+ case cmTarget::STATIC_LIBRARY:
+ e << "a static library ";
+ break;
+ 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;
}
}
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index f3714cb..4c99df1 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -132,7 +132,8 @@ public:
/**
* 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
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index cf89a4c..84f4217 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -3322,6 +3322,25 @@ void cmake::DefineProperties(cmake *cm)
"at the beginning of native build system generation. "
"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
("IN_TRY_COMPILE", cmProperty::GLOBAL,
"Read-only property that is true during a try-compile configuration.",