使用VS 2019進行Linux遠程開發

2020-12-11 51cto

通常,當我們開發Linux程序時有兩種方案:

  • 在Linux上直接編寫程序並進行運行測試和調試
  • 在Windows或Mac OS X上藉助工具進行遠程開發

雖然我自己是在Linux環境上直接進行開發的,但也有許多的人是在Windows環境上從事開發工作的,如果離開自己熟悉的系統到陌生的環境上也許會影響到工作效率。

因此今天我們就來看下如何在Windows上使用Visual Studio 2019進行Linux遠程開發以及如何避免常見的陷阱。

Visual Studio的跨平臺開發功能簡介

從Visual Studio 2017開始微軟推出了VS的跨平臺開發功能,你可以在VS中編輯代碼,隨後進行跨平臺編譯和遠程調試,將原先我們需要手動完成的工作進行了自動化,大幅減輕了我們的負擔。其中支持的平臺包括Android和Linux,也就是我們今天要重點介紹的主角。

也許你會好奇,VS究竟是怎樣進行遠程開發的,雖然你不用了解這些知識也可以進行開發,但我還是希望能用兩分鐘做個簡短的解釋。

VS進行遠程開發分為兩步:

  1. 創建遠程環境的連接,隨後讓vs將遠程環境中的系統頭文件同步到本地(也可以指定其他地方的頭文件,後面會講解),c++的代碼補全只需要頭文件即可。
  2. 當代碼寫好後,選擇合適的遠程環境,vs將目標文件和代碼複製到遠程環境的指定位置,接著根據你的配置進行編譯。
  3. 隨後vs將會在console的gdb或gdbserver中運行你的程序,在此期間你可以充分享受vs debugger帶來的高效和便利。

經過上述步驟之後你就可以在vs裡調試自己編寫的跨平臺程序了。

使用 VS 2019進行Linux遠程開發

簡介到此結束了,下面我們來看看在VS 2019進行Linux開發的圖文教程。在我們開始之前,首先要做點準備工作:

  1. 安裝好VS 2019,且勾選了C++ for Linux功能;
  2. 準備一個可用的Linux遠程環境,例如配置了靜態IP的Linux虛擬機,並且已經安裝好了GCC工具鏈以及openssh。

做好準備後我們就該進入正題了。

創建項目

安裝好C++ for Linux功能後我們會在創建新項目的面板中看到Linux的選項,如圖:

這裡我們選擇了使用傳統的vs項目解決方案構建的空白控制臺程序,後續的文章中你還可以看到如何創建cmake項目,這裡暫且不提。

下面沒什麼要說的,選擇項目的存儲位置,注意是本地的位置,遠程機器的位置在後面會進行配置:

點擊創建,我們的遠程開發項目就創建成功了。

配置遠程項目

VS不能編輯空項目的配置,所以我們先在項目中創建一個main.cpp,然後點擊頂部菜單:項目->屬性,你就能看到項目的配置界面了:

遠程計算機是在調試中的遠程連接管理器中添加的。這裡一般不需要改動,除非你需要改變項目的類型或編譯結果的存放位置。如果有多個遠程環境時,也可以在這裡進行選擇。

調試部分提供了gdb和gdbserver,前者是讓VS在Linux上啟動一個console,然後在其中運行gdb並返回輸出,如果你的Linux上的終端配置了彩色輸出,那麼和遺憾vs並不認識他們,會顯示成原始的字符串;

使用gdbserver時會在遠程啟用gdbserver 本地VS解析回傳的數據不會出現雜音。

這裡我們選擇了gdbserver,如果你發現無法打斷點,那麼參考微軟的建議,換回gdb方案:

接著是配置的重點,首先是配置需要同步的遠程環境的頭文件,有了這些文件vs才能對你的代碼進行自動補全和提示:

默認複製的路徑通常已經包含了Linux上大部分的頭文件,通常我們也不需要做更改。頭文件的同步發生在***次構建項目成功後或添加遠程連接後手動同步。

接著是C/C++編譯器的選擇,也就是對gcc和g++編譯參數的配置,講解這些參數超出了我們的討論範圍,我們這裡只需要選擇合適的C++標準版本:

這裡我們選擇了c++17。其他設置與在Windows上進行開發時一樣,vs可以自動轉換成g++的參數,這裡就不再贅述。

添加遠程環境

有了遠程環境我們才能同步頭文件或者進行調試運行。

在***次編譯或調試你的項目時vs會自動讓你連接遠程環境,當然,我們推薦在調試->選項->跨平臺->連接管理器中進行設置:

填入你的遠程ip/域名,埠ssh默認為22,安全起見你需要修改成其他埠,這裡方便演示使用了默認配置,密碼同上,你應該考慮使用更安全的ssh私鑰登錄。

登錄成功後這個連接就添加完成了,我們看到管理器下面還有一個遠程標頭管理器的設置項,這就是用來同步頭文件的:

點擊更新按鈕就會開始同步頭文件,這些文件會被緩存在本地,因為要從遠程一次性複製大量文件,所以可能會花費較長的時間。

這樣遠程環境就添加好了,可以開始寫代碼了。

本地編寫和遠程調試

至此你已經可以在VS中編寫面向Linux平臺的代碼了,自動補全可以正常工作:

可以看到Linux中的頭文件和結構體都已經可以識別了。如果你發現無法自動補全(通常發生在剛添加遠程連接或是項目設置發生了變化後),先試試關閉vs重新打開,如果沒用請嘗試刷新intellisense或重新同步頭文件。

在編輯結束後我們就能點擊調試按鈕運行我們的程序了:

注意,構建的體系架構必須是和遠程環境一致的,比如遠程環境是x64,這裡可以選擇x64或x86,但是不能選擇arm,否則會報錯。

這是測試代碼,它將輸出當前Linux系統內核的版本:

  1. #include <sys/utsname.h> 
  2. #include <iostream> 
  3. #include <cstdio> 
  4. int main() 
  5.     auto start = chrono::high_resolution_clock::now(); 
  6.     utsname names; 
  7.     if (uname(&names) != 0) { 
  8.         std::perror("cannot get unames"); 
  9.     } 
  10.     std::cout << "Linux kernel version: " << names.release << std::endl; 

點擊調試->Linux 控制臺,會顯示一個可以交互的console,你可以在其中輸入內容或是看到程序的輸出:

程序運行成功。

避免踩坑

遠程編譯順利完成後,我們就可以接著利用vs debugger設置斷點,在斷點處查看變量,甚至對運行中的Linux進行動態性能分析了。

不過在此之前,還有一些坑需要提前踩掉。

中文亂碼

編碼問題帶來的麻煩永遠會被放在***位,畢竟當人們看到預想的輸出實際上是一堆亂碼時總會不可避免得緊張起來。

眾所周知,編碼問題一直是老大難,特別是Windows上中文環境通常是GB18030或GBK,而Linux上統一為utf8時。

下面看個實際例子,通常我們的程序裡只包含ASCII字符的話不容易產生問題,所以我們加上一點中文字符:

  1. #include <sys/utsname.h> 
  2. #include <iostream> 
  3. #include <cstdio> 
  4. #include <string> 
  5.  
  6. int main() 
  7.     utsname names; 
  8.     if (uname(&names) != 0) { 
  9.         std::perror("cannot get unames"); 
  10.     } 
  11.     std::cout << "Linux kernel version: " << names.release << std::endl; 
  12.     std::cout << "輸入內容:"
  13.     std::string input; 
  14.     std::cin >> input; 
  15.     std::cout << "你輸入了:" << input << std::endl; 

對於上面的測試程序,我們添加了一點中文輸出信息,現在打開控制臺進行調試:

可以看到中文輸出變成了亂碼,我們輸入一些信息進去,這是運行結果:

可以看到,程序內寫入的中文發生了亂碼,而我們的輸入沒有。原因很簡單,輸入時實在linux的控制臺環境下,編碼默認是utf8的,所以我們的輸入被正確編碼,而源文件中的內容是GB18030的,所以在Linux控制臺(默認以utf8解碼數據並顯示)中會發生亂碼。

錯誤的原因知道了解決起來也就很簡單了,把源文件的編碼改成utf8就行,我們選擇最簡單的方法,在高級保存選項中修改編碼(這個菜單選項默認被隱藏,網上有很多介紹如何顯示它的方法的資料):

設置好後保存文件,現在文件的編碼已經被改為了utf8了。

現在運行修改後的程序:

運行結果也是正常的:

使用數學函數和第三方庫

在Linux上使用標準庫提供的數學函數也是一個老生常談的問題,根據你使用cpp還是C會有如下幾個情況:

使用cpp時,libstdc++依賴於libm,所以使用g++編譯你的程序時會自動連結數學函數庫;

使用c時,如果是sqrt(4)這樣的形式,較新的gcc提供了替換措施,不需要顯示連結libm;

接上一條,如果你的參數是個變量,那麼編譯器可能會選擇需要你連結libm。

通常在Windows上我們無需操心這點,但在Linux上使用c語言時就很難忽略這個問題了。

因此保險起見,如果你正在編寫一個使用了數學函數的c程序,那麼總是指定連接libm是沒錯的。(具體可以參考http://www.linuxforums.org/forum/programming-scripting/125526-c-gcc-math-h-lm.html)

另外當你使用例如boost這類第三方庫時,也需要注意。在Windows上我們通常指定好附加包含目錄和附加庫目錄即可正常編譯,但是Linux上必須明確指定連結庫的名字,因此我們在項目屬性中進行設置。

在Linux上我們可以使用pkg-config來減輕上述的重複勞動,而在vs中我們不能直接利用這一工具,當你的項目使用了大量第三方庫時就會成為不小的麻煩,如果想要解決這一問題,可以參考後續文章裡我會介紹的vs+cmake構建項目。

下面我們給例子加上一點boost chrono的功能測試,在Linux上需要指定-lboost_chrono,這是設置:

下面是完整的代碼:

  1. #include <sys/utsname.h> 
  2. #include <iostream> 
  3. #include <cstdio> 
  4. #include <string> 
  5. #include <boost/chrono.hpp> 
  6.  
  7. int main() 
  8.     namespace chrono = boost::chrono; 
  9.     auto start = chrono::high_resolution_clock::now(); 
  10.     utsname names; 
  11.     if (uname(&names) != 0) { 
  12.         std::perror("cannot get unames"); 
  13.     } 
  14.  
  15.     std::cout << "Linux kernel version: " << names.release << std::endl; 
  16.     std::cout << "輸入內容:"
  17.     std::string input; 
  18.     std::cin >> input; 
  19.     std::cout << "你輸入了:" << input << std::endl; 
  20.     auto counter = chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start); 
  21.     std::cout << "程序運行了:" << counter.count() << "ms\n"

點擊運行按鈕,程序就能正常調試了,否則會報錯:

【編輯推薦】

【責任編輯:

武曉燕

TEL:(010)68476606】

點讚 0

相關焦點

  • VS Code Remote 發布!開啟遠程開發新時代
    北京時間 2019 年 5 月 3 日,在 PyCon 2019 大會上,微軟發布了 VS Code Remote,開啟了遠程開發的新時代!你可以: 在部署相同的作業系統上進行開發,或者使用更大或更專業的硬體。 把開發環境作為沙箱,以避免影響本地計算機配置。 讓新手輕鬆上手,讓每個人都保持一致的開發環境。 使用原本在本地環境不可用的工具或運行時,或者管理它們的多個版本。 在 WSL 裡開發 Linux 應用。
  • 使用密鑰認證機制遠程登錄linux
    Linux一般作為伺服器使用,而伺服器一般放在機房,你不可能在機房操作你的Linux伺服器。這事我們就需要遠程登錄到Linux伺服器來管理維護系統。Linux系統中是通過ssh服務實現的遠程登錄功能,默認ssh服務埠號為 22。
  • 沒有公網IP,花生殼+SSH實現Windows連接遠程Linux執行命令
    在我們學習、工作中,常遇到需要使用Windows系統的電腦,來訪問遠程Linux系統進行相關部署操作,但遠程Linux系統服務與本地Windows不在同一個區域網,而且Linux系統所在的外網IP是動態變化的,那麼,有沒有簡單、高效的辦法解決這個遠程訪問難題?
  • 適用於kali linux的遠程桌面開啟方法
    適用於 kali linux 的遠程桌面開啟方法 ( 從 windows xp  遠程登錄到 kali linux )為了解決 Windows
  • 用Visual Studio調試Linux程序
    使用Visual Studio+VisualGDB調試遠程linux程序需要工具:Visual Studio 2013或以上版本(以下簡稱VS)VisualGDB(一款VS插件,官網為:http://visualgdb.com/)含有調試符號的linux程序文件(該程序文件為調試目標)Visual Assistant(番茄助手
  • 在Visual Studio Code 中像本地一樣連接遠程進行Python開發
    在PyCon 2019大會上,微軟VSC團隊和Python團隊宣布發布VSC的Python遠程開發組件,實現在VSC中遠程連接docker容器、SSH連接服務,以及遠程連接Windows WSL Linux子系統實現無縫Python開發。本文蟲蟲就給大家介紹一下這個遠程開發插件。
  • Linux下scp命令使用教程
    scp是secure copy的簡寫,用於在Linux下進行遠程拷貝文件的命令,scp傳輸是加密的,可能會稍微影響一下速度其佔用的系統資源非常小。非常適合遠程文件的拷貝。本篇我們就詳細介紹下scp的用法。
  • 如何使Java程式設計師擁有高效率的開發環境
    如何使Java程式設計師擁有高效率的開發環境 作為一名程式設計師,好的開發環境可以提升你的工作效率,事半功倍。那麼一名Java程式設計師應該擁有什麼樣的開發工具呢。
  • WinSCP軟體雙系統(Win-Linux)文件傳輸教程
    WinSCP軟體是windows下的一款使用ssh協議的開源圖形化SFTP客戶端,也就是一個文件傳輸的軟體,它有什麼優點嗎,咱們嵌入式開發中經常會將windows中的文件複製到linux系統當中,比較常用的方式就是添加共享文件夾,每次通過添加的共享文件夾來相互傳輸文件,這裡介紹的是一款能夠跨系統使用的文件傳輸軟體。
  • Linux系統從入門到放棄?
    Linux是一個命令行組成的作業系統,精髓在命令行,學習如何在Linux環境中執行linux命令,包括有關文件、目錄、文件系統、進程等概念,如何使用相應的命令對文件、目錄、進程等進行管理,了解遇到問題時,如何找到幫助信息等等。都將是我們學習入門Linux的第二大步。
  • IT運維工程師們為什麼選擇使用Linux系統
    linux自誕生之日起,便受到了全世界優秀黑客程式設計師們的百般寵愛與關注。曾經,linux似乎離我們非常遙遠;而現在,越來越多的人聽說了linux,會去討論linux發行版,會去關注linux內核。而程式設計師們更是熱衷於使用linux,在linux開發。
  • deepin使用遠程工具控制windows系統
    #deepin國產作業系統#遠程連接功能可以提高工作效率1、在應用商店裡查找「遠程桌面查看器」,找到相應軟體後,點擊下載即可安裝在deepin作業系統中。2、安裝完成後,打開遠程桌面查看器軟體。界面如下:3、遠程菜單欄中,有連接功能,也就是連接遠程主機使用的功能,工具欄第一項也是它。最近連接會記錄常用的連接地址,方便使用。
  • 最簡單的虛擬機下安裝Linux並實現遠程登陸控制
    (面向對象是新手 所以我們選擇在虛擬機上安裝Centos)下載vmware(虛擬機),centOs7(系統),xshell5(遠程控制),下載連結和相關破解補丁可以私密十二,由於涉及到相關的問題就不公開連結啦。
  • Enum4linux-ng:面向安全專業人士和CTF玩家的下一代Enum4linux
    其一,Enum4linux-ng是出於教育目的開發的。其二,我們也是為了解決enum4linux.pl現有的問題才開發Enum4linux-ng的。跟enum4linux.pl相比,Enum4linux-ng不僅包含了原始工具原有的功能,而且還增加了許多特性修改,支持解析Samba工具的所有輸出,並允許將所有結果導出為YAML或JSON文件。
  • 使用nc命令檢查Linux系統遠程埠是否打開
    使用nc命令檢查Linux系統遠程埠是否打開 我們可以使用 netstat 或其他幾個 Linux 命令如 NMAP 在本地機器上輕鬆地列出 Linux 中的打開埠。在本指南中,我們將向你展示如何使用簡單的 netcat(簡稱 nc)命令來確定遠程主機上的埠是否可訪問/打開。
  • VSCode 1.35 穩定版使用全新圖標,支持遠程開發
    此次更新的亮點有:更新 Visual Studio Code 圖標開發團隊結合社區反饋,更新了 VS Code 的產品 logo。現在所有平臺都使用同樣的新 logo,如下圖:△ Insiders 版 logo 遠程開發遠程開發擴展現可用於 VS Code 穩定版,允許您使用容器、遠程機器或 Windows Linux 子系統(WSL)作為一個功能齊全的開發環境
  • 如何使用VsCode連接雲伺服器進行開發
    2.設置配置文件,Ctrl+Shift+p選擇 Remote-SSH Conntect to Host,然後選擇Configure SSH Host進行配置文件配置。5.選擇伺服器系統,我這裡是linux,輸入私鑰的密碼,如果需要。6.連接成功之後,在terminal裡面可以看到熟悉的命令行界面,可以直接選擇打開文件夾,就可以打開伺服器上的文件夾,進行工作了,這樣進行開發就方便很多了。
  • Linux下C應用程式開發
    本文介紹了在 Linux 下能用於 C 應用程式開發和調試的工具. 本文的主旨是介紹如何在 Linux 下使用 C 編譯器和其他 C 編程工具, 而非 C 語言編程的教程.本節將介紹如何使用 GCC 和一些 GCC 編譯器最常用的選項.
  • vxworks和linux有什麼區別
    自己目前開發的嵌入式開發所用的作業系統是VxWorks,以前讀大學的時候用的最多的是linux作業系統,但是,對於這兩種作業系統之間到底有什麼區別,還真沒有真正去細心的總結過,被別人問起時,難免有些尷尬的感覺 Linux是一類Unix計算機作業系統的統稱。Linux作業系統的內核的名字也是「Linux」。
  • Linux 系統內核的調試
    本文將首先介紹 Linux 內核上的一些內核代碼監視和錯誤跟蹤技術,這些調試和跟蹤方法因所要求的使用環境和使用方法而各有不同,然後重點介紹三種 Linux 內核的原始碼級的調試方法。  調試是軟體開發過程中一個必不可少的環節,在 Linux 內核開發的過程中也不可避免地會面對如何調試內核的問題。