VSCode基础

Settings

  • VSCode配置文件分为两种(其中项目会重复)

    • User Settings:用户对所有项目的配置
    • Workspace Settings:针对当前项目的设置
  • 配置方式分为两种完全相同

    • UI:提示丰富
    • JSON:配置快捷,JSON字典格式

Command Palette

Python

  • 选择默认python环境

Terminal

  • 选择默认terminal,可能的terminal包括cmd、powershell、 WSL(若启用Linux子系统)

Original Setting

Terminal

1
2
3
4
5
6
7
8
{
"terminal.integrated.shell.windows""/path/to/shell",
// 默认shell
"terminal.integrated.shellArgs.windows": [ ],
"terminal.integrated.shellArgs.linux": [ ],
"terminal.integrated.shellArgs.osx": [ ],
// VSCode创建terminal启动参数(3系统分别配置)
}
  • VSCode terminal分为很integrated、external

  • VSCode应该是兼容所有terminal shell,如

    • C:/Windows/System32/cmd.exe
    • C:/Windows/System32/powershell.exe
    • C:/Windows/System32/wsl.exe:WSL启用
    • “/path/to/git/bin/bash.exe”:Git中bash等
  • VSCode terminal虽然兼容多种shell,但只能创建默认shell

    • 需要多种shell只能切换默认shell再创建
    • python shell等shell是特殊shell,无法默认创建,必须要 在命令面板中创建(虽然在普通shell中打开python环境, 但是VSCode不认可)

Python

1
2
3
4
5
6
7
8
9
10
11
{
"python.condaPath": "/path/to/conda/Scripts",
// conda安装目录Scripts文件夹
"python.venvPath": "/path/to/conda/envs",
// 虚拟环境目录,VSCode会在其中查找虚拟环境,作为
// Command Palette中的备选项
"python.pythonPath": "/path/to/python.exe",
// 默认python解释器路径
"python.terminal.activateEnvironment": true,
// 创建python shell时,尝试中激活虚拟环境
}
  • python.terminal.activateEnviroment激活的虚拟环境由 python.pythonPath决定

    • VSCode会尝试执行python.pythonPath同级中 Scripts/activate.bat激活虚拟环境

    • 因此虚拟环境需要安装conda,否则没有 Scripts/ativate.bat无法正常激活默认虚拟环境

CPPC

配置文件

  • .vscode/c_cpp_properties.json

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    {
    "configurations": [
    {
    "name": "WSL",
    "includePath": [
    "${workspaceFolder}/**"
    ],
    "defines": [
    "LOCAL",
    "_DEBUG",
    "UNICODE",
    "_UNICODE"
    ],
    "compilerPath": "/usr/bin/gcc",
    "cStandard": "c11",
    "cppStandard": "c++14",
    "intelliSenseMode": "gcc-x64"
    }
    ],
    "version": 4
    }
    • C/C++项目基本配置
  • .vscode/tasks.json:利用VSCode的Tasks功能调用WSL的 GCC/G++编译器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    {
    // tasks.json
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format

    "version": "2.0.0",
    "tasks": [
    {
    "label": "Build",
    "command": "g++",
    "args": [
    "-g",
    "-Wall",
    "-std=c++14",
    "/mnt/c/Users/xyy15926/Code/cppc/${fileBasename}",
    "-o",
    "/mnt/c/Users/xyy15926/Code/cppc/a.out",
    "-D",
    "LOCAL"
    ],
    "problemMatcher": {
    "owner": "cpp",
    "fileLocation": [
    "relative",
    "${workspaceRoot}"
    ],
    "pattern": {
    "regexp": "^(.*):(\\d+):(\\d+):\\s+(warining|error):\\s+(.*)$",
    "file": 1,
    "line": 2,
    "column": 3,
    "severity": 4,
    "message": 5
    }
    },
    "type": "shell",
    "group": {
    "kind": "build",
    "isDefault": true
    },
    "presentation": {
    "echo": true,
    "reveal": "silent",
    "focus": true,
    "panel": "shared"
    }
    },
    {
    "label": "Run",
    "command": "/mnt/c/Users/xyy15926/Code/cppc/a.out",
    "type": "shell",
    "dependsOn": "Build",
    "group": {
    "kind": "test",
    "isDefault": true
    },
    "presentation":{
    "echo": true,
    "reveal": "always",
    "focus": true,
    "panel": "shared",
    "showReuseMessage": true
    }
    }
    ]
    }
    • 这里为方便将运行程序任务同> Task: Run Test Task 任务关联,可以在命令面板执行此指令
  • .vscode/launch.json:gdb调试配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    {
    // launch.json
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
    {
    "name": "(gdb) Bash on Windows Launch",
    "type": "cppdbg",
    "request": "launch",
    "program": "/mnt/c/Users/xyy15926/Code/cppc/a.out",
    "args": ["-f", "Threading"],
    "stopAtEntry": false,
    "cwd": "/mnt/c/Users/xyy15926/Code/cppc/",
    "environment": [],
    "externalConsole": true,
    "MIMode": "gdb",
    "pipeTransport": {
    "debuggerPath": "/usr/bin/gdb",
    "pipeProgram": "C:\\windows\\system32\\bash.exe",
    "pipeArgs": ["-c"],
    "pipeCwd": ""
    },
    "setupCommands": [
    {
    "description": "Enable pretty-printing for gdb",
    "text": "-enable-pretty-printing",
    "ignoreFailures": false
    }
    ],
    "sourceFileMap": {
    "/mnt/c": "c:\\",
    "/mnt/d": "d:\\"
    },
    "preLaunchTask": "Build"
    },
    ]
    }

Git

1
2
3
4
{
"git.ignore.MissingGitWarning": true,
"git.path": "/path/to/xxxgit.exe"
}
  • “git.path”既可以是windows下Git,也可以是“伪装”Git,使用 工具wslgit,让VSCode 直接使用WSL内的Git

KeyMapper

  • <c-s-\>`:新建默认terminal绘画
  • <c-s-p>:command palette

网络设置

VMware网络模式

虚拟网络组件

虚拟交换机

Virtual Network Editor中默认有三个虚拟交换机

  • VMnet0(Bridged):桥接模式下的虚拟交换机
  • VMnet1(Host-only);仅主机模式下的虚拟交换机
  • VMnet8(NAT):NAT模式下虚拟交换机

虚拟网卡

在宿主机上安装完成VMware后,在网络适配器中会安装有两块 虚拟网卡

  • VMware Network Adapter VMnet1:主机模式下虚拟网卡
  • VMware Network Adapter VMnet8:NAT模式下虚拟网卡

卸载虚拟网卡后,可以Virtual Network Editor->还原默认设置, 还原虚拟网卡

Bridged

桥接模式:将主机网卡同虚拟机网卡利用虚拟网桥进行通信

  • 网络结构

    • 在桥接作用下,类似从物理主机虚拟出一个交换机
    • 所有桥接设置的虚拟机都连接到这个交换机的接口上
    • 物理主机也同样连接在此交换机上
    • 虚拟机就像是外部局域网中的独立主机,同宿主机逻辑上 同等地位
  • 网络连通性

    • 所以桥接下的网卡与网卡的都是交换模式的, 可以相互访问,不受干扰
    • 虚拟机可以在外部网络上可见
  • 机器网络配置

    • 虚拟机IP地址需要和宿主机在同一网段(外网网段)
    • 需要手动配置虚拟机配置IP地址、子网掩码
    • 若需要联网,虚拟机Gateway、DNS需要和主机一致

vmware_bridged

适用场景

  • 利用VMware在局域网中新建虚拟服务器,位局域网提供网络服务
  • 网络环境ip资源充裕

网络设置

  • 宿主机网络连接

    • 网络连接属性中VMware Bridge Protocal是否勾选 (安装VMware后一般会默认勾选)
    • 确认宿主机:IP、Gateway、DNS
  • 虚拟机网络设置

    • 编辑虚拟机设置->网络适配器->Bridged/桥接模式
  • 虚拟机网卡配置:网卡配置文件方式参见config_file

    • IP地址要和宿主机IP在同一网段
    • Gateway默认网关要和宿主机一致

NAT

Network Address Translation:网络地址转换,借助 虚拟NAT设备虚拟DHCP服务器,使得虚拟机能够联网

  • 网络结构

    • 主机网卡与虚拟NAT设备相连
    • 虚拟NAT设备、虚拟DHCP服务器、虚拟机共同连接在虚拟 交换机VMnet8上
    • VMnet8通过虚拟网卡VMware Network Adapter VMnet8和 宿主机相连,宿主机成为双网卡主机,同时参与宿主网络 和虚拟网络
  • 网络连通性

    • 借助虚拟NAT设备连通宿主机网卡、虚拟机,实现了 虚拟机通过宿主机网卡联网,所以虚拟机在外部网络 不可见
    • VNAV8连通宿主机、虚拟机,使得宿主机可以和虚拟机连通 ,要注意此时宿主机双网卡,连通虚拟局域网的网卡是虚拟 网卡
    • 虚拟网卡只是起连通虚拟机、宿主机的作用,卸载不影响 虚拟机连通外网
  • 机器网络配置

    • 由于虚拟DHCP服务器的存在,虚拟机无需特殊配置,只需要 启用虚拟机网卡DHCP服务即可

vmware_nat

适用场景

  • 虚拟系统介入互联网简单,不需要其他配置,只需要宿主机能 访问网络即可
  • 网络ip资源紧缺,且需要虚拟机能够联网

网络配置

  • 宿主机服务设置

    • 检查宿主机VMware DHCP ServiceVMware NAT Service 服务是否启动(VMware安装一般默认启动此服务)
  • Virtual Network Eidtor配置

    • VMnet8虚拟交换机默认为NAT模式
    • 配置VMnet8->子网IPVMnet8->子网掩码
    • 配置VMnet8->NAT设置VMnet8->DHCP参数
  • 虚拟机网络配置

    • 编辑虚拟机设置->网络适配器->NAT模式
  • 虚拟机网卡配置

    • NAT虚拟网络有DHCP服务,只需要修改BOOTPRPOTO=dhcp, 使用DHCP协议即可
    • 也可以设置静态ip,但是需要注意要在DHCP范围内

Host-Only

仅主机模式:将虚拟机与外网隔开,使得虚拟机成为独立系统,只和 主机相互通讯

  • 网络结构:类似于NAT模式

    • NAT模式去除了虚拟NAT设备
    • 使用VMware Network Adapter VMnet1虚拟网卡连接宿主机 、VMnet1交换机
    • 虚拟局域网可以认为是单独从属当前宿主机的私有网络
  • 连通性

    • 虚拟机网络、真实网络相互隔离,两者不相互连通
    • 宿主机、虚拟机相互通过虚拟网卡VNAV1相互连接
    • 事实上,可以在宿主机中设置,通过将主机网卡共享给 虚拟网卡VNAV1实现虚拟机联网

vmware_host_only

适用场景

  • 特殊的网络调试环境下,要求真实环境、虚拟环境隔离开

网络设置

  • 虚拟机网络设置

    • 编辑虚拟机设置->网络适配器->Host-only/仅主机模式
  • Virtual Network Eidtor配置:类似于NAT模式,只是VMnet1 虚拟交换机才默认为Host-only模式

  • 虚拟机网卡配置:类似NAT模式

共享宿主机网卡

Host-only模式下下,虚拟局域网默认无法联网,需要将宿主机网卡 共享给给虚拟网卡VNAV8才能实现联网

  • 网络连接->属性->共享->选择VMAV1

  • 共享宿主机网卡可能会要强制修改虚拟网卡VMAV1的ip地址, 需要根据提示在虚拟网络编辑其中修改虚拟网络的DHCP参数 host_only_network_sharing

  • 然后修改虚拟网卡Gateway、DNS为VMAV1的ip地址

Windows Linux Subsystem

说明

WSL是一个兼容层,类似反过来的Wine,但更底层

  • Linux、Windows程序不兼容,是因为二者内核提供的接口不同

    • ls/dir命令
      • 在Linux下调用getdents内核调用
      • 在Windows下调用NtQueryDirectoryFile内核调用
  • WSL提供Linux内核接口,并转换为NT内核接口

    • 在WSL中执行ls仍然调用getdents
    • WSL收到请求,将系统调用转换为NT内核接口 NTQueryDirectoryFile
    • NT内核收到WSL请求,返回执行结果
    • WSL将结果包装后返回
  • 毕相较于真正Linux系统仍然有不足

    • Docker等涉及未实现的内核特性软件如法使用
    • Raw socket相关相关操作容易出错
    • I/O性能相对孱弱

Cygwin对比

wsl_architecture

  • Cygwin提供了完整的POSIX系统调用API(以运行库 Cygwin*.dll形式提供,但是仍然工作在User Mode

    • Cygwin将POSIX系统调用转换为Win32 API(因为其架设在 Win32子系统上),很多内核操作(如:fork)受限于 Win32实现

    • Linux应用程序必须链接到Cynwin*.dll,需要修改源码 重新编译后才能执行,这样应用程序才不会直接请求内核, 而是调用Cygwin运行库,且编译出的可执行文件为 Win32 PE格式封装,只能在Windows下执行

  • WSL中Linux应用程序进程被包裹在Pico Process中,其发出的 所有系统调用会被直接送往Kernel Mode中的 lxcore.syslxss.sys

    • WSL将POSIX系统调用转换为更底层的NP API调用(WSL和 Win32平行,直接架设在NT内核上)

    • 可以直接执行ELF格式封装的Linux可执行程序

启用

  • 控制面板 ->
  • 程序和功能 ->
  • 启用或关闭windows功能 ->
  • 适用于Linux的Windows子系统

其他

使用

进入WSL

除在图形界面中点击图标,以默认参数启动,还可以在terminal (cmd/powershell等)自定义进入WSL参数

  • wsl.exe:打开默认发行版中默认shell
  • distroname.exe:打开指定发行版中默认shell
  • bash.exe:打开默认发行版中bash shell
  • 这些应用程序默认在path中,可以直接执行

版本管理

  • wslconfig.exe可以用于管理多个子系统的发行版

WSL、Windows互操作

文件

  • Windows所有盘符挂载在WSL中/mnt目录下

  • WSL中所有数据存放在%HOME%/AppData/Local/Packages/{linux发行包名}/LocalState/rootfs

    • 不要在Windows下直接修改,造成权限错误

命令

  • 在cmd中直接调用WSL命令
    1
    2
    PS> wsl [-e] ls -al
    // wsl带参数执行
  • 在WSL中调用Windows命令行程序(在$PATH中)

    1
    2
    $ which ipconfig.exe
    $ ipconfig.exe
  • 在WSL中启动Windows应用(在$PATH中)

    1
    $ notepad.exe
  • 通过pipes通信

    1
    2
    $ cat foo.txt | clip.exe
    PS> ipconfig | wsl grep IPv4

端口、环境变量

  • WSL与Windows共享端口(NT内核?)
  • WSL继承Windows的部分环境变量,如:PATH

Terminal推荐

  • wsl-terminal: 专为WSL开发的终端模拟器,基于minttywslbridge,稳定 易用

  • ConEmu:老牌终端模拟器, 功能强大

  • Hyper:基于Electron的跨平台 终端模拟器

WSL-Terminal

  • WSL-Terminal中包含一些快捷工具

    • tools目录中包含一些脚本,可以通过wscripts.exe 执行修改注册列表,添加一些功能
      • 添加WSL中vim、emacs等打开到右键菜单
      • 添加在WSL中打开文件夹到右键菜单
    • run-wsl-file.exe可以用于在快捷执行wsl脚本,只需要 将其选择为文件打开方式
    • vim.exe可以用WSL中vim打开任何文件,当然一般是配合 tools/中脚本在右键注册后使用
  • 配置

    • 配置文件etc/wsl-terminal.conf
    • 主题文件etc/themes/
    • mintty配置文件etc/mintty

其他问题

文件权限问题

  • 在WSL中,windows实现了两种文件系统用于支持不同使用场景

VolFs

VolFs:着力于在windows文件系统上提供完整的linux文件系统特性 ,通过各种手段实现了对InodesDirectory EntriesFile ObjectsFile DescriptorsSpecial File Types 的支持

  • 为支持Inodes,VolFS会把文件权限等信息保存在 NTFS Extended Attributes

    • 在Windows中新建的文件缺少此扩展参数,有些编辑器也会 在保存文件是去掉这些附加参数
    • 所以不要在Windows中修改WSL文件,否则VolFs无法正确 获得文件metadata
  • WSL中/就是VolFs文件系统

DrvFs

DrvFs:着力提供于Windows系统的互操作性,从Windows的文件权限 (即文件->属性->安全选项卡中的权限)推断出文件对应Linux权限

  • 所有windows盘符挂在在WSL中/mnt是都使用DrvFs文件系统

  • 由于DrvFs文件权限继承机制很微妙,结果就是所有文件权限 都是0777

    • 所以ls结果都是绿色的
    • 早期DrvFs不支持metadata,在Build 17063之后支持 文件写入metadata,但是需要重新挂载磁盘
  • 可以通过设置DrvFs metadata设置默认文件权限

    1
    2
    3
    4
    5
    $ sudo umount /mnt/e
    $ sudo mount -t drvfs E: /mnt/e -o metadata
    // 此时虽然支持文件权限修改,但默认权限仍然是*0777*
    $ sudo mount -t drvfs E: /mnt/e -o metadata,uid=1000,gid=1000,umask=22,fmask=111
    // 此时磁盘中默认文件权限为*0644*
  • 更合适的方式是通过/etc/wsl.conf配置DrvFs自动挂载属性

AutoMatically Configuring WSL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 # `/etc/wsl.conf`
[automount]
# 是否自动挂载
enabled = true
# 是否处理`/etc/fstab`文件
mountFsTab = true
# 挂载路径
root = /mnt/
# DrvFs挂载选项,若需要针对不同drive配置,建议使用`/etc/fstab`
options = "metadata,umask=023,dmask=022,fmask=001"
[network]
generateHosts = true
generateResolvConf = true
[interop]
# 是否允许WSL载入windows进程
enabled = true
appendWindowsPath = true
  • 如果需要给不同盘符设置不同挂载参数,需要修改 /etc/fstab

    1
    E: /mnt/e drvfs rw,relatime,uid=1000,gid=1000,metadata,umask=22,fmask=111 0 0