在 Windows 环境下,笔者主要通过 Visual Studio 进行较大型项目的查看和运行调试。这里记录下使用 Visual Studio 编译、运行和调试可能包含有多个可执行程序的多文件项目的方法,特别的,这里记录的是使用 CMake 进行自动化构建的多文件项目。
使用 Visual Studio 打开项目
目前许多大文件项目使用跨平台自动化构建系统 CMake 进行项目内部依赖关系的管理。简单而言,CMake 使用统一规则的配置文件 CMakeLists.txt 记录项目的依赖关系,再根据目标编译平台生成对应的构建规则,如在 Linux 下可依据 CMakeLists.txt 生成项目对应的 Makefile ,在 Windows 环境下则生成项目的 Visual Studio 工程。
Windows 环境下首先使用 CMake 生成项目对应的 Visual Studio 工程,通常项目的 README 文件中会有相应的描述。使用 CMake 的一般流程如下所示。
( Windows 环境需通过安装包安装 CMake,具体安装见官方文档,Windows 环境下,在项目根目录下 Shift + 右键,在弹出菜单中选择"在此处打开命令窗口",即可直接使用工作目录为项目根目录的命令行窗口)
mkdir build //在项目根目录下新建名为 build 的目录
cd build //进入 build 目录
cmake .. -G "Visual Studio 15 2017 Win64" //在当前目录中(即 build 目录),以 .. (表示 build 的上一目录,即为项目根目录)作为源目录生成 Visual Studio 工程文件
最后一个命令中,-G 命令可以指定生成的 Visual Studio 工程的 Win64 版本,系统安装的 CMake 支持的 Visual Studio 版本可通过命令行命令 cmake --help 命令查看。
在上述命令执行完成后,当前 build 目录中即存放有 cmake 生成的项目的 Visual Studio 工程,此时双击目录中的 .sln 文件即自动通过 Visual Studio 打开该项目。
Visual Studio 运行和调试程序
在打开的 Visual Studio 界面中,主要通过解决方案资源管理器查看项目的文件结构,双击对应的文件从而显示文件的具体内容,通过界面上部的生成、调试等工具栏进行程序的编译、运行和调试工作。
运行可能含有多个可执行程序的项目
如下图所示,在一个项目的解决方案中,可能存在多个子项目( 源文件、所需资源的集合 ),子项目以某种方式划分,同时存在相互依赖关系。如下图的 decoder 子项目包含有程序的起始调用函数 main 函数,该子项目最终会生成可执行文件( .exe 文件),而 decode 子项目则是生成与 decoder 相关的库文件( .lib 文件),供 decoder 调用。不同子项目的依赖关系等信息是在 CMake 配置中即指定了的。在使用 Visual Studio 进行程序的运行和调试时,需要人为的设置运行/调试时具体使用哪一个子项目(所对应的可执行程序)。具体而言,存在多个子项目可生成可执行程序时,选中需要运行/调试的可执行程序所对应的子项目(main函数所在的子项目),右键 -> 设为启动项目。后续 VS 运行程序时,即启动被设置为启动项的子项目所生成的可执行程序。
设置项目属性
对于每一个子项目,(如果默认设置不满足需求时)可以分别设置它的属性,以满足各自的编译/运行/调试等环境需求。选中某个子项目,右键 -> 属性 (快捷键 Alt + Enter)可以进行该子项目的属性设置。常规的属性窗口如下图所示。简单使用时,主要配置 调试 条目中的命令参数和工作目录,即可满足程序运行的基本要求。其中,命令参数为执行可执行程序时传递给可执行程序的参数,而工作目录指定了在进行相对路径寻址的根目录。另外需要注意,左上角的配置选项中,可以对 Release 和 Debug 进行切换,需要注意 Release 和 Debug 分别拥有自己的属性设置,需要分别进行设置( 非共用 )。不同子项目的配置也需要分别进行指定。
完整的 Visual Studio 的属性设置和使用可以参考官方文档 Windows C++项目属性页引用 和 设置编译器和生成属性。
在对可执行程序进行 Debug/Release 属性设置后,可以通过 Visual Studio 界面顶部的按钮切换当前使用的配置,如下图所示中正在使用的即为 Release 版本所设置的属性。
项目运行调试
Visual Studio 可以通过界面顶端的 调试 选项中的条目对项目进行运行/调试。其中,运行/调试启动的可执行程序是被设置为启动项的子项目所生成的可执行程序,生成/调试使用的是顶部工具栏中确定的 Release/Debug 版本所对应的属性。
这里记录下一些 Visual Studio 中运行和调试的常用操作。
开始运行和调试
F5 //进入调试,或者通过界面上方工具栏的 调试 -> 开始调试 条目
Ctrl + F5 //直接运行,或者通过工具栏 调试 -> 开始执行 条目,程序运行结束后会保留控制台,而不是立即退出,可以查看程序运行结束后输出至控制台的信息
调试操作
F5 //继续运行调试,直至触发下一处断点
F10 //逐过程运行,如遇到函数时不会步入,而是直接运行至函数返回
F11 //逐语句运行,如遇到函数时,会进入函数内部,从其第一条语句开始执行
浏览文件
Alt + F12 //速览定义,会生成一个小窗口查看对应对象的定义
F12 //跳转至对象定义的位置
Ctrl + F12 //跳转至对象声明的位置
Shift + F12 //查找所有引用
使用 Visual Studio 的一些问题
1.关闭某些 warning 的方法
在 Visual Studio 环境下,会进行较为严格的编译检查,使得编译程序时可能会出现较多数量的警告,在理想状况下,应该修改代码从而消除 warning。当然,用户在某些情况下也可以直接将对应输出的 warning 屏蔽,从而不让其在编译阶段出现( 请注意这样做的风险 )。用户可以在对应文件中加入如下语句,从而关闭该文件中对应编号的 warning。
#pragma warning( disable : 4101) //编译时关闭错误编号为 4101 的 warning
2.LNK1104 无法打开文件“/path/to/xxx.exe”
在点击 Visual Studio 2017 的运行按钮时,产生上述报错。笔者遇到该问题的情况中,主要由于系统中有一个 "xxx.exe" 进程正在运行中,即对应的可执行文件已经被某个进程占用了,从而使得 Visual Studio 提示找不到文件。用户可以打开控制面板,寻找到 "xxx.exe" 的同名进程,再 右键 -> 结束任务 尝试解决上述问题。若无法直接关闭,可以将任务管理器由 "进程" 切换到 "详细信息" 栏目,找到的对应的进程进行关闭,或者直接重启电脑。
3.打开项目,通过 F5 或 Ctrl + F5 运行/调试程序时,编译过程正常进行,但 VS 报错显示 "无法启动程序xxxxx\ALL_BUILD。系统找不到指定的文件"
在 VS中, 调试 -> 选项 -> 项目和解决方案 -> 生成并运行 中,默认会选中 "在运行时仅生成启动项目和依赖项",即 VS 运行时只会编译生成被设置为启动项的子项目所对应的可执行程序以及它的依赖项。笔者查看的项目中, encoder 和 decoder 两个子项目是可以生成独立的可执行程序的,但刚使用 VS 打开项目时没有设置它们为启动项目( 刚打开 Visual Studio 时默认启动项为 ALL_BUILD )。所以点击 "本地 Windows 调试器 "或 Ctrl + F5 运行时,VS 会编译和生成 ALL_BUILD 对应的可执行程序以及其所依赖的程序( 在解决方案资源管理器中,ALL_BUILD 子项目本身及其依赖的项,也就是整个项目本身 ) 。但是运行时,系统会认为 ALL_BUILD 是一个可执行文件的名字,从而去尝试启动 ALL_BUILD ,进而出现上述找不到指定 ALL_BUILD 文件的错误。解决方法是选中具体的某个可执行程序对应的子项目,右键 -> 设为启动项目 将其设置为启动项,则 VS 运行时会自动运行设置为启动项的子项目所生成的可执行程序。
参考
Visual Studio 中的解决方案和项目
设置编译器和生成属性
Windows C++项目属性页引用