web-dev-qa-db-fra.com

Comment modifier le projet de démarrage d'une solution Visual Studio via CMake?

J'utilise CMake pour générer des projets Visual Studio. Tout fonctionne bien sauf une chose.

Le projet de démarrage dans la solution est toujours ALL_BUILD. Comment changer le projet de démarrage en projet réel que je veux via CMake?

57
giggle

Tu ne peux pas. Le projet de démarrage est stocké dans un fichier binaire, qui n'est PAS généré par CMake. Sans ce fichier binaire, Visual Studio passera par défaut au premier projet dans le fichier de solution et le projet ALL_BUILD est toujours le premier ...

Mise à jour: cette réponse est "obsolète" car elle est désormais possible avec CMake 3.6. Voir la réponse de ComicSansMS .

20
André

CMake prend désormais cela en charge avec les versions 3.6 et supérieures via VS_STARTUP_PROJECT propriété de répertoire:

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)

Cela définira bar comme projet de démarrage pour le foo.sln Solution.

92
ComicSansMS

Depuis Visual 2005, la configuration est stockée dans un nom de fichier projectname.vc (x) proj.user, qui est du XML brut.

Je ne sais pas comment changer le projet de démarrage, mais vous pouvez certainement configurer ALL_BUILD pour exécuter l'exécutable souhaité au lieu d'afficher la stupide 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
)

Ce module est disponible sur github de rpavlik . Vous devez simplement ajouter ceci dans votre CMakeLists.txt le plus haut:

list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/external/rpavlik-cmake-modules-1c73e35") # or whichever path you put the module in.
include(CreateLaunchers)

Exemples disponibles ici .

15
Calvin1602

Si vous ne pouvez pas autoriser une dépendance Perl comme moi, je viens d'écrire un petit utilitaire de ligne de commande pour Windows appelé slnStartupProject pour résoudre ce problème. Il définit automatiquement le projet de démarrage comme ceci:

slnStartupProject slnFilename projectName

Je l'utilise personnellement pour définir le projet après avoir généré la solution avec cmake qui définit toujours un projet factice ALL_BUILD comme premier projet dans la solution.

La source est sur github:

https://github.com/michaKFromParis/slnStartupProject

Les fourchettes et les retours sont les bienvenus.

J'espère que cela t'aides!

6
michaK

Il est correct que le choix explicite que l'utilisateur fait en appuyant sur "Définir comme projet de démarrage" dans IDE est stocké dans un fichier binaire. Mais j'ai trouvé ailleurs que Visual Studio prend le premier projet dans le solution en tant que projet de démarrage implicite lors de la première ouverture d'une solution, donc CMake a une influence sur cela.

Notre problème maintenant: ALL_BUILD est toujours le premier projet. Pour changer cela, j'exécute un court script Perl après CMake qui coupe la définition de projet souhaitée dans le fichier et la colle à l'avant. Chemin d'accès au fichier de solution dans le premier paramètre, nom du projet dans le 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";

Une fois la solution ouverte, le projet de démarrage implicite est enregistré dans le fichier binaire et devient ainsi explicite, ce qui survit même à une réexécution CMake (par exemple déclenchée par ZERO-CHECK, qui ne permet pas la post-exécution). De la même manière, un choix utilisateur explicite est également conservé.

(Écrit et testé sur une machine Win7 avec ActiveState Perl)

1
SvenS