# VSC 建構 C/C++ 開發環境在 Ubuntu/Linux and Windows ## Ubuntu ### 編譯器 GCC (GNU Compiler Collection) GCC 為一個集合,包含了 C 的編譯器 (gnu's c compiler, gcc) and C++ 的編譯器 (gnu's c++ compiler, g++) 等工具,可以參考 [GCC wiki](https://zh.wikipedia.org/zh-tw/GCC),可以看到 gcc 並不只有編譯器,還有包含 linker, assember ... gcc 在 Ubuntu 可以透過 `apt install build-essential` 安裝,`build-essential` 實際上是用來安裝編譯核心的工具,gcc 是其中一個工具,安裝完後打 `gcc -v` 就可以看到相關的訊息。`build-essential` 預設安裝的 gcc 版本是 11.4,最新的則是 13.1,所以需要最新版本則需要另外安裝。 ``` kola@kola-Z590-GAMING-X:~$ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/11/lto-wrapper OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 11.4.0-1ubuntu1~22.04' --with-bugurl=file:///usr/share/doc/gcc-11/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-11 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-11-XeT9lY/gcc-11-11.4.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-11-XeT9lY/gcc-11-11.4.0/debian/tmp-gcn/usr --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2 Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04) ``` 各個 GCC 支援的 ISO C/C++ 版本可以參考 [2 Language Standards Supported by GCC](https://gcc.gnu.org/onlinedocs/gcc/Standards.html#C-Language), gcc and g++ 預設安裝的位置為 /usr/bin/,所以編譯 C 語言要呼叫 /usr/bin/gcc, C++ 則是 /usr/bin/g++ 手動的編譯跟執行的流程為 ``` $ /usr/bin/gcc hello.c # 編譯 c file $ ./a.out # 執行執行檔 $ /usr/bin/g++ hello.cpp # 編譯 c file $ ./a.out # 執行執行檔 ``` ### GDB GDB 跟 GCC 同為 GNU Project 的一部分,使用 `apt install gdb` 安裝。 手動 debug 的方式為 ``` $ /usr/bin/gdb ./a.out # 對編譯完成的執行檔除錯 ``` ### VSCode 準備 現在我們有了工具,要設定 VSC 讓它可以找到這些工具,以及執行它,VSC 專案的設定檔是放在專案的 `.vscode` 資料夾下。 而我們要透過在 .vscode 下面的 1. c_cpp_properties.json (一些設定變數,可以用在 tasks.json and lauch.json) 2. tasks.json (告訴如何編譯 C/C++ file) 3. lauch.json (告訴如何除錯 C/C++ file) ### c_cpp_properties.json 按下 F1 輸入 C/C++: Edit Configuration (JSON),如圖上,它就會自動產生 json file in .vscode,內容如下,我們也就用預設的內容就好了。 ![](https://hackmd.io/_uploads/HJckpQmhh.png) ``` { "configurations": [ { "name": "Linux", "includePath": [ "${workspaceFolder}/**" ], "defines": [], "compilerPath": "/usr/bin/gcc", "cStandard": "c17", "cppStandard": "gnu++17", "intelliSenseMode": "linux-gcc-x64" } ], "version": 4 } ``` ### tasks.json 按下 F1 輸入 Tasks: Configure Default Build Task,它會有選項讓你選擇,自動產生範本,我目前的內容如下,可以看到它使用的 command 為 gcc,然後有一些 compile option,所以當你 run build tasks(ctrl + shift + b),它就會按照這邊寫的內容編譯檔案,並且執行編譯完的檔案。 ``` { "version": "2.0.0", "tasks": [ { "type": "cppbuild", "label": "C/C++: gcc build active file", "command": "/usr/bin/gcc", "args": [ "-fdiagnostics-color=always", "-g", "${file}", "-o", "${fileDirname}/${fileBasenameNoExtension}" ], "options": { "cwd": "${fileDirname}" }, "problemMatcher": [ "$gcc" ], "group": { "kind": "build", "isDefault": true }, "detail": "compiler: /usr/bin/gcc" } ] } ``` 但其實上面只有設定 gcc,所以在編譯 c++ 的時候會出錯,所以可以設定成這樣。 ``` { "version": "2.0.0", "tasks": [ { "label": "Compile C", "type": "shell", "command": "gcc", "args": ["-g", "-o", "${fileDirname}/${fileBasenameNoExtension}", "${file}"], "group": { "kind": "build", "isDefault": true }, "presentation": { "echo": true, "reveal": "always", "focus": false, "panel": "shared" }, "problemMatcher": [] }, { "label": "Compile C++", "type": "shell", "command": "g++", "args": ["-g", "-o", "${fileDirname}/${fileBasenameNoExtension}", "${file}"], "group": { "kind": "build", "isDefault": true }, "presentation": { "echo": true, "reveal": "always", "focus": false, "panel": "shared" }, "problemMatcher": [] } ] } ``` 或這只設定 g++,g++ 也可以編譯 c file,但不確定是不是預期的行為,網路上文章好像也都是這樣。 ### lauch.json F1 輸入 C/C++ Add debug configuration,選擇 gdb (Lauch),lauch 代表對整個檔案 debug 而不是執行的檔案,這邊會有預設的內容,但我們要改成下面的內容。 ``` { "configurations": [ { "name": "(gdb) Launch with C", "type": "cppdbg", "preLaunchTask": "Compile C", "request": "launch", "program": "${fileDirname}\\${fileBasenameNoExtension}", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": false, "MIMode": "gdb", "miDebuggerPath": "/usr/bin/gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true }, { "description": "Set Disassembly Flavor to Intel", "text": "-gdb-set disassembly-flavor intel", "ignoreFailures": true } ] }, { "name": "(gdb) Launch with C++", "type": "cppdbg", "preLaunchTask": "Compile C++", "request": "launch", "program": "${fileDirname}\\${fileBasenameNoExtension}", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": false, "MIMode": "gdb", "miDebuggerPath": "/usr/bin/gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true }, { "description": "Set Disassembly Flavor to Intel", "text": "-gdb-set disassembly-flavor intel", "ignoreFailures": true } ] } ], "version": "2.0.0" } ``` 上面內容我們有設定在 debug 之前執行在 tasks.json 的任務,可以看成我們先 compile,在用 gdb debug。 ## Reference * [VS Code 建置 C 語言環境](https://medium.com/@k053170/vs-code-%E5%BB%BA%E7%BD%AE-c-%E8%AA%9E%E8%A8%80%E7%92%B0%E5%A2%83-f0da35437c01) * [Configure C/C++ debugging](https://code.visualstudio.com/docs/cpp/launch-json-reference)