Merge topic 'vs-startup-project'

ad140c6e VS: Put ALL_BUILD in the PREDEFINED_TARGETS_FOLDER
f069be05 VS: Fix default target support for targets nested inside a folder
c05ea485 VS: Improve unit test macros
78ec0461 VS: Add option to choose the `.sln` startup project (#15578)
This commit is contained in:
Brad King 2016-03-24 08:49:41 -04:00 committed by CMake Topic Stage
commit 5b2acf6c1c
16 changed files with 122 additions and 10 deletions

View File

@ -76,6 +76,7 @@ Properties on Directories
/prop_dir/VARIABLES /prop_dir/VARIABLES
/prop_dir/VS_GLOBAL_SECTION_POST_section /prop_dir/VS_GLOBAL_SECTION_POST_section
/prop_dir/VS_GLOBAL_SECTION_PRE_section /prop_dir/VS_GLOBAL_SECTION_PRE_section
/prop_dir/VS_STARTUP_PROJECT
.. _`Target Properties`: .. _`Target Properties`:

View File

@ -0,0 +1,12 @@
VS_STARTUP_PROJECT
------------------
Specify the default startup project in a Visual Studio solution.
The property must be set to the name of an existing target. This
will cause that project to be listed first in the generated solution
file causing Visual Studio to make it the startup project if the
solution has never been opened before.
If this property is not specified, then the "ALL_BUILD" project
will be the default.

View File

@ -0,0 +1,6 @@
vs-startup-project
------------------
* The :ref:`Visual Studio Generators` learned to honor a new
:prop_dir:`VS_STARTUP_PROJECT` directory property that specifies
the default startup project for generated solutions (``.sln`` files).

View File

@ -94,16 +94,34 @@ void cmGlobalVisualStudio71Generator
TargetDependSet projectTargets; TargetDependSet projectTargets;
TargetDependSet originalTargets; TargetDependSet originalTargets;
this->GetTargetSets(projectTargets, originalTargets, root, generators); this->GetTargetSets(projectTargets, originalTargets, root, generators);
OrderedTargetDependSet orderedProjectTargets(projectTargets, "ALL_BUILD"); OrderedTargetDependSet orderedProjectTargets(
projectTargets, this->GetStartupProjectName(root));
this->WriteTargetsToSolution(fout, root, orderedProjectTargets); // Generate the targets specification to a string. We will put this in
// the actual .sln file later. As a side effect, this method also
// populates the set of folders.
std::ostringstream targetsSlnString;
this->WriteTargetsToSolution(targetsSlnString, root, orderedProjectTargets);
// VS 7 does not support folders specified first.
if (this->GetVersion() <= VS71)
{
fout << targetsSlnString.str();
}
// Generate folder specification.
bool useFolderProperty = this->UseFolderProperty(); bool useFolderProperty = this->UseFolderProperty();
if (useFolderProperty) if (useFolderProperty)
{ {
this->WriteFolders(fout); this->WriteFolders(fout);
} }
// Now write the actual target specification content.
if (this->GetVersion() > VS71)
{
fout << targetsSlnString.str();
}
// Write out the configurations information for the solution // Write out the configurations information for the solution
fout << "Global\n"; fout << "Global\n";
// Write out the configurations for the solution // Write out the configurations for the solution

View File

@ -89,19 +89,13 @@ void cmGlobalVisualStudioGenerator::AddExtraIDETargets()
cmGeneratorTarget* gt = new cmGeneratorTarget(allBuild, gen[0]); cmGeneratorTarget* gt = new cmGeneratorTarget(allBuild, gen[0]);
gen[0]->AddGeneratorTarget(gt); gen[0]->AddGeneratorTarget(gt);
#if 0
// Can't activate this code because we want ALL_BUILD
// selected as the default "startup project" when first
// opened in Visual Studio... And if it's nested in a
// folder, then that doesn't happen.
// //
// Organize in the "predefined targets" folder: // Organize in the "predefined targets" folder:
// //
if (this->UseFolderProperty()) if (this->UseFolderProperty() && this->GetVersion() > VS71)
{ {
allBuild->SetProperty("FOLDER", this->GetPredefinedTargetsFolder()); allBuild->SetProperty("FOLDER", this->GetPredefinedTargetsFolder());
} }
#endif
// Now make all targets depend on the ALL_BUILD target // Now make all targets depend on the ALL_BUILD target
for(std::vector<cmLocalGenerator*>::iterator i = gen.begin(); for(std::vector<cmLocalGenerator*>::iterator i = gen.begin();
@ -518,6 +512,32 @@ cmGlobalVisualStudioGenerator::GetUtilityDepend(
return i->second; return i->second;
} }
//----------------------------------------------------------------------------
std::string
cmGlobalVisualStudioGenerator::GetStartupProjectName(
cmLocalGenerator const* root) const
{
const char* n = root->GetMakefile()->GetProperty("VS_STARTUP_PROJECT");
if (n && *n)
{
std::string startup = n;
if (this->FindTarget(startup))
{
return startup;
}
else
{
root->GetMakefile()->IssueMessage(
cmake::AUTHOR_WARNING,
"Directory property VS_STARTUP_PROJECT specifies target "
"'" + startup + "' that does not exist. Ignoring.");
}
}
// default, if not specified
return this->GetAllTargetName();
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
#include <windows.h> #include <windows.h>

View File

@ -106,6 +106,8 @@ public:
void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const; void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const;
std::string GetStartupProjectName(cmLocalGenerator const* root) const;
void AddSymbolExportCommand( void AddSymbolExportCommand(
cmGeneratorTarget*, std::vector<cmCustomCommand>& commands, cmGeneratorTarget*, std::vector<cmCustomCommand>& commands,
std::string const& configName); std::string const& configName);

View File

@ -235,7 +235,10 @@ endif()
if("${CMAKE_GENERATOR}" MATCHES "Visual Studio") if("${CMAKE_GENERATOR}" MATCHES "Visual Studio")
add_RunCMake_test(include_external_msproject) add_RunCMake_test(include_external_msproject)
add_RunCMake_test(VSSolution) if("${CMAKE_GENERATOR}" MATCHES "Visual Studio ([789]|10)" AND NOT CMAKE_VS_DEVENV_COMMAND)
set(NO_USE_FOLDERS 1)
endif()
add_RunCMake_test(VSSolution -DNO_USE_FOLDERS=${NO_USE_FOLDERS})
endif() endif()
if("${CMAKE_GENERATOR}" MATCHES "Visual Studio ([^789]|[789][0-9])") if("${CMAKE_GENERATOR}" MATCHES "Visual Studio ([^789]|[789][0-9])")

View File

@ -8,3 +8,9 @@ run_cmake(MorePost)
run_cmake(PrePost) run_cmake(PrePost)
run_cmake(Override1) run_cmake(Override1)
run_cmake(Override2) run_cmake(Override2)
run_cmake(StartupProject)
run_cmake(StartupProjectMissing)
if(RunCMake_GENERATOR MATCHES "Visual Studio ([^7]|[7][0-9])" AND NOT NO_USE_FOLDERS)
run_cmake(StartupProjectUseFolders)
endif()

View File

@ -0,0 +1,5 @@
getProjectNames(projects)
list(GET projects 0 first_project)
if(NOT first_project STREQUAL "TestStartup")
error("TestStartup is not the startup project")
endif()

View File

@ -0,0 +1,2 @@
add_custom_target(TestStartup)
set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT "TestStartup")

View File

@ -0,0 +1,5 @@
getProjectNames(projects)
list(GET projects 0 first_project)
if(NOT first_project STREQUAL "ALL_BUILD")
error("ALL_BUILD is not the startup project")
endif()

View File

@ -0,0 +1,4 @@
^CMake Warning \(dev\) in CMakeLists.txt:
Directory property VS_STARTUP_PROJECT specifies target 'DoesNotExist' that
does not exist. Ignoring.
This warning is for project developers. Use -Wno-dev to suppress it.$

View File

@ -0,0 +1 @@
set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT "DoesNotExist")

View File

@ -0,0 +1,9 @@
getProjectNames(projects)
list(GET projects 0 first_project)
if(NOT first_project STREQUAL "CMakePredefinedTargets")
error("CMakePredefinedTargets is not the first project")
endif()
list(GET projects 1 second_project)
if(NOT second_project STREQUAL "TestStartup")
error("TestStartup does not immediately follow the CMakePredefinedTargets project")
endif()

View File

@ -0,0 +1,3 @@
add_custom_target(TestStartup)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT "TestStartup")

View File

@ -50,6 +50,21 @@ macro(parseGlobalSections arg_out_pre arg_out_post testName)
endmacro() endmacro()
macro(getProjectNames arg_out_projects)
set(${arg_out_projects} "")
set(sln "${RunCMake_TEST_BINARY_DIR}/${test}.sln")
if(NOT EXISTS "${sln}")
error("Expected solution file ${sln} does not exist")
endif()
file(STRINGS "${sln}" project_lines REGEX "^Project\\(")
foreach(project_line IN LISTS project_lines)
string(REGEX REPLACE ".* = \"" "" project_line "${project_line}")
string(REGEX REPLACE "\", .*" "" project_line "${project_line}")
list(APPEND ${arg_out_projects} "${project_line}")
endforeach()
endmacro()
macro(testGlobalSection prefix sectionName) macro(testGlobalSection prefix sectionName)
if(NOT DEFINED ${prefix}_${sectionName}) if(NOT DEFINED ${prefix}_${sectionName})
error("Section ${sectionName} does not exist") error("Section ${sectionName} does not exist")