我們接觸程式的時候,一般編譯和鏈結是一起做的,所以不容易看到編譯和鏈結的不同,這裡我們講一下編譯和鏈結的區別。
範例1:
#main.c
int main()
對main.c生成執行檔案
$gcc -o main main.c
生成可執行檔案main(沒有字尾名),這個檔案什麼也不幹,但是可以執行。
gcc -o的過程同時呼叫了編譯和鏈結指令。
假如我們要在main中呼叫linuxframe.c中的startkernel()函式
範例2:
#main.c
#include "linuxframe.h"
int main()
這個時候我們編譯鏈結它
$gcc -o main main.c
undefined symbols for architecture x86_64:
"_startkernel", referenced from:
_main in main-856f96.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
說_startkernel這個函式在鏈結的時候系統找不到。
但是我們執行以下編譯指令
$gcc -c main.c
這個時候順利的生成main.o檔案
也就是說,main.c檔案編譯是可以的,沒有語法錯誤,但是鏈結的時候,就是去尋找startkernel()函式的時候,找不到了。要怎麼做呢?
試一下:
$gcc -o main main.c linuxframe.c
就沒有問題了,執行成功,順利的生成可執行檔案main(沒有字尾)
把linuxframe.c裡面新增乙個列印語句如下:
#include "stdio.h"
#include "linuxframe.h"
void loadbootcodefromexdisk();
void startkernel()
void loadbootcodefromexdisk()
$gcc -o main main.c linuxframe.c
順利生成可執行檔案main。執行main如下
$./main
順利輸出abcdefg。
這裡順便講一下.h檔案的作用,如果把main.c中的#include "linuxframe.h"語句去掉會怎麼樣?
#gcc -o main main.c linuxframe.c
main.c:14:5:warning:implicit declaration of function 'startkernel' is invalid in c99 [-wimplicit-function-declaration]
startkernel();
^
1 warning generated.
系統提示startkernel沒有定義。
缺少linuxframe.h,main.c和linuxframe.c就缺少了聯絡,main.c中呼叫的startkernel就不知道是linuxframe.c中的那個startkernel了。
執行以下生成的可執行檔案main
$./main
$什麼也沒有輸出。
預編譯,編譯,彙編,鏈結
2.編譯的工作內容 3.彙編的工作內容 4.鏈結器的工作內容 參考 include int main 使用gcc編譯器 gcc hello.c a.out a.out 含義是 assembler output 即 彙編輸出 上述過程可以分解為四個步驟 1.預處理 prepressing gcc e ...
C 預編譯 編譯 彙編 鏈結
windows中以2 2劃分核心 使用者空間,linux中以1 3劃分核心 使用者空間。在text段中,只有普通區域性變數是指令 int gdata1 10 data 已初始化且初始化不為零的資料 int gdata2 0 bss 未初始化或初始化為零的資料 int gdata3 bss stati...
深入理解include預編譯原理
1.include 命令的作用 1.1 什麼情況不使用 include 檔案 void test a 檔案 void test a 函式宣告 void test b 其實,這樣的工程,可以不用使用 include 預編譯命令。1.2 什麼情況使用 include 如果工程裡面的函式特別多,那麼按照上...