How do I change the startup project of a Visual Studio solution via CMake?

試著忘記壹切 提交于 2019-11-30 04:10:06
André

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.

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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!