How do I change the startup project of a Visual Studio solution via CMake?
I am using CMake to generate Visual Studio projects. Everything works fine e开发者_如何转开发xcept one thing.
The startup project in the solution is always ALL_BUILD
. How do I change the startup project to the real project I want via CMake?
CMake now supports this with versions 3.6 and higher through the VS_STARTUP_PROJECT
directory property:
cmake_minimum_required(VERSION 3.6)
project(foo)
# ...
add_executable(bar ${BAR_SOURCES})
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT bar)
This will set bar
as the startup project for the foo.sln
solution.
You can't. The startup-project is stored in a binary file, which is NOT generated by CMake. Without that binary file, visual studio will default to the first project in the solution file and the ALL_BUILD project is always first...
Update: this answer is "out-of-date" since it is now feasible with CMake 3.6. See the answer by ComicSansMS.
Since Visual 2005, the configuration is stored in a file name projectname.vc(x)proj.user, which is plain xml.
I don't know about a way to change the startup project, but you certainly can set ALL_BUILD to run the desired executable instead of displaying the stupid popup :
create_default_target_launcher(
your_desired_target_name
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/desired_path/"
# or ${CMAKE_CURRENT_BINARY_DIR}, depending on your setup
)
This module is available on rpavlik's github. You simply need to add this in your topmost CMakeLists.txt :
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/external/rpavlik-cmake-modules-1c73e35") # or whichever path you put the module in.
include(CreateLaunchers)
Examples available here.
If you can't allow a perl dependency like me, I just wrote a little command line utility for windows called slnStartupProject to solve this. It sets the Startup Project automatically like this:
slnStartupProject slnFilename projectName
I personally use it to set the project after generating the solution with cmake that always sets a dummy ALL_BUILD project as the first project in the solution.
The source is on github:
https://github.com/michaKFromParis/slnStartupProject
Forks and feedbacks are welcome.
Hope this helps!
It is correct that the explicit choice the user makes when hitting "Set as startup project" in IDE is stored in a binary file. But I found somewhere else that Visual Studio takes the first Project in the solution as an implicit Startup Project when first opening a solution, so CMake does have an influence on this.
Our problem now: ALL_BUILD is always the first project. To change this, I am running a short perl script after CMake that cuts the desired project definition out of the file and pastes it into the front. Path to solution file in first parameter, project name in second:
use strict;
use File::Spec;
# variables
my $slnPath = File::Spec->rel2abs($ARGV[0]);
my $projectName = $ARGV[1];
my $contents;
my $header;
my $project;
my $GUID = "[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}";
my $fh;
# read file content (error if not found)
print "Setting \"$projectName\" as Startup Project in \"$slnPath\"...\n";
die "Error: path \"$slnPath\" not found!\n" if not -f $slnPath;
open($fh, "<", $slnPath) or die "Error: cannot read $slnPath: $!";
$contents = do { local $/; <$fh> };
close($fh) or warn "close failed: $!";
# extract part before Projects definition section (the first mention of "Project([GUID])")
$header = $1 if $contents =~ s{(.*?(?=Project\("\{${GUID}\}"\)))}{}si;
# extract definition of the project specified (error if not found)
$project = $1 if $contents =~ s{(Project\("\{${GUID}\}"\) = \"${projectName}\".*?EndProject\s)}{}si;
die "Error: Project not found!\n" if not defined $project or not length $project;
# write header, project definition and remaining content back into the file
`attrib -R "$slnPath"`;
open($fh, ">", $slnPath) or die "Error: cannot write to $slnPath: $!";
print $fh $header, $project, $contents;
close($fh) or warn "close failed: $!";
print "Successfully done.\n";
Once the solution has been opened, the implicit startup project is saved in the binary file and thus becomes explicit, so this even survives a CMake rerun (e.g. triggered by ZERO-CHECK, which doesn't allow post-execution). In the same way, anm explicit user choice is also preserved.
(Written and tested on Win7 machine with ActiveState Perl)
With cmake 3.5, the startup project (for VS 2010) can be changed with
SET(CMAKE_DEFAULT_STARTUP_PROJECT myFavoriteProject)
in the main CMakeLists.txt of the project. By default, it is set to ALL_BUILD.
精彩评论