gcc編譯, gdb調試, makefile寫法


//test.c:

#include <stdio.h>

int main(void)

{

  printf("hello world!");

  return 0;

}

======================================

一、

1. 編譯過程:預處理(processing)-》編譯(compilation)-》匯編(assembly)->Linking

 

2. 預處理:

gcc -E test.c -o test.i  /  gcc -E test.c

預處理的結果就是將stdio.h文件中的內容插入到test.c中

 

3.編譯為匯編代碼:

gcc -S test.i -o test.s

-S選項表示生成匯編代碼, -o表示輸出匯編代碼文件。

 

4. 匯編:

gcc -C test.s -o test.o

匯編器將匯編代碼編譯成目標文件

 

5. 鏈接:

gcc test.o -o test

 

二、

1.對多個文件進行編譯:

gcc test1.c test2.c -o test

 

2.檢錯

gcc -pedantic illcode.c -o illcode

-pedantic 幫助程序員發現不符合ansi/iso標准代碼。

-Wall 使gcc產生盡可能多的警告信號

-Werror會在警告的地方停止編譯,迫使程序員對自己代碼進行修改

 

三、庫文件的鏈接:

函數庫是由一些頭文件(.h)和庫文件(.so, .lib, .dll)的集合。 LINUX默認將頭文件放在/usr/include/, 庫文件放在/usr/lib/; 如果我們要用的庫不在這些目錄下,所以在gcc編譯的時候必須用自己的辦法來查找所需要的頭文件和庫文件。

例: test.c鏈接mysql,我們要下載mysql的庫——MySQL Connectors, 下下來以后由個include的文件夾, 里面包含頭文件, 還有一個lib的文件夾,里面包含二進制so文件libmysqlclient.so,其中include的路徑是/usr/dev/mysql/include, lib的文件夾是/usr/dev/mysql/lib

1. 編譯成目標文件:

gcc -c -I /usr/dev/mysql/include test.c -o test.o

2. 鏈接:最后我們把所有的目標文件鏈接成可執行文件。

gcc -L /usr/dev/mysql/lib -lmysqlclient test.o -o test

linux下動態鏈接庫用so結尾,靜態鏈接庫由a結尾。

3.強制鏈接時使用靜態鏈接庫:

加-static

gcc -L /usr/dev/mysql/lib -static -lmysqlclient test.o -o test

靜態庫搜索順序

(1). ld 會去找gcc命令中參數-L

(2)再找gcc環境變量library_PATH

 (3)再找內定目錄/lib, /usr/lib, /usr/local/lib

 

動態鏈接搜索順序:

(1)編譯目標代碼時候指定的搜索路徑

(2)環境變量LD_LIBRARY_PATH

(3)配置文件/etc/ld.so.con

(4)/lib, /usr/lib

 

GDB調試:

1. gcc -g main.c -o main

在用gcc時候,加上-g表示在生成的目標文件中加入源代碼信息以便調試

2. l, list 從第一行開始列出源代碼

3. start, 開始執行程序,第一行break

4. n, next下一行

5. s, step進入函數

6. bt, backtrace查看函數棧

7. i locals, 用info命令查看局部變量

8. f 1, 到棧幀1

9. p sum, print出sum的值

10. finish, 運行到返回點——如果是從s進來的函數

11. set var sum=0, 調試過程中給變量sum賦值

12. p result[2]=33, 用p賦值

13. display sum, 每次程序停止的時候顯示sum的值

14. b, break當前的循環

15. b 9, 在第9行設置斷點

16. c, 連續運行continue

17. i breakpoints, 查看所有斷點

18. delete breakpoint 2, 刪除斷點2

19. disable breakpoint 2 , 禁用斷點2

20. enable breakpoint 2 , 啟用

21. break 9 if sum!=0 , 當滿足條件時候斷點激活

22. r , 從頭開始執行run

 

Makefile基礎:

1. Makefile 是由一組rule組成, 每條rule信息如下:

target ...: prerequistites ...

<tab>command1

<tab>command2

例:

main: main.o stack.o maze.o

  gcc main.o stack.o maze.o -o main

只要有一個prerequisities更新了,目標也會被更新,就是執行command

 

2. clean規則

用於清除編譯產生的二進制文件,保留源文件:

clean:

  @echo "cleaning project"

  -rm main *.o

  @echo "clean completed"

如果命令前加@則不顯示命令本身,只顯示結果。 如果加-表示即使命令出錯也不會停止。 通常rm或者mkdir前面要加-,因為可能沒有這個文件,或者已經有了這個文件。

如果存在有文件名字就叫做clean,則會出錯,那么就要添加一行,將clean關鍵字申明成偽目標

.PHONY:clean 

 

3. 4個規則關鍵字:

install:將可執行文件、配置文件、docs分別拷貝到不同安裝目錄

all:執行主要編譯工作,通常用作缺省目標

clean:刪除編譯生成的二進制文件

distclean:不僅刪除二進制文件,還刪除其他的,只留下源文件。

 

4. 隱含規則和模式規則:

其中有一條

%.o: %.c

  $(compile.c) $(output_option) $<

$@為規則中的target, $<為規則中的第一個條件,上面那句相當於 cc -c $@ $<

進而相當於所有符合這樣的依賴關系:

main.o:main.h statk.h maze.h

可以隱含

main.o: main.c

  cc -c o main.o main.c

 

5. 變量:

main.o: main.c

  $(CC) $(CFLAGS) $(CPPFLAGS) -c $<

CC = gcc

CFLAGS = -o -g

CPPFLAGS = -Iinclude

 

:=, 立即賦值

?=, 如果沒有賦過值才進行賦值

+=, 追加賦值

$^, 表示將所有條件組成的列表

$?, 表示所有比目標新的條件組成的列表

 

6. 自動處理依賴關系:

例:

all: main

main: main.o stack.o maze.o

  gcc $^ -o $@

clean:

  -rm main *.o

.PHONY: clean

sources = main.c stack.c maze.c

include $(souces: .c = .d)

%.d: %.c

  set -e; rm -f $@;\

  $(CC) -MM $(CPPFLAGS) $< > $@.$$$$;\      # $$$$相當於兩個$ , 表示進程

  ....略...

      


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM