在 Windows 寫 Linux 程式:Visual Studio + Windows Subsystem for Linux


微軟的 VIsual Studio 在 Heresy 來看,算是 Windows 上最好的 C++ 開發環境,但是缺點就是沒有 Linux 版了。不過,微軟在這幾年正積極地往跨平台、開放原始碼的方向走,所以這部分的狀況倒也有些改變了~

在 2015 年,微軟也已經發表了跨平台的開發環境、Visual Studio Code,雖然還是沒有開放原始碼,但是也算是聊勝於無了。而同時,Visual Studio 2015 也加入了跨平台的程式開發功能!除了 Windows 外,也支援了 Android、iOS 以及 Linux~(不過當時 Heresy 想測試 Linux 的偵錯一直沒有成功就是了…)

這篇,則是 Heresy 看到微軟的 Visual C++ Team Blog 的《Targeting the Windows Subsystem for Linux from Visual Studio》後,才想起可以嘗試讓 Visual Studio 搭配 Windows 10 的 Bash on Ubuntu on Windows(Windows Subsystem for Linux、以下簡稱 WSL)來在單台 Windows PC 上、進行 Linux 上的 C++ 程式開發、偵錯

這篇的基本需求,主要是:

要透過 Visual Studio 來開發 Linux 上的程式,主要是透過 SSH 來連到一個 Linux 系統來進行的;而偵錯的部分,則是會使用 gdbserver 來進行,也可以支援中斷點、以及中斷時的變數監控。

下面就是簡單的環境設定紀錄:


WSL 的設定

  1. 安裝必要的套件

    由於實際上會在 WSL 的環境下,進行程式的編譯,所以必須要安裝編譯程式時,所需要使用到的套件;一般來說就是 g++ 、make 等套件了~而根據專案的不同,也會需要安裝必要的函式庫。

    官方建議的安裝命令,是直接安裝「build-essential」:

    sudo apt install build-essential

    不過,由於接下來要使用 Visual Studio 透過 SSH 連線來做遠端編譯的控制,所以還需要安裝「openssh-server」;而如果還要遠端偵錯的話,也還需要安裝「gdbserver」。

    所以這邊也可以透過下面的指令,來安裝這兩個套件:

    sudo apt install openssh-server gdbserver

  2. 設定 SSH Server

    在將套件安裝好了之後,接下來則是要針對 OpenSSH Server 做基本的設定。他的設定檔是「/etc/ssh/sshd_config」,只要以系統管理員權限、使用文字編輯器打開就可以了。

    這邊官方的範例是使用 nano 這個簡易式的文字編輯器,其指令為:

    sudo nano /etc/ssh/sshd_config

    至於要修改的地方呢,官方只有說要將「PasswordAuthentication」的值由「no」改為「yes」,但是不確定是否是版本不同的關係,Heresy 只改這項還是不能用。

    摸了好一陣子後,最後總共要修改三個地方才行:

    # What ports, IPs and protocols we listen for 
    Port 22222
    
    #Privilege Separation is turned on for security 
    UsePrivilegeSeparation no
    
    # Change to no to disable tunnelled clear text passwords 
    PasswordAuthentication yes

    其中,要把 port 由 22 改成其他 port(這邊是 22222)的原因,是因為在新版的 Windows 10 中,在某些狀況下似乎有內建 SSH Server、並且也是處於啟動狀態(參考《Windows 10 Insider: integrated SSH server》) ,所以如果不改成 22 以外的連接埠的話,會無法正確連線到 WSL 中的 OpenSSH Server。

    在修改好了之後,只要按 Ctrl + X,然後再按 y,就可以儲存修改的內容了。

    而在都設定好了之後,接下來還要產生一組 SSH 的金鑰,其指令是:

    sudo ssh-keygen -A

  3. 啟動 SSH Server

    上面的設定步驟,基本上都是只要做一次的設定,當設定好了之後,以後就會存下來,不用每次都重新跑一次。

    不過,由於 WSL 的設計並不支援自動啟動的背景服務,所以 SSH Server 不但無法自動啟動、當每次把 bash 視窗關閉時,已經開啟的 SSH Server 也都會被自動關閉。

    所以,每次要使用時,都需要手動啟動 OpenSSH Server!其指令是:

    sudo service ssh start

    而在開啟後,也記得在還需要連線時都不要把 bash 視窗關閉,以避免 SSH Server 被關閉。

    另外,在 Heresy 這邊,雖然會出現「initctl: Unable to connect to Upstart: Failed to connect to socket /com/ubuntu/upstart: Connection refused」的警告,不過還是可以正確地開啟 SSH Server。


Visual Studio 的基本使用

Visual Studio 2015 安裝好 Visual C++ for Linux Development 後,在建立新專案時,可以在 Visual C++ 下的「跨平台」中,找到「Linux」的分類,這邊會有一些範例專案可以選擇:

而最簡單的,應該就是先選「Console Application (Linux)」來做測試;如此一來,他會建立一個只有「main.cpp」的專案,讓開發者可以做後續的修改。

當第一次要編譯這個專案的時候,他會跳出一個「Connect to Linux」對話框、要求使用者輸入 Linux 機器的設定。

這邊由於是連到本機上 WSL 的 SSH Server,所以「host name」就是「127.0.0.1」、port 則是前面設定的數值;之後再把「authentication type」改成「password」,然後再輸入 WSL 的帳號、密碼,按下「Connect」就可以了。

而之後如果要修改設定的話,也可以在 Visual Studio 的「工具」、「選項」中的「Cross Platform」中,找到「Connection Manager」來做刪除、新增。

如果一切順利的話,Visual Stuio 在編譯後會在「輸出」的視窗中,出現下面的紀錄:

1>------ 已開始建置: 專案: LinuxConsole, 組態: Debug x64 ------
1>  Validating architecture
1>  Validating sources
1>  Copying sources remotely
1>  Starting remote build
1>  Compiling sources:
1>  main.cpp
1>  Linking objects
1>  LinuxConsole.vcxproj -> E:\VIML\LinuxConsole\LinuxConsole\bin\x64\Debug\LinuxConsole.out
========== 建置: 1 成功、0 失敗、0 最新、0 略過 ==========

可以看到,他會先把檔案複製到遠端、然後在遠端進行編譯。

而如果是以偵錯模式來進行除錯的話,也可以按照 VIsual Studio 本來的操作習慣,加入中斷點來偵錯!而此時也可以看到各變數的值。

而如果程式在執行階段會當掉的話(例如 Segmentation fault),Visual Studio 也會停在死掉的那行,讓開發者可以根據當下的狀況,來判斷問題是什麼~


整體來說,透過這樣的機制,可以讓熟系 VIsual Studio 的開發者,以熟悉的方式、介面、來開發 Linux 上的程式;並可以使用 Visual Studio 的圖形介面,來做方便的除錯!在 Heresy 來看,如果是 Linux 程式有問題的時候,應該算是一個滿方便的方案~

不過,Heresy 這邊碰到一個問題,就是這樣透過 WSL 執行的時候,看不到程式輸出的內容啊!另外,如果是要跑有圖形介面的程式,大概還是很難透過 WSL 來做吧…

除此之外,Heresy 覺得他最大的缺點應該是還需要另外建立一個專案,而不能以現有專案的額外組態來做設定,感覺算是比較麻煩的地方。不過,必要時應該還算可以拿來玩的東西吧?


額外參考:Linux 工程師新法寶 – 在 Visual Studio 上用 C++ 寫 Linux 程式

對「在 Windows 寫 Linux 程式:Visual Studio + Windows Subsystem for Linux」的想法

  1. […] 另外,上面也可以看到,現在 C++ 的專案甚至還可以把編譯工具切換成「Clang with Microsoft COdeGen」、透過 Clang 這個 LLVM 的編譯器來建置程式~所以如果要玩跨平台的話,應該可以更方便地測試了!至於 gcc 呢?目前還是得用比較麻煩的方法才行了。 […]

發表留言

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料