gcc 編譯器使用指南

目錄

  • 安裝
  • 準備test.cpp
  • 編譯
  • g++ 編譯參數
    • -g :編譯帶調試信息的可執行文件
    • -O[n] :開啟優化
    • -l 和 -L :指定庫文件 | 指定庫文件路徑
    • -I :指定頭文件搜索目錄
    • -Wall 和 -w:打印警告信息 | 關閉警告信息
    • -std=c++11 :設置編譯標準
    • -o :指定輸出文件名
    • -D :定義宏
  • 實例演示
    • 直接編譯
    • 生成庫文件并編譯

參考:
https://b23.tv/tWqKrC
我的linux版本如下:
Linux version 5.4.0-88-generic (buildd@lgw01-amd64-008) (gcc version 9.3.0 (Ubuntu 9.3.0-17ubuntu1~20.04))
使用命令:

cat /proc/version

即可查看

安裝

sudo apt update
# 安裝編譯器和調試器
sudo apt install build-essential gdb
# 安裝完成后,確認是否成功
gcc --version
g++ --version
gdb --version

準備test.cpp

mkdir test
cd test
touch test.cpp
vim test.cpp
# 設置tab縮進
:set tabstop=4

然后寫代碼:

#include<iostream>
using namespace std;
int main()
{cout << "test" << endl;return 0;
}

編譯

在實際使用中,使用gcc指令編譯c代碼,g++指令編譯c++代碼。
一般cpp文件需要通過四個過程生成可執行文件:
預處理、編譯、匯編、鏈接

# 預處理 .cpp -> .i
# -E 表示編譯器只對輸入文件進行預處理
g++ -E test.cpp -o test.i
# 編譯 .i -> .s
# -S 表示在c++代碼產生了匯編語言文件后停止編譯,產生的匯編語言文件為 .s
g++ -S test.i -o test.s
#  匯編 .s -> .o
# -c g++僅把源代碼編譯為機器語言的目標代碼
g++ -c test.s -o test.o
# 鏈接 .o -> bin文件
# -o 為將來產生的可執行文件用指定的文件名
g++ test.o -o test 

以上的步驟也可以直接用一個步驟代替:

g++ test.cpp -o test

現在test文件夾里面是這樣:

drwxrwxrwx 2 dyy dyy  4096 1019 14:44 ./
drwxrwxrwx 8 777 dyy  4096 1019 13:54 ../
-rwxrwxr-x 1 dyy dyy 17320 1019 14:44 test*
-rw-rw-r-- 1 dyy dyy    91 1019 14:38 test.cpp

運行它: 成功

dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/test$ ./test 
test

g++ 編譯參數

-g :編譯帶調試信息的可執行文件

# -g 選項告訴 GCC 產生能被 GNU 調試器GDB使用的調試信息,以調試程序。
g++ -g test.cpp

-O[n] :開啟優化

# -O 選項告訴 g++ 對源代碼進行基本優化。這些優化在大多數情況下都會使程序執行的更快。 -
# -O0 表示不做優化
# -O1 為默認優化
# -O2 除了完成-O1的優化之外,還進行一些額外的調整工作,如指令調整等。
# -O3 則包括循環展開和其他一些與處理特性相關的優化工作。
g++ -O2 test.cpp

-l 和 -L :指定庫文件 | 指定庫文件路徑

# -l參數(小寫)就是用來指定程序要鏈接的庫,-l參數緊接著就是庫名
# 在/lib和/usr/lib和/usr/local/lib里的庫直接用-l參數就能鏈接# 鏈接glog庫
g++ -lglog test.cpp# 如果庫文件沒放在上面三個目錄里,需要使用-L參數(大寫)指定庫文件所在目錄
# -L參數跟著的是庫文件所在的目錄名
# 鏈接mytest庫,libmytest.so在/home/bing/mytestlibfolder目錄下
g++ -L/home/bing/mytestlibfolder -lmytest test.cpp

-I :指定頭文件搜索目錄

# -I
# /usr/include目錄一般是不用指定的,gcc知道去那里找,但 是如果頭文件不在/usr/icnclude
# 里我們就要用-I參數指定了,比如頭文件放在/myinclude目錄里,那編譯命令行就要加上-
# I/myinclude 參數了,如果不加你會得到一個”xxxx.h: No such file or directory”的錯
# 誤。-I參數可以用相對路徑,比如頭文件在當前 目錄,可以用-I.來指定。上面我們提到的–cflags參
# 數就是用來生成-I參數的。
g++ -I/myinclude test.cpp

-Wall 和 -w:打印警告信息 | 關閉警告信息

# 打印出gcc提供的警告信息
g++ -Wall test.cpp
# 關閉警告信息
g++ -w test.cpp

-std=c++11 :設置編譯標準

# 使用c++11的標準編譯 test.cpp
g++ -std=c++11 test.cpp

-o :指定輸出文件名

# 若不指定,生成文件為a.out
g++ test.cpp -o test

-D :定義宏

# 常用場景:
# -DDEBUG 定義DEBUG宏,可能文件中有DEBUG宏部分的相關信息,用個DDEBUG來選擇開啟或關閉
# DEBUG
g++ -DDEBUG debugTest.cpp -o debugTest

比如:

#include<stdio.h>
using namespace std;
int main()
{#ifdef DEBUGprintf("DEBUG LOG\n");#endifprintf("in\n");
}

我們編譯運行:

g++ -DDEBUG debugTest.cpp -o debugTest
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/test$ ./debugTest 
DEBUG LOG
in

實例演示

test項目錄如下:

dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ tree
.
├── include
│   └── swap.h
├── main.cpp
└── src└── swap.cpp2 directories, 3 files

main.cpp內容

#include<iostream>
#include<swap.h>
using namespace std;
int main()
{int val1 = 10;int val2 = 20;cout << "before" << endl;cout << val1 << " " << val2 << endl;swap(val1, val2);cout << "after" << endl;cout << val1 << " " << val2 <<endl;return 0; 
}

swap.h內容

#ifndef _swap_h_
#define _swap_h_
#include<stdio.h>
void swap(int& a, int& b);
#endif

swap.cpp內容

#include"swap.h"
void swap(int& a, int& b)
{int tmp = a;a = b;b = tmp;
}    

直接編譯

最簡單編譯運行

# 將 main.cpp src/Swap.cpp 編譯為可執行文件
g++ main.cpp src/Swap.cpp -Iinclude
# 運行可執行文件
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ ./a.out 
before
10 20
after
20 10

增加編譯參數運行

g++ main.cpp src/swap.cpp -Iinclude -std=c++11 -O2 -Wall -o b.out

生成庫文件并編譯

首先嘗試生成靜態庫

cd src
# 匯編,生成swap.o文件
g++ swap.cpp -c -I../include
# 生成靜態庫libswap.a
ar rs libswap.a swap.o
cd ..
# 鏈接 生成可執行文件staticmain
g++ main.cpp -Iinclude -Lsrc -lswap -o staticmain

現在觀察一下項目文件:

dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ tree
.
├── include
│   └── swap.h
├── main.cpp
├── src
│   ├── libswap.a
│   ├── swap.cpp
│   └── swap.o
└── staticmain2 directories, 6 files
dyy@dyy-Lenovo-ThinkBo

現在嘗試動態鏈接

cd src
# 生成動態庫
g++ swap.cpp -I../include -fPIC -shared -o libswap.so
# 上面的命令等同于以下兩條合起來:
# g++ swap.cpp -I../include -c -fPIC
# g++ -shared -o libswap.so swap.o
cd ..
# 鏈接,生成可執行文件
g++ main.cpp -Iinclude -Lsrc -lswap -o sharemain

現在觀察一下項目文件:

dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ tree
.
├── include
│   └── swap.h
├── main.cpp
├── sharemain
├── src
│   ├── libswap.a
│   ├── libswap.so
│   ├── swap.cpp
│   └── swap.o
└── staticmain

運行可執行文件

# 運行靜態鏈接的可執行文件
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ ./staticmain 
before
10 20
after
20 10
# 運行含有動態鏈接的可執行文件
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ ./sharemain 
./sharemain: error while loading shared libraries: libswap.so: cannot open shared object file: No such file or directory
# 指定一下動態庫目錄然后再運行
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ LD_LIBRARY_PATH=src ./sharemain 
before
10 20
after
20 10

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/376841.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/376841.shtml
英文地址,請注明出處:http://en.pswp.cn/news/376841.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

bug found:定義對象時

看下面代碼 class Test{ }; class Test2{public:Test2(Test *t){}};int main(){Test test();//把定義一個對象 “Test test;” 寫成 “Test test();”函數聲明了&#xff01;Test2 test2(&test);//return 0;}Dev-cpp的提示信息&#xff1a; no matching function for c…

CMake學習使用(基于vscode)

目錄語法一些重要指令CMake常用變量CMake編譯工程編譯流程兩種構建方式實例展示參考&#xff1a; 基于VSCode和CMake實現C/C開發 | Linux篇 語法 基本語法格式&#xff1a;指令(arg1 arg2 …) 參數使用括弧括起來參數之間使用空格或者分號分開 指令是大小寫無關的&#xff0…

idhttp.post方式 調用datasnap rest 遠程方法

idhttp.get方式調用&#xff0c;這種比較簡單&#xff0c;大家都會。post方式網上卻沒有任何成功的代碼&#xff0c;本人也是摸索了一個上午才搞定。 分享給大家。 &#xff08;1&#xff09;post方式調用的遠程方法&#xff0c;方法名必須加“update”前綴&#xff0c;不加行不…

[轉]連接excel數據源時,首行包含列名稱選項在連接字符串中的設置。

關于Excel導入的HDRYES; IMEX1詳解 ProviderMicrosoft.Jet.OLEDB.4.0;Data Source111.xls;Extended Properties"Excel 8.0;HDRNO"; 其中HDRNO或YES即首行包含列名稱選項 (參數HDR的值&#xff1a;HDRYes&#xff0c;這代表第一行是標題&#xff0c;不做為數據使用&am…

C++多線程快速入門(一):基本常用操作

目錄case1&#xff1a;創建線程1 join、detachcase2&#xff1a;創建線程2 線程傳參 傳值或者傳引用case3&#xff1a;創建線程 線程傳參 functional object作為參數case4&#xff1a;觀察多線程程序加速計算case5&#xff1a;future get 獲取并發結果case6&#xff1a;互斥鎖…

android:configChanges屬性總結

原文地址&#xff1a;http://blog.csdn.net/zhaokaiqiang1992/article/details/19921703 android中的組件Activity在manifest.xml文件中可以指定參數android&#xff1a;ConfigChanges&#xff0c;用于捕獲手機狀態的改變。 在Activity中添加了android:configChanges屬性&#…

eclipse 中修改 M2_REPO的值

從eclipse中增加了maven2的插件之后&#xff0c;maven默認的本地庫的路徑是${user}/.m2/repository/下&#xff0c;一般windows用戶的操作系統都安裝在C盤&#xff0c;所以這個目錄 下的jar包比較危險。我嘗試從myeclipse->preferences->java->build path->classpa…

C++多線程快速入門(二)共享數據同步以及數據競爭

目錄std::unique_lock類模板僅調用一次線程局部存儲原子變量往期內容回顧std::unique_lock類模板 互斥鎖保證了線程間的同步&#xff0c;卻將并行操作變成了串行操作&#xff0c;對性能有較大影響&#xff0c;所以我們要盡可能減小鎖的區間粒度。 lock_guard只能保證在析構的時…

DNS安全淺議、域名A記錄(ANAME),MX記錄,CNAME記錄

相關學習資料 http://baike.baidu.com/link?url77B3BYIuVsB3MpK1nOQXI-JbS-AP5MvREzSnnedU7F9_G8l_Kvbkt_O2gKqFw7vm http://www.rfc-editor.org/rfc/rfc1035.txt http://www.rfc-editor.org/rfc/rfc3596.txt http://www.rfc-editor.org/rfc/rfc2782.txt http://www.rfc-edito…

ThinkInJava4讀書筆記之第一章對象入門

那句話怎么說來著&#xff0c;原句記不住了好像是出來混的遲早要還的。話說當初學校剛開Java課程&#xff0c;自己沒有好好學啊&#xff0c;后來直接做了jsp和servlet&#xff0c;然后學了SSH框架和Extjs、jQuery&#xff0c;接著是mybatis&#xff08;ibatis&#xff09;、fre…

C++多線程快速入門(三):生產者消費者模型與條件變量使用

互斥鎖完成 #include <iostream> #include <deque> #include <thread> #include <mutex>std::deque<int> q; std::mutex mtx;static void produce(int val) {while(val--) {std::unique_lock<std::mutex> guard(mtx);q.push_front(val);m…

【blade利刃出鞘】一起進入移動端webapp開發吧

前言 在移動浪潮襲來的時候&#xff0c;小釵有幸進入框架組做webapp框架開發&#xff0c;過程中遇到了移動端的各種坑&#xff0c;也產生了各種激情&#xff0c;就我們公司的發展歷程來說 第一階段&#xff1a;使用傳統方式開發移動站點&#xff0c;少量引入HTML5元素 第二階段…

題目理解。。

有時候一道大水題&#xff0c;因為英文描述可能有點復雜或者其它云云&#xff0c; 就比如那道PRO。。 別先被一道題嚇一跳&#xff0c;&#xff0c;&#xff0c; 英文描述看深入一點總歸會能解決的&#xff0c;盡可能多的考慮情況。大膽嘗試。轉載于:https://www.cnblogs.com/c…

C++多線程快速入門(四)shared_mutex以及讀寫鎖應用

在前面的三講中我們使用的mutex都是普通的std::mutex&#xff0c;這里介紹一下shared_mutex&#xff0c;版本為C17 std::shared_mutex的底層實現時操作系統提供的讀寫鎖&#xff0c;在讀多寫少的情況下&#xff0c;該shared_mutex比mutex更加高效。 它提供了常用的四種方法&am…

Tornado/Python 學習筆記(一)

1.源代碼下載及安裝&#xff1a;http://www.tornadoweb.org/en/stable/ 2.python中xmlrpc庫官方文檔&#xff1a;https://docs.python.org/3/library/xmlrpc.html?highlightxmlrpc 3.xml介紹與學習&#xff1a;http://www.w3school.com.cn/xml/xml_intro.asp XML 被設計為傳輸…

spring-aop-annotation

1。假設你已經配好依賴注入那一塊。此時的bean.xml為 <?xml version"1.0" encoding"UTF-8"?><beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xmlns:cont…

c++實現簡單線程池代碼

目錄完整代碼TaskPool.cppTaskPool.hmain.cpp完整代碼 TaskPool.cpp // // Created by LENOVO on 2021/10/25. //#include "TaskPool.h" #include <functional>std::mutex printMutex;TaskPool::TaskPool() : m_bRunning(false) {}TaskPool::~TaskPool() {re…

Android靜態圖片人臉識別的完整demo(附完整源碼)

Demo功能&#xff1a;利用android自帶的人臉識別進行識別&#xff0c;標記出眼睛和人臉位置。點擊按鍵后進行人臉識別&#xff0c;完畢后顯示到imageview上。 第一部分&#xff1a;布局文件activity_main.xml [html] view plaincopyprint?<RelativeLayout xmlns:android&qu…

圖論:最短路徑搜索--Dijkstra算法(c代碼實現)

最近因為辭職&#xff0c;有不少閑功夫&#xff0c;重溫下數據結構&#xff0c;順便練練手。今天說說最短路徑搜索算法中的Dijkstra原理和實現。 一&#xff1a;簡介 這個算法用于解決圖中單源最短路徑問題。所謂單源節點是指給定源節點&#xff0c;求圖中其它節點到此源節點的…

C++多線程快速入門(五)簡單線程池設計

目錄設計思路主線程運行邏輯task以及taskpool設計詳細流程講解完整代碼打印結果往期回顧設計思路 線程池實際上就是一組線程&#xff0c;當我們需要異步執行一些任務時&#xff0c;經常要通過OS頻繁創建和銷毀線程&#xff0c;不如直接創建一組在程序生命周期內不會退出的線程…