起因
最近因为CS537操作系统课程的原因,经常需要开发Unix下的小应用程序,比如实现个Shell啊什么的。 我目前的桌面台式机是同时装了Windows(10), Linux(两个发行版), macOS(黑苹果)三个操作系统的,并且都是实体安装, 这就导致Windows下办公完了想去Linux下写写程序就需要重启。而在去年的时候微软宣布他们的Visual Studio支持开发Linux的应用程序了,所以觉得我也折腾一把之后或许会方便一些。
原料
这个特性貌似是Visual Studio 2017 15.4才加进来的特性,所以各位没装的或者旧版本的可能需要升级才可以使用这个功能。
尝试新建Linux Console项目

输入项目名称,文件夹路径,选Linux Console Application,点完成
之后就可以按照正常的Visual Studio项目配置过程来配置Linux项目了。
微软远程编译、调试的原理就是在本地生成CMakeCache以及Unix Makefile,然后将源码和构建脚本直接复制到Linux机器上远程调用编译器编译。 这个过程是单向的,本地源码永远是最新,远程工作目录每次编译的时候更新一次,然后Visual Studio根据本地的CMakeCache来了解这个项目。
于是就可以在全宇宙最好用的IDE Visual Studio 下写这个菜的抠脚的操作系统课作业了。
以为这样就完了?Windows才不会让你这么轻易的解决问题…
微软家的编译器和所有IDE配套工具链都有个共同的问题,分不清C和C++,根本原因就是自家的cl.exe同时支持C/C++编译并且不作分开处理。 然后在项目配置里有两个选项直接致命,第一个是-frtti
,另一个是-fno-strict-aliasing
两个在GCC上都是C++-only的选项。 而我们的教授要求我们用-Wall -Werror
编译程序,所以这两个warning直接报错:(
然后尝试自定义命令行参数,或者覆盖之前的参数,然后查文档发现Visual Studio自然是不支持覆盖编译参数的,至少在Linux项目里不行。
不过意外地发现Visual Studio 2017引进了CMake支持,并且在2017 15.4的时候支持了Linux的CMake项目,那当然是CMake直接上了
尝试打开Linux CMake项目
CMakeLists:
cmake_minimum_required(VERSION 2.8.9) project (wish) SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror") add_executable(wish wish.c)
然后配置CMakeSettings然Visual Studio生成对应Cache以及自动连上我宿舍常开的Linux机器远程编译、调试:
{ // 请参阅 https://go.microsoft.com//fwlink//?linkid=834763 了解有关此文件的详细信息。 "configurations": [ { "name": "Manjaro-Debug", "generator": "Unix Makefiles", "remoteMachineName": "${defaultRemoteMachineName}", "configurationType": "Debug", "remoteCMakeListsRoot": "/tmp/src/${workspaceHash}/${name}", "cmakeExecutable": "/usr/bin/cmake", "buildRoot": "${env.LOCALAPPDATA}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", "remoteBuildRoot": "/tmp/build/${workspaceHash}/build/${name}", "remoteCopySources": true, "remoteCopySourcesOutputVerbosity": "Normal", "remoteCopySourcesConcurrentCopies": "10", "cmakeCommandArgs": "", "buildCommandArgs": "", "ctestCommandArgs": "", "inheritEnvironments": [ "linux-x64" ] }, { "name": "Manjaro-Release", "generator": "Unix Makefiles", "remoteMachineName": "${defaultRemoteMachineName}", "configurationType": "Release", "remoteCMakeListsRoot": "/tmp/src/${workspaceHash}/${name}", "cmakeExecutable": "/usr/bin/cmake", "buildRoot": "${env.LOCALAPPDATA}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", "remoteBuildRoot": "/tmp/build/${workspaceHash}/build/${name}", "remoteCopySources": true, "remoteCopySourcesOutputVerbosity": "Normal", "remoteCopySourcesConcurrentCopies": "10", "cmakeCommandArgs": "", "buildCommandArgs": "", "ctestCommandArgs": "", "inheritEnvironments": [ "linux-x64" ] } ] }
大概就是如下图所示的配置:

这时候就可以完美编译了,-Wall -Werror
也在乐呵呵地向我招手,远程GDB调试也是完美的,表扬一下VS的调试器可能是全宇宙最好用的。
以为这样就完了?Windows才不会让你这么轻易的解决问题…
Intellisense在Linux CMake项目下的补全
是炸的,补不全的。
巨硬家的Intellisense依靠理解C/C++的文件依赖关系并且遍历源文件中的函数/变量标记来帮你智能补全。
正常写Windows代码的时候这个补全是相当智能的,我在Vim下尝试过多个全功能的补全插件,但是都没有VS家的用得得心应手。
但是写Linux程序的时候需要Linux/Unix标准的头文件,没有是没有办法补全的。
所以理所当然尝试从隔壁Manjaro复制了一份/usr/include
到项目目录,并且配置CppProperties如下:
{ "configurations": [ { "inheritEnvironments": [ "x64-Debug", "linux-x64" ], "name": "Manjaro-Debug", "includePath": [ "D:\\Code\\Wish", "D:\\Code\\Wish\\mjro-include", "D:\\Code\\Wish\\mjro-include\\x86_64-linux-gnu" ], "defines": [ "WIN32", "_DEBUG", "UNICODE", "_UNICODE" ], "intelliSenseMode": "linux-gcc-x64" } ] }
这样Intellisense就可以找到本地的Linux头文件并且提供补全和语法检查了。
以为这样就完了?Windows才不会让你这么轻易的解决问题…
Intellisense 根本找不到那些头文件!!!

可以看到所有Linux头文件的include以及用到那些头文件的语句都是标红的。
这么惊天一个大Bug值得开一个Issue,结果早就有人吃过这坨shi了,
Github:Microsoft/VSLinux, Issue #195 和 #215, 现在仍然没有解决。。。
这样就完了?嗯…这样就完了
作业还是要写的,最后一部分由WSL下开Vim完成,至少我配置的补全和检查都是在工作的。

Tmux和ssh都在工作,只是需要手动操作了。

微软如果想吸引Linux开发者来用他们的VS写出程序的话,可能还需要好好优化一下VS在这方面的兼容性和易用性。欢迎使用Vim,全宇宙最好的编辑器。
Leave a comment