Правильно, что явный выбор, который пользователь делает при нажатии «Установить как стартовый проект» в IDE, сохраняется в двоичном файле. Но в другом месте я обнаружил, что Visual Studio воспринимает первый проект в решении как неявный стартовый проект при первом открытии решения, поэтому CMake действительно влияет на это.
Наша проблема сейчас: ALL_BUILD - это всегда первый проект. Чтобы изменить это, я запускаю короткий сценарий Perl после CMake, который вырезает из файла желаемое определение проекта и вставляет его в начало. Путь к файлу решения в первом параметре, имя проекта во втором:
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";
После того, как решение было открыто, неявный стартовый проект сохраняется в двоичном файле и, таким образом, становится явным, так что это даже сохраняется после повторного запуска CMake (например, запускается ZERO-CHECK, который не допускает пост-выполнения). Таким же образом, явный выбор пользователя также сохраняется.
(Написано и протестировано на машине Win7 с ActiveState Perl)