GCC/G++ 基礎區別
gcc / cc:C 編譯器,也能編 C++ 但不自動鏈接 C++ 標準庫
g++ / c++:C++ 編譯器,自動鏈接 libstdc++
- 習慣:
.c 用 gcc,.cpp/.cc 用 g++
最常用編譯流程
# 單文件直接生成可執行文件
gcc test.c -o test
# 分步編譯:預處理→編譯→彙編→鏈接
gcc -E test.c -o test.i # 預處理
gcc -S test.i -o test.s # 生成彙編
gcc -c test.s -o test.o # 生成目標文件
gcc test.o -o test # 鏈接
# 多文件
gcc main.c util.c -o app
# 或
gcc -c main.c -o main.o
gcc -c util.c -o util.o
gcc main.o util.o -o app
核心參數分類速查表
優化與調試
| 參數 | 說明 |
-O0 | 無優化(默認),適合調試 |
-O1 / -O | 基礎優化 |
-O2 | 推薦發布優化,速度/大小平衡 |
-O3 | 激進優化(內聯、向量化),可能增大體積 |
-Os | 優化體積 |
-g | 生成調試信息(DWARF),配合 GDB |
-Wall | 開啟常見警告(強烈建議常開) |
-Wextra | 額外警告 |
-Werror | 警告視為錯誤 |
頭文件與庫路徑
| 參數 | 作用 | 示例 |
-I | 添加頭文件搜索路徑 | -I./include -I/opt/mylib/include |
-L | 添加庫文件搜索路徑 | -L./lib -L/opt/mylib/lib |
-l | 鏈接指定庫(去掉 lib 前綴、.so/.a 後綴) | -lm -lpthread -lssl |
鏈接順序很重要:依賴關系的庫要放在被依賴者後面,如 gcc main.o -L./lib -lmylib -lother。
動態/靜態鏈接控制
-static # 完全靜態鏈接(glibc 不建議全靜態)
-Wl,-Bstatic -lfoo -Wl,-Bdynamic -lbar # 部分靜態
-shared -fPIC # 編譯生成 .so 動態庫
-Wl,-rpath,/path # 運行時庫搜索路徑嵌入可執行文件
C/C++ 標準控制
-std=c11 -std=c++17 # 指定標準
-ansi # 等同 -std=c90(C)或 -std=c++98(C++)
-pedantic # 嚴格標準模式,禁用 GNU 擴展
預處理器宏
-DDEBUG # 定義 DEBUG=1
-DVERSION=\"1.0.0\" # 定義字符串宏
-UDEBUG # 取消定義
輸出控制
-o file # 指定輸出文件名
-c # 僅編譯不鏈接,產出 .o
-S # 僅編譯到 .s
-E # 僅預處理
-MMD -MP # 自動生成 .d 依賴文件,配合 make
pkg-config 自動化獲取編鏈參數
# 查看支持的庫
pkg-config --list-all
# 獲取 GTK+ 編譯鏈接參數
pkg-config --cflags --libs gtk+-3.0
# 輸出示例:-I... -pthread ... -lgtk-3 -lgdk-3 ...
# 在編譯命令中直接嵌入(反引號或 $())
gcc main.c -o main `pkg-config --cflags --libs gtk+-3.0`
交叉編譯指南
概念
在宿主機(如 x86_64 Linux)編譯目標機(如 ARM Linux)可執行文件。
工具鏈命名
arm-linux-gnueabihf-gcc
aarch64-linux-gnu-g++
mipsel-linux-gnu-gcc
關鍵:指定目標系統根目錄
# sysroot 包含目標機的 /lib, /usr/include 等
arm-linux-gnueabihf-gcc --sysroot=/opt/arm-rootfs test.c -o test
# 或環境變量
export PKG_CONFIG_SYSROOT_DIR=/opt/arm-rootfs
export PKG_CONFIG_PATH=/opt/arm-rootfs/usr/lib/pkgconfig
避免污染
- 絕不使用宿主機的
/usr/include、/usr/lib
- 所有
-I、-L、pkg-config 必須指向 sysroot 內路徑
常用環境變量
| 變量 | 作用 |
CC | C 編譯器(如 export CC=clang) |
CXX | C++ 編譯器 |
CFLAGS | C 編譯參數 |
CXXFLAGS | C++ 編譯參數 |
LDFLAGS | 鏈接參數 |
LIBS | 庫參數 |
PKG_CONFIG_PATH | .pc 文件搜索路徑 |
Makefile 典型模板片段
CC = gcc
CFLAGS = -Wall -O2 -I./include
LDFLAGS = -L./lib
LIBS = -lmylib -lpthread
SRCS = $(wildcard *.c)
OBJS = $(SRCS:.c=.o)
TARGET = myapp
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) -o $@ $^ $(LDFLAGS) $(LIBS)
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
rm -f $(OBJS) $(TARGET)
- 上一篇文章: Linux 內核 container_of 宏深度解析:從成員指針獲取結構體指針
- 下一篇文章: C語言 strtol 函數詳解:字符串轉長整型的健壯選擇
Copyright ©
程式碼之家 All Rights Reserved