我正在使用 CMake 生成 Visual Studio 项目。除了一件事,一切都很好。
解决方案中的启动项目始终是ALL_BUILD
. 如何通过 CMake 将启动项目更改为我想要的真实项目?
我正在使用 CMake 生成 Visual Studio 项目。除了一件事,一切都很好。
解决方案中的启动项目始终是ALL_BUILD
. 如何通过 CMake 将启动项目更改为我想要的真实项目?
VS_STARTUP_PROJECT
CMake 现在通过目录属性支持 3.6 及更高版本:
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)
这将设置bar
为foo.sln
解决方案的启动项目。
你不能。启动项目存储在一个二进制文件中,该文件不是由 CMake 生成的。如果没有该二进制文件,Visual Studio 将默认为解决方案文件中的第一个项目,并且 ALL_BUILD 项目始终是第一个......
更新:这个答案是“过时的”,因为它现在在 CMake 3.6 中是可行的。请参阅ComicSansMS 的答案。
从 Visual 2005 开始,配置存储在一个名为 projectname.vc(x)proj.user 的文件中,它是纯 xml。
我不知道改变启动项目的方法,但你当然可以设置 ALL_BUILD 来运行所需的可执行文件,而不是显示愚蠢的弹出窗口:
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
)
该模块在rpavlik 的 github上可用。您只需将其添加到最顶层的 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)
此处提供示例。
如果你不能允许像我这样的 perl 依赖,我只是为 Windows 编写了一个名为slnStartupProject的小命令行实用程序来解决这个问题。它像这样自动设置启动项目:
slnStartupProject slnFilename projectName
在使用cmake生成解决方案后,我个人使用它来设置项目,该解决方案始终将虚拟ALL_BUILD项目设置为解决方案中的第一个项目。
源码在github上:
https://github.com/michaKFromParis/slnStartupProject
欢迎分叉和反馈。
希望这可以帮助!
用户在 IDE 中点击“设置为启动项目”时所做的明确选择存储在二进制文件中是正确的。但是我在其他地方发现,Visual Studio 在首次打开解决方案时将解决方案中的第一个项目作为隐式启动项目,因此 CMake 确实对此有影响。
我们现在的问题:ALL_BUILD 始终是第一个项目。为了改变这一点,我在 CMake 之后运行了一个简短的 perl 脚本,它将所需的项目定义从文件中剪切出来并将其粘贴到前面。第一个参数中的解决方案文件路径,第二个参数中的项目名称:
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 触发)中幸存下来。同样,还保留了显式用户选择。
(使用 ActiveState Perl 在 Win7 机器上编写和测试)
使用 cmake 3.5,启动项目(对于 VS 2010)可以更改为
SET(CMAKE_DEFAULT_STARTUP_PROJECT myFavoriteProject)
在项目的主要 CMakeLists.txt 中。默认情况下,它设置为 ALL_BUILD。