summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2009-06-17 13:40:09 -0400
committerBrad King <brad.king@kitware.com>2009-06-17 13:40:09 -0400
commitc790b1fabbc7b160bd67e1654a34964fd897a36c (patch)
tree35af1a3c2f59d02c85f3fd1908b9fbde32b0e75c
parentf61f8e538383ee632aafc7ac74cd1d118288b310 (diff)
downloadcmake-c790b1fabbc7b160bd67e1654a34964fd897a36c.tar.gz
ENH: Create CMP0013 to disallow duplicate dirs
In CMake 2.6.3 and below we silently accepted duplicate build directories whose build files would then conflict. At first this was considured purely a bug that confused beginners but would not be used in a real project. In CMake 2.6.4 we explicitly made it an error. However, some real projects took advantage of this as a "feature" and got lucky that the subtle build errors it can cause did not occur. Therefore we need a policy to deal with the case more gracefully. See issue #9173.
-rw-r--r--Source/cmMakefile.cxx59
-rw-r--r--Source/cmMakefile.h2
-rw-r--r--Source/cmPolicies.cxx17
-rw-r--r--Source/cmPolicies.h1
4 files changed, 69 insertions, 10 deletions
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index fc572767fe..57904b4c56 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -1545,17 +1545,8 @@ void cmMakefile::AddSubDirectory(const char* srcPath, const char *binPath,
}
// Make sure the binary directory is unique.
- cmGlobalGenerator* gg = this->LocalGenerator->GetGlobalGenerator();
- if(!gg->BinaryDirectoryIsNew(binPath))
+ if(!this->EnforceUniqueDir(srcPath, binPath))
{
- cmOStringStream e;
- e << "The binary directory\n"
- << " " << binPath << "\n"
- << "is already used to build another source directory, so it cannot "
- << "be used to build source directory\n"
- << " " << srcPath << "\n"
- << "Specify a unique binary directory name.";
- this->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
@@ -3720,6 +3711,54 @@ bool cmMakefile::EnforceUniqueName(std::string const& name, std::string& msg,
}
//----------------------------------------------------------------------------
+bool cmMakefile::EnforceUniqueDir(const char* srcPath, const char* binPath)
+{
+ // Make sure the binary directory is unique.
+ cmGlobalGenerator* gg = this->LocalGenerator->GetGlobalGenerator();
+ if(gg->BinaryDirectoryIsNew(binPath))
+ {
+ return true;
+ }
+ cmOStringStream e;
+ switch (this->GetPolicyStatus(cmPolicies::CMP0013))
+ {
+ case cmPolicies::WARN:
+ // Print the warning.
+ e << this->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0013)
+ << "\n"
+ << "The binary directory\n"
+ << " " << binPath << "\n"
+ << "is already used to build a source directory. "
+ << "This command uses it to build source directory\n"
+ << " " << srcPath << "\n"
+ << "which can generate conflicting build files. "
+ << "CMake does not support this use case but it used "
+ << "to work accidentally and is being allowed for "
+ << "compatibility.";
+ this->IssueMessage(cmake::AUTHOR_WARNING, e.str());
+ case cmPolicies::OLD:
+ // OLD behavior does not warn.
+ return true;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ e << this->GetPolicies()->GetRequiredPolicyError(cmPolicies::CMP0013)
+ << "\n";
+ case cmPolicies::NEW:
+ // NEW behavior prints the error.
+ e << "The binary directory\n"
+ << " " << binPath << "\n"
+ << "is already used to build a source directory. "
+ << "It cannot be used to build source directory\n"
+ << " " << srcPath << "\n"
+ << "Specify a unique binary directory name.";
+ this->IssueMessage(cmake::FATAL_ERROR, e.str());
+ break;
+ }
+
+ return false;
+}
+
+//----------------------------------------------------------------------------
cmPolicies::PolicyStatus
cmMakefile::GetPolicyStatus(cmPolicies::PolicyID id)
{
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 5efe2d9489..7a235f9bb3 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -900,6 +900,8 @@ private:
bool ParseDefineFlag(std::string const& definition, bool remove);
+ bool EnforceUniqueDir(const char* srcPath, const char* binPath);
+
void ReadSources(std::ifstream& fin, bool t);
friend class cmMakeDepend; // make depend needs direct access
// to the Sources array
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index 5e80e2fad1..1f8bb89287 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -369,6 +369,23 @@ cmPolicies::cmPolicies()
"The NEW behavior for this policy is to treat strings like true as a "
"boolean constant.",
2,6,5, cmPolicies::WARN);
+
+ this->DefinePolicy(
+ CMP0013, "CMP0013",
+ "Duplicate binary directories are not allowed.",
+ "CMake 2.6.3 and below silently permitted add_subdirectory() calls "
+ "to create the same binary directory multiple times. "
+ "During build system generation files would be written and then "
+ "overwritten in the build tree and could lead to strange behavior. "
+ "CMake 2.6.4 and above explicitly detect duplicate binary directories. "
+ "CMake 2.6.4 always considers this case an error. "
+ "In CMake 2.6.5 and above this policy determines whether or not "
+ "the case is an error. "
+ "The OLD behavior for this policy is to allow duplicate binary "
+ "directories. "
+ "The NEW behavior for this policy is to disallow duplicate binary "
+ "directories with an error.",
+ 2,6,5, cmPolicies::WARN);
}
cmPolicies::~cmPolicies()
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 43b193411c..391b91c44c 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -53,6 +53,7 @@ public:
CMP0010, // Bad variable reference syntax is an error
CMP0011, // Strong policy scope for include and find_package
CMP0012, // Strong handling of boolean constants
+ CMP0013, // Duplicate binary directories not allowed
// Always the last entry. Useful mostly to avoid adding a comma
// the last policy when adding a new one.