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

后端 未结 6 1511
刺人心
刺人心 2020-12-05 09:13

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. Ho

6条回答
  •  孤城傲影
    2020-12-05 09:50

    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)

提交回复
热议问题