国产精品一区二区精品_久久小视频_天堂va在线观看_99久久夜色精品国产亚洲96_日本手机在线视频_av成人免费

當(dāng)前位置:首頁 > 網(wǎng)站舊欄目 > 學(xué)習(xí)園地 > 設(shè)計軟件教程 > Dmd編譯器學(xué)習(xí)筆記

Dmd編譯器學(xué)習(xí)筆記
2010-01-13 22:54:06  作者:  來源:
Dmd編譯器學(xué)習(xí)筆記

英文原文在這里:
http://digitalmars.com/d/dcompiler.html
在這里有一篇翻譯文章:
http://sofire.javaeye.com/blog/111667
不過,主要是關(guān)于windows的;我更關(guān)心Linux下的使用。
順便看看兩者有啥區(qū)別。

相關(guān)文件
注意:

Linux的dmd配置文件是dmd.conf
Windows的配置文件是sc.ini


  • /dmd/bin/dmd     D 編譯器的可執(zhí)行文件
     
  • /dmd/bin/dumpobj     Elf file dumper
     
  • /dmd/bin/obj2asm     Elf文件反匯編器
     
  • /dmd/bin/dmd.conf     全局配置文件(復(fù)制到 /etc/dmd.conf)
     
  • /dmd/lib/libphobos.a     D運行庫(復(fù)制到 /usr/lib/libphobos.a)
     


DMD的安裝
[list=1]
  • 下載dmd程序:http://ftp.digitalmars.com/dmd.zip,解壓到~/dmd目錄
  • 復(fù)制dmd.conf文件到/etc目錄
    Java代碼 復(fù)制代碼
    1. cp ~/dmd/bin/dmd.conf /etc  
  • 給下面的文件添加執(zhí)行權(quán)限
    Java代碼 復(fù)制代碼
    1. chmod u+x ~/dmd/bin/{dmd,dumpobj,obj2asm,rdmd}  
  • 把~/dmd/bin添加到PATH環(huán)境變量;或者把它們復(fù)制到/usr/local/bin目錄下(不要只復(fù)制可執(zhí)行程序)
  • 復(fù)制庫文件到/usr/lib目錄
    Java代碼 復(fù)制代碼
    1. cp ~/dmd/lib/libphobos.a /usr/lib  

    [/list]

    以上安裝過程比較簡單,只有PATH環(huán)境變量設(shè)置正確了,就應(yīng)該沒有什么問題

    編譯參數(shù)和開關(guān)
    命令的格式:
    Java代碼 復(fù)制代碼
    1. dmd   files...  -switches...   

    [Windows]支持以下類型的文件:
    Java代碼 復(fù)制代碼
    1. Extension      File Type     
    2. none           D source files     
    3. .d             D source files     
    4. .di            D interface files     
    5. .obj           Object files to link in     
    6. .lib           Object code libraries to search     
    7. .exe           Name output executable file     
    8. .def           module definition file     
    9. .res           resource file    

    [Linux]支持以下類型的文件:
    Java代碼 復(fù)制代碼
    1. Extension      File Type   
    2. none           D source files   
    3. .d             D source files   
    4. .di            D interface files   
    5. .o             Object files to link in   
    6. .a             Library files to link in  

    好像不支持.so文件--這一點不肯定

    編譯開關(guān)之一
    Java代碼 復(fù)制代碼
    1. -debug   
    2.     編譯調(diào)試代碼   
    3.   
    4. -debug=level   
    5.     編譯調(diào)試代碼:code <= level   
    6.   
    7. -debug=ident   
    8.     編譯調(diào)試代碼:標(biāo)識符為ident   
    9.   
    10. -version=level   
    11.     生成版本代碼:>=level   
    12.   
    13. -version=ident   
    14.     生成版本代碼:==ident   
    15.        
    16. -unittest   
    17.     編譯單元測試代碼(還有斷言)   
    18.   
    19. -cov   
    20.     添加覆蓋率分析指令;運行程序后,會生成.lst文件   
    21.   
    22. -release   
    23.     生成發(fā)行版本;會去掉契約和斷言等信息  


    -debug / -version
    debug、version的使用方法很相似
    Java代碼 復(fù)制代碼
    1. //debug.d   
    2. import std.stdio;   
    3.   
    4. void main()   
    5. {   
    6.     debug    { writefln("debug"); }   
    7.     debug(1) { writefln("debug(1)"); }   
    8.     debug(2) { writefln("debug(2)"); }   
    9.   
    10.     debug(ERROR) { writefln("debug(ERROR)"); }   
    11.     debug(WARN)  { writefln("debug(WARN)"); }   
    12.   
    13.     version(HOME)      { writefln("version(HOME)"); }   
    14.     version(BUSINESS)  { writefln("version(BUSINESS)"); }   
    15.   
    16.     version(WINDOWS) {} else { writefln("version(!WINDOWS)"); }   
    17. }  

    編譯并運行之:
    Java代碼 復(fù)制代碼
    1. # dmd -debug -run debug.d   
    2. debug   
    3. debug(1)   
    4. version(!WINDOWS)   
    5.   
    6. # dmd -debug=1 -run debug.d   
    7. debug   
    8. debug(1)   
    9. version(!WINDOWS)   
    10.   
    11. # dmd -debug=2 -run debug.d   
    12. debug   
    13. debug(1)   
    14. debug(2)   
    15. version(!WINDOWS)   
    16.   
    17. # dmd -debug=ERROR -run debug.d   
    18. debug(ERROR)   
    19. version(!WINDOWS)   
    20.   
    21. # dmd -debug=WARN -run debug.d   
    22. debug(WARN)   
    23. version(!WINDOWS)   
    24.   
    25. # dmd -version=HOME -run debug.d   
    26. version(HOME)   
    27. version(!WINDOWS)   
    28.   
    29. # dmd -version=BUSINESS -version=WINDOWS -run debug.d   
    30. version(BUSINESS)  


    -unittest
    Java代碼 復(fù)制代碼
    1. //unittest.d   
    2. import std.stdio;   
    3.   
    4. class A   
    5. {   
    6.     int i;   
    7.     this(int v) {   
    8.         i = v;   
    9.     }      
    10.   
    11.     unittest {   
    12.         A a = new A(1);   
    13.         assert(a.i == 1);    
    14.         assert(a.i != 0);    
    15.     }      
    16. }   
    17.   
    18. int add(int a, int b)   
    19. {   
    20.     return a - b;   
    21.     // 這里沒有unittest   
    22. }   
    23.   
    24. void main()   
    25. {   
    26.     // 這里沒有unittest   
    27. }   
    28.   
    29. unittest {   
    30.     assert(add(12) == 3);    
    31. }  

    先正常編譯,沒有語法錯誤:
    Java代碼 復(fù)制代碼
    1. # dmd -run unittest.d  

    再編譯單元測試代碼
    Java代碼 復(fù)制代碼
    1. # dmd -unittest -run unittest.d    
    2. Error: AssertError Failure unittest(30)  

    30行有錯誤?add函數(shù)寫錯了:(

    -cov
    看看覆蓋率分析選項:
    Java代碼 復(fù)制代碼
    1. //cov.d   
    2. import std.stdio;   
    3.   
    4. void main()   
    5. {   
    6.     for (int i; i < 2; i++)   
    7.     {   
    8.         if (i < 5)   
    9.             writefln("i < 5");   
    10.         else  
    11.             writefln("i >= 5");   
    12.     }   
    13. }  

    編譯并運行:
    Java代碼 復(fù)制代碼
    1. # dmd -cov -run cov.d   
    2. i < 5  
    3. i < 5  

    得到覆蓋率分析文件:cov.lst:(注意:編譯完并不會有這個文件;運行程序后才會生成)
    Java代碼 復(fù)制代碼
    1.        |//cov.d   
    2.        |import std.stdio;   
    3.        |   
    4.        |void main()   
    5.        |{   
    6.       6|    for (int i; i < 2; i++)   
    7.        |    {   
    8.       2|        if (i < 5)   
    9.       2|            writefln("i < 5");   
    10.        |        else  
    11. 0000000|            writefln("i >= 5");   
    12.        |    }   
    13.        |}   
    14. cov.d is 75% covered  

    第6行運行了6次--自己算算是不是;
    第11行運行了0次--搜索000000字符串,就能輕松找到?jīng)]有覆蓋到地方;
    更多詳情參考:http://digitalmars.com/d/code_coverage.html

    -release
    用法很簡單,不舉例了

    編譯開關(guān)之二
    Java代碼 復(fù)制代碼
    1. -D   
    2.     生成文檔   
    3.   
    4. -Dddocdir   
    5.     把文檔生成到docdir目錄;注意是 -Dd   
    6.        
    7. -Dffilename   
    8.     指定文檔的文件名;  

    編譯命令很簡單:
    Java代碼 復(fù)制代碼
    1. dmd -D debug.d  

    關(guān)于文檔的更多信息參考:http://sofire.javaeye.com/blog/111881

    編譯開關(guān)之三
    Java代碼 復(fù)制代碼
    1. -H   
    2.     生成.di接口文件   
    3.   
    4. -Hddir   
    5.     把接口文件生成到dir目錄;注意是 -Hd   
    6.   
    7. -Hffilename   
    8.     指定接口文件名;注意是 -Hf  

    關(guān)于接口,看一段翻譯:
    當(dāng)處理源文件中的import聲明時,編譯器會搜索import對應(yīng)的源文件,從中提取出需要的信息。
    編譯器同時也會搜索D接口文件,D接口文件中只包含模塊中需要導(dǎo)入的內(nèi)容,而不是整個模塊。
    使用D接口文件的好處是:

      D接口文件更小,和D源文件相比處理起來更快。
      可以隱藏源代碼。比如以接口文件和object庫的方式提供源程序,而不是提供全部源代碼。

    D接口文件可以在編譯D源文件時用-H開關(guān)創(chuàng)建,D接口文件的后綴是.di。
    當(dāng)編譯器分解import聲明時,搜索尋找.di形式的D接口文件,再尋找D源文件。
    D接口文件有點和C++頭文件相似,但這不是必需的,它不屬于D語言,只是編譯器的一個功能,只是用來優(yōu)化程序的構(gòu)建。

    dmd -H生成的接口文件包括了源代碼;只是去掉了注釋,斷言等信息;具體怎么回事,待弄明白了再來改這里(TODO)



    編譯開關(guān)之四
    Java代碼 復(fù)制代碼
    1. -c   
    2.     只編譯,不鏈接;簡單點說就是只生成.o文件,不生成可執(zhí)行文件   
    3.   
    4. -Ipath   
    5.     指定import路徑;多個路徑之間用分號(;)分割;允許有多個-I,并按照-I指定的路徑順序進(jìn)行搜索   
    6.   
    7. -Jpath   
    8.     指定D源程序中import表達(dá)式的搜索路徑;多個路徑之間用分號(;)分割;   
    9.     允許有多個-J,并按照-J指定的路徑順序進(jìn)行搜索   
    10.   
    11. -Llinkerflag   
    12.      把linkerflag傳遞給連接程序(linker),比如: -L-L/usr/lib   
    13.   
    14. -o-   
    15.     不生成.o文件,一般和-H、-D一起使用   
    16.   
    17. -offilename   
    18.     指定輸出文件名;可以是可執(zhí)行程序,也可以是其他文件;注意是:-of   
    19.   
    20. -odobjdir   
    21.     把.o文件生成到objdir目錄;默認(rèn)是生成到當(dāng)前目錄;注意是:-od   
    22.   
    23. -op   
    24.     默認(rèn)生成的object文件(.o)會在當(dāng)前目錄;添加-op參數(shù)則會生成到源文件所在目錄  


    -c
    Java代碼 復(fù)制代碼
    1. dmd debug.d     # 生成debug可執(zhí)行文件   
    2. dmd -c debug.d  # 生成debug.o文件  

    dmd編譯器默認(rèn)是編譯成.o文件后,再和其他庫連接成可執(zhí)行文件;
    某些情況下不需要編譯成可執(zhí)行文件,比如沒有main函數(shù)--也編譯不成
    這時就可以只編譯成.o文件

    bud等程序build工具,可以自動判斷文件是否有main函數(shù),并生成相應(yīng)的文件;
    但dmd編譯器不是這樣的;所以,熟悉了dmd編譯器后,可以只使用bud等工具來編譯程序

    -I / -J
    Java代碼 復(fù)制代碼
    1. import std.stdio;               // -I   
    2. void main()   
    3. {   
    4.     auto b = import("x.d");     // -J   
    5. }  


    自己體會它們的用途吧:)
    注意:如果在搜索路徑下有同名文件的話,可能出現(xiàn)奇怪的問題;避免出現(xiàn)這種情況,或者改變參數(shù)的順序

    -Llinkerflag
    一般是-L-L 和 -L-l參數(shù),指定lib路徑和庫文件
    比如:-L-L/usr/local/lib  -L-lsqlite3
    對linker不熟悉,回頭在詳細(xì)寫這塊

    -o-
    如果只想生成文檔,連.o文件都不想要;則-o- 就是你想要的了

    -offilename
    默認(rèn)情況下,是根據(jù)源文件名來確定后續(xù)文件的文件名;
    比如foo.d 會生成 foo.ofoo 文件;
    通過-of參數(shù)可以改變輸出文件的名字:
    dmd -ofbar.exe foo.d

    它不會自動添加后綴:
    dmd -c -ofbar foo.d
    生成文件是 bar,而不是bar.o,這可能不是你想要的

    -odobjdir -op
    .o文件默認(rèn)生成在當(dāng)前目錄下;
    -od 是指定生成目錄,-od.和默認(rèn)相同
    -op 是把.o生成到源文件所在目錄
    具體生成到什么目錄下,就看自己的愛好了;
    喜歡干凈,就用-od吧;對了,-run參數(shù)能生成更干凈的代碼;)

    編譯開關(guān)之五
    Java代碼 復(fù)制代碼
    1. -O   
    2.     優(yōu)化生成的代碼,使程序運行得更快   
    3.   
    4. -g   
    5.     添加調(diào)試信息   
    6.   
    7. -gc   
    8.     添加C風(fēng)格的調(diào)試信息(為舊的gdb)   
    9.   
    10. -inline   
    11.     用內(nèi)聯(lián)函數(shù)的方式進(jìn)行優(yōu)化;相當(dāng)于C的inline   
    12.   
    13. -fPIC   
    14.     生成位置無關(guān)代碼   
    15.   
    16. -d   
    17.     允許廢棄的特征   
    18.   
    19. -profile   
    20.     profile the runtime performance of the generated code    
    21.     參見:http://www.digitalmars.com/ctg/trace.html  


    這幾個參數(shù),要么很簡單,要么不懂含義;也懶得去研究具體的意思了。
    其中的-g參數(shù)涉及到使用調(diào)試器;我喜歡用writefln調(diào)試;唉,回頭再研究吧。


    編譯開關(guān)之六
    Java代碼 復(fù)制代碼
    1. --help   
    2.     打印幫助   
    3.   
    4. -quiet   
    5.     安靜模式,不輸出無關(guān)緊要的信息   
    6.   
    7. -v   
    8.     顯示編譯細(xì)節(jié)   
    9.   
    10. -w   
    11.     顯示編譯警告  


    編譯開關(guān)之七
    Java代碼 復(fù)制代碼
    1. -run srcfile args...   
    2.     編譯,鏈接,然后運行程序srcfile;args...(到命令行結(jié)束)都是程序的參數(shù);   
    3.     它不會保留.o和可執(zhí)行程序(No .o or executable file is left behind)  


    文章開始就有怎么使用的例子
    需要注意的是參數(shù)的順序,因為很多寫法都是錯誤的,正確的是:
    Java代碼 復(fù)制代碼
    1. dmd 相關(guān)文件 編譯開關(guān) -run 含main的源文件 程序參數(shù)1 程序參數(shù)2  

    各種參數(shù)放在-run前面,然后是含有main的源程序,再后面的內(nèi)容會全部傳遞給運行程序,作為參數(shù)

    鏈接Linking
    在dmd編譯成功后,它會再調(diào)用連接程序;用-c參數(shù)可以不進(jìn)行連接
    連接的實際處理程序其實是gcc;這樣能保證和gcc編譯的模塊兼容


    環(huán)境變量
    CC
    默認(rèn)是用gcc進(jìn)行連接,可以通過設(shè)置CC環(huán)境變量,使用其他連接器

    DFLAGS
    The value of DFLAGS is treated as if it were appended to the command line to dmd.
    沒有弄明白它是怎么回事;(

    dmd.conf初始化文件
    dmd會按照下面的目錄順序查找
    1. 當(dāng)前工作目錄
    2. 環(huán)境變量HOME指定的目錄
    3. dmd命令所在目錄,即bin目錄
    4. /etc目錄


    dmd.conf的內(nèi)容看起來像這樣:
    Java代碼 復(fù)制代碼
    1. ; dmd.conf 是dmd的配置文件   
    2. ; 分號是注釋符號   
    3. ; %%包含的名字會用相應(yīng)的環(huán)境變量替換   
    4. ; %@P%會被本文件的路徑替換,即dmd.conf文件所在路徑   
    5. [Environment]   
    6. DFLAGS="-I%@P%/../src/phobos"  
    7. DDOCFILE=candydoc/proj.ddoc  


    格式是 NAME=value;NAME即使是小寫,也會被處理成大寫;
    里面的DFLAGS的值會覆蓋環(huán)境變量指定的值

    和Windows版本的區(qū)別
    • 字符串文章量是只讀的;對它寫會導(dǎo)致段錯誤
    • 配置文件是dmd.conf,而不是sc.ini
    • Windows有一個@cmdfile開關(guān)
    • Windows有一個-nofloat開關(guān)
    • 環(huán)境變量上有些不一樣


    總結(jié):
    和gcc比起來,參數(shù)少多了 ;)
    雖然可以用bud進(jìn)行編譯,但理解dmd還是必要的。
    反正也不復(fù)雜,花點時間學(xué)習(xí)一下還算值得。
     

安徽新華電腦學(xué)校專業(yè)職業(yè)規(guī)劃師為你提供更多幫助【在線咨詢
国产精品一区二区精品_久久小视频_天堂va在线观看_99久久夜色精品国产亚洲96_日本手机在线视频_av成人免费
<button id="0mgmq"><pre id="0mgmq"></pre></button>
  • <tr id="0mgmq"></tr>
  • <abbr id="0mgmq"><source id="0mgmq"></source></abbr> <button id="0mgmq"></button>
  • 成人免费视频网站| 欧美主播一区二区三区美女 久久精品人| 国产精品三上| 欧美日韩精品一本二本三本| 国产日韩在线一区二区三区| 亚洲欧美日韩视频二区| 亚洲国产日韩欧美| 欧美女激情福利| 亚洲一区二区自拍偷拍| 日本不卡一区二区三区在线观看| 97se国产在线视频| 麻豆久久婷婷| 亚洲欧美日韩另类精品一区二区三区| 亚洲国产日韩欧美一区二区三区| 欧美日韩国产免费观看| 一区二区av| 亚洲视频欧美在线| 亚洲综合av一区| 亚洲高清精品中出| 日韩一区二区电影在线观看| 欧美人与性禽动交精品| 精品无人乱码一区二区三区的优势| 国产高清精品一区二区三区| 国产成人精品福利一区二区三区| 91久久精品www人人做人人爽 | 欧美一区亚洲| 亚洲综合欧美日韩| 欧美视频观看一区| 亚洲全部视频| 国产伦精品一区二区三区四区免费 | 精品国产91亚洲一区二区三区www| 99超碰麻豆| 久久国产主播精品| 欧美日韩国产高清视频| 香蕉久久夜色| 伊人精品成人久久综合软件| 亚洲激情专区| 久久国产日韩| 久久本道综合色狠狠五月| 欧美精品v日韩精品v国产精品| 欧美一级爱爱| 国产精品v日韩精品v欧美精品网站| 亚洲视屏一区| 91在线播放视频| 欧美日韩高清在线一区| 亚洲欧美综合一区| 国产欧美在线| 激情伦成人综合小说| 日韩三级电影网站| 在线精品亚洲| 国产66精品久久久久999小说| 日韩精彩视频| 亚洲另类视频| 国产精品加勒比| 在线免费一区| 另类av一区二区| 久久久久高清| 亚洲成色精品| 高清视频在线观看一区| 亚洲一区免费看| 欧美主播一区二区三区美女 久久精品人| 国产成人av一区二区三区| 亚洲一区二区在线免费观看| 亚洲欧美久久| 午夜精品一区二区三区在线观看| 国产自产在线视频一区| 99久久无色码| 欧美日韩ab| 国产午夜精品一区| 在线国产日韩| 欧美一区二区综合| 国产精品区二区三区日本| 欧美日韩天天操 | 欧美大片专区| 国产精品免费视频一区二区| 国产自产在线视频一区| 精品日本一区二区三区| 亚洲国产日韩美| 性欧美精品一区二区三区在线播放| 国产女主播一区二区| 在线一区亚洲| 国产自产在线视频一区| 99亚洲一区二区| 亚洲一卡二卡三卡| 国产精品乱码视频| 一本久道久久久| 欧美尤物一区| 久久久福利视频| 久久国产日本精品| 亚洲精品欧洲精品| 一道精品一区二区三区| 精品国产免费一区二区三区| 蜜桃av久久久亚洲精品| 亚洲国产精品久久久久婷婷老年| 欧美日韩在线精品一区二区三区| 99国产在线视频| 国产偷自视频区视频一区二区| 亚洲一区三区| 日韩在线电影一区| 韩国一区二区三区美女美女秀| 国产精品免费一区二区三区在线观看| 欧美日本一区二区高清播放视频| 97超级碰碰| 欧美激情第二页| 欧美亚洲精品日韩| 狠狠色综合色区| 色视频一区二区三区| 国产三级精品在线不卡| 91黄在线观看| 免费日韩av片| 国产伦精品一区二区三区四区免费 | 操一操视频一区| 国产偷国产偷亚洲高清97cao| 伊人天天综合| 精品1区2区| 亚洲三级网站| 日韩视频一区二区三区在线播放免费观看| 亚洲看片网站| 一区二区91美女张开腿让人桶| 亚洲精品不卡| 欧美一区影院| 黄色亚洲大片免费在线观看| 欧美片第1页综合| 一区精品在线| 欧美精品97| 在线观看欧美亚洲| 亚洲国产高清视频| 国产乱码精品一区二区三区不卡| 国产精品日韩二区| 97se国产在线视频| 精品一区二区三区自拍图片区| 乱一区二区三区在线播放| 茄子视频成人在线观看 | 国产精品一区二区三区在线观| 精品九九九九| 奇米影视首页 狠狠色丁香婷婷久久综合 | 国产精品亚洲综合久久| 国产欧美日韩一区二区三区| 久久国产日韩| 久久精品国产综合精品| 三区精品视频观看| 国产综合网站| 久久精品系列| 久久人人九九| 午夜亚洲福利| 美女精品一区| 日韩在线三级| 一区二区福利| 久久精精品视频| 狠狠干综合网| 成人av片网址| 一区二区三区电影| 国产一级精品aaaaa看| 国产精品国产精品| 女生裸体视频一区二区三区| 亚洲一区一卡| 欧美激情www| 亚洲毛片播放| 久久草视频在线看| 欧美激情aⅴ一区二区三区| 米奇777在线欧美播放| 色大师av一区二区三区| 9色国产精品| 日韩欧美激情一区二区| 亚洲国产午夜| 欧美日韩精品免费在线观看视频| 在线精品亚洲| 日本精品免费| 先锋影音一区二区三区| 亚洲a∨一区二区三区| 久久婷婷影院| 午夜性色一区二区三区免费视频 | 午夜精品区一区二区三| 国产精品一区视频网站| 一区二区av| 国外成人免费视频| 一级成人国产| 在线视频91| 国产三级精品在线不卡| 亚洲精品九九| 亚洲综合视频一区| 国产欧美综合精品一区二区| 亚洲黄页一区| 欧美在线黄色| 久久99热只有频精品91密拍| 亚洲欧美清纯在线制服| 中文字幕成人一区| 国内精品一区二区| 久久国产99| 精品91视频| 中文字幕日韩一区二区三区不卡 | 国产精品一区免费观看| 欧美fxxxxxx另类| 日本一区二区三区视频在线播放| 91在线在线观看| 亚洲免费中文| 亚洲人成免费| 国内精品久久久久久久影视麻豆 | 久久久精品网| 噜噜噜91成人网|