直接 gcc 沒有-o 的話出來的輸出exe文件沒有調(diào)試信息,相比-o的大小會小一點,只有包含了調(diào)試信息文件才可以執(zhí)行
argc argv參數(shù)
./hello shan
argc = 2
argv[0] = ./hello
argv[1] = shan
頭文件
頭文件在編譯器的include目錄中,編譯時 -I 指定庫
函數(shù)庫默認路徑在編譯器的lib目錄中,編譯時 -L指定目錄,-l 小寫L 指定庫
函數(shù)或者是在別的c與cpp文件中
find -name "stdio.h"
編譯過程
gcc hello.c // 輸出一個名為 a.out 的可執(zhí)行程序,然后可以執(zhí)行./a.out
gcc -o hello hello.c // 輸出名為 hello 的可執(zhí)行程序,然后可以執(zhí)行./hello
gcc -o hello hello.c -static // 靜態(tài)鏈接 默認情況使用動態(tài)鏈接
gcc -c -o hello.o hello.c // 先編譯(不鏈接)
gcc -o hello hello.o // 再鏈接
執(zhí)行“gcc -o hello hello.c -v”時,可以查看到這些步驟:
cc1 main.c -o /tmp/ccXCx1YG.s
as -o /tmp/ccZfdaDo.o /tmp/ccXCx1YG.s
cc1 sub.c -o /tmp/ccXCx1YG.s
as -o /tmp/ccn8Cjq6.o /tmp/ccXCx1YG.s
collect2 -o test /tmp/ccZfdaDo.o /tmp/ccn8Cjq6.o ....
可以手工執(zhí)行以下命令體驗一下:
gcc -E -o hello.i hello.c
gcc -S -o hello.s hello.i
gcc -c -o hello.o hello.s
gcc -o hello hello.o
靜態(tài)鏈接,動態(tài)鏈接,靜態(tài)庫,動態(tài)庫
靜態(tài)鏈接(static linking)和動態(tài)鏈接(dynamic linking)都是將代碼庫連接到應(yīng)用程序中的方法,以便于執(zhí)行應(yīng)用程序。
靜態(tài)鏈接是將庫中的所有代碼復(fù)制到可執(zhí)行文件中的過程。在編譯時,編譯器會將庫的代碼直接嵌入到最終生成的可執(zhí)行文件中,因此可執(zhí)行文件可以完全獨立運行,無需依賴任何外部庫或資源。這樣做的好處是,可執(zhí)行文件在不同機器或操作系統(tǒng)上的兼容性更高。缺點是,應(yīng)用程序的大小通常會更大,并且更新庫可能需要重新編譯整個應(yīng)用程序。
動態(tài)鏈接是將庫的代碼保留為單獨的文件,操作系統(tǒng)只在應(yīng)用程序運行時將其加載到內(nèi)存中。因此,一個庫的多個應(yīng)用程序可以共享同一份庫文件,從而節(jié)省了磁盤空間并減少了內(nèi)存的使用。同時,如果有多個應(yīng)用程序需要加載同一份庫文件,那么這份文件只需要在內(nèi)存中存在一次。這使得庫的升級變得更加容易。然而,動態(tài)鏈接的應(yīng)用程序依賴于系統(tǒng)中可用的動態(tài)庫,如果要運行動態(tài)鏈接的應(yīng)用程序,需要確保在系統(tǒng)上安裝了所需的庫。
靜態(tài)庫(static library)是一組預(yù)編譯的目標(biāo)文件或?qū)ο笪募?,它們被打包成一個文件并在編譯時鏈接到應(yīng)用程序中。靜態(tài)庫的代碼完全復(fù)制到可執(zhí)行文件中,因此它會增加可執(zhí)行文件的大小。
優(yōu)點是,靜態(tài)庫允許應(yīng)用程序完全獨立運行。缺點是,如果靜態(tài)庫的源代碼發(fā)生變化,則必須重新編譯整個應(yīng)用程序。
動態(tài)庫(dynamic library)是在運行時加載的庫。動態(tài)庫的代碼只有一個副本,在內(nèi)存中由多個應(yīng)用程序共享。
動態(tài)庫的優(yōu)點是,多個應(yīng)用程序可以使用同一份庫文件,從而減少內(nèi)存和磁盤空間。如果動態(tài)庫的源代碼發(fā)生變化,則只需要更新動態(tài)庫文件本身即可。
缺點是,動態(tài)庫在啟動時需要額外的時間進行初始化,并且在不適當(dāng)?shù)厥褂脮r可能會導(dǎo)致內(nèi)存泄漏或其他問題。
-shared
在 GCC 中,"-shared"選項用于指示編譯器創(chuàng)建動態(tài)鏈接庫(也稱為共享庫)而非可執(zhí)行文件。
當(dāng)使用"-shared"選項編譯源文件時,GCC會將目標(biāo)文件打包成一個控制導(dǎo)出符號的動態(tài)鏈接庫。這意味著其他程序可以在運行時加載這個庫,并鏈接到其中定義的符號和函數(shù)。共享庫可以被多個應(yīng)用程序共享,因此它們可以提高系統(tǒng)資源的利用率并減少內(nèi)存占用量。
在您提供的命令中,使用"-shared"選項創(chuàng)建了一個名為"libsub.so"的動態(tài)鏈接庫,其中包含 sub.o、sub2.o 和 sub3.o 編譯后的目標(biāo)文件。該庫可以用于鏈接到其他程序中。
需要注意的是,如果庫的依賴關(guān)系不正確,則可能會導(dǎo)致在加載庫時發(fā)生錯誤。因此,在編譯和鏈接動態(tài)庫時,必須確保正確指定所有必需的庫及其路徑。
制作使用動態(tài)庫
gcc -c -o main.o main.c
gcc -c -o sub.o sub.c
gcc -shared -o libsub.so sub.o sub2.o sub3.o(可以使用多個.o 生成動態(tài)庫)
gcc -o test main.o -lsub -L /libsub.so/所在目錄/
第7步 運行:
① 先把 libsub.so 放到 Ubuntu 的/lib 目錄,然后就可以運行 test 程序。
② 如果不想把 libsub.so 放到/lib,也可以放在某個目錄比如/a,然后如下執(zhí)
行:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/a
./test
這個命令將編譯和鏈接 main.o 源文件,并將其與名為"libsub.so"的動態(tài)庫鏈接起來。"-lsub"選項告訴編譯器鏈接到名為"libsub.so"的庫,"-L"選項則指定尋找?guī)煳募穆窂健?
因此,生成的可執(zhí)行文件 test 將會依賴于名為"libsub.so"的動態(tài)鏈接庫,而不是與其他默認庫鏈接。
需要注意的是,如果要鏈接到多個庫文件,則需要在命令行中指定所有這些庫的名稱(使用"-l"選項)和路徑(使用"-L"選項)。否則,編譯器將無法找到所需的庫文件并產(chǎn)生錯誤。
libxxx。so
"-lsub"中的"sub"并不是隨意命名的,而是根據(jù)動態(tài)庫文件名"libsub.so"來確定的。
在默認情況下,GCC 會將庫文件名解釋為 libXXX.so 形式,其中 XXX 是庫的名稱。因此,在使用"-l"選項指定要鏈接的庫時,可以省略"lib"和".so"部分,只指定庫的名稱即可。
例如,如果您有一個名為"libsub.so"的動態(tài)庫,則可以使用"-lsub"選項將其鏈接到您的代碼中。
需要注意的是,庫文件名必須以"lib"開頭,并以".so"結(jié)尾才能被識別為動態(tài)庫。如果您的庫文件名不符合這種命名約定,則需要使用"-l"選項顯式指定完整的文件名和路徑。
此外,您還可以使用"-Wl,-soname,NAME"選項來指定共享庫的 soname,它是庫的邏輯名稱,是庫的用戶感知名稱。例如,您可以使用以下命令來編譯和鏈接一個共享庫,并指定其 soname:
gcc -shared -Wl,-soname,libfoo.so.1 -o libfoo.so.1.0.1 foo.o bar.o
這將生成一個名為"libfoo.so.1.0.1"的共享庫,并將其邏輯名稱設(shè)置為"libfoo.so.1"。這樣,用戶可以鏈接到"libfoo.so.1"而不必擔(dān)心底層庫的實際名稱和版本。
沖突
在這個例子中,使用-Wl,-soname,libfoo.so.1
選項指定了庫的邏輯名稱為"libfoo.so.1",而不是默認的"libfoo.so"。并且使用-o libfoo.so.1.0.1
選項指定生成的共享庫名稱為"libfoo.so.1.0.1"。這樣設(shè)計的目的是為了在為共享庫命名時提供更多的靈活性和精確度。
而foo.o bar.o
是需要鏈接進共享庫的目標(biāo)文件列表。
如果要將這個共享庫鏈接到其他程序中,則需要使用-lfoo
選項將其指定為依賴庫。
例如,如果你想編譯一個名為test
的程序,并鏈接上面的共享庫,則可以使用以下命令:
gcc -o test test.o -L/path/to/lib -lfoo
其中,-L
選項用于指定共享庫所在的路徑,-lfoo
選項用于指定需要鏈接的庫的名稱。編譯器將搜索指定路徑下的libfoo.so
或libfoo.a
文件,并將其鏈接到程序中。由于我們已經(jīng)在編譯共享庫時使用了-Wl,-soname,libfoo.so.1
選項來指定了邏輯名稱,因此鏈接器將自動匹配庫的名稱為"libfoo.so.1",而不是"libfoo.so"。
需要注意的是,如果在鏈接時指定的共享庫名稱不是由-Wl,-soname
選項指定的邏輯名稱,則可能會導(dǎo)致運行時錯誤。此外,如果要鏈接的庫不在默認路徑中,還需要使用-rpath
選項來指定運行時搜索庫的路徑,以確保程序能夠正確地加載庫。
如果目錄下同時有libfoo.so.1.0.1
和libfoo.so
這兩個文件,那么在使用-lfoo
選項編譯鏈接程序時,鏈接器可能會優(yōu)先選擇libfoo.so
而不是libfoo.so.1.0.1
,因為它具有更短的名稱。
為了避免這種情況的發(fā)生,我們一般會將動態(tài)庫的版本號包含在庫文件名中,以便在有多個版本的庫文件存在時,可以根據(jù)需要精確地選擇需要的版本。例如,在之前的例子中,-soname
選項指定了邏輯名稱為"libfoo.so.1",因此生成的共享庫的實際名稱為libfoo.so.1.0.1
,這樣可以避免與libfoo.so
發(fā)生命名沖突。
另外,你也可以通過設(shè)置LD_LIBRARY_PATH
環(huán)境變量來改變動態(tài)庫的搜索路徑,這樣可以讓鏈接器在默認路徑之外搜索動態(tài)庫。例如:
export LD_LIBRARY_PATH=/path/to/libs:$LD_LIBRARY_PATH
這將把/path/to/libs
目錄添加到動態(tài)庫的搜索路徑中。然后,當(dāng)你使用-lfoo
選項編譯鏈接程序時,鏈接器會先在/path/to/libs
目錄下查找libfoo.so
或libfoo.so.1.0.1
文件,如果找到則使用它。
是的,通常情況下,我們會將不同版本的.so文件放到不同的目錄中,這樣可以避免不同版本之間的文件名沖突問題。
在編譯時,你可以通過-L
選項來添加庫文件的搜索路徑。例如:
gcc -o myprogram myprogram.o -L/path/to/libs -lfoo
這里的-L/path/to/libs
選項指定了庫文件所在的路徑為"/path/to/libs",而-lfoo
選項指定了需要鏈接的庫的名稱為"libfoo.so"或"libfoo.a"。如果這個路徑中有多個不同版本的庫文件,鏈接器會根據(jù)庫文件的版本號以及程序?qū)μ囟ò姹镜膸斓男枨髞碜詣舆x擇合適的庫文件進行鏈接。
當(dāng)程序運行時,動態(tài)鏈接器將會按照一定的規(guī)則搜索庫文件,并將其加載到內(nèi)存中供程序使用。具體的搜索順序可以通過設(shè)置LD_LIBRARY_PATH
或修改/etc/ld.so.conf
等方式來改變,這樣可以使動態(tài)鏈接器在不同的目錄中查找?guī)煳募?/p>
靜態(tài)庫
在編譯好上面提到的兩個目標(biāo)文件(main.o和sub.o)后,你可以使用ar
命令來將它們打包成靜態(tài)庫。具體來說,你需要執(zhí)行以下命令:
ar rcs libmystatic.a main.o sub.o
其中,r
選項表示將目標(biāo)文件添加到靜態(tài)庫中(如果目標(biāo)文件已經(jīng)存在于靜態(tài)庫中,則將其替換),c
選項表示創(chuàng)建一個新的靜態(tài)庫,如果靜態(tài)庫不存在則創(chuàng)建,s
選項表示為靜態(tài)庫創(chuàng)建索引表,以提高鏈接速度。libmystatic.a
是指定生成的靜態(tài)庫文件名。
執(zhí)行完以上命令后,就會在當(dāng)前目錄下生成名為libmystatic.a
的靜態(tài)庫文件。你可以使用nm
命令來查看靜態(tài)庫中包含的符號列表,例如:
nm libmystatic.a
如果要使用這個靜態(tài)庫來鏈接其它程序,可以使用-L
和-l
選項,例如:
gcc -o myprogram myprogram.o -L. -lmystatic
這里的-L.
選項表示在當(dāng)前目錄中搜索庫文件,而-lmystatic
選項表示鏈接名為libmystatic.a
的靜態(tài)庫。在鏈接階段,靜態(tài)庫被直接嵌入到可執(zhí)行程序中,因此在運行時不需要依賴外部庫文件。
預(yù)處理
以#開頭的就是預(yù)處理命令
編譯
生成匯編代碼,使用到了ccl工具
匯編
生成機器代碼,用到的工具為as
鏈接
將上步生成的OBJ文件和系統(tǒng)庫的OBJ文件,庫文件鏈接起來
用到的工具為ld或collect2
目錄選項
-Idir 大寫I
比如 -I. 表示在當(dāng)前目錄下搜索-Idir
選項是用來指定編譯器在搜索頭文件時需要添加的目錄路徑。具體來說,當(dāng)你在代碼中使用#include <header.h>
形式的語句時,編譯器會在一些默認的目錄和用戶指定的目錄中查找header.h
頭文件,如果找到則進行編譯,否則就報錯。
這里的-I
選項就是用來指定額外的頭文件搜索路徑的。例如,假設(shè)你的頭文件位于/usr/local/include
目錄下,那么你可以通過以下命令來指定這個目錄為頭文件搜索路徑:
gcc -o myprogram myprogram.c -I/usr/local/include
這樣,編譯器在搜索頭文件時就會先搜索/usr/local/include
目錄,如果目錄下存在需要的頭文件,則不會報錯。
需要注意的是,-I
選項僅僅是將指定的目錄添加到搜索路徑中,并不會取代默認的搜索路徑。如果你希望完全使用自定義的頭文件搜索路徑,可以使用-nostdinc
選項禁止編譯器使用默認的搜索路徑。例如:
gcc -o myprogram myprogram.c -nostdinc -I/usr/local/include
這樣,編譯器就只會按照-I
選項中指定的路徑搜索頭文件了。
include<> 與 " "
如果以“#include < >”包含文件,則只在標(biāo)準庫
目錄開始搜索(包括使用-Idir 選項定義的目錄);如果以“#include “ ””包
含文件,則先從用戶的工作目錄開始搜索,再搜索標(biāo)準庫目錄。
-I -I- 與 -I- -I
-I -I- 只 適 用 于 `#include
"file"'這種情況;它們不能用來搜索`#include <file>'包含的頭文件
-I- -I
可以在這些路徑中搜索
所有的`#include'指令(一般說來-I 選項就是這么用的)。
ld/objdump/objcopy 選項
ld
、objdump
和objcopy
都是常用的GNU工具,它們在各自的領(lǐng)域內(nèi)都有很多實用的選項。
ld
ld
是用來將多個目標(biāo)文件鏈接成一個可執(zhí)行文件或動態(tài)鏈接庫的工具。它的一些常用選項如下:
-
-o file
:指定輸出文件名稱; -
-l library
:指定需要鏈接的庫; -
-L path
:指定庫搜索路徑; -
-shared
:生成動態(tài)鏈接庫; -
-static
:靜態(tài)鏈接所有庫。
objdump
objdump
是一個反匯編器,可以將目標(biāo)文件反匯編為匯編代碼。它的一些常用選項如下:
-
-D
:反匯編所有節(jié)(包括已被標(biāo)記為debugging信息的節(jié)); -
-S
:反匯編同時顯示源代碼; -
-M options
:設(shè)置反匯編器選項,例如-Mintel
表示使用Intel語法。
objcopy
objcopy
是一個目標(biāo)文件格式轉(zhuǎn)換工具,可以將目標(biāo)文件從一種格式轉(zhuǎn)換為另一種格式,也可以改變目標(biāo)文件的各種屬性等。它的一些常用選項如下:
-
-O format
:指定轉(zhuǎn)換后的目標(biāo)文件格式; -
--strip-all
:刪除所有符號表及重定位表等調(diào)試信息; -
--strip-debug
:刪除debugging信息; -
--only-section name
:只拷貝指定的節(jié)。
這些工具在開發(fā)和調(diào)試過程中非常有用,可以幫助開發(fā)者完成目標(biāo)文件的相關(guān)操作,例如鏈接庫、調(diào)試和格式轉(zhuǎn)換等。
gcc -shared 和 ld
ld
和gcc -shared
都可以用來生成動態(tài)鏈接庫,它們在功能上確實是相當(dāng)?shù)?。不過,gcc -shared
命令其實是一個包含了gcc
和ld
的封裝工具,它可以將多個目標(biāo)文件和庫文件鏈接成一個動態(tài)鏈接庫,而且更加簡單易用。
具體來說,gcc -shared
的使用方式如下:
gcc -shared -o libmymodule.so mymodule.o
這條命令會將mymodule.o
目標(biāo)文件鏈接為名為libmymodule.so
的動態(tài)鏈接庫。其中,-shared
選項表示生成動態(tài)鏈接庫,-o
選項用于指定輸出文件的名稱和路徑。
與之相比,直接使用ld
生成動態(tài)鏈接庫需要手動指定很多參數(shù),例如鏈接器腳本、鏈接器選項等,相對比較麻煩。因此,在實際開發(fā)中,通常優(yōu)先考慮使用gcc -shared
命令生成動態(tài)鏈接庫。
gcc -g
gcc -g
是用來生成調(diào)試信息的編譯選項之一。指定了-g
選項,就可以在編譯生成的目標(biāo)文件中嵌入調(diào)試信息,方便程序調(diào)試。
具體來說,使用gcc -g
命令編譯源代碼時,會在生成的可執(zhí)行文件中嵌入調(diào)試符號表,包含了函數(shù)名、變量名等信息,同時還包含了源代碼的行號和文件名等信息。這些調(diào)試信息可以幫助開發(fā)者定位和修復(fù)程序的bug。
例如,假設(shè)有一個名為test.c
的C語言源文件,可以通過以下命令來生成帶調(diào)試信息的可執(zhí)行文件:
gcc -g -o test test.c
其中,-o
選項用于指定輸出文件名稱,-g
選項用于生成調(diào)試信息。
需要注意的是,在生產(chǎn)環(huán)境中,通常不建議在生產(chǎn)代碼中包含調(diào)試信息,因為它會增加可執(zhí)行文件的體積,并且可能泄漏敏感信息。因此,需要在生成生產(chǎn)環(huán)境可執(zhí)行文件時去掉-g
選項。
多文件
xxx.h里面聲明
xxx.cpp include "xxx.h"函數(shù)實現(xiàn)
main.cpp include "xxx.h"
gcc -g .\main.cpp .\xxx.cpp -o my_multi
報錯
自動生成的task是編譯單個文件的
需要自己配置launch和task文件
他視頻里是通過自己的 gcc命令生成命令了
就只需要改動launch文件下的
program值 指定生成的exe文件路徑
然后把 prelaunchtask給注釋。
基于cmake
創(chuàng)建 cmakelist.txt
project(myswap)
add_executable(文件名字別稱 文件名.cpp 文件2.cpp)
ctrl shift p
選定cmake編譯器
Cmake:configure
然后選擇
GCC 8.1.0 編譯器
可以看到終端信息以及生成的build文件夾
之后回到終端中
再build目錄下執(zhí)行
cmake..
他會到上一級目錄查找CMakeLists.txt文件并生成相應(yīng)的構(gòu)建工程。最后,再執(zhí)行make命令,將源代碼編譯成可執(zhí)行文件或庫文件等二進制文件,并將其輸出到build目錄下。
因此,在使用CMake進行非ROS項目構(gòu)建時,你必須確保使用正確的目錄結(jié)構(gòu),即將源代碼存放在根目錄下,而將構(gòu)建過程中生成的中間文件和構(gòu)建工件等內(nèi)容存放在build目錄下。如果你需要直接修改或查看具體的編譯文件,可以到build目錄下找到,但一般來說在大多數(shù)情況下,你只需要在build目錄下找到最終的可執(zhí)行文件或庫文件等內(nèi)容即可。
之后linux和windows下執(zhí)行的程序不太一樣,這里執(zhí)行了 mingw32-make.exe
可以看到編譯, 然后是鏈接,生成文件
調(diào)試
要到launch.json下給到program路徑,同樣把prelaunch給注釋掉
注意
注意2
當(dāng)cpp代碼更改后,如果把prelaunch代碼注釋了,調(diào)試的時候他不會生成新的可執(zhí)行文件,他是按照舊的代碼運行的。
當(dāng)重新執(zhí)行 mingw32命令后,他重新building,linking,buildt后才會執(zhí)行新的代碼。
cmake與mingw32-make.exe關(guān)系
CMake是一款跨平臺的自動化建構(gòu)系統(tǒng),可以幫助開發(fā)者在不同的操作系統(tǒng)和編譯環(huán)境下生成可執(zhí)行文件、庫文件等項目產(chǎn)物。執(zhí)行CMake命令會根據(jù)CMakeLists.txt中的描述生成相應(yīng)的Makefile或Visual Studio工程等項目文件,然后使用Make或Visual Studio等原生工具對項目進行編譯和鏈接。
當(dāng)你使用CMake生成了Makefile之后,你還需要執(zhí)行make
命令或mingw32-make.exe
命令(如果你正在使用MinGW32編譯器的話)來實際編譯和鏈接項目代碼,最終生成可執(zhí)行文件或庫文件等項目產(chǎn)物。
具體來說,在執(zhí)行mingw32-make.exe
命令時,它會讀取Makefile文件中的指令和依賴關(guān)系,按照規(guī)定的順序?qū)υ创a進行編譯和鏈接。通過這種方式,編譯器會將源代碼編譯成目標(biāo)文件,鏈接器則將目標(biāo)文件與庫文件等依賴項進行鏈接,最終生成可執(zhí)行文件或庫文件等項目產(chǎn)物。
總之,CMake負責(zé)生成Makefile文件,而mingw32-make.exe
負責(zé)根據(jù)Makefile文件中的指令和依賴關(guān)系對項目進行編譯和鏈接。因此,在使用CMake生成Makefile之后,你需要通過運行mingw32-make.exe
來完成整個項目的編譯和鏈接過程。
task文件
當(dāng)你把launch文件里的prelaunchtask注釋取消后,F(xiàn)5按下后報錯
系統(tǒng)里沒有執(zhí)行 名稱為xxx的task,你需要創(chuàng)建這個task,
ctrl shift p ------ task configuration
或者 c/c++ g++.exe build active file creat task from file
相當(dāng)于就是在shell中執(zhí)行了 command,
g++ -g (文件名)main.cpp swap.cpp -o out.exe
默認生成的是單文件調(diào)試,此時需要將${file} 改為 "main.cpp","swap.cpp",
同時需要將最后一個參數(shù)改為輸出文件所需要的文件名參數(shù)
注意3
他這里重現(xiàn)編譯了,需要再次更改 program的文件路徑
生成路徑和指向路徑要對應(yīng)
prelaunchtask
最為關(guān)鍵的作用, 就是調(diào)試的時候會先調(diào)用 prelaunch的task任務(wù),進行編譯生成。否則就會默認調(diào)用之前生成的文件。
相當(dāng)于調(diào)用task文件里的指令
多條指令 更改為 每次按F5調(diào)試一次性
每次更改代碼都要執(zhí)行多條指令,比如說make以及mingw32等等。
可以全部整合到task.josn文件中
到達build目錄空間下
三個lable三個task,第三個lable包含了前兩個task
這里需要把第二個task的command的 make 改為 mingw32-make.exe
需要到launch中prelaunchtask名字改為 Build
settings.json 和cpp proporties.json
ros課堂里面的 什么自定義srv文件 msg文件都是在這里面配置的
ctrl shift b
{
// 有關(guān) tasks.json 格式的文檔,請參見
// https://go.microsoft.com/fwlink/?LinkId=733558
"version": "2.0.0",
"tasks": [
{
"label": "catkin_make:debug", //代表提示的描述性信息
"type": "shell", //可以選擇shell或者process,如果是shell代碼是在shell里面運行一個命令,如果是process代表作為一個進程來運行
"command": "catkin_make",//這個是我們需要運行的命令
"args": [],//如果需要在命令后面加一些后綴,可以寫在這里,比如-DCATKIN_WHITELIST_PACKAGES=“pac1;pac2”
"group": {"kind":"build","isDefault":true},
"presentation": {
"reveal": "always"//可選always或者silence,代表是否輸出信息
},
"problemMatcher": "$msCompile"
}
]
}
這段文本是一個 `tasks.json` 文件的示例,用于定義 Visual Studio Code 編輯器中工作區(qū)的任務(wù)列表。該示例包含一個名為 `catkin_make:debug` 的任務(wù),用于在 ROS (Robot Operating System) 環(huán)境下編譯項目代碼并生成調(diào)試版本的二進制文件。
具體來說,`tasks` 數(shù)組中的每個元素都表示一個任務(wù),該示例中只定義了一個任務(wù)。下面對各個字段進行解釋:
1. `"label"`:任務(wù)的標(biāo)簽,用于在編輯器中顯示該任務(wù)的描述信息;
2. `"type"`:任務(wù)類型,可以是 "shell" 或者 "process"。如果是 "shell",則表示該任務(wù)使用 shell 命令,在終端中運行,如果是 "process",則表示該任務(wù)以進程的方式運行;
3. `"command"`:表示需要執(zhí)行的命令,該示例中需要執(zhí)行的命令是 `catkin_make`;
4. `"args"`:表示執(zhí)行命令時傳遞的參數(shù),該示例中沒有傳遞任何參數(shù);
5. `"group"`:表示任務(wù)所屬的分組,可以指定 build、test、或者其他自定義分組。該示例中將該任務(wù)設(shè)置為默認構(gòu)建任務(wù);
6. `"presentation"`: 表示任務(wù)執(zhí)行過程中輸出信息的提示配置。在該示例中設(shè)置為 `reveal: "always"`,表示總是在終端中顯示任務(wù)的輸出信息;
7. `"problemMatcher"`: 表示用于匹配輸出信息中的錯誤信息的正則表達式,以便錯誤信息可以在編輯器中被定位和高亮顯示。該示例中使用了 Visual C++ 的問題匹配器,用于匹配 C/C++ 編譯器輸出的錯誤信息。
總之,這段示例代碼定義了一個 "catkin_make:debug" 的任務(wù),用于在 ROS 環(huán)境下編譯項目代碼,并生成調(diào)試版本的二進制文件。該任務(wù)被設(shè)置為默認構(gòu)建任務(wù),并在終端中輸出任務(wù)的輸出信息。
在 Microsoft Visual Studio Code 編輯器中,使用快捷鍵 Ctrl + Shift + B
可以調(diào)用編譯命令,可以快速編譯并構(gòu)建項目。
但需要注意的是,這個組合鍵需要先配置對應(yīng)的編譯任務(wù)才能正常工作。具體來說,你需要在 Visual Studio Code 中打開項目文件夾,然后使用菜單欄中的“終端”菜單或快捷鍵 Ctrl + ~
打開集成終端。接著,在終端中輸入 task list
命令,查看當(dāng)前項目中已經(jīng)定義的所有任務(wù)。
如果沒有定義編譯任務(wù),可以通過添加 tasks.json
文件來定義編譯任務(wù),例如:
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "g++",
"args": [
"-o",
"hello",
"hello.cpp"
]
}
]
}
這個示例中,我們定義了一個名為 build
的編譯任務(wù),它的命令是 g++ -o hello hello.cpp
。執(zhí)行 Ctrl + Shift + B
快捷鍵時,Visual Studio Code 會自動查找并執(zhí)行名為 build
的任務(wù),從而完成編譯操作。
總之,使用快捷鍵 Ctrl + Shift + B
調(diào)用編譯命令需要先配置相應(yīng)的編譯任務(wù),并確保該任務(wù)的名稱與 tasks.json
文件中定義的一致。文章來源:http://www.zghlxwxcb.cn/news/detail-482679.html
catkin make 和make
分別為cmake 和 make -j8 -l8
跑完第一條后在相應(yīng)目錄跑第二條, 他這里是在linux下 所以后面一條命令是make,這樣的話就說的通了文章來源地址http://www.zghlxwxcb.cn/news/detail-482679.html
到了這里,關(guān)于cpp文件編譯過程 makefile cmake的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!