系:安裝、版本切換與排錯全解析)
很多人在Ubuntu上第一次準(zhǔn)備寫C/C程序都是從一句網(wǎng)上隨手搜到的命令開始的sudo apt install gcc。這句話沒法說它是錯的但你照著敲完往往會在第二步就卡住。寫個hello.cpp、輸入gcc hello.cpp編譯有時候能過一用std::cout或者某些標(biāo)準(zhǔn)庫功能亂七八糟的undefined reference就冒出來了回頭看教程人家又說你缺g讓你再裝一遍然后你就開始懷疑自己是不是裝了個假Linux。實際上這不是假Linux而是沒有理解GCC和G之間的關(guān)系也不清楚Ubuntu里軟件包、編譯器版本、構(gòu)建工具是怎么協(xié)作的。這篇文章就從安裝命令出發(fā)把gcc/g的選擇、apt安裝方式、版本管理、常見報錯、以及和VS Code這類IDE/編輯器配合的問題一次性講清楚。適合剛開始用Ubuntu學(xué)C/C的人也適合每次換機器都要重裝一遍環(huán)境、但總在同一個坑里栽跟頭的朋友。1. 動手之前先把GCC、G和Ubuntu的關(guān)系理清楚1.1 GCC不是“一個編譯器”而是一整套工具鏈GCC是GNU Compiler Collection的縮寫看起來像個編譯器其實它是一整套編譯器工具鏈的集合。gcc和g是這套工具鏈暴露給用戶的“前端命令”它們負責(zé)調(diào)用預(yù)處理、編譯、匯編、鏈接等一系列后臺組件最終幫你把源代碼變成可執(zhí)行文件。gcc最初用于編譯C語言g用于編譯C語言但嚴格來說兩者都能處理C和C代碼。真正的區(qū)別在于鏈接階段用g編譯C程序時它會自動鏈接libstdcC標(biāo)準(zhǔn)庫以及相關(guān)的運行時庫而直接用gcc去編譯一個.cpp文件如果代碼里用了標(biāo)準(zhǔn)庫里的東西鏈接時通常會報一堆undefined reference。所以搜“ubuntu安裝gcc和gcc c的命令”這個標(biāo)題本質(zhì)上是想同時搞定兩個命令一個是gcc一個是g。很多教程只寫裝gcc結(jié)果C代碼能跑C代碼一編譯就各種報錯原因就在這兒。如果你只打算寫純C那只裝gcc也能湊合但凡是學(xué)Cg必須一起裝上。1.2 為什么Ubuntu上優(yōu)先用apt而不是源碼編譯Linux下安裝軟件的方式很多可以用apt也可以自己下載源碼編譯。對GCC這種基礎(chǔ)工具鏈絕大多數(shù)情況下都應(yīng)該用apt安裝。理由很直白apt能自動處理依賴關(guān)系。GCC不是一個孤立的程序它依賴binutils、libc6-dev、cpp等一堆底層包手動下載源碼時這些依賴都要自己搞定對新手來說相當(dāng)折磨。apt安裝的版本和Ubuntu發(fā)行版做過適配會和系統(tǒng)庫的ABI兼容踩坑概率低。后續(xù)升級維護簡單sudo apt upgrade就能統(tǒng)一更新。從源碼編譯GCC不是不可以但那是給有明確需求的人準(zhǔn)備的比如需要某個特定版本、要做交叉編譯、或者想修改編譯器內(nèi)部行為。只是想在Ubuntu上寫C/C程序的話完全沒必要自己折騰編譯過程直接交給apt處理就行。1.3 裝之前先確認三件事安裝雖然是一行命令的事但前提條件最好先查一遍避免出了錯再去排查。用cat /etc/os-release或lsb_release -a看一下當(dāng)前系統(tǒng)是哪個版本。Ubuntu 22.04、24.04這類LTS版本源里的GCC版本是不同的先知道系統(tǒng)版本后面排查問題會方便很多。檢查軟件源狀態(tài)執(zhí)行sudo apt update把包索引刷一遍。這一步能避免“軟件源信息太舊導(dǎo)致找不到包”的問題也能順帶確認網(wǎng)絡(luò)狀況。最后用apt list --installed 2/dev/null | grep -E ^(gcc|g)看看系統(tǒng)里現(xiàn)在有沒有已經(jīng)安裝過的編譯器殘留避免裝重復(fù)了還以為自己是第一次裝。這幾個判斷步驟花不了半分鐘但能把后面大量莫名其妙的報錯擋在門外。2. 核心安裝常用命令與安裝之后的驗證2.1 正式安裝命令在Ubuntu上安裝gcc和g的命令很簡單核心就兩條sudo apt update sudo apt install gcc g -ysudo apt update是刷新軟件包索引確保你本地記錄的包版本信息是最新的。sudo apt install gcc g -y里的-y代表自動確認跳過安裝前的“是否繼續(xù)”提問適合在終端里連續(xù)操作時用。如果不想一條一條確認也可以把兩個包寫在一起apt支持一次安裝多個軟件包空格分隔就行。這里我強烈建議額外來一個元包build-essential。sudo apt install build-essential -ybuild-essential是一個“元包”它本身不提供功能但會拉取一套基本的編譯工具鏈包括gcc、g、make、dpkg-dev和一些基礎(chǔ)開發(fā)庫。很多情況下你只裝gcc和g后面跑make時又會提示找不到make命令而裝了build-essential就把這些基礎(chǔ)問題一次性都解決了。2.2 安裝后應(yīng)該看到什么版本驗證裝完不是直接寫代碼先驗證一下環(huán)境到底有沒有生效。在終端里依次執(zhí)行g(shù)cc --version g --version正常情況下你會看到類似這樣的輸出gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0 Copyright (C) 2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.g同理只是名字換成g。這個版本號就是你當(dāng)前編譯器工具鏈的版本不同Ubuntu系統(tǒng)版本輸出會不同比如Ubuntu 24.04上默認可能是13.x這都很正常。還可以用which gcc和which g看一下命令的具體路徑which gcc # /usr/bin/gcc which g # /usr/bin/g這一條在排查“為什么我明明裝了新版卻還是用舊版”的時候特別有用等會第3節(jié)會細說。2.3 用第一個程序驗證編譯鏈路是真的通的看到版本號還不夠真正要驗證的是從源碼到可執(zhí)行文件這條鏈路是通的。新建一個hello.ccat hello.c EOF #include stdio.h int main() { printf(Hello, GCC!\n); return 0; } EOF編譯并運行g(shù)cc hello.c -o hello ./hello看到輸出Hello, GCC!就說明C語言編譯鏈路正常。再驗證C新建hello.cppcat hello.cpp EOF #include iostream int main() { std::cout Hello, G! std::endl; return 0; } EOF編譯并運行g(shù) hello.cpp -o hello_cpp ./hello_cpp這里有個小細節(jié)如果你非要用gcc去編譯這個C程序比如執(zhí)行g(shù)cc hello.cpp -o hello_cpp很多系統(tǒng)會報錯或出現(xiàn)鏈接錯誤類似undefined reference to std::cout。原因就是前面說的gcc不會自動鏈接C標(biāo)準(zhǔn)庫所以學(xué)C老老實實用g這是很關(guān)鍵的一個好習(xí)慣。-o參數(shù)表示指定輸出文件名不帶這個參數(shù)的話默認會生成a.outLinux下那也是個可執(zhí)行文件但命名太抽象了建議每次都明確指定輸出名。2.4 擴展包gcc-multilib、libc6-dev這些要不要裝默認情況下gcc/g裝好后能編譯當(dāng)前架構(gòu)比如x86_64的普通程序。但你可能會在一些教程里看到gcc-multilib、g-multilib這樣的包它們的作用是讓你在64位系統(tǒng)上交叉編譯32位程序也就是生成32位架構(gòu)的可執(zhí)行文件。如果你的目標(biāo)是給嵌入式設(shè)備交叉編譯或者需要編譯32位的老代碼那就得裝multilib相關(guān)包如果只是寫普通的應(yīng)用程序不需要碰。還有l(wèi)ibc6-dev一般是作為依賴被自動裝上的不用特意去管。判斷標(biāo)準(zhǔn)很簡單遇到“bits/libc-header-start.h找不到”這類32位頭文件缺失問題時再考慮裝multilib平時不需要預(yù)先安裝一堆用不上的包。3. 版本管理為什么你“升級”了還是舊版本3.1 Ubuntu自帶的GCC版本本來就不是“最新版”很多從Windows開發(fā)環(huán)境轉(zhuǎn)過來的朋友有個習(xí)慣就是追求軟件版本越新越好。但Ubuntu源里的GCC版本策略跟這個思路不一樣它更看重穩(wěn)定性和兼容性。系統(tǒng)預(yù)裝的GCC版本通常是發(fā)布該Ubuntu版本時選定的一個穩(wěn)定版本不會頻繁跟著上游更新。比如Ubuntu 22.04 LTS默認自帶的是GCC 11系列Ubuntu 24.04 LTS默認是GCC 13系列。這個版本不是“舊”而是經(jīng)過發(fā)行版測試、和該版本系統(tǒng)的庫文件兼容性最好的一個版本。系統(tǒng)自帶的軟件包為了整體穩(wěn)定性犧牲“最新”是很正常的。3.2 很多人說的“升級后還是舊版本”其實是這三個原因第一種情況你在終端里執(zhí)行sudo apt upgrade以為能把GCC升到新大版本結(jié)果一看gcc --version還是原來的版本。這其實沒有錯apt upgrade只會在你已經(jīng)安裝的軟件包范圍內(nèi)更新到軟件源里的最新修復(fù)版不會把一個軟件從GCC 11“升級”成GCC 13因為那是另一個軟件包比如gcc-13而不是gcc。跨大版本升級需要顯式安裝新的大版本包。第二種情況你自己裝了gcc-12選擇了某個教程里的install gcc-12命令但在終端敲gcc得到的還是舊版本。這在Ubuntu里太常見了。原因在于/usr/bin/gcc只是一個軟鏈接默認指向系統(tǒng)選定的版本。新安裝的gcc-12只是多了一個/usr/bin/gcc-12文件并不會自動改變/usr/bin/gcc這個軟鏈接的指向。這時候你需要查看一下ls -l /usr/bin/gcc*你會看到類似這樣的輸出lrwxrwxrwx 1 root root 21 ... /usr/bin/gcc - /etc/alternatives/gcc lrwxrwxrwx 1 root root 23 ... /usr/bin/gcc-11 - x86_64-linux-gnu-gcc-11 lrwxrwxrwx 1 root root 23 ... /usr/bin/gcc-12 - x86_64-linux-gnu-gcc-12也就是說gcc命令可能通過/etc/alternatives/gcc指向gcc-11你裝的gcc-12根本沒被選為默認。第三種情況即使你把系統(tǒng)默認版本切到了新版本某些項目或構(gòu)建系統(tǒng)還是會調(diào)用舊版本。這跟編譯器的搜索路徑和環(huán)境變量有關(guān)。make或CMake可能會優(yōu)先使用CC和CXX這兩個變量指定的編譯器或者項目里寫死了編譯器路徑。此時你改了系統(tǒng)的gcc軟鏈接但項目還是用舊編譯器在編譯表現(xiàn)就是“升級了還是舊版本”。3.3 用update-alternatives做多版本切換當(dāng)你安裝了多個GCC版本想手動切換系統(tǒng)默認版本時最好用的工具是update-alternatives。它專門用來管理系統(tǒng)里同一命令的多版本軟鏈接。把gcc和g的各個版本加入備選列表sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 110 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 120 sudo update-alternatives --install /usr/bin/g g /usr/bin/g-11 110 sudo update-alternatives --install /usr/bin/g g /usr/bin/g-12 120數(shù)字110和120是優(yōu)先級數(shù)字越大優(yōu)先級越高。然后執(zhí)行sudo update-alternatives --config gcc sudo update-alternatives --config g終端會出現(xiàn)一個交互式列表輸入對應(yīng)的編號回車就能切換默認版本。如果不想用update-alternatives也可以直接改軟鏈接比如sudo rm /usr/bin/gcc sudo ln -s /usr/bin/gcc-12 /usr/bin/gcc但這樣比較粗暴而且以后系統(tǒng)更新可能給你改回去沒有update-alternatives優(yōu)雅。3.4 想要更新版本的GCC怎么裝更穩(wěn)妥如果你確實需要比較新的GCC但又不想自己從源碼編譯最簡單的方法是使用Ubuntu Toolchain測試倉庫也就是社區(qū)里常說的toolchain-r/test PPA。這個PPA專門提供比系統(tǒng)源更新的GCC/G版本兼容性和打包質(zhì)量都不錯。sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt update sudo apt install gcc-13 g-13 -y裝完之后你可以通過/usr/bin/gcc-13這個命令來調(diào)用新版本。要不要把它設(shè)為默認版本跟前面的邏輯一樣用update-alternatives去切換。還有一種更保守的做法從源碼編譯一個新版GCC單獨安裝到/opt/gcc-14這樣的目錄不改動系統(tǒng)默認的任何文件。這樣系統(tǒng)編譯內(nèi)核模塊或者別的東西都還用原有工具鏈你自己編譯項目時通過CMAKE_CXX_COMPILER指定新編譯器路徑就行。不過源碼編譯GCC的步驟有點多依賴也要注意新手不建議一開始就走這條路。3.5 編譯器搜索路徑的優(yōu)先級搞清楚這個才能根治不管你怎么切換系統(tǒng)默認版本還是要理解編譯器是怎么被定位的。當(dāng)你在終端輸入gccshell會從PATH環(huán)境變量里按順序查找第一個匹配的gcc就會被執(zhí)行。通常/usr/bin在PATH比較靠前而/usr/bin/gcc是個軟鏈接最終指向誰就是你當(dāng)前的默認版本。但在工程構(gòu)建里GCC的定位方式會更多樣make默認會使用cc而cc通常也是一個軟鏈接指向系統(tǒng)默認的gcc。CMake在配置項目時會調(diào)用編譯器來測試特性并把找到的編譯器路徑記錄在CMakeCache.txt里。你之后切換了系統(tǒng)默認GCC再重新運行cmake時如果檢測到緩存可能還是會用之前記錄的舊編譯器。遇到這種情況刪掉build目錄或CMakeCache.txt再重新配置一次即可。一些項目會在CMakeLists.txt里直接寫set(CMAKE_C_COMPILER gcc-11)這就不受系統(tǒng)默認版本影響了需要手動改配置。說到底“升級后還是舊版本”很多時候不是沒升級成功而是調(diào)用鏈上某個環(huán)節(jié)根本沒用到你升級后的那個版本。先在終端敲which gcc、ls -l /usr/bin/gcc、echo $CC、echo $CXX基本上能定位到大多數(shù)問題。4. 高頻問題與排查記錄4.1 提示E: Unable to locate package gcc是什么情況這個報錯有幾個常見原因。最常見的是沒有先執(zhí)行sudo apt update軟件源索引太舊apt根本不知道有g(shù)cc這個包。還有就是軟件源列表里禁用了某些倉庫或者網(wǎng)絡(luò)不通apt更新源失敗索引不完整。處理辦法是sudo apt update如果apt update的過程里出現(xiàn)很多連接超時或404錯誤那就是源配置的問題。需要檢查/etc/apt/sources.list以及/etc/apt/sources.list.d/目錄下的源配置文件確認源地址可用。新手換源時一定要用對應(yīng)自己Ubuntu版本的源版本代號對不上就會出現(xiàn)404或找不到包的情況。網(wǎng)絡(luò)方面如果更新源一直失敗先確認網(wǎng)絡(luò)本身通不通再考慮換源但具體用什么鏡像源、什么配置每個網(wǎng)絡(luò)環(huán)境不一樣這里不展開。4.2 apt安裝中途報鎖錯誤Could not get lock /var/lib/dpkg/lock這個報錯很典型通常是另一個apt進程還在跑或者上次安裝中斷后鎖沒釋放。完整報錯類似E: Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavailable)處理思路很簡單先看有沒有apt或dpkg進程還在運行。如果有等它結(jié)束如果確認沒有其他進程在運行但鎖還是存在可以刪除鎖文件但要先確認沒有任何apt/dpkg進程在跑否則可能損壞包數(shù)據(jù)庫。sudo ps aux | grep -E apt|dpkg確認沒有相關(guān)進程后sudo rm /var/lib/dpkg/lock sudo rm /var/lib/dpkg/lock-frontend sudo dpkg --configure -a再重新執(zhí)行sudo apt install。更安全的方式是等一會兒再試因為auto-update之類的定時任務(wù)可能正在后臺運行殺掉它反而會引發(fā)其他問題。我個人的習(xí)慣是先看進程確認沒有才刪鎖。4.3 IDE自帶的GCC和系統(tǒng)GCC是一回事嗎不少嵌入式IDE比如MounRiver Studio會在安裝目錄里自帶一套GCC工具鏈用于交叉編譯RISC-V或者8051等目標(biāo)平臺的固件。這個自帶工具鏈和Ubuntu系統(tǒng)里/usr/bin下的gcc是兩套完全獨立的東西。它們的位置也不一樣。MounRiver Studio這類Eclipse系IDE通常會在安裝目錄的plugin目錄下找到一個toolchain相關(guān)路徑里面放著riscv-none-embed-gcc等交叉編譯器。想在IDE里確認它實際使用的編譯器位置可以在工程的屬性Properties里看C/C Build相關(guān)設(shè)置里面一般會寫清楚Compiler path。這兩套編譯器互不干擾IDE自帶的工具鏈編譯出來的文件是給MCU跑的Ubuntu系統(tǒng)里的gcc編譯出來的程序直接在電腦上運行。所以在Ubuntu上裝系統(tǒng)的gcc/g不影響IDE使用反過來IDE裝沒裝、裝在哪也不影響你終端里寫C。4.4 在VS Code里怎么讓C/C代碼跑起來VS Code本身不是一個編譯器它只是一個編輯器。你在VS Code里裝好微軟的C/C擴展后它還需要知道用什么編譯器來構(gòu)建、調(diào)試代碼。最直接的辦法就是指向前面剛裝好的/usr/bin/g。在VS Code里寫C程序你需要兩個關(guān)鍵文件。一個是.vscode/tasks.json用于告訴VS Code怎么構(gòu)建{ version: 2.0.0, tasks: [ { label: build cpp, type: shell, command: /usr/bin/g, args: [ -g, -stdc17, ${file}, -o, ${fileDirname}/${fileBasenameNoExtension} ], group: { kind: build, isDefault: true } } ] }另一個是.vscode/c_cpp_properties.json讓擴展知道編譯器的位置和標(biāo)準(zhǔn)版本{ configurations: [ { name: Linux, includePath: [${workspaceFolder}/**], compilerPath: /usr/bin/g, cStandard: c11, cppStandard: c17, intelliSenseMode: linux-gcc-x64 } ], version: 4 }配置完后按CtrlShiftB就能調(diào)用g編譯當(dāng)前文件然后按F5進入調(diào)試。用命令本身是最佳調(diào)試思路這也是為什么前面堅持要把命令行的GCC環(huán)境先弄明白因為VS Code圖形界面背后調(diào)用的還是命令行工具。4.5 一編譯就報undefined reference / iostream找不到是沒裝好嗎這兩個報錯也是最容易讓新手誤以為“GCC沒裝好”的典型場景。如果編譯C文件時提示fatal error: iostream: No such file or directory多半是你確實在用gcc而不是g來編譯或者系統(tǒng)里g沒裝。C標(biāo)準(zhǔn)庫頭文件不是C標(biāo)準(zhǔn)庫的一部分gcc默認搜索路徑里不包含完整的C標(biāo)準(zhǔn)庫所以找不到iostream很正常。如果提示undefined reference to std::cout或者一堆libstdc相關(guān)符號找不到那是鏈接階段的問題。gcc編譯C源文件時不會自動把libstdc鏈接進來導(dǎo)致源代碼編譯通過但最后鏈接失敗。解決辦法還是那句C程序使用g來編譯和鏈接。5. 從編譯器到開發(fā)環(huán)境讓GCC真正干活5.1 一個完整的工具鏈組合裝完gcc/g只是拿到了編譯器但一個像樣的C/C開發(fā)環(huán)境還需要構(gòu)建工具和調(diào)試器。推薦一次性安裝sudo apt install build-essential gdb make cmake -ybuild-essential包含gcc、g、make等基礎(chǔ)構(gòu)建工具前面提過。gdbGNU調(diào)試器程序出問題的時候可以在源代碼級別斷點調(diào)試。make最常見的構(gòu)建工具通過Makefile管理編譯流程。cmake更高級的跨平臺構(gòu)建工具廣泛用于現(xiàn)代C項目。裝完之后你的Ubuntu環(huán)境才算真正具備“從源碼到調(diào)試”的完整能力。5.2 一個練習(xí)級C小例子驗證整個環(huán)境下行現(xiàn)在來編譯一個稍微實用一點的示例比如判斷一個數(shù)是不是質(zhì)數(shù)這個也是搜索熱詞里出現(xiàn)過的需求。#include iostream bool is_prime(int n) { if (n 2) return false; for (int i 2; i * i n; i) { if (n % i 0) return false; } return true; } int main() { for (int i 2; i 100; i) { if (is_prime(i)) { std::cout i ; } } std::cout std::endl; return 0; }保存為prime.cpp編譯運行g(shù) -O2 -stdc17 prime.cpp -o prime ./prime這里用了-O2優(yōu)化選項編譯器會做循環(huán)優(yōu)化讓運行速度更快。-stdc17指定C版本標(biāo)準(zhǔn)這在寫現(xiàn)代C代碼時幾乎是必須的不然有些新特性用不了。同樣如果你在練冒泡排序、二分查找這些經(jīng)典算法流程也都是一樣把代碼存成.cpp文件用g編譯然后運行。這個流程本身不會因為算法復(fù)雜度改變而改變編譯器的主要工作是把你寫的邏輯翻譯成機器碼算法的好壞靠你自己來優(yōu)化。5.3 從單文件到多文件什么時候需要CMake當(dāng)你的項目從一個.cpp文件變成十幾個.cpp文件和一個頭文件目錄時再手動敲g命令就不現(xiàn)實了。這時候CMake就派上用場。一個最簡單的CMakeLists.txt長這樣cmake_minimum_required(VERSION 3.16) project(cpp_demo) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) add_executable(demo main.cpp sort.cpp utils.cpp)然后mkdir build cd build cmake .. make ./demo這里cmake ..會根據(jù)CMakeLists.txt生成Makefilemake會調(diào)用g完成實際編譯。在整個流程里系統(tǒng)里的g版本和路徑?jīng)Q定了最終編譯行為。如果你剛切換過編譯器版本在build目錄里重新cmake ..前建議把build目錄刪掉或清掉CMakeCache.txt否則CMake可能還在復(fù)用舊編譯器緩存又會遇到前面說的“新版本不生效”問題。5.4 新手常犯的錯覺編輯器能運行就代表環(huán)境沒問題最后說一個很多人容易忽略的認知問題。你用VS Code、Clion或者某些IDE在編輯器里點一下運行程序正常運行了就覺得自己電腦上的GCC環(huán)境完全沒問題。這個結(jié)論在大多數(shù)情況下是對的但要注意IDE里可能內(nèi)置了自己的編譯器或者幫你配置了不同于系統(tǒng)默認的編譯配置路徑。我自己見過不少情況在IDE里編譯運行一切正常但打開終端想執(zhí)行g(shù)編譯卻發(fā)現(xiàn)command not found就是因為IDE內(nèi)置了一套工具鏈根本不依賴系統(tǒng)的gcc。對日常學(xué)習(xí)來說這兩者不沖突但如果你想真正理解C/C程序的編譯流程還是建議至少能在命令行里完成一次“寫代碼、編譯、運行”的完整閉環(huán)。命令行能跑通說明這個環(huán)境的底層是可靠的。最后補兩句踩過坑之后的心得裝GCC/G這件事看著是一行命令真正的門檻在于理解“系統(tǒng)里有哪幾套編譯器、你現(xiàn)在調(diào)用的是哪一套”。在終端里敲which gcc和g --version只要幾秒鐘但能省掉大半的疑難雜癥。另外如果你經(jīng)常需要在不同GCC版本之間切換除了update-alternatives還可以在自己的~/.bashrc里加上CC和CXX環(huán)境變量比如export CCgcc-13 export CXXg-13這樣能保證像CMake這類構(gòu)建工具會用你指定的版本來編譯而不至于又被系統(tǒng)默認版本帶偏。這個辦法不算什么高深技巧但在實際開發(fā)里真的能減少很多“版本不對”的焦慮。