summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/manual/cmake-properties.7.rst1
-rw-r--r--Help/prop_dir/VS_STARTUP_PROJECT.rst12
-rw-r--r--Help/release/dev/vs-startup-project.rst6
-rw-r--r--Source/cmGlobalVisualStudio71Generator.cxx22
-rw-r--r--Source/cmGlobalVisualStudioGenerator.cxx34
-rw-r--r--Source/cmGlobalVisualStudioGenerator.h2
-rw-r--r--Tests/RunCMake/CMakeLists.txt5
-rw-r--r--Tests/RunCMake/VSSolution/RunCMakeTest.cmake6
-rw-r--r--Tests/RunCMake/VSSolution/StartupProject-check.cmake5
-rw-r--r--Tests/RunCMake/VSSolution/StartupProject.cmake2
-rw-r--r--Tests/RunCMake/VSSolution/StartupProjectMissing-check.cmake5
-rw-r--r--Tests/RunCMake/VSSolution/StartupProjectMissing-stderr.txt4
-rw-r--r--Tests/RunCMake/VSSolution/StartupProjectMissing.cmake1
-rw-r--r--Tests/RunCMake/VSSolution/StartupProjectUseFolders-check.cmake9
-rw-r--r--Tests/RunCMake/VSSolution/StartupProjectUseFolders.cmake3
-rw-r--r--Tests/RunCMake/VSSolution/solution_parsing.cmake15
16 files changed, 122 insertions, 10 deletions
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 578f85a..73d1142 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -76,6 +76,7 @@ Properties on Directories
/prop_dir/VARIABLES
/prop_dir/VS_GLOBAL_SECTION_POST_section
/prop_dir/VS_GLOBAL_SECTION_PRE_section
+ /prop_dir/VS_STARTUP_PROJECT
.. _`Target Properties`:
diff --git a/Help/prop_dir/VS_STARTUP_PROJECT.rst b/Help/prop_dir/VS_STARTUP_PROJECT.rst
new file mode 100644
index 0000000..edd4832
--- /dev/null
+++ b/Help/prop_dir/VS_STARTUP_PROJECT.rst
@@ -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.
diff --git a/Help/release/dev/vs-startup-project.rst b/Help/release/dev/vs-startup-project.rst
new file mode 100644
index 0000000..f467400
--- /dev/null
+++ b/Help/release/dev/vs-startup-project.rst
@@ -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).
diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx
index 8227b82..7b51fdf 100644
--- a/Source/cmGlobalVisualStudio71Generator.cxx
+++ b/Source/cmGlobalVisualStudio71Generator.cxx
@@ -94,16 +94,34 @@ void cmGlobalVisualStudio71Generator
TargetDependSet projectTargets;
TargetDependSet originalTargets;
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();
if (useFolderProperty)
{
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
fout << "Global\n";
// Write out the configurations for the solution
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index 00bb511..04146fb 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -89,19 +89,13 @@ void cmGlobalVisualStudioGenerator::AddExtraIDETargets()
cmGeneratorTarget* gt = new cmGeneratorTarget(allBuild, gen[0]);
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:
//
- if (this->UseFolderProperty())
+ if (this->UseFolderProperty() && this->GetVersion() > VS71)
{
allBuild->SetProperty("FOLDER", this->GetPredefinedTargetsFolder());
}
-#endif
// Now make all targets depend on the ALL_BUILD target
for(std::vector<cmLocalGenerator*>::iterator i = gen.begin();
@@ -519,6 +513,32 @@ cmGlobalVisualStudioGenerator::GetUtilityDepend(
}
//----------------------------------------------------------------------------
+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>
//----------------------------------------------------------------------------
diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h
index ac9111e..723a75f 100644
--- a/Source/cmGlobalVisualStudioGenerator.h
+++ b/Source/cmGlobalVisualStudioGenerator.h
@@ -106,6 +106,8 @@ public:
void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const;
+ std::string GetStartupProjectName(cmLocalGenerator const* root) const;
+
void AddSymbolExportCommand(
cmGeneratorTarget*, std::vector<cmCustomCommand>& commands,
std::string const& configName);
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 048b5e3..d22c39c 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -235,7 +235,10 @@ endif()
if("${CMAKE_GENERATOR}" MATCHES "Visual Studio")
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()
if("${CMAKE_GENERATOR}" MATCHES "Visual Studio ([^789]|[789][0-9])")
diff --git a/Tests/RunCMake/VSSolution/RunCMakeTest.cmake b/Tests/RunCMake/VSSolution/RunCMakeTest.cmake
index 6ae158d..afd74a1 100644
--- a/Tests/RunCMake/VSSolution/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VSSolution/RunCMakeTest.cmake
@@ -8,3 +8,9 @@ run_cmake(MorePost)
run_cmake(PrePost)
run_cmake(Override1)
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()
diff --git a/Tests/RunCMake/VSSolution/StartupProject-check.cmake b/Tests/RunCMake/VSSolution/StartupProject-check.cmake
new file mode 100644
index 0000000..f36aab2
--- /dev/null
+++ b/Tests/RunCMake/VSSolution/StartupProject-check.cmake
@@ -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()
diff --git a/Tests/RunCMake/VSSolution/StartupProject.cmake b/Tests/RunCMake/VSSolution/StartupProject.cmake
new file mode 100644
index 0000000..7192f3d
--- /dev/null
+++ b/Tests/RunCMake/VSSolution/StartupProject.cmake
@@ -0,0 +1,2 @@
+add_custom_target(TestStartup)
+set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT "TestStartup")
diff --git a/Tests/RunCMake/VSSolution/StartupProjectMissing-check.cmake b/Tests/RunCMake/VSSolution/StartupProjectMissing-check.cmake
new file mode 100644
index 0000000..b1017dd
--- /dev/null
+++ b/Tests/RunCMake/VSSolution/StartupProjectMissing-check.cmake
@@ -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()
diff --git a/Tests/RunCMake/VSSolution/StartupProjectMissing-stderr.txt b/Tests/RunCMake/VSSolution/StartupProjectMissing-stderr.txt
new file mode 100644
index 0000000..da92c6d
--- /dev/null
+++ b/Tests/RunCMake/VSSolution/StartupProjectMissing-stderr.txt
@@ -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.$
diff --git a/Tests/RunCMake/VSSolution/StartupProjectMissing.cmake b/Tests/RunCMake/VSSolution/StartupProjectMissing.cmake
new file mode 100644
index 0000000..907a877
--- /dev/null
+++ b/Tests/RunCMake/VSSolution/StartupProjectMissing.cmake
@@ -0,0 +1 @@
+set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT "DoesNotExist")
diff --git a/Tests/RunCMake/VSSolution/StartupProjectUseFolders-check.cmake b/Tests/RunCMake/VSSolution/StartupProjectUseFolders-check.cmake
new file mode 100644
index 0000000..c0a545a
--- /dev/null
+++ b/Tests/RunCMake/VSSolution/StartupProjectUseFolders-check.cmake
@@ -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()
diff --git a/Tests/RunCMake/VSSolution/StartupProjectUseFolders.cmake b/Tests/RunCMake/VSSolution/StartupProjectUseFolders.cmake
new file mode 100644
index 0000000..8e422a4
--- /dev/null
+++ b/Tests/RunCMake/VSSolution/StartupProjectUseFolders.cmake
@@ -0,0 +1,3 @@
+add_custom_target(TestStartup)
+set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT "TestStartup")
diff --git a/Tests/RunCMake/VSSolution/solution_parsing.cmake b/Tests/RunCMake/VSSolution/solution_parsing.cmake
index dd158ef..4e5bb59 100644
--- a/Tests/RunCMake/VSSolution/solution_parsing.cmake
+++ b/Tests/RunCMake/VSSolution/solution_parsing.cmake
@@ -50,6 +50,21 @@ macro(parseGlobalSections arg_out_pre arg_out_post testName)
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)
if(NOT DEFINED ${prefix}_${sectionName})
error("Section ${sectionName} does not exist")