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

6

72

I am using CMake to generate Visual Studio projects. Everything works fine except 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?

Erinnerinna answered 5/9, 2011 at 6:45 Comment(0)
R
22

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.

Rape answered 5/9, 2011 at 7:25 Comment(3)
In Visual Studio you can use the context menu command "Set as Startup Project" as a work-around once the project has been created.Gautama
Note that CMake finally introduced support for this in version 3.6. See my answer for details.Rostock
That's great news, thanks for the update. I will definitely use itGlanville
R
146

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.

Rostock answered 23/6, 2016 at 14:22 Comment(2)
This just worked for me in Visual Studio 2019, thanks alot!Simla
Sadly, that doesn't let me set the "currently selected" option.Nairobi
R
22

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.

Rape answered 5/9, 2011 at 7:25 Comment(3)
In Visual Studio you can use the context menu command "Set as Startup Project" as a work-around once the project has been created.Gautama
Note that CMake finally introduced support for this in version 3.6. See my answer for details.Rostock
That's great news, thanks for the update. I will definitely use itGlanville
S
16

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.

Sonia answered 6/10, 2012 at 9:34 Comment(0)
F
7

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!

Frivolity answered 4/10, 2014 at 10:40 Comment(0)
T
1

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)

Thermionic answered 18/8, 2014 at 12:2 Comment(0)
R
-3

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.

Romaineromains answered 15/9, 2016 at 13:34 Comment(2)
Can you provide documentation around this command and how it differs from the VS_STARTUP_PROJECT directive as explained by @RostockVersieversification
Unfortunately I can't find out how the command worked with VS2010 using cmake 3.5. I now use the VS_STARTUP_PROJECT property for VS 2010/2015 solutionsRomaineromains

© 2022 - 2024 — McMap. All rights reserved.