環境:
win7_x64旗艦版、VS2017企業版、VMware10.0.2、CentOS7
在CentOS7上首先需要安裝gcc、g++和gdbserver,這里就不多說
一、安裝VS2017
1.1 安裝VS2017時,必須要勾選“使用C++的Linux開發”工具集
二、創建Linux項目
2.1 創建一個名稱為"TestLinux"的解決方案,我們稍后會在這個解決方案內新建多個Linux項目(包括可執行程序、動態庫、靜態庫等)
2.2 添加新建項目可執行程序項目"test"
2.2.1
2.2.2
2.3 添加新建項目,創建動態庫
2.3.1
2.3.2
2.4 添加新建項目,創建靜態庫
2.4.1
2.4.2
三、添加測試代碼
3.1 "test"項目中main.cpp代碼:
#include <cstdio> #include "static_library/static.h" #include "dynamic_library/dynamic.h.h" int main() { printf("hello from test!\n"); printf("static_library test : %d\n", static_test(1)); printf("dynamic_library test : %d\n", dynamic_test(1)); return 0; }
3.2 在"static_library"項目中添加static.h和static.cpp
static.h
#ifndef _STATIC_LIBRARY_H_ #define _STATIC_LIBRARY_H_ int static_test(int n); #endif // !_STATIC_LIBRARY_H_
static.cpp
#include "static.h" int static_test(int n) { return n * 3; }
3.3 在"dynamic_library"項目中添加dynamic.h和dynamic.cpp
dynamic.h
#ifndef _DYNAMIC_LIBRARY_H_ #define _DYNAMIC_LIBRARY_H_ int dynamic_test(int n); #endif // !_DYNAMIC_LIBRARY_H_
dynamic.cpp
#include "dynamic.h" int dynamic_test(int n) { return n * 2; }
四、項目配置
4.1 "常規"配置
配置主程序:
本地輸出目錄:"$(ProjectDir)bin\$(Platform)\$(Configuration)\"修改為"$(ProjectDir)..\bin\$(Platform)\$(Configuration)\",是為了將所有項目輸出文件放到同一個目錄中,方便相互引用。
目標文件擴展名:".out"修改為"",是為了不生成文件后綴,一般的Linux可執行程序是沒有擴展名稱的,可修改也可不修改。
遠程生成根目錄:"~/projects"修改為"/root/projects/$(SolutionName)","~"和"/root"是等價的,但是運行時動態庫搜索目錄不支持~路徑,添加“$(SolutionName)”是為了區分不同的解決方案下相同名稱的項目。
遠程生成項目目錄:"~/projects"修改為"/root/projects/$(SolutionName)","~"和"/root"是等價的,但是運行時動態庫搜索目錄不支持~路徑,添加“$(SolutionName)”是為了區分不同的解決方案下相同名稱的項目。
配置動態庫:"$(RemoteRootDir)/$(ProjectName)"修改為"$(RemoteRootDir)"
本地輸出目錄:"$(ProjectDir)bin\$(Platform)\$(Configuration)\"修改為"$(ProjectDir)..\bin\$(Platform)\$(Configuration)\"
目標文件擴展名:".out"修改為".so"
遠程生成根目錄:"~/projects"修改為"/root/projects/$(SolutionName)"
配置類型:"應用程序(.out)"修改為"動態庫(.so)"
配置靜態庫:
本地輸出目錄:"$(ProjectDir)bin\$(Platform)\$(Configuration)\"修改為"$(ProjectDir)..\bin\$(Platform)\$(Configuration)\"
目標文件擴展名:".out"修改為".a"
遠程生成根目錄:"~/projects"修改為"/root/projects/$(SolutionName)"
配置類型:"應用程序(.out)"修改為"動態庫(.a)"
4.2 "調試"配置
程序:"$(RemoteTargetPath)"修改為"$(RemoteRootDir)/bin/$(Platform)/$(Configuration)/$(TargetName)$(TargetExt)",因為前面修改了本地輸出目錄導致遠程輸出目錄也相應發生變化,這里修改一致。
工作目錄:"$(RemoteOutDir)"修改為"$(RemoteRootDir)/bin/$(Platform)/$(Configuration)",這個是遠程主機CentOS上的路徑,如果設置不正確將找不到引用的動態庫,調試程序無法啟動。
其他調試程序命令:""修改為"set solib-search-path $(SolutionDir)bin/$(Platform)/$(Configuration)",這個是本地路徑,調試符號是從本地加載的,否則調試動態庫時,gdb會輸出沒有找到調試符號文件。
4.3 "C/C++"配置
附加包含目錄:在"$(StlIncludeDirectories);%(AdditionalIncludeDirectories)"前面添加"./..;",這個是遠程主機CentOS上的路徑,相當於gcc編譯時指定"-I[路徑]"選項;一般是先把需要的頭文件從CentOS復制到windows,然后設置"配置屬性"->"VC+ +目錄"->"包含目錄",這樣在編寫Linux程序時,提示信息更加的友好^^。
4.4 "鏈接器"配置
附加庫目錄:在"%(AdditionalLibraryDirectories)"前面添加"$(RemoteRootDir)/bin/$(Platform)/$(Configuration);",這個是遠程主機CentOS上的路徑,相當於gcc編譯時指定"-L[路徑]"選項,用於指定引用動態庫和靜態庫的目錄;
庫依賴項:添加"dynamic_library;static_library",相當於gcc設置"-l[庫名稱]"選項,用於指定鏈接時所需要的動態庫和靜態庫名稱,如果找不到依賴的庫文件,鏈接時會錯誤,顯示"無法解析的符號"。
其他選項:添加"-Wl,-rpath=$(RemoteRootDir)/bin/$(Platform)/$(Configuration) ",指定程序運行時搜索動態庫的路徑。
五、開始調試
5.1 設置遠程調試主機
5.2 顯示Linux控制台
最后的Demo下載地址:TestLinux.zip
其他錯誤:
1)Inferior 1 (process 6074) exited normally
通常是沒有生成Debug可執行文件,若使用cmake,則添加CMAKE_BUILD_TYPE=Debug,重新生成即可。
2)如果使用附加到進程(Native GDB代碼)進行調試,提示輸出"Cannot find or open the symbol file"
我們一般會在Linux中設置動態庫加載路徑,例如:export LD_LIBRARY_PATH=lib
此時程序加載動態庫使用的就是相對路徑,使用ldd命令查看
因為是相對路徑,所以VS2017遠程附加到進程后,不能在此路徑加載動態庫的符號
解決辦法:
設置動態庫加載的絕對路徑,例如:export LD_LIBRARY_PATH=/lib,重新啟動程序,然后再使用VS2017重新附加進程
3)Window下使用的Linux頭文件與開發的遠程Linux系統不一致
需要到Linux遠程開發上將相關頭文件需要手動拷貝到Window系統下
將/usr/include目錄拷貝到C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\VC\Linux\include\usr\include
將/usr/lib/gcc/x86_64-redhat-linux目錄拷貝到C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\VC\Linux\include\usr\lib\gcc