diff options
36 files changed, 429 insertions, 62 deletions
diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake index 1f28c50..32dd546 100644 --- a/Modules/Platform/Windows-MSVC.cmake +++ b/Modules/Platform/Windows-MSVC.cmake @@ -154,6 +154,11 @@ else() set(_FLAGS_CXX " /GR /GX") set(CMAKE_C_STANDARD_LIBRARIES_INIT "kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib") endif() + + if(MSVC_VERSION LESS 1310) + set(_FLAGS_C " /Zm1000${_FLAGS_C}") + set(_FLAGS_CXX " /Zm1000${_FLAGS_CXX}") + endif() endif() set(CMAKE_CXX_STANDARD_LIBRARIES_INIT "${CMAKE_C_STANDARD_LIBRARIES_INIT}") @@ -233,7 +238,7 @@ macro(__windows_compiler_msvc lang) set(CMAKE_${lang}_LINK_EXECUTABLE "${_CMAKE_VS_LINK_EXE}<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} ${CMAKE_START_TEMP_FILE} <FLAGS> /Fe<TARGET> /Fd<TARGET_PDB> <OBJECTS> /link /implib:<TARGET_IMPLIB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR> <CMAKE_${lang}_LINK_FLAGS> <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}") - set(CMAKE_${lang}_FLAGS_INIT "${_PLATFORM_DEFINES}${_PLATFORM_DEFINES_${lang}} /D_WINDOWS /W3 /Zm1000${_FLAGS_${lang}}") + set(CMAKE_${lang}_FLAGS_INIT "${_PLATFORM_DEFINES}${_PLATFORM_DEFINES_${lang}} /D_WINDOWS /W3${_FLAGS_${lang}}") set(CMAKE_${lang}_FLAGS_DEBUG_INIT "/D_DEBUG /MDd /Zi /Ob0 /Od ${_RTC1}") set(CMAKE_${lang}_FLAGS_RELEASE_INIT "/MD /O2 /Ob2 /D NDEBUG") set(CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT "/MD /Zi /O2 /Ob1 /D NDEBUG") diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index a59c501..300abd7 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -2,5 +2,5 @@ set(CMake_VERSION_MAJOR 2) set(CMake_VERSION_MINOR 8) set(CMake_VERSION_PATCH 10) -set(CMake_VERSION_TWEAK 20121117) +set(CMake_VERSION_TWEAK 20121120) #set(CMake_VERSION_RC 1) diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index ee7a9b3..154e629 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -828,6 +828,7 @@ void cmGlobalGenerator::Configure() this->LocalGenerators.clear(); this->TargetDependencies.clear(); this->TotalTargets.clear(); + this->ImportedTargets.clear(); this->LocalGeneratorToTargetMap.clear(); this->ProjectMap.clear(); this->RuleHashes.clear(); diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx index 67aa8b1..db584b8 100644 --- a/Source/cmGlobalVisualStudio71Generator.cxx +++ b/Source/cmGlobalVisualStudio71Generator.cxx @@ -128,6 +128,9 @@ void cmGlobalVisualStudio71Generator fout << "\tEndGlobalSection\n"; } + // Write out global sections + this->WriteSLNGlobalSections(fout, root); + // Write the footer for the SLN file this->WriteSLNFooter(fout); } @@ -273,9 +276,10 @@ void cmGlobalVisualStudio71Generator // Write a dsp file into the SLN file, Note, that dependencies from // executables to the libraries it uses are also done here void cmGlobalVisualStudio71Generator -::WriteProjectConfigurations(std::ostream& fout, const char* name, - bool partOfDefaultBuild, - const char* platformMapping) +::WriteProjectConfigurations( + std::ostream& fout, const char* name, + const std::set<std::string>& configsPartOfDefaultBuild, + const char* platformMapping) { std::string guid = this->GetGUID(name); for(std::vector<std::string>::iterator i = this->Configurations.begin(); @@ -284,7 +288,9 @@ void cmGlobalVisualStudio71Generator fout << "\t\t{" << guid << "}." << *i << ".ActiveCfg = " << *i << "|" << (platformMapping ? platformMapping : "Win32") << std::endl; - if(partOfDefaultBuild) + std::set<std::string>::const_iterator + ci = configsPartOfDefaultBuild.find(*i); + if(!(ci == configsPartOfDefaultBuild.end())) { fout << "\t\t{" << guid << "}." << *i << ".Build.0 = " << *i << "|" @@ -294,17 +300,6 @@ void cmGlobalVisualStudio71Generator } //---------------------------------------------------------------------------- -// Standard end of dsw file -void cmGlobalVisualStudio71Generator::WriteSLNFooter(std::ostream& fout) -{ - fout << "\tGlobalSection(ExtensibilityGlobals) = postSolution\n" - << "\tEndGlobalSection\n" - << "\tGlobalSection(ExtensibilityAddIns) = postSolution\n" - << "\tEndGlobalSection\n" - << "EndGlobal\n"; -} - -//---------------------------------------------------------------------------- // ouput standard header for dsw file void cmGlobalVisualStudio71Generator::WriteSLNHeader(std::ostream& fout) { diff --git a/Source/cmGlobalVisualStudio71Generator.h b/Source/cmGlobalVisualStudio71Generator.h index dfbbe43..e9cab06 100644 --- a/Source/cmGlobalVisualStudio71Generator.h +++ b/Source/cmGlobalVisualStudio71Generator.h @@ -62,16 +62,15 @@ protected: const char* name, const char* path, cmTarget &t); virtual void WriteProjectDepends(std::ostream& fout, const char* name, const char* path, cmTarget &t); - virtual void WriteProjectConfigurations(std::ostream& fout, - const char* name, - bool partOfDefaultBuild, - const char* platformMapping = NULL); + virtual void WriteProjectConfigurations( + std::ostream& fout, const char* name, + const std::set<std::string>& configsPartOfDefaultBuild, + const char* platformMapping = NULL); virtual void WriteExternalProject(std::ostream& fout, const char* name, const char* path, const char* typeGuid, const std::set<cmStdString>& depends); - virtual void WriteSLNFooter(std::ostream& fout); virtual void WriteSLNHeader(std::ostream& fout); std::string ProjectConfigurationSectionName; diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index d02dca8..b82a4f4 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -10,6 +10,7 @@ See the License for more information. ============================================================================*/ #include "windows.h" // this must be first to define GetCurrentDirectory +#include <assert.h> #include "cmGlobalVisualStudio7Generator.h" #include "cmGeneratedFileStream.h" #include "cmLocalVisualStudio7Generator.h" @@ -243,20 +244,23 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations( const char* expath = target->GetProperty("EXTERNAL_MSPROJECT"); if(expath) { + std::set<std::string> allConfigurations(this->Configurations.begin(), + this->Configurations.end()); this->WriteProjectConfigurations( fout, target->GetName(), - true, target->GetProperty("VS_PLATFORM_MAPPING")); + allConfigurations, target->GetProperty("VS_PLATFORM_MAPPING")); } else { - bool partOfDefaultBuild = this->IsPartOfDefaultBuild( - root->GetMakefile()->GetProjectName(), target); + const std::set<std::string>& configsPartOfDefaultBuild = + this->IsPartOfDefaultBuild(root->GetMakefile()->GetProjectName(), + target); const char *vcprojName = target->GetProperty("GENERATOR_FILE_NAME"); if (vcprojName) { this->WriteProjectConfigurations(fout, vcprojName, - partOfDefaultBuild); + configsPartOfDefaultBuild); } } } @@ -431,6 +435,9 @@ void cmGlobalVisualStudio7Generator this->WriteTargetConfigurations(fout, root, orderedProjectTargets); fout << "\tEndGlobalSection\n"; + // Write out global sections + this->WriteSLNGlobalSections(fout, root); + // Write the footer for the SLN file this->WriteSLNFooter(fout); } @@ -579,9 +586,10 @@ cmGlobalVisualStudio7Generator // Write a dsp file into the SLN file, Note, that dependencies from // executables to the libraries it uses are also done here void cmGlobalVisualStudio7Generator -::WriteProjectConfigurations(std::ostream& fout, const char* name, - bool partOfDefaultBuild, - const char* platformMapping) +::WriteProjectConfigurations( + std::ostream& fout, const char* name, + const std::set<std::string>& configsPartOfDefaultBuild, + const char* platformMapping) { std::string guid = this->GetGUID(name); for(std::vector<std::string>::iterator i = this->Configurations.begin(); @@ -590,7 +598,9 @@ void cmGlobalVisualStudio7Generator fout << "\t\t{" << guid << "}." << *i << ".ActiveCfg = " << *i << "|" << (platformMapping ? platformMapping : "Win32") << "\n"; - if(partOfDefaultBuild) + std::set<std::string>::const_iterator + ci = configsPartOfDefaultBuild.find(*i); + if(!(ci == configsPartOfDefaultBuild.end())) { fout << "\t\t{" << guid << "}." << *i << ".Build.0 = " << *i << "|" @@ -624,14 +634,73 @@ void cmGlobalVisualStudio7Generator::WriteExternalProject(std::ostream& fout, +void cmGlobalVisualStudio7Generator +::WriteSLNGlobalSections(std::ostream& fout, + cmLocalGenerator* root) +{ + bool extensibilityGlobalsOverridden = false; + bool extensibilityAddInsOverridden = false; + const cmPropertyMap& props = root->GetMakefile()->GetProperties(); + for(cmPropertyMap::const_iterator itProp = props.begin(); + itProp != props.end(); ++itProp) + { + if(itProp->first.find("VS_GLOBAL_SECTION_") == 0) + { + std::string sectionType; + std::string name = itProp->first.substr(18); + if(name.find("PRE_") == 0) + { + name = name.substr(4); + sectionType = "preSolution"; + } + else if(name.find("POST_") == 0) + { + name = name.substr(5); + sectionType = "postSolution"; + } + else + continue; + if(!name.empty()) + { + if(name == "ExtensibilityGlobals" && sectionType == "postSolution") + extensibilityGlobalsOverridden = true; + else if(name == "ExtensibilityAddIns" && sectionType == "postSolution") + extensibilityAddInsOverridden = true; + fout << "\tGlobalSection(" << name << ") = " << sectionType << "\n"; + std::vector<std::string> keyValuePairs; + cmSystemTools::ExpandListArgument(itProp->second.GetValue(), + keyValuePairs); + for(std::vector<std::string>::const_iterator itPair = + keyValuePairs.begin(); itPair != keyValuePairs.end(); ++itPair) + { + const std::string::size_type posEqual = itPair->find('='); + if(posEqual != std::string::npos) + { + const std::string key = + cmSystemTools::TrimWhitespace(itPair->substr(0, posEqual)); + const std::string value = + cmSystemTools::TrimWhitespace(itPair->substr(posEqual + 1)); + fout << "\t\t" << key << " = " << value << "\n"; + } + } + fout << "\tEndGlobalSection\n"; + } + } + } + if(!extensibilityGlobalsOverridden) + fout << "\tGlobalSection(ExtensibilityGlobals) = postSolution\n" + << "\tEndGlobalSection\n"; + if(!extensibilityAddInsOverridden) + fout << "\tGlobalSection(ExtensibilityAddIns) = postSolution\n" + << "\tEndGlobalSection\n"; +} + + + // Standard end of dsw file void cmGlobalVisualStudio7Generator::WriteSLNFooter(std::ostream& fout) { - fout << "\tGlobalSection(ExtensibilityGlobals) = postSolution\n" - << "\tEndGlobalSection\n" - << "\tGlobalSection(ExtensibilityAddIns) = postSolution\n" - << "\tEndGlobalSection\n" - << "EndGlobal\n"; + fout << "EndGlobal\n"; } @@ -763,26 +832,34 @@ cmGlobalVisualStudio7Generator } } -bool cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(const char* project, - cmTarget* target) +std::set<std::string> +cmGlobalVisualStudio7Generator::IsPartOfDefaultBuild(const char* project, + cmTarget* target) { - if(target->GetPropertyAsBool("EXCLUDE_FROM_DEFAULT_BUILD")) - { - return false; - } + std::set<std::string> activeConfigs; // if it is a utilitiy target then only make it part of the // default build if another target depends on it int type = target->GetType(); if (type == cmTarget::GLOBAL_TARGET) { - return false; + return activeConfigs; } - if(type == cmTarget::UTILITY) + if(type == cmTarget::UTILITY && !this->IsDependedOn(project, target)) { - return this->IsDependedOn(project, target); + return activeConfigs; + } + // inspect EXCLUDE_FROM_DEFAULT_BUILD[_<CONFIG>] properties + for(std::vector<std::string>::iterator i = this->Configurations.begin(); + i != this->Configurations.end(); ++i) + { + const char* propertyValue = + target->GetFeature("EXCLUDE_FROM_DEFAULT_BUILD", i->c_str()); + if(cmSystemTools::IsOff(propertyValue)) + { + activeConfigs.insert(*i); + } } - // default is to be part of the build - return true; + return activeConfigs; } //---------------------------------------------------------------------------- diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h index b59c0b1..9eb9687 100644 --- a/Source/cmGlobalVisualStudio7Generator.h +++ b/Source/cmGlobalVisualStudio7Generator.h @@ -107,10 +107,12 @@ protected: const char* name, const char* path, cmTarget &t); virtual void WriteProjectDepends(std::ostream& fout, const char* name, const char* path, cmTarget &t); - virtual void WriteProjectConfigurations(std::ostream& fout, - const char* name, - bool partOfDefaultBuild, - const char* platformMapping = NULL); + virtual void WriteProjectConfigurations( + std::ostream& fout, const char* name, + const std::set<std::string>& configsPartOfDefaultBuild, + const char* platformMapping = NULL); + virtual void WriteSLNGlobalSections(std::ostream& fout, + cmLocalGenerator* root); virtual void WriteSLNFooter(std::ostream& fout); virtual void WriteSLNHeader(std::ostream& fout); virtual std::string WriteUtilityDepend(cmTarget* target); @@ -138,8 +140,8 @@ protected: std::string ConvertToSolutionPath(const char* path); - bool IsPartOfDefaultBuild(const char* project, - cmTarget* target); + std::set<std::string> IsPartOfDefaultBuild(const char* project, + cmTarget* target); std::vector<std::string> Configurations; std::map<cmStdString, cmStdString> GUIDMap; diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index 7aad9b2..855727b 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -320,9 +320,10 @@ cmGlobalVisualStudio8Generator //---------------------------------------------------------------------------- void cmGlobalVisualStudio8Generator -::WriteProjectConfigurations(std::ostream& fout, const char* name, - bool partOfDefaultBuild, - const char* platformMapping) +::WriteProjectConfigurations( + std::ostream& fout, const char* name, + const std::set<std::string>& configsPartOfDefaultBuild, + const char* platformMapping) { std::string guid = this->GetGUID(name); for(std::vector<std::string>::iterator i = this->Configurations.begin(); @@ -332,7 +333,9 @@ cmGlobalVisualStudio8Generator << "|" << this->GetPlatformName() << ".ActiveCfg = " << *i << "|" << (platformMapping ? platformMapping : this->GetPlatformName()) << "\n"; - if(partOfDefaultBuild) + std::set<std::string>::const_iterator + ci = configsPartOfDefaultBuild.find(*i); + if(!(ci == configsPartOfDefaultBuild.end())) { fout << "\t\t{" << guid << "}." << *i << "|" << this->GetPlatformName() << ".Build.0 = " << *i << "|" diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h index 7b8f254..f68bb9e 100644 --- a/Source/cmGlobalVisualStudio8Generator.h +++ b/Source/cmGlobalVisualStudio8Generator.h @@ -72,10 +72,10 @@ protected: static cmIDEFlagTable const* GetExtraFlagTableVS8(); virtual void WriteSLNHeader(std::ostream& fout); virtual void WriteSolutionConfigurations(std::ostream& fout); - virtual void WriteProjectConfigurations(std::ostream& fout, - const char* name, - bool partOfDefaultBuild, - const char* platformMapping = NULL); + virtual void WriteProjectConfigurations( + std::ostream& fout, const char* name, + const std::set<std::string>& configsPartOfDefaultBuild, + const char* platformMapping = NULL); virtual bool ComputeTargetDepends(); virtual void WriteProjectDepends(std::ostream& fout, const char* name, const char* path, cmTarget &t); diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index f067da4..8498d72 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -3937,6 +3937,46 @@ void cmMakefile::DefineProperties(cmake *cm) "See the global property of the same name for details. " "This overrides the global property for a directory.", true); + + cm->DefineProperty + ("VS_GLOBAL_SECTION_PRE_<section>", cmProperty::DIRECTORY, + "Specify a preSolution global section in Visual Studio.", + "Setting a property like this generates an entry of the following form " + "in the solution file:\n" + " GlobalSection(<section>) = preSolution\n" + " <contents based on property value>\n" + " EndGlobalSection\n" + "The property must be set to a semicolon-separated list of key=value " + "pairs. Each such pair will be transformed into an entry in the solution " + "global section. Whitespace around key and value is ignored. List " + "elements which do not contain an equal sign are skipped." + "\n" + "This property only works for Visual Studio 7 and above; it is ignored " + "on other generators. The property only applies when set on a directory " + "whose CMakeLists.txt conatins a project() command."); + cm->DefineProperty + ("VS_GLOBAL_SECTION_POST_<section>", cmProperty::DIRECTORY, + "Specify a postSolution global section in Visual Studio.", + "Setting a property like this generates an entry of the following form " + "in the solution file:\n" + " GlobalSection(<section>) = postSolution\n" + " <contents based on property value>\n" + " EndGlobalSection\n" + "The property must be set to a semicolon-separated list of key=value " + "pairs. Each such pair will be transformed into an entry in the solution " + "global section. Whitespace around key and value is ignored. List " + "elements which do not contain an equal sign are skipped." + "\n" + "This property only works for Visual Studio 7 and above; it is ignored " + "on other generators. The property only applies when set on a directory " + "whose CMakeLists.txt conatins a project() command." + "\n" + "Note that CMake generates postSolution sections ExtensibilityGlobals " + "and ExtensibilityAddIns by default. If you set the corresponding " + "property, it will override the default section. For example, setting " + "VS_GLOBAL_SECTION_POST_ExtensibilityGlobals will override the default " + "contents of the ExtensibilityGlobals section, while keeping " + "ExtensibilityAddIns on its default."); } //---------------------------------------------------------------------------- diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index 942c7ab..9423208 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -85,6 +85,18 @@ static std::string extractSubDir(const std::string& absPath, } +static void copyTargetProperty(cmTarget* destinationTarget, + cmTarget* sourceTarget, + const char* propertyName) +{ + const char* propertyValue = sourceTarget->GetProperty(propertyName); + if (propertyValue) + { + destinationTarget->SetProperty(propertyName, propertyValue); + } +} + + cmQtAutomoc::cmQtAutomoc() :Verbose(cmsys::SystemTools::GetEnv("VERBOSE") != 0) ,ColorOutput(true) @@ -152,9 +164,13 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) std::string automocComment = "Automoc for target "; automocComment += targetName; - makefile->AddUtilityCommand(automocTargetName.c_str(), true, + cmTarget* automocTarget = makefile->AddUtilityCommand( + automocTargetName.c_str(), true, workingDirectory.c_str(), depends, commandLines, false, automocComment.c_str()); + // inherit FOLDER property from target (#13688) + copyTargetProperty(automocTarget, target, "FOLDER"); + target->AddUtility(automocTargetName.c_str()); // configure a file to get all information to automoc at buildtime: diff --git a/Source/cmSetTargetPropertiesCommand.h b/Source/cmSetTargetPropertiesCommand.h index 65c89fa..9dd7848 100644 --- a/Source/cmSetTargetPropertiesCommand.h +++ b/Source/cmSetTargetPropertiesCommand.h @@ -156,7 +156,9 @@ public: "\n" "The EXCLUDE_FROM_DEFAULT_BUILD property is used by the visual " "studio generators. If it is set to 1 the target will not be " - "part of the default build when you select \"Build Solution\"." + "part of the default build when you select \"Build Solution\". " + "This can also be set on a per-configuration basis using " + "EXCLUDE_FROM_DEFAULT_BUILD_<CONFIG>." ; } diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index a81fa3e..7c62ea8 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -266,6 +266,21 @@ void cmTarget::DefineProperties(cmake *cm) "bundle."); cm->DefineProperty + ("EXCLUDE_FROM_DEFAULT_BUILD", cmProperty::TARGET, + "Exclude target from \"Build Solution\".", + "This property is only used by Visual Studio generators 7 and above. " + "When set to TRUE, the target will not be built when you press " + "\"Build Solution\"."); + + cm->DefineProperty + ("EXCLUDE_FROM_DEFAULT_BUILD_<CONFIG>", cmProperty::TARGET, + "Per-configuration version of target exclusion from \"Build Solution\". ", + "This is the configuration-specific version of " + "EXCLUDE_FROM_DEFAULT_BUILD. If the generic EXCLUDE_FROM_DEFAULT_BUILD " + "is also set on a target, EXCLUDE_FROM_DEFAULT_BUILD_<CONFIG> takes " + "precedence in configurations for which it has a value."); + + cm->DefineProperty ("FRAMEWORK", cmProperty::TARGET, "This target is a framework on the Mac.", "If a shared library target has this property set to true it will " diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 03a538f..f2a198c 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1442,6 +1442,35 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} --test-command VSMidl) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSMidl") + + if(NOT MSVC60 AND NOT CMAKE_TEST_MAKEPROGRAM MATCHES "[mM][sS][bB][uU][iI][lL][dD]\\.[eE][xX][eE]") + # The test (and tested property) works with .sln files, so it's skipped when: + # * Using VS6, which doesn't use .sln files + # * cmake --build is set up to use MSBuild, since the MSBuild invocation does not use the .sln file + set(_last_test "") + foreach(config ${CMAKE_CONFIGURATION_TYPES}) + add_test(NAME VSExcludeFromDefaultBuild-${config} COMMAND ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/VSExcludeFromDefaultBuild" + "${CMake_BINARY_DIR}/Tests/VSExcludeFromDefaultBuild" + --build-config ${config} + --build-two-config + --build-generator ${CMAKE_TEST_GENERATOR} + --build-project VSExcludeFromDefaultBuild + --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} + --test-command ${CMAKE_COMMAND} + -D "activeConfig=${config}" + -D "allConfigs=${CMAKE_CONFIGURATION_TYPES}" + -D "dir=${CMake_BINARY_DIR}/Tests/VSExcludeFromDefaultBuild" + -P "${CMake_SOURCE_DIR}/Tests/VSExcludeFromDefaultBuild/ResultTest.cmake") + if(_last_test) + set_property(TEST VSExcludeFromDefaultBuild-${config} PROPERTY DEPENDS ${_last_test}) + endif() + set(_last_test "VSExcludeFromDefaultBuild-${config}") + endforeach() + unset(_last_test) + list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSExcludeFromDefaultBuild") + endif() endif() if (APPLE) diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 360ad78..722d9c3 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -59,4 +59,5 @@ add_RunCMake_test(load_command) if("${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio [^6]") add_RunCMake_test(include_external_msproject) + add_RunCMake_test(SolutionGlobalSections) endif() diff --git a/Tests/RunCMake/SolutionGlobalSections/CMakeLists.txt b/Tests/RunCMake/SolutionGlobalSections/CMakeLists.txt new file mode 100644 index 0000000..e8db6b0 --- /dev/null +++ b/Tests/RunCMake/SolutionGlobalSections/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 2.8) +project(${RunCMake_TEST} NONE) +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/SolutionGlobalSections/MorePost-check.cmake b/Tests/RunCMake/SolutionGlobalSections/MorePost-check.cmake new file mode 100644 index 0000000..0f7e370 --- /dev/null +++ b/Tests/RunCMake/SolutionGlobalSections/MorePost-check.cmake @@ -0,0 +1,5 @@ +parseGlobalSections(pre post MorePost) +testGlobalSection(post TestSec2 Key1=Value1 "Key2=Value with spaces") +testGlobalSection(post TestSec4 Key6=Value1 "Key7=Value with spaces" Key8=ValueWithoutSpaces) +testGlobalSection(post ExtensibilityGlobals) +testGlobalSection(post ExtensibilityAddIns) diff --git a/Tests/RunCMake/SolutionGlobalSections/MorePost.cmake b/Tests/RunCMake/SolutionGlobalSections/MorePost.cmake new file mode 100644 index 0000000..2eb3f60 --- /dev/null +++ b/Tests/RunCMake/SolutionGlobalSections/MorePost.cmake @@ -0,0 +1,2 @@ +set_property(DIRECTORY PROPERTY VS_GLOBAL_SECTION_POST_TestSec2 Key1=Value1 "Key2=Value with spaces") +set_property(DIRECTORY PROPERTY VS_GLOBAL_SECTION_POST_TestSec4 Key6=Value1 "Key7=Value with spaces" "Key8 =ValueWithoutSpaces") diff --git a/Tests/RunCMake/SolutionGlobalSections/MorePre-check.cmake b/Tests/RunCMake/SolutionGlobalSections/MorePre-check.cmake new file mode 100644 index 0000000..45e7419 --- /dev/null +++ b/Tests/RunCMake/SolutionGlobalSections/MorePre-check.cmake @@ -0,0 +1,5 @@ +parseGlobalSections(pre post MorePre) +testGlobalSection(pre TestSec1 Key1=Value1 "Key2=Value with spaces") +testGlobalSection(pre TestSec3 Key3=Value1 "Key4=Value with spaces" Key5=ValueWithoutSpaces) +testGlobalSection(post ExtensibilityGlobals) +testGlobalSection(post ExtensibilityAddIns) diff --git a/Tests/RunCMake/SolutionGlobalSections/MorePre.cmake b/Tests/RunCMake/SolutionGlobalSections/MorePre.cmake new file mode 100644 index 0000000..07f4eb8 --- /dev/null +++ b/Tests/RunCMake/SolutionGlobalSections/MorePre.cmake @@ -0,0 +1,2 @@ +set_property(DIRECTORY PROPERTY VS_GLOBAL_SECTION_PRE_TestSec1 Key1=Value1 "Key2=Value with spaces") +set_property(DIRECTORY PROPERTY VS_GLOBAL_SECTION_PRE_TestSec3 Key3=Value1 "Key4=Value with spaces" "Key5 = ValueWithoutSpaces") diff --git a/Tests/RunCMake/SolutionGlobalSections/OnePost-check.cmake b/Tests/RunCMake/SolutionGlobalSections/OnePost-check.cmake new file mode 100644 index 0000000..6af5156 --- /dev/null +++ b/Tests/RunCMake/SolutionGlobalSections/OnePost-check.cmake @@ -0,0 +1,4 @@ +parseGlobalSections(pre post OnePost) +testGlobalSection(post TestSec2 Key1=Value1 "Key2=Value with spaces") +testGlobalSection(post ExtensibilityGlobals) +testGlobalSection(post ExtensibilityAddIns) diff --git a/Tests/RunCMake/SolutionGlobalSections/OnePost.cmake b/Tests/RunCMake/SolutionGlobalSections/OnePost.cmake new file mode 100644 index 0000000..2295cfb --- /dev/null +++ b/Tests/RunCMake/SolutionGlobalSections/OnePost.cmake @@ -0,0 +1 @@ +set_property(DIRECTORY PROPERTY VS_GLOBAL_SECTION_POST_TestSec2 Key1=Value1 "Key2=Value with spaces") diff --git a/Tests/RunCMake/SolutionGlobalSections/OnePre-check.cmake b/Tests/RunCMake/SolutionGlobalSections/OnePre-check.cmake new file mode 100644 index 0000000..70b18b2 --- /dev/null +++ b/Tests/RunCMake/SolutionGlobalSections/OnePre-check.cmake @@ -0,0 +1,4 @@ +parseGlobalSections(pre post OnePre) +testGlobalSection(pre TestSec1 Key1=Value1 "Key2=Value with spaces") +testGlobalSection(post ExtensibilityGlobals) +testGlobalSection(post ExtensibilityAddIns) diff --git a/Tests/RunCMake/SolutionGlobalSections/OnePre.cmake b/Tests/RunCMake/SolutionGlobalSections/OnePre.cmake new file mode 100644 index 0000000..1499b47 --- /dev/null +++ b/Tests/RunCMake/SolutionGlobalSections/OnePre.cmake @@ -0,0 +1 @@ +set_property(DIRECTORY PROPERTY VS_GLOBAL_SECTION_PRE_TestSec1 Key1=Value1 "Key2=Value with spaces") diff --git a/Tests/RunCMake/SolutionGlobalSections/Override1-check.cmake b/Tests/RunCMake/SolutionGlobalSections/Override1-check.cmake new file mode 100644 index 0000000..a19e2e1 --- /dev/null +++ b/Tests/RunCMake/SolutionGlobalSections/Override1-check.cmake @@ -0,0 +1,4 @@ +parseGlobalSections(pre post Override1) +testGlobalSection(post TestSec Key2=Value2 Key3=Value3) +testGlobalSection(post ExtensibilityGlobals Key1=Value1) +testGlobalSection(post ExtensibilityAddIns) diff --git a/Tests/RunCMake/SolutionGlobalSections/Override1.cmake b/Tests/RunCMake/SolutionGlobalSections/Override1.cmake new file mode 100644 index 0000000..a726c9f --- /dev/null +++ b/Tests/RunCMake/SolutionGlobalSections/Override1.cmake @@ -0,0 +1,2 @@ +set_property(DIRECTORY PROPERTY VS_GLOBAL_SECTION_POST_ExtensibilityGlobals Key1=Value1) +set_property(DIRECTORY PROPERTY VS_GLOBAL_SECTION_POST_TestSec Key2=Value2 Key3=Value3) diff --git a/Tests/RunCMake/SolutionGlobalSections/Override2-check.cmake b/Tests/RunCMake/SolutionGlobalSections/Override2-check.cmake new file mode 100644 index 0000000..d9656e1 --- /dev/null +++ b/Tests/RunCMake/SolutionGlobalSections/Override2-check.cmake @@ -0,0 +1,4 @@ +parseGlobalSections(pre post Override2) +testGlobalSection(pre TestSec Key2=Value2 Key3=Value3) +testGlobalSection(post ExtensibilityGlobals) +testGlobalSection(post ExtensibilityAddIns Key1=Value1) diff --git a/Tests/RunCMake/SolutionGlobalSections/Override2.cmake b/Tests/RunCMake/SolutionGlobalSections/Override2.cmake new file mode 100644 index 0000000..0ce43cc --- /dev/null +++ b/Tests/RunCMake/SolutionGlobalSections/Override2.cmake @@ -0,0 +1,2 @@ +set_property(DIRECTORY PROPERTY VS_GLOBAL_SECTION_POST_ExtensibilityAddIns Key1=Value1) +set_property(DIRECTORY PROPERTY VS_GLOBAL_SECTION_PRE_TestSec Key2=Value2 Key3=Value3) diff --git a/Tests/RunCMake/SolutionGlobalSections/PrePost-check.cmake b/Tests/RunCMake/SolutionGlobalSections/PrePost-check.cmake new file mode 100644 index 0000000..322a689 --- /dev/null +++ b/Tests/RunCMake/SolutionGlobalSections/PrePost-check.cmake @@ -0,0 +1,6 @@ +parseGlobalSections(pre post PrePost) +testGlobalSection(post Postsec Key1=Value2) +testGlobalSection(pre Presec Key1=Value1 "Key2=Value with some spaces") +testGlobalSection(post Emptysec) +testGlobalSection(post ExtensibilityGlobals) +testGlobalSection(post ExtensibilityAddIns) diff --git a/Tests/RunCMake/SolutionGlobalSections/PrePost.cmake b/Tests/RunCMake/SolutionGlobalSections/PrePost.cmake new file mode 100644 index 0000000..976c341 --- /dev/null +++ b/Tests/RunCMake/SolutionGlobalSections/PrePost.cmake @@ -0,0 +1,4 @@ +set_directory_properties(PROPERTIES + VS_GLOBAL_SECTION_POST_Postsec Key1=Value2 + VS_GLOBAL_SECTION_PRE_Presec "Key1=Value1;Key2= Value with some spaces" + VS_GLOBAL_SECTION_POST_Emptysec "") diff --git a/Tests/RunCMake/SolutionGlobalSections/RunCMakeTest.cmake b/Tests/RunCMake/SolutionGlobalSections/RunCMakeTest.cmake new file mode 100644 index 0000000..6ae158d --- /dev/null +++ b/Tests/RunCMake/SolutionGlobalSections/RunCMakeTest.cmake @@ -0,0 +1,10 @@ +include(RunCMake) +include(${CMAKE_CURRENT_LIST_DIR}/solution_parsing.cmake) + +run_cmake(OnePre) +run_cmake(OnePost) +run_cmake(MorePre) +run_cmake(MorePost) +run_cmake(PrePost) +run_cmake(Override1) +run_cmake(Override2) diff --git a/Tests/RunCMake/SolutionGlobalSections/solution_parsing.cmake b/Tests/RunCMake/SolutionGlobalSections/solution_parsing.cmake new file mode 100644 index 0000000..dd158ef --- /dev/null +++ b/Tests/RunCMake/SolutionGlobalSections/solution_parsing.cmake @@ -0,0 +1,60 @@ +macro(error text) + set(RunCMake_TEST_FAILED "${text}") + return() +endmacro() + + +macro(parseGlobalSections arg_out_pre arg_out_post testName) + set(out_pre ${arg_out_pre}) + set(out_post ${arg_out_post}) + set(sln "${RunCMake_TEST_BINARY_DIR}/${testName}.sln") + if(NOT EXISTS "${sln}") + error("Expected solution file ${sln} does not exist") + endif() + file(STRINGS "${sln}" lines) + set(sectionLines "") + set(store FALSE) + foreach(line IN LISTS lines) + if(line MATCHES "^\t*Global\n?$") + set(store TRUE) + elseif(line MATCHES "^\t*EndGlobal\n?$") + set(store FALSE) + elseif(store) + list(APPEND sectionLines "${line}") + endif() + endforeach() + set(sectionName "") + set(sectionType "") + foreach(line IN LISTS sectionLines) + if(line MATCHES "^\t*GlobalSection\\((.*)\\) *= *(pre|post)Solution\n?$") + set(sectionName "${CMAKE_MATCH_1}") + set(sectionType ${CMAKE_MATCH_2}) + list(APPEND ${out_${sectionType}} "${sectionName}") + if(DEFINED ${out_${sectionType}}_${sectionName}) + error("Section ${sectionName} defined twice") + endif() + set(${out_${sectionType}}_${sectionName} "") + elseif(line MATCHES "\t*EndGlobalSection\n?$") + set(sectionName "") + set(sectionType "") + elseif(sectionName) + string(REGEX MATCH "^\t*([^=]*)=([^\n]*)\n?$" matches "${line}") + if(NOT matches) + error("Bad syntax in solution file: '${line}'") + endif() + string(STRIP "${CMAKE_MATCH_1}" key) + string(STRIP "${CMAKE_MATCH_2}" value) + list(APPEND ${out_${sectionType}}_${sectionName} "${key}=${value}") + endif() + endforeach() +endmacro() + + +macro(testGlobalSection prefix sectionName) + if(NOT DEFINED ${prefix}_${sectionName}) + error("Section ${sectionName} does not exist") + endif() + if(NOT "${${prefix}_${sectionName}}" STREQUAL "${ARGN}") + error("Section ${sectionName} content mismatch\n expected: ${ARGN}\n actual: ${${prefix}_${sectionName}}") + endif() +endmacro() diff --git a/Tests/VSExcludeFromDefaultBuild/CMakeLists.txt b/Tests/VSExcludeFromDefaultBuild/CMakeLists.txt new file mode 100644 index 0000000..d30414b --- /dev/null +++ b/Tests/VSExcludeFromDefaultBuild/CMakeLists.txt @@ -0,0 +1,32 @@ +cmake_minimum_required(VERSION 2.8.9) +project(VSExcludeFromDefaultBuild) + +# First step is to clear all .exe files in output so that possible past +# failures of this test do not prevent it from succeeding. +add_custom_target(ClearExes ALL + COMMAND "${CMAKE_COMMAND}" + -Ddir=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} + -P ${CMAKE_CURRENT_SOURCE_DIR}/ClearExes.cmake + VERBATIM) + +# Make sure ClearExes is executed before other targets are built +function(add_test_executable target) + add_executable("${target}" ${ARGN}) + add_dependencies("${target}" ClearExes) +endfunction() + +add_test_executable(DefaultBuilt main.c) + +add_test_executable(AlwaysBuilt main.c) +set_target_properties(AlwaysBuilt PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD FALSE) + +add_test_executable(NeverBuilt main.c) +set_target_properties(NeverBuilt PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE) + +foreach(config ${CMAKE_CONFIGURATION_TYPES}) + string(TOUPPER ${config} Config) + add_test_executable(BuiltIn${config} main.c) + set_target_properties(BuiltIn${config} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE EXCLUDE_FROM_DEFAULT_BUILD_${Config} FALSE) + add_test_executable(ExcludedIn${config} main.c) + set_target_properties(ExcludedIn${config} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD_${Config} TRUE) +endforeach() diff --git a/Tests/VSExcludeFromDefaultBuild/ClearExes.cmake b/Tests/VSExcludeFromDefaultBuild/ClearExes.cmake new file mode 100644 index 0000000..ece30ad --- /dev/null +++ b/Tests/VSExcludeFromDefaultBuild/ClearExes.cmake @@ -0,0 +1,4 @@ +file(GLOB exeFiles "${dir}/*.exe") +foreach(exeFile IN LISTS exeFiles) + file(REMOVE "${exeFile}") +endforeach() diff --git a/Tests/VSExcludeFromDefaultBuild/ResultTest.cmake b/Tests/VSExcludeFromDefaultBuild/ResultTest.cmake new file mode 100644 index 0000000..8fb00bf --- /dev/null +++ b/Tests/VSExcludeFromDefaultBuild/ResultTest.cmake @@ -0,0 +1,23 @@ +message(STATUS "Testing configuration ${activeConfig}.") + +macro(TestExists exeName) + set(exeFile "${dir}/${activeConfig}/${exeName}.exe") + if(${ARGN} EXISTS "${exeFile}") + message(STATUS "File ${exeFile} was correctly found ${ARGN} to exist.") + else() + message(FATAL_ERROR "File ${exeFile} was expected ${ARGN} to exist!") + endif() +endmacro() + +TestExists(DefaultBuilt) +TestExists(AlwaysBuilt) +TestExists(NeverBuilt NOT) +foreach(config ${allConfigs}) + if(config STREQUAL activeConfig) + TestExists(BuiltIn${config}) + TestExists(ExcludedIn${config} NOT) + else() + TestExists(BuiltIn${config} NOT) + TestExists(ExcludedIn${config}) + endif() +endforeach() diff --git a/Tests/VSExcludeFromDefaultBuild/main.c b/Tests/VSExcludeFromDefaultBuild/main.c new file mode 100644 index 0000000..8488f4e --- /dev/null +++ b/Tests/VSExcludeFromDefaultBuild/main.c @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} |