diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 2f69c2541..22d4bf06d 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -717,6 +717,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( cmake cm; cm.SetHomeDirectory(""); cm.SetHomeOutputDirectory(""); + cm.GetCurrentSnapshot().SetDefaultDefinitions(); cm.AddCMakePaths(); cm.SetProgressCallback(cmCPackGeneratorProgress, this); cmGlobalGenerator gg(&cm); diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index f6447eceb..c08897fa4 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -199,6 +199,7 @@ int main (int argc, char const* const* argv) cmake cminst; cminst.SetHomeDirectory(""); cminst.SetHomeOutputDirectory(""); + cminst.GetCurrentSnapshot().SetDefaultDefinitions(); cminst.GetState()->RemoveUnscriptableCommands(); cmGlobalGenerator cmgg(&cminst); cmsys::auto_ptr globalMF( diff --git a/Source/CTest/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx index ca5d05a58..749a5beec 100644 --- a/Source/CTest/cmCTestLaunch.cxx +++ b/Source/CTest/cmCTestLaunch.cxx @@ -736,6 +736,7 @@ void cmCTestLaunch::LoadConfig() cmake cm; cm.SetHomeDirectory(""); cm.SetHomeOutputDirectory(""); + cm.GetCurrentSnapshot().SetDefaultDefinitions(); cmGlobalGenerator gg(&cm); cmsys::auto_ptr mf(new cmMakefile(&gg, cm.GetCurrentSnapshot())); std::string fname = this->LogDir; diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx index b9016af23..ee15271a0 100644 --- a/Source/CTest/cmCTestScriptHandler.cxx +++ b/Source/CTest/cmCTestScriptHandler.cxx @@ -314,6 +314,7 @@ void cmCTestScriptHandler::CreateCMake() this->CMake = new cmake; this->CMake->SetHomeDirectory(""); this->CMake->SetHomeOutputDirectory(""); + this->CMake->GetCurrentSnapshot().SetDefaultDefinitions(); this->CMake->AddCMakePaths(); this->GlobalGenerator = new cmGlobalGenerator(this->CMake); diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index 968a30732..fa3b41684 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -1590,6 +1590,7 @@ void cmCTestTestHandler::GetListOfTests() cmake cm; cm.SetHomeDirectory(""); cm.SetHomeOutputDirectory(""); + cm.GetCurrentSnapshot().SetDefaultDefinitions(); cmGlobalGenerator gg(&cm); cmsys::auto_ptr mf(new cmMakefile(&gg, cm.GetCurrentSnapshot())); mf->AddDefinition("CTEST_CONFIGURATION_TYPE", diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index 67eb042e0..f3e7121f7 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -517,6 +517,7 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command) cmake cm; cm.SetHomeDirectory(""); cm.SetHomeOutputDirectory(""); + cm.GetCurrentSnapshot().SetDefaultDefinitions(); cmGlobalGenerator gg(&cm); cmsys::auto_ptr mf(new cmMakefile(&gg, cm.GetCurrentSnapshot())); if ( !this->ReadCustomConfigurationFileTree(this->BinaryDir.c_str(), diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 218e702e5..41df27057 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -589,6 +589,7 @@ void cmGlobalUnixMakefileGenerator3 (this->CMakeInstance->GetHomeDirectory()); snapshot.GetDirectory().SetCurrentBinary (this->CMakeInstance->GetHomeOutputDirectory()); + snapshot.SetDefaultDefinitions(); mf = new cmMakefile(this, snapshot); } diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx index 2023697fe..b3cf91e02 100644 --- a/Source/cmGraphVizWriter.cxx +++ b/Source/cmGraphVizWriter.cxx @@ -67,6 +67,7 @@ void cmGraphVizWriter::ReadSettings(const char* settingsFileName, cmake cm; cm.SetHomeDirectory(""); cm.SetHomeOutputDirectory(""); + cm.GetCurrentSnapshot().SetDefaultDefinitions(); cmGlobalGenerator ggi(&cm); cmsys::auto_ptr mf( new cmMakefile(&ggi, cm.GetCurrentSnapshot())); diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 73d35226a..ce95b2c6c 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -50,14 +50,11 @@ cmMakefile::cmMakefile(cmGlobalGenerator* globalGenerator, { this->IsSourceFileTryCompile = false; - // Initialize these first since AddDefaultDefinitions calls AddDefinition this->WarnUnused = this->GetCMakeInstance()->GetWarnUnused(); this->CheckSystemVars = this->GetCMakeInstance()->GetCheckSystemVars(); this->SuppressWatches = false; - // Setup the default include file regular expression (match everything). - this->SetProperty("INCLUDE_REGULAR_EXPRESSION", "^.*$"); // Setup the default include complaint regular expression (match nothing). this->ComplainFileRegularExpression = "^$"; // Source and header file extensions that we can handle @@ -88,8 +85,6 @@ cmMakefile::cmMakefile(cmGlobalGenerator* globalGenerator, this->DefineFlags = " "; - this->AddDefaultDefinitions(); - this->cmDefineRegex.compile("#cmakedefine[ \t]+([A-Za-z_0-9]*)"); this->cmDefine01Regex.compile("#cmakedefine01[ \t]+([A-Za-z_0-9]*)"); this->cmAtVarRegex.compile("(@[A-Za-z_0-9/.+-]+@)"); @@ -119,36 +114,6 @@ cmMakefile::cmMakefile(cmGlobalGenerator* globalGenerator, this->AddSourceGroup("Resources", "\\.plist$"); this->AddSourceGroup("Object Files", "\\.(lo|o|obj)$"); #endif - - this->AddDefinition("CMAKE_SOURCE_DIR", - this->GetCMakeInstance()->GetHomeDirectory()); - this->AddDefinition("CMAKE_BINARY_DIR", - this->GetCMakeInstance()->GetHomeOutputDirectory()); - { - const char* dir = this->StateSnapshot.GetDirectory().GetCurrentSource(); - if (dir) - { - this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR", dir); - } - else - { - this->AddDefinition("CMAKE_CURRENT_SOURCE_DIR", - this->GetCMakeInstance()->GetHomeDirectory()); - } - } - { - const char* dir = this->StateSnapshot.GetDirectory().GetCurrentBinary(); - if (dir) - { - cmSystemTools::MakeDirectory(dir); - this->AddDefinition("CMAKE_CURRENT_BINARY_DIR", dir); - } - else - { - this->AddDefinition("CMAKE_CURRENT_BINARY_DIR", - this->GetCMakeInstance()->GetHomeOutputDirectory()); - } - } } cmMakefile::~cmMakefile() @@ -1682,6 +1647,7 @@ void cmMakefile::Configure() std::vector::iterator sdi = subdirs.begin(); for (; sdi != subdirs.end(); ++sdi) { + (*sdi)->StateSnapshot.InitializeFromParent_ForSubdirsCommand(); this->ConfigureSubDirectory(*sdi); } @@ -1761,6 +1727,8 @@ void cmMakefile::AddSubDirectory(const std::string& srcPath, newSnapshot.GetDirectory().SetCurrentSource(srcPath); newSnapshot.GetDirectory().SetCurrentBinary(binPath); + cmSystemTools::MakeDirectory(binPath.c_str()); + cmMakefile* subMf = new cmMakefile(this->GlobalGenerator, newSnapshot); this->GetGlobalGenerator()->AddMakefile(subMf); @@ -3152,58 +3120,6 @@ void cmMakefile::RemoveVariablesInString(std::string& source, } } -/** - * Add the default definitions to the makefile. These values must not - * be dependent on anything that isn't known when this cmMakefile instance - * is constructed. - */ -void cmMakefile::AddDefaultDefinitions() -{ -/* Up to CMake 2.4 here only WIN32, UNIX and APPLE were set. - With CMake must separate between target and host platform. In most cases - the tests for WIN32, UNIX and APPLE will be for the target system, so an - additional set of variables for the host system is required -> - CMAKE_HOST_WIN32, CMAKE_HOST_UNIX, CMAKE_HOST_APPLE. - WIN32, UNIX and APPLE are now set in the platform files in - Modules/Platforms/. - To keep cmake scripts (-P) and custom language and compiler modules - working, these variables are still also set here in this place, but they - will be reset in CMakeSystemSpecificInformation.cmake before the platform - files are executed. */ -#if defined(_WIN32) - this->AddDefinition("WIN32", "1"); - this->AddDefinition("CMAKE_HOST_WIN32", "1"); -#else - this->AddDefinition("UNIX", "1"); - this->AddDefinition("CMAKE_HOST_UNIX", "1"); -#endif -#if defined(__CYGWIN__) - if(cmSystemTools::IsOn(cmSystemTools::GetEnv("CMAKE_LEGACY_CYGWIN_WIN32"))) - { - this->AddDefinition("WIN32", "1"); - this->AddDefinition("CMAKE_HOST_WIN32", "1"); - } -#endif -#if defined(__APPLE__) - this->AddDefinition("APPLE", "1"); - this->AddDefinition("CMAKE_HOST_APPLE", "1"); -#endif - - char temp[1024]; - sprintf(temp, "%d", cmVersion::GetMinorVersion()); - this->AddDefinition("CMAKE_MINOR_VERSION", temp); - sprintf(temp, "%d", cmVersion::GetMajorVersion()); - this->AddDefinition("CMAKE_MAJOR_VERSION", temp); - sprintf(temp, "%d", cmVersion::GetPatchVersion()); - this->AddDefinition("CMAKE_PATCH_VERSION", temp); - sprintf(temp, "%d", cmVersion::GetTweakVersion()); - this->AddDefinition("CMAKE_TWEAK_VERSION", temp); - this->AddDefinition("CMAKE_VERSION", cmVersion::GetCMakeVersion()); - - this->AddDefinition("CMAKE_FILES_DIRECTORY", - cmake::GetCMakeFilesDirectory()); -} - //---------------------------------------------------------------------------- std::string cmMakefile::GetConfigurations(std::vector& configs, diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 0a8dcd53e..96d584962 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -867,7 +867,6 @@ private: friend class cmMakeDepend; // make depend needs direct access // to the Sources array - void AddDefaultDefinitions(); typedef std::vector FunctionBlockersType; FunctionBlockersType FunctionBlockers; std::vector FunctionBlockerBarriers; diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index 36b130570..fc690f83b 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -175,6 +175,7 @@ bool cmQtAutoGenerators::Run(const std::string& targetDirectory, cmake cm; cm.SetHomeOutputDirectory(targetDirectory); cm.SetHomeDirectory(targetDirectory); + cm.GetCurrentSnapshot().SetDefaultDefinitions(); cmGlobalGenerator gg(&cm); cmState::Snapshot snapshot = cm.GetCurrentSnapshot(); diff --git a/Source/cmState.cxx b/Source/cmState.cxx index 72c7330f9..825204c1e 100644 --- a/Source/cmState.cxx +++ b/Source/cmState.cxx @@ -12,6 +12,7 @@ #include "cmState.h" #include "cmake.h" +#include "cmVersion.h" #include "cmCacheManager.h" #include "cmCommand.h" #include "cmAlgorithms.h" @@ -306,11 +307,21 @@ cmState::Snapshot cmState::Reset() pos->PolicyScope = this->PolicyStack.Root(); assert(pos->Policies.IsValid()); assert(pos->PolicyRoot.IsValid()); + + { + std::string srcDir = + cmDefinitions::Get("CMAKE_SOURCE_DIR", pos->Vars, pos->Root); + std::string binDir = + cmDefinitions::Get("CMAKE_BINARY_DIR", pos->Vars, pos->Root); this->VarTree.Clear(); pos->Vars = this->VarTree.Extend(this->VarTree.Root()); pos->Parent = this->VarTree.Root(); pos->Root = this->VarTree.Root(); + pos->Vars->Set("CMAKE_SOURCE_DIR", srcDir.c_str()); + pos->Vars->Set("CMAKE_BINARY_DIR", binDir.c_str()); + } + this->DefineProperty ("RULE_LAUNCH_COMPILE", cmProperty::DIRECTORY, "", "", true); @@ -837,7 +848,9 @@ cmState::CreateBuildsystemDirectorySnapshot(Snapshot originSnapshot, cmState::Snapshot snapshot = cmState::Snapshot(this, pos); originSnapshot.Position->BuildSystemDirectory->Children.push_back(snapshot); + snapshot.SetDefaultDefinitions(); snapshot.InitializeFromParent(); + snapshot.SetDirectoryDefinitions(); return snapshot; } @@ -1009,6 +1022,8 @@ void cmState::Directory::SetCurrentSource(std::string const& dir) loc, this->DirectoryState->CurrentSourceDirectoryComponents); this->ComputeRelativePathTopSource(); + + this->Snapshot_.SetDefinition("CMAKE_CURRENT_SOURCE_DIR", loc.c_str()); } const char* cmState::Directory::GetCurrentBinary() const @@ -1027,6 +1042,8 @@ void cmState::Directory::SetCurrentBinary(std::string const& dir) loc, this->DirectoryState->CurrentBinaryDirectoryComponents); this->ComputeRelativePathTopBinary(); + + this->Snapshot_.SetDefinition("CMAKE_CURRENT_BINARY_DIR", loc.c_str()); } void cmState::Snapshot::SetListFile(const std::string& listfile) @@ -1318,6 +1335,70 @@ void InitializeContentFromParent(T& parentContent, contentEndPosition = thisContent.size(); } +void cmState::Snapshot::SetDefaultDefinitions() +{ + /* Up to CMake 2.4 here only WIN32, UNIX and APPLE were set. + With CMake must separate between target and host platform. In most cases + the tests for WIN32, UNIX and APPLE will be for the target system, so an + additional set of variables for the host system is required -> + CMAKE_HOST_WIN32, CMAKE_HOST_UNIX, CMAKE_HOST_APPLE. + WIN32, UNIX and APPLE are now set in the platform files in + Modules/Platforms/. + To keep cmake scripts (-P) and custom language and compiler modules + working, these variables are still also set here in this place, but they + will be reset in CMakeSystemSpecificInformation.cmake before the platform + files are executed. */ + #if defined(_WIN32) + this->SetDefinition("WIN32", "1"); + this->SetDefinition("CMAKE_HOST_WIN32", "1"); + #else + this->SetDefinition("UNIX", "1"); + this->SetDefinition("CMAKE_HOST_UNIX", "1"); + #endif + #if defined(__CYGWIN__) + if(cmSystemTools::IsOn(cmSystemTools::GetEnv("CMAKE_LEGACY_CYGWIN_WIN32"))) + { + this->SetDefinition("WIN32", "1"); + this->SetDefinition("CMAKE_HOST_WIN32", "1"); + } + #endif + #if defined(__APPLE__) + this->SetDefinition("APPLE", "1"); + this->SetDefinition("CMAKE_HOST_APPLE", "1"); + #endif + + char temp[1024]; + sprintf(temp, "%d", cmVersion::GetMinorVersion()); + this->SetDefinition("CMAKE_MINOR_VERSION", temp); + sprintf(temp, "%d", cmVersion::GetMajorVersion()); + this->SetDefinition("CMAKE_MAJOR_VERSION", temp); + sprintf(temp, "%d", cmVersion::GetPatchVersion()); + this->SetDefinition("CMAKE_PATCH_VERSION", temp); + sprintf(temp, "%d", cmVersion::GetTweakVersion()); + this->SetDefinition("CMAKE_TWEAK_VERSION", temp); + this->SetDefinition("CMAKE_VERSION", + cmVersion::GetCMakeVersion()); + + this->SetDefinition("CMAKE_FILES_DIRECTORY", + cmake::GetCMakeFilesDirectory()); + + // Setup the default include file regular expression (match everything). + this->Position->BuildSystemDirectory + ->Properties.SetProperty("INCLUDE_REGULAR_EXPRESSION", "^.*$"); +} + +void cmState::Snapshot::SetDirectoryDefinitions() +{ + this->SetDefinition("CMAKE_SOURCE_DIR", + this->State->GetSourceDirectory()); + this->SetDefinition("CMAKE_CURRENT_SOURCE_DIR", + this->State->GetSourceDirectory()); + this->SetDefinition("CMAKE_BINARY_DIR", + this->State->GetBinaryDirectory()); + this->SetDefinition("CMAKE_CURRENT_BINARY_DIR", + this->State->GetBinaryDirectory()); +} + void cmState::Snapshot::InitializeFromParent() { PositionType parent = this->Position->DirectoryParent; @@ -1366,6 +1447,20 @@ std::string cmState::Snapshot::GetProjectName() const return this->Position->BuildSystemDirectory->ProjectName; } +void cmState::Snapshot::InitializeFromParent_ForSubdirsCommand() +{ + std::string currentSrcDir = this->GetDefinition("CMAKE_CURRENT_SOURCE_DIR"); + std::string currentBinDir = this->GetDefinition("CMAKE_CURRENT_BINARY_DIR"); + this->InitializeFromParent(); + this->SetDefinition("CMAKE_SOURCE_DIR", + this->State->GetSourceDirectory()); + this->SetDefinition("CMAKE_BINARY_DIR", + this->State->GetBinaryDirectory()); + + this->SetDefinition("CMAKE_CURRENT_SOURCE_DIR", currentSrcDir.c_str()); + this->SetDefinition("CMAKE_CURRENT_BINARY_DIR", currentBinDir.c_str()); +} + cmState::Directory::Directory( cmLinkedTree::iterator iter, const cmState::Snapshot& snapshot) diff --git a/Source/cmState.h b/Source/cmState.h index 2f66f7f8e..f2c0c6fb0 100644 --- a/Source/cmState.h +++ b/Source/cmState.h @@ -90,12 +90,17 @@ public: void SetProjectName(std::string const& name); std::string GetProjectName() const; + void InitializeFromParent_ForSubdirsCommand(); + struct StrictWeakOrder { bool operator()(const cmState::Snapshot& lhs, const cmState::Snapshot& rhs) const; }; + void SetDirectoryDefinitions(); + void SetDefaultDefinitions(); + private: friend bool operator==(const cmState::Snapshot& lhs, const cmState::Snapshot& rhs); diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 6846f1b52..7d499de54 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -186,6 +186,7 @@ void cmake::CleanupCommandsAndMacros() { this->CurrentSnapshot = this->State->Reset(); this->State->RemoveUserDefinedCommands(); + this->CurrentSnapshot.SetDefaultDefinitions(); } // Parse the args @@ -378,6 +379,7 @@ void cmake::ReadListFile(const std::vector& args, (cmSystemTools::GetCurrentWorkingDirectory()); snapshot.GetDirectory().SetCurrentSource (cmSystemTools::GetCurrentWorkingDirectory()); + snapshot.SetDefaultDefinitions(); cmsys::auto_ptr mf(new cmMakefile(gg, snapshot)); if (this->GetWorkingMode() != NORMAL_MODE) { @@ -420,6 +422,7 @@ bool cmake::FindPackage(const std::vector& args) snapshot.GetDirectory().SetCurrentSource (cmSystemTools::GetCurrentWorkingDirectory()); // read in the list file to fill the cache + snapshot.SetDefaultDefinitions(); cmsys::auto_ptr mf(new cmMakefile(gg, snapshot)); cmsys::auto_ptr lg(gg->CreateLocalGenerator(mf.get())); @@ -980,6 +983,10 @@ cmGlobalGenerator* cmake::CreateGlobalGenerator(const std::string& gname) void cmake::SetHomeDirectory(const std::string& dir) { this->State->SetSourceDirectory(dir); + if (this->CurrentSnapshot.IsValid()) + { + this->CurrentSnapshot.SetDefinition("CMAKE_SOURCE_DIR", dir); + } } const char* cmake::GetHomeDirectory() const @@ -990,6 +997,10 @@ const char* cmake::GetHomeDirectory() const void cmake::SetHomeOutputDirectory(const std::string& dir) { this->State->SetBinaryDirectory(dir); + if (this->CurrentSnapshot.IsValid()) + { + this->CurrentSnapshot.SetDefinition("CMAKE_BINARY_DIR", dir); + } } const char* cmake::GetHomeOutputDirectory() const @@ -1920,6 +1931,7 @@ int cmake::CheckBuildSystem() cmake cm; cm.SetHomeDirectory(""); cm.SetHomeOutputDirectory(""); + cm.GetCurrentSnapshot().SetDefaultDefinitions(); cmGlobalGenerator gg(&cm); cmsys::auto_ptr mf(new cmMakefile(&gg, cm.GetCurrentSnapshot())); if(!mf->ReadListFile(this->CheckBuildSystemArgument.c_str()) || @@ -1950,6 +1962,7 @@ int cmake::CheckBuildSystem() ggd(this->CreateGlobalGenerator(genName)); if(ggd.get()) { + cm.GetCurrentSnapshot().SetDefaultDefinitions(); cmsys::auto_ptr mfd(new cmMakefile(ggd.get(), cm.GetCurrentSnapshot())); cmsys::auto_ptr lgd( diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx index ca4611148..be492ed31 100644 --- a/Source/cmcmd.cxx +++ b/Source/cmcmd.cxx @@ -765,6 +765,7 @@ int cmcmd::ExecuteCMakeCommand(std::vector& args) startOutDir = cmSystemTools::CollapseFullPath(startOutDir); cm.SetHomeDirectory(homeDir); cm.SetHomeOutputDirectory(homeOutDir); + cm.GetCurrentSnapshot().SetDefaultDefinitions(); if(cmGlobalGenerator* ggd = cm.CreateGlobalGenerator(gen)) { cm.SetGlobalGenerator(ggd); diff --git a/Tests/SubDir/CMakeLists.txt b/Tests/SubDir/CMakeLists.txt index 6822e6bd9..32aa93ffc 100644 --- a/Tests/SubDir/CMakeLists.txt +++ b/Tests/SubDir/CMakeLists.txt @@ -1,6 +1,10 @@ cmake_minimum_required (VERSION 2.6) project(SUBDIR) + subdirs(Executable EXCLUDE_FROM_ALL Examples) + +set(DEFINED_AFTER_SUBDIRS_COMMAND 42) + write_file(${SUBDIR_BINARY_DIR}/ShouldBeHere "This file should exist.") #WATCOM WMAKE does not support + in the name of a file! if(WATCOM) diff --git a/Tests/SubDir/Executable/CMakeLists.txt b/Tests/SubDir/Executable/CMakeLists.txt index 77e6751cd..fbe338ef4 100644 --- a/Tests/SubDir/Executable/CMakeLists.txt +++ b/Tests/SubDir/Executable/CMakeLists.txt @@ -1 +1,13 @@ add_executable(test test.cxx) + +if (NOT DEFINED_AFTER_SUBDIRS_COMMAND) + message(FATAL_ERROR "DEFINED_AFTER_SUBDIRS_COMMAND should be defined.") +endif() + +string(FIND "${CMAKE_CURRENT_BINARY_DIR}" "SubDir/Executable" location) +string(LENGTH "${CMAKE_CURRENT_BINARY_DIR}" dirLength) +math(EXPR suffixLength "${dirLength} - ${location}") + +if (NOT suffixLength EQUAL 17) + message(FATAL_ERROR "CMAKE_CURRENT_BINARY_DIR does not end with \"SubDir/Executable\"") +endif()