《電子技術應用》
您所在的位置:首頁 > 可編程邏輯 > 業界動態 > 編譯器的工作過程

編譯器的工作過程

2015-09-18
關鍵詞: 編譯器

  源碼要運行,必須先轉成二進制的機器碼。這是編譯器的任務。
  比如,下面這段源碼(假定文件名叫做test.c)。
  #include <stdio.h>
  int main(void)
  {
  fputs("Hello, world!\n", stdout);
  return 0;
  }
  要先用編譯器處理一下,才能運行。
  $ gcc test.c
  $ ./a.out
  Hello, world!
  對于復雜的項目,編譯過程還必須分成三步。
  $ ./configure
  $ make
  $ make install
  這些命令到底在干什么?大多數的書籍和資料,都語焉不詳,只說這樣就可以編譯了,沒有進一步的解釋。
  本文將介紹編譯器的工作過程,也就是上面這三個命令各自的任務。我主要參考了Alex Smith的文章《Building C Projects》。需要聲明的是,本文主要針對gcc編譯器,也就是針對C和C++,不一定適用于其他語言的編譯。
  第一步 配置(configure)
  編譯器在開始工作之前,需要知道當前的系統環境,比如標準庫在哪里、軟件的安裝位置在哪里、需要安裝哪些組件等等。這是因為不同計算機的系統環境不一樣,通過指定編譯參數,編譯器就可以靈活適應環境,編譯出各種環境都能運行的機器碼。這個確定編譯參數的步驟,就叫做"配置"(configure)。
  這些配置信息保存在一個配置文件之中,約定俗成是一個叫做configure的腳本文件。通常它是由autoconf工具生成的。編譯器通過運行這個腳本,獲知編譯參數。
  configure腳本已經盡量考慮到不同系統的差異,并且對各種編譯參數給出了默認值。如果用戶的系統環境比較特別,或者有一些特定的需求,就需要手動向configure腳本提供編譯參數。
  $ ./configure --prefix=/www --with-mysql
  上面代碼是php源碼的一種編譯配置,用戶指定安裝后的文件保存在www目錄,并且編譯時加入mysql模塊的支持。
  第二步 確定標準庫和頭文件的位置
  源碼肯定會用到標準庫函數(standard library)和頭文件(header)。它們可以存放在系統的任意目錄中,編譯器實際上沒辦法自動檢測它們的位置,只有通過配置文件才能知道。
  編譯的第二步,就是從配置文件中知道標準庫和頭文件的位置。一般來說,配置文件會給出一個清單,列出幾個具體的目錄。等到編譯時,編譯器就按順序到這幾個目錄中,尋找目標。
  第三步 確定依賴關系
  對于大型項目來說,源碼文件之間往往存在依賴關系,編譯器需要確定編譯的先后順序。假定A文件依賴于B文件,編譯器應該保證做到下面兩點。
 ?。?)只有在B文件編譯完成后,才開始編譯A文件。
 ?。?)當B文件發生變化時,A文件會被重新編譯。
  編譯順序保存在一個叫做makefile的文件中,里面列出哪個文件先編譯,哪個文件后編譯。而makefile文件由configure腳本運行生成,這就是為什么編譯時configure必須首先運行的原因。
  在確定依賴關系的同時,編譯器也確定了,編譯時會用到哪些頭文件。
  第四步 頭文件的預編譯(precompilation)
  不同的源碼文件,可能引用同一個頭文件(比如stdio.h)。編譯的時候,頭文件也必須一起編譯。為了節省時間,編譯器會在編譯源碼之前,先編譯頭文件。這保證了頭文件只需編譯一次,不必每次用到的時候,都重新編譯了。
  不過,并不是頭文件的所有內容,都會被預編譯。用來聲明宏的#define命令,就不會被預編譯。
  第五步 預處理(Preprocessing)
  預編譯完成后,編譯器就開始替換掉源碼中bash的頭文件和宏。以本文開頭的那段源碼為例,它包含頭文件stdio.h,替換后的樣子如下。
  extern int fputs(const char *, FILE *);
  extern FILE *stdout;
  int main(void)
  {
  fputs("Hello, world!\n", stdout);
  return 0;
  }
  為了便于閱讀,上面代碼只截取了頭文件中與源碼相關的那部分,即fputs和FILE的聲明,省略了stdio.h的其他部分(因為它們非常長)。另外,上面代碼的頭文件沒有經過預編譯,而實際上,插入源碼的是預編譯后的結果。編譯器在這一步還會移除注釋。
  這一步稱為"預處理"(Preprocessing),因為完成之后,就要開始真正的處理了。
  第六步 編譯(Compilation)
  預處理之后,編譯器就開始生成機器碼。對于某些編譯器來說,還存在一個中間步驟,會先把源碼轉為匯編碼(assembly),然后再把匯編碼轉為機器碼。
  下面是本文開頭的那段源碼轉成的匯編碼。
  .file   "test.c"
  .section    .rodata
  .LC0:
  .string "Hello, world!\n"
  .text
  .globl  main
  .type   main, @function
  main:
  .LFB0:
  .cfi_startproc
  pushq   %rbp
  .cfi_def_cfa_offset 16
  .cfi_offset 6, -16
  movq    %rsp, %rbp
  .cfi_def_cfa_register 6
  movq    stdout(%rip), %rax
  movq    %rax, %rcx
  movl    $14, %edx
  movl    $1, %esi
  movl    $.LC0, %edi
  call    fwrite
  movl    $0, %eax
  popq    %rbp
  .cfi_def_cfa 7, 8
  ret
  .cfi_endproc
  .LFE0:
  .size   main, .-main
  .ident  "GCC: (Debian 4.9.1-19) 4.9.1"
  .section    .note.GNU-stack,"",@progbits
  這種轉碼后的文件稱為對象文件(object file)。
  第七步 連接(Linking)
  對象文件還不能運行,必須進一步轉成可執行文件。如果你仔細看上一步的轉碼結果,會發現其中引用了stdout函數和fwrite函數。也就是說,程序要正常運行,除了上面的代碼以外,還必須有stdout和fwrite這兩個函數的代碼,它們是由C語言的標準庫提供的。
  編譯器的下一步工作,就是把外部函數的代碼(通常是后綴名為.lib和.a的文件),添加到可執行文件中。這就叫做連接(linking)。這種通過拷貝,將外部函數庫添加到可執行文件的方式,叫做靜態連接(static linking),后文會提到還有動態連接(dynamic linking)。
  make命令的作用,就是從第四步頭文件預編譯開始,一直到做完這一步。
  第八步 安裝(Installation)
  上一步的連接是在內存中進行的,即編譯器在內存中生成了可執行文件。下一步,必須將可執行文件保存到用戶事先指定的安裝目錄。
  表面上,這一步很簡單,就是將可執行文件(連帶相關的數據文件)拷貝過去就行了。但是實際上,這一步還必須完成創建目錄、保存文件、設置權限等步驟。這整個的保存過程就稱為"安裝"(Installation)。
  第九步 操作系統連接
  可執行文件安裝后,必須以某種方式通知操作系統,讓其知道可以使用這個程序了。比如,我們安裝了一個文本閱讀程序,往往希望雙擊txt文件,該程序就會自動運行。
  這就要求在操作系統中,登記這個程序的元數據:文件名、文件描述、關聯后綴名等等。Linux系統中,這些信息通常保存在/usr/share/applications目錄下的.desktop文件中。另外,在Windows操作系統中,還需要在Start啟動菜單中,建立一個快捷方式。
  這些事情就叫做"操作系統連接"。make install命令,就用來完成"安裝"和"操作系統連接"這兩步。
  第十步 生成安裝包
  寫到這里,源碼編譯的整個過程就基本完成了。但是只有很少一部分用戶,愿意耐著性子,從頭到尾做一遍這個過程。事實上,如果你只有源碼可以交給用戶,他們會認定你是一個不友好的家伙。大部分用戶要的是一個二進制的可執行程序,立刻就能運行。這就要求開發者,將上一步生成的可執行文件,做成可以分發的安裝包。
  所以,編譯器還必須有生成安裝包的功能。通常是將可執行文件(連帶相關的數據文件),以某種目錄結構,保存成壓縮文件包,交給用戶。
  第十一步 動態連接(Dynamic linking)
  正常情況下,到這一步,程序已經可以運行了。至于運行期間(runtime)發生的事情,與編譯器一概無關。但是,開發者可以在編譯階段選擇可執行文件連接外部函數庫的方式,到底是靜態連接(編譯時連接),還是動態連接(運行時連接)。所以,最后還要提一下,什么叫做動態連接。
  前面已經說過,靜態連接就是把外部函數庫,拷貝到可執行文件中。這樣做的好處是,適用范圍比較廣,不用擔心用戶機器缺少某個庫文件;缺點是安裝包會比較大,而且多個應用程序之間,無法共享庫文件。動態連接的做法正好相反,外部函數庫不進入安裝包,只在運行時動態引用。好處是安裝包會比較小,多個應用程序可以共享庫文件;缺點是用戶必須事先安裝好庫文件,而且版本和安裝位置都必須符合要求,否則就不能正常運行。
  現實中,大部分軟件采用動態連接,共享庫文件。這種動態共享的庫文件,Linux平臺是后綴名為.so的文件,Windows平臺是.dll文件,Mac平臺是.dylib文件。

本站內容除特別聲明的原創文章之外,轉載內容只為傳遞更多信息,并不代表本網站贊同其觀點。轉載的所有的文章、圖片、音/視頻文件等資料的版權歸版權所有權人所有。本站采用的非本站原創文章及圖片等內容無法一一聯系確認版權者。如涉及作品內容、版權和其它問題,請及時通過電子郵件或電話通知我們,以便迅速采取適當措施,避免給雙方造成不必要的經濟損失。聯系電話:010-82306118;郵箱:aet@chinaaet.com。
热re99久久精品国产66热_欧美小视频在线观看_日韩成人激情影院_庆余年2免费日韩剧观看大牛_91久久久久久国产精品_国产原创欧美精品_美女999久久久精品视频_欧美大成色www永久网站婷_国产色婷婷国产综合在线理论片a_国产精品电影在线观看_日韩精品视频在线观看网址_97在线观看免费_性欧美亚洲xxxx乳在线观看_久久精品美女视频网站_777国产偷窥盗摄精品视频_在线日韩第一页
  • <strike id="ygamy"></strike>
  • 
    
      • <del id="ygamy"></del>
        <tfoot id="ygamy"></tfoot>
          <strike id="ygamy"></strike>
          美女诱惑黄网站一区| 欧美日韩综合另类| 欧美一区深夜视频| 欧美日韩不卡一区| 免费欧美视频| 久热爱精品视频线路一| 樱桃成人精品视频在线播放| 欧美日韩国产色综合一二三四| 91久久精品一区二区别| 欧美亚洲在线播放| 亚洲日本精品国产第一区| 亚洲精品一区在线| 国产精品国产三级国产aⅴ无密码| 国产精品国产三级国产a| 欧美精选午夜久久久乱码6080| 国内综合精品午夜久久资源| 久久婷婷蜜乳一本欲蜜臀| 欧美午夜精品一区二区三区| 亚洲精品美女在线| 黄色在线一区| 99精品热视频| 久久成人精品电影| 欧美三级不卡| av不卡在线看| 久久久一区二区| 亚洲特级片在线| 国产午夜精品一区理论片飘花| 欧美激情性爽国产精品17p| 久久综合狠狠综合久久激情| 欧美国产日韩一区二区在线观看| 亚洲美女在线观看| 国产一区二区三区精品久久久| 一区二区三区在线视频观看| 可以看av的网站久久看| 精品电影一区| 久久精品女人的天堂av| 伊人久久综合97精品| 国内视频精品| 久久精品卡一| 欧美一区2区视频在线观看| 欧美日韩调教| 欧美日韩网站| 久久精品国产亚洲aⅴ| 欧美精品一区在线| 男女视频一区二区| 亚洲欧美日韩精品久久奇米色影视| 亚洲理伦在线| 国产伦精品一区二区三区| 国产日本欧美视频| 亚洲精品欧美在线| 日韩一二在线观看| 国产在线拍偷自揄拍精品| 欧美在线观看天堂一区二区三区| 久久久久久日产精品| 亚洲无限乱码一二三四麻| 亚洲婷婷综合色高清在线| 久久久久国产精品人| 国产精品久久久久久久久免费樱桃| 欧美大片免费久久精品三p| 欧美激情亚洲另类| 国产精品久久久久久久久| 久久亚洲欧美国产精品乐播| 久久av一区二区三区亚洲| 欧美一区三区三区高中清蜜桃| 亚洲综合首页| 亚洲一区999| 久久免费视频在线观看| 欧美日韩国产123区| 亚洲毛片一区二区| 亚洲视频 欧洲视频| 在线播放不卡| 在线观看视频欧美| 99精品国产高清一区二区| 国产精品久久久久一区二区| 精品成人一区二区三区| 午夜久久美女| 能在线观看的日韩av| 国产一区二三区| 欧美高清在线精品一区| 亚洲第一色在线| 一区二区三区精品视频在线观看| 国产日韩在线看片| 精品盗摄一区二区三区| 欧美激情一二区| 国产精品日韩久久久久| 亚洲欧美日韩中文视频| 夜夜爽av福利精品导航| 亚洲日产国产精品| 欧美国产综合视频| 香蕉久久a毛片| 日韩视频免费观看高清在线视频| 国产精品区一区二区三| 欧美**字幕| 国产欧美一区二区三区久久| 久久狠狠一本精品综合网| 亚洲第一精品久久忘忧草社区| 亚洲一区二区三区高清| 欧美午夜大胆人体| 久久久久久久久久久久久女国产乱| 亚洲国产一区二区三区高清| 激情丁香综合| 99国产精品99久久久久久粉嫩| 国产一区观看| 欧美一区二粉嫩精品国产一线天| 日韩一级大片| 亚洲亚洲精品在线观看| 国产一区日韩一区| 久久综合国产精品台湾中文娱乐网| 久久嫩草精品久久久久| 欧美巨乳波霸| 欧美3dxxxxhd| 欧美日产一区二区三区在线观看| 日韩视频在线一区| 欧美一级一区| 欧美视频在线观看视频极品| 国产日本欧美一区二区| 女女同性女同一区二区三区91| 亚洲欧美综合一区| 欧美人与禽猛交乱配视频| 久久久久五月天| 精品成人免费| 国产精品久久久久国产精品日日| 娇妻被交换粗又大又硬视频欧美| 亚洲欧美一级二级三级| 午夜久久影院| 99精品久久免费看蜜臀剧情介绍| 亚洲第一狼人社区| 在线亚洲精品福利网址导航| 一区二区三区产品免费精品久久75| 在线观看av一区| 欧美一区二区三区另类| 久久久国产亚洲精品| 激情另类综合| 国产日韩欧美高清| 亚洲作爱视频| 国产一区二区无遮挡| 午夜综合激情| 国产精品中文字幕欧美| 国产精品亚洲网站| 悠悠资源网久久精品| 国产精品盗摄久久久| 久久久久久久久久久久久女国产乱| 亚洲高清一二三区| 精品av久久久久电影| 国产精品青草久久| 国产精品欧美风情| 国产一区二区三区高清在线观看| 亚洲视频图片小说| 亚洲国产高清自拍| 久久只有精品| 久久精品网址| 欧美与黑人午夜性猛交久久久| 午夜亚洲一区| 国产一区二区高清| 亚洲午夜激情| 欧美午夜精品久久久久久孕妇| 亚洲精品一区二区网址| 亚洲成色www8888| 欧美区日韩区| 久久久久综合| 国产女精品视频网站免费| 激情久久五月天| 欧美日韩免费观看一区=区三区| 亚洲欧美电影在线观看| 国产精品久久久久久久电影| 欧美不卡一区| 亚洲福利视频网| 亚洲免费成人av| 亚洲字幕一区二区| 久久精品日产第一区二区三区| 亚洲免费在线视频| 中日韩男男gay无套| 久久精品免费看| 亚洲在线观看视频| 亚洲一区二区精品在线| 国产精品成人一区二区三区吃奶| 欧美精品亚洲| 久久久久久综合网天天| 久久久91精品国产一区二区三区| 亚洲精品久久久久久久久久久久久| 日韩一级大片在线| 欧美激情在线播放| 亚洲午夜成aⅴ人片| 亚洲一区二区三区高清不卡| 国产精品久久久久aaaa九色| 国产一区视频观看| 国产亚洲精品福利| 免费黄网站欧美| 老司机午夜精品视频在线观看| 亚洲天堂激情| 久久超碰97人人做人人爱| 亚洲欧美国产高清| 欧美精品一区二| 国产精品v欧美精品∨日韩| 一本色道综合亚洲| 极品裸体白嫩激情啪啪国产精品| 99精品久久| 欧美成人午夜影院| 影音先锋中文字幕一区| 久久在精品线影院精品国产| 嫩草伊人久久精品少妇av杨幂| 欧美.com| 亚洲欧美视频一区二区三区| 亚洲第一精品久久忘忧草社区| 欧美精品手机在线| 亚洲天堂久久| 亚洲清纯自拍| 日韩一区二区精品| 欲香欲色天天天综合和网| 国产精品国产三级国产| 99精品国产在热久久| 你懂的国产精品永久在线| 国产一区二区三区直播精品电影| 国产欧美日韩中文字幕在线| 午夜精品久久久久久99热软件| 国内成人精品一区| 艳女tv在线观看国产一区| 欧美精品在线一区二区| 国产精品久久久99| 国产亚洲成av人片在线观看桃| 99riav1国产精品视频| 免费看成人av| 欧美丰满少妇xxxbbb| 日韩亚洲欧美综合| 亚洲精品一区二区三区四区高清| 欧美精品免费播放| 欧美一级大片在线免费观看| 99这里只有精品| 欧美一区二区高清| 欧美性大战xxxxx久久久| 欧美黄色免费| 久久青草欧美一区二区三区| 国产精品一区二区男女羞羞无遮挡| 免费成人av在线| 一区二区三区高清在线观看| 国产精品一区二区久激情瑜伽| 国内外成人免费视频| 久久免费精品视频| 亚洲小视频在线观看| 激情欧美丁香| 欧美日韩一视频区二区| 国产欧美精品xxxx另类| 亚洲视频免费在线观看| 亚洲国产片色| 国产精品久久久久久久久动漫| 欧美日韩日本国产亚洲在线| 一区二区毛片| 欧美在线电影| 欧美va亚洲va香蕉在线| 久热精品视频| 欧美激情一区二区三级高清视频| 久久国产精品一区二区三区| 裸体歌舞表演一区二区| 久久aⅴ国产紧身牛仔裤| 亚洲第一页中文字幕| 91久久久久久国产精品| 老司机午夜精品视频| 99精品视频免费| 亚洲人成在线观看一区二区| 夜夜嗨一区二区三区| 老司机午夜精品视频| 国产精品美女一区二区| 欧美在线观看视频在线| 狠狠入ady亚洲精品经典电影| 日韩视频免费观看高清完整版| 国产精品国产三级国产aⅴ9色| 国产欧美日韩一区二区三区在线| 亚洲人成绝费网站色www| 亚洲国产成人久久综合| 欧美成人伊人久久综合网| 99国产精品视频免费观看| 黑丝一区二区三区| 亚洲成人在线观看视频| 日韩视频免费观看高清完整版| 国产精品久99| 国产精品一级在线| 欧美激情乱人伦| 在线不卡中文字幕播放| 国产精品一区二区女厕厕| 午夜精品久久久久久| 亚洲免费中文字幕| 亚洲国产小视频| 亚洲无线一线二线三线区别av| 国产日韩欧美综合精品| 亚洲午夜性刺激影院| 欧美激情一二区| 午夜精彩视频在线观看不卡| 欧美xxx成人| 亚洲人线精品午夜| 国产麻豆精品视频| 日韩亚洲欧美综合| 亚洲另类春色国产| 欧美午夜电影在线| 在线观看成人av| 久久人人爽爽爽人久久久| 亚洲精品美女久久久久| 校园春色国产精品| 久久婷婷国产综合尤物精品| 精品成人乱色一区二区| 欧美性天天影院| 亚洲欧美一区二区原创| 国产精品女主播在线观看| 亚洲国产另类久久久精品极度| 免费观看成人| 国产精品欧美日韩一区二区| 国产精品xxxxx| 亚洲影视在线播放| 欧美区在线播放| 欧美激情综合亚洲一二区| 亚洲第一区在线观看| 午夜精品在线| 国产日韩一区在线| 久热这里只精品99re8久| 国产精品久久久一区二区三区| 欧美日韩精品综合| 亚洲黄网站黄| 欧美v亚洲v综合ⅴ国产v| 亚洲精品美女在线观看播放| 国产精品无码永久免费888| 国产亚洲精品bt天堂精选| 欧美成人免费在线观看| 久久久亚洲成人| 亚洲精品123区| 激情六月婷婷综合| 国产热re99久久6国产精品| 国产主播一区| 日韩视频在线永久播放| 在线观看视频一区|