<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 第?18?章?編譯工具鏈 **目錄** [](ch18.html#id3083823) [標準編譯安裝](ch18s02.html) [為什么要編譯安裝](ch18s02.html#id3083834) [編譯環境](ch18s02.html#id3083233) [標準編譯安裝](ch18s02.html#id3083952) [編譯過程](ch18s03.html) [gcc 編譯器](ch18s04.html) [自動化編譯](ch18s05.html) [autoconf](ch18s05.html#id3084783) [automake](ch18s05.html#id3084909) [Makefile](ch18s05.html#id3084989) [使用 make](ch18s06.html) [emerge](ch18s07.html) [設置 USE標記](ch18s07.html#id3085722) [編譯選項](ch18s07.html#id3085838) [微調](ch18s07.html#id3086063) [使用 emerge](ch18s07.html#id3086226) ## 標準編譯安裝 ### 為什么要編譯安裝 包管理系統是絕大多數發行版的必備組件,也是一個發行版區別于其它發行版的主要特征。但是有些軟件,并不能通過包管理系統安裝,這就需要下載源碼編譯安裝。 一個軟件可能有許多功能,但是發行版中提供的安裝包,通常只具有一些常見的功能。如果提供所有功能,那么無疑會占用更多的資源,而這些功能,大多數用戶不會用到;[[24](ch18s02.html#ftn.id3083206)]而你會用到的功能,可能安裝包中剛好沒有。編譯安裝可以靈活地定制軟件,選擇自己需要的,取消自己不需要的。 編譯安裝還可以針對特定的硬件進行優化,以獲得更好的性能表現。[[25](ch18s02.html#ftn.id3083225)] ### 編譯環境 編譯環境包括多個工具,它們環環相扣,稱作編譯工具鏈。主要包括以下工具: | 工具 | 簡介 | | --- | --- | | binutils | 連接器、匯編器和其他用于目標文件和檔案的工具 | | gcc | 編譯器,將源代碼轉換為機器代碼 | | glibc | C庫,提供標準例程(C函數) | 還有一些工具,能夠調用工具鏈,實現自動化編譯: | | | | --- | --- | | autoconf | 自動生成 `Makefile` 文件 | | automake | | make | 按照 `Makefile` 文件中的規則編譯程序 | 在后面的部分將分別介紹這些工具 ### 標準編譯安裝 首先,下載源代碼,通常是壓縮包,如:`xxx.tar.gz` 或者 `xxx.tar.bz2`,解包: | 壓縮包格式 | 命令 | | --- | --- | | .tar.gz | tar zxvf xxx.tgz | | .tgz | | .tar.bz2 | tar jxvf xxx.tar.bz2 | 通常解包后會在當前位置得到一個 `xxx/` 目錄,進入這個目錄 ``` cd xxx/ ``` 使用下列命令編譯安裝: ``` ./configure --prefix=/opt/xxx make sudo make install make clean ``` > [![1](https://box.kancloud.cn/2015-10-12_561bcb76795ae.png)](ch18s02.html#build-01) 配置軟件特性,檢查編譯環境,生成 `Makefile文件` > [![2](https://box.kancloud.cn/2015-10-12_561bcb768596e.png)](ch18s02.html#build-05) 最常用配置選項:指定軟件的安裝路徑 > [![3](https://box.kancloud.cn/2015-10-12_561bcb94ee26f.png)](ch18s02.html#build-02) 根據 `Makefile` 編譯源代碼 > [![4](https://box.kancloud.cn/2015-10-12_561bcb9508b82.png)](ch18s02.html#build-03) 將編譯完成的程序安裝到系統中。通常需要 root權限 > [![5](https://box.kancloud.cn/2015-10-12_561bcb95133e7.png)](ch18s02.html#build-04) 清除源代碼目錄中的編譯結果 * * * > [[24](ch18s02.html#id3083206)] Windows 系統下的一些經典軟件,如 ACDsee、Nero、Winamp 等,集成了越來越多的功能,使它們越來越臃腫。而且不能夠只選擇自己喜歡的功能,要么全盤接收,要么改尋它途 > [[25](ch18s02.html#id3083225)] 通常發行版提供的安裝包,已經進行了優化。自己編譯的軟件,性能未必更好 ## 編譯過程 將下面代碼保存為 `Hello.c`: ``` #include <stdio.h> int main(void) { printf("Hello World!\n"); return 0; } ``` > [![1](https://box.kancloud.cn/2015-10-12_561bcb76795ae.png)](ch18s03.html#build-20) **printf()** 函數 執行命令 `cc Hello.c`[[26](ch18s03.html#ftn.id3084190)],得到一個可執行文件 `a.out`,執行它 `./a.out` 可以看到,C的源代碼(`Hello.c`)是純文本,不能夠直接執行。可執行代碼是計算機的本機語言或機器語言表示的代碼,這種語言是由數字代碼表示的詳細指令組成,不同的計算機具有不同的機器語言。 編譯器是一個程序,其工作是將源代碼轉換為可執行代碼。 * 編譯器用來將 C語言 轉換成特定的機器語言。 * 編譯器還從C的庫中向最終程序加入代碼。[[27](ch18s03.html#ftn.id3084254)] * 編譯器還檢查源代碼是否為有效的C語言程序。如果編譯器發現錯誤,將報告錯誤,而且不生成可執行文件 編譯器分三步完成這個工作: | | | | --- | --- | | 預處理 | 調用預處理器 cpp 對源代碼文件中的文件包含(include)、預編譯語句(如宏定義 define 等) 進行分析 | | 編譯 | 調用編譯器 cc 將源代碼轉換為中間代碼 | | 鏈接 | 調用鏈接器 ld 將中間代碼與其它代碼結合起來生成可執行文件 | * 這種方法使用程序便于模塊化。分別編譯各個模塊,然后使用鏈接器將編譯過的模塊結合起來。這樣,如果需要改變一個模塊,則不必重新編譯所有其它模塊。 可執行文件包含`目標文件`、`庫例程`和`啟動代碼` 編譯器將源代碼轉換為機器語言代碼(中間代碼),將結果放置在目標文件(`*.o`)中。雖然目標文件包含機器代碼,但該文件還不能運行,它還不是一個完整的程序。 啟動代碼(start-up code)相當于程序和操作系統之間的接口。[[28](ch18s03.html#ftn.id3084399)] 庫例程為函數的實現。幾乎所有C程序都利用標準C庫中所包含的例程,目標代碼文件不包含這一函數的代碼,它只包含調用函數的指令。實際代碼存儲在一個稱為“庫”的文件中。庫文件中包含許多函數的目標代碼 鏈接器的作用是將這3個元素(目標代碼、系統的標準啟動代碼和庫代碼[[29](ch18s03.html#ftn.id3084420)])結合在一起,并將它們存放在可執行文件中。 * * * > [[26](ch18s03.html#id3084190)] 在 Linux 系統中,編譯器為gcc,cc為它的鏈接 > [[27](ch18s03.html#id3084254)] 庫中包含許多標準例程供您使用,例如**printf()**。更準確的說,是一個被稱為鏈接器(linker)的程序將庫例程引入的,但在多數系統上,編譯器為您運行鏈接器。 > [[28](ch18s03.html#id3084399)] 硬件相同的情況下,在 DOS 或 Linux 下可以使用同樣的目標代碼,但 DOC 與 Linux 要使用不同的啟動代碼,因為這兩種系統處理程序的方式是不同的。 > [[29](ch18s03.html#id3084420)] 程序有兩種方法來使用這些庫函數,如果靜態連接一個程序,這些函數就會被復制到可執行程序中,這就是`lib*.a`函數庫的作用 > 如果你動態的連接一個程序(默認),那么當程序運行時需要庫中的代碼,它就會調用`lib*.so`中的內容。 ## gcc 編譯器 gcc 是 GNU 推出的功能強大、性能優越的多平臺編譯器,是 GNU 的代表作品之一。它能將C、C++語言源程序、匯編語言源程序和目標程序編譯、鏈接成可執行文件,如果沒有給出可執行文件的名字,gcc 將生成一個名為 `a.out` 的文件。 gcc 通過后綴來區分輸入文件的類型: | 后綴 | 類型 | | --- | --- | | .c | C語言源代碼文件 | | .a | 由目標文件構成的檔案庫文件 | | .C&#124;.cc&#124;.cxx | C++源代碼文件 | | .h | 程序所包含的頭文件 | | .i | 預處理過的C源代碼文件 | | .ii | 預處理過的C++源代碼文件 | | .m | Objective-C源代碼文件 | | .o | 編譯后的目標文件 | | .s | 匯編語言源代碼文件 | | .S | 預編譯的匯編語言源代碼文件 | 前面我們已經使用 gcc 編譯了一個程序:`cc Hello.c` gcc 還有許多選項: | | | | --- | --- | | -c | 只編譯,不鏈接成為可執行文件 | | -o 文件名 | 設定輸出文件名。默認為`a.out` | | -g | 加入調試符號(默認)。![1](https://box.kancloud.cn/2015-10-12_561bcb76795ae.png) | | -O | 編譯、鏈接時進行優化,耗時比較多,但產生的可執行文件執行效率更高 | | -O2 | 更高的優化級別,耗時更多 | > [![1](https://box.kancloud.cn/2015-10-12_561bcb76795ae.png)](ch18s04.html#build-21) 可以使用 gdb 進行調試使用下面的命令去掉調試符號: > ``` > strip --strip-unneeded a.out > strip --strip-debug a.out > ``` > 不要在庫文件上使用 **--strip-unneeded** ## 自動化編譯 在前面的[標準編譯安裝](ch18s02.html#std-build)中,第一步是`./configure`[[30](ch18s05.html#ftn.id3084729)],它會根據`Makefile.in`生成`Makefile`文件,然后make根據`Makefile`自動編譯軟件 通常在一個源碼包中,已經包含了`configure`腳本和`Makefile`文件,作為課外知識,我們大致了解一下怎么生成這兩個文件 ### autoconf autoconf用來生成`configure`腳本,它可以檢查系統特性、編譯環境、環境變量、軟件參數、依賴關系等 autoconf需要用到 m4 1. 用autoscan描源代碼目錄生成`configure.scan`文件 2. 將`configure.scan`改名為`configure.in` 3. 用aclocal根據`configure.in`文件的內容,自動生成`aclocal.m4`文件 4. 使用autoconf,根據`configure.in`和`aclocal.m4`來產生`configure`文件 ### automake automake可以從`Makefile.am`文件自動生成`Makefile.in`,它主要用來配置源代碼 automake需用到perl * 手工寫`Makefile.am` * 使用`automake`,根據`configure.in`和`Makefile.am`來產生`Makefile.in` ### Makefile 使用`configure`腳本,配合`Makefile.in`可以生成`Makefile`文件,然后用make自動化的編譯軟件 這里有一張生成`Makefile`的流程圖: ![](https://box.kancloud.cn/2016-08-07_57a6a934d835a.gif) `Makefile`的用途不只是編譯軟件,還可以利用它完成一些瑣碎的工作,只要最后輸出一個文件,都可以用make來完成 這是一個最簡單的`Makefile` ``` filelist:* ls -lF > filelist ``` > [![1](https://box.kancloud.cn/2015-10-12_561bcb76795ae.png)](ch18s05.html#build-31) 輸出的目標文件,不能省略。如果有多個文件,可以使用**all** > [![2](https://box.kancloud.cn/2015-10-12_561bcb768596e.png)](ch18s05.html#build-32) 分隔符,不能省略 > [![3](https://box.kancloud.cn/2015-10-12_561bcb94ee26f.png)](ch18s05.html#build-33) 輸入文件,可以省略 > [![4](https://box.kancloud.cn/2015-10-12_561bcb9508b82.png)](ch18s05.html#build-34) 這一行必須以`TAB`字符起始,不能使用空格代替 > [![5](https://box.kancloud.cn/2015-10-12_561bcb95133e7.png)](ch18s05.html#build-35) make的命令 可以使用變量代替命令,便于維護 ``` TARGET = filelist SOURCE = * ARG = -lF APPLICATION = ls $(TARGET):$(SOURCE) $(APPLICATION) $(ARG) $(SOURCE) > $(TARGET) ``` > [![1](https://box.kancloud.cn/2015-10-12_561bcb76795ae.png)](ch18s05.html#build-41) 定義變量,傳統上用大寫 > [![2](https://box.kancloud.cn/2015-10-12_561bcb768596e.png)](ch18s05.html#build-42) 使用變量寫`Makefile` `Makefile`可以有多個目標文件,我們前面提到,gcc編譯時先生成目標文件,再把目標文件鏈接成可執行文件,Makefile應該是這樣的: ``` OBJECTS = main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o exe : $(OBJECTS) cc -o exe $(OBJECTS) main.o : main.c defs.h cc -c main.c kbd.o : kbd.c defs.h command.h cc -c kbd.c command.o : command.c defs.h command.h cc -c command.c display.o : display.c defs.h buffer.h cc -c display.c insert.o : insert.c defs.h buffer.h cc -c insert.c search.o : search.c defs.h buffer.h cc -c search.c files.o : files.c defs.h buffer.h command.h cc -c files.c utils.o : utils.c defs.h cc -c utils.c clean : rm exe $(OBJECTS) ``` > [![1](https://box.kancloud.cn/2015-10-12_561bcb76795ae.png)](ch18s05.html#build-51) 如果寫在多行,要用脫字符換行 > [![2](https://box.kancloud.cn/2015-10-12_561bcb768596e.png)](ch18s05.html#build-52) 如何生成中間文件 > [![3](https://box.kancloud.cn/2015-10-12_561bcb94ee26f.png)](ch18s05.html#build-53) 偽目標文件,`make clean`并不生成`clean`文件,而是清理編譯結果 `Makefile`還有很多強大的機制,這里就不詳細介紹了 * * * > [[30](ch18s05.html#id3084729)] 執行當前目錄下的`configure`腳本 ## 使用 make 利用 `configure`所產生的`Makefile`文件有幾個預先設定的目標可供使用: | 目標 | 用途 | | --- | --- | | make all | 產生預設的目標,只敲入`make`也可以 | | make clean | 清除編譯結果 | | make distclean | 除了清除編譯結果,也把configure所產生的 `Makefile` 清除掉 | | make install | 將程序安裝到系統中 | | make dist | 將程序和相關的文檔打包為一個壓縮文檔以供發布 | | make distcheck | 打包并檢驗 | ## emerge 雖然我們能夠使用autoconf、automake、make等工具實現自動化編譯,但這種針對單個軟件包的編譯系統,在編譯多個軟件時仍然十分繁瑣 假設需要編譯emacs和vim,使用 xft字體、圖形界面支持,并去掉調試符號,需要分別作如下配置 ``` emacs ./configure --prefix=/usr/local/ \ `--no-debug` \ `--with-xft --with-x-toolkit=gtk` \ --with-freetype vim ./configure --prefix=/usr/local/ \ `--no-debug` \ `--with-xft --with-x-toolkit=gtk` ``` 這就像點菜時,你必須告訴廚師:魚香肉絲(多放辣椒、不放蒜)、宮保雞丁(多放辣椒、不放蒜)、麻婆豆腐(多放辣椒、不放蒜)…… 實際上,大多數人這樣點菜:魚香肉絲、宮保雞丁、麻婆豆腐……多放辣椒、不放蒜 emerge就是這樣一種點菜方式,它是gentoo的包管理系統,提供了更為現代化的編譯方式 可以通過指定USE標記`xft`、`gtk`、`-debug`來確定所有軟件的編譯方式 ### 設置 USE標記 以下方法按優先級由低到高排列: `/etc/make.profile/`目錄是一個符號鏈接,里面包含一些`make.defaults`文件,放置開發者設置的 USE標記[[31](ch18s07.html#ftn.id3085747)]: ``` /usr/portage/profile/base/make.defaults /usr/portage/profile/default-linux/make.defaults /usr/portage/profile/default-linux/x86/make.defaults /usr/portage/profile/default-linux/x86/2008.0/make.defaults ``` 在`/etc/make.conf`文件中聲明永久 USE標記(推薦) ``` USE="nptl nptlonly nls cjk php mysql -kde -qt3 -qt4" ``` * 帶`-`的 USE標記,表示排除 在`/etc/portage/package.use`文件中為單個包聲明 USE標記 ``` app-editors/emacs-cvs xft www-servers/lighttpd fastcgi dev-lang/php mysqli cgi gd ctype pcre session unicode pic posix dev-db/phpmyadmin vhosts app-shells/zsh doc net-ftp/pure-ftpd -ldap mysql pam ssl vchroot ``` 使用環境變量聲明臨時 USE標記 ``` USE="-java" emerge seamonkey ``` 查看使用的 USE標記: ``` merge --pretend --verbose seamonkey Calculating dependencies ...done! [ebuild R ] www-client/seamonkey-1.0.7 USE="crypt gnome java -debug -ipv6 -ldap -mozcalendar -mozdevelop -moznocompose -moznoirc -moznomail -moznopango -moznoroaming -postgres -xinerama -xprint" 0 kB ``` ### 編譯選項 `/etc/make.conf` ``` CFLAGS="-O2 -march=i686 -pipe" CXXFLAGS="-O2 -march=i686 -pipe" CHOST="i686-pc-linux-gnu" MAKEOPTS="-j2" FEATURES="parallel-fetch ccache" CCACHE_DIR="/var/tmp/ccache" CCACHE_SIZE="2G" ACCEPT_KEYWORDS="x86" USE="nptl nptlonly nls cjk php mysql" FETCHCOMMAND="/usr/bin/axel -a -n4 \${URI} -o \${DISTDIR}" RESUMECOMMAND="/usr/bin/axel -a -n4 \${URI} -o \${DISTDIR}" ``` > [![1](https://box.kancloud.cn/2015-10-12_561bcb76795ae.png)](ch18s07.html#build-e21) 針對C語言的優化選項,**-march=**設置目標架構 > [![2](https://box.kancloud.cn/2015-10-12_561bcb768596e.png)](ch18s07.html#build-e22) 針對C++語言的優化選項 > [![3](https://box.kancloud.cn/2015-10-12_561bcb94ee26f.png)](ch18s07.html#build-e23) 進行編譯工作的機器架構 > [![4](https://box.kancloud.cn/2015-10-12_561bcb9508b82.png)](ch18s07.html#build-e24) 編譯選項 > [![5](https://box.kancloud.cn/2015-10-12_561bcb95133e7.png)](ch18s07.html#build-e25) emerge 特性。并行下載、使用 ccache 緩沖編譯結果 > [![6](https://box.kancloud.cn/2016-01-06_568cdb4f32753.png)](ch18s07.html#build-e26) ccache 緩存目錄 > [![7](https://box.kancloud.cn/2016-01-06_568cdb4f41fcc.png)](ch18s07.html#build-e27) ccache 緩存大小 > [![8](https://box.kancloud.cn/2016-01-06_568cdb4f5948a.png)](ch18s07.html#build-e28) 通過關鍵字選擇分支。`x86`表示 x86 架構的穩定分支,`~x86`表示 x86 架構的不穩定分支 > [![9](https://box.kancloud.cn/2016-01-06_568cdb4f68749.png)](ch18s07.html#build-e29) USE標記 > [![10](https://box.kancloud.cn/2016-01-06_568cdb4f83cf0.png)](ch18s07.html#build-e30) 使用axel加速下載 gentoo支持多種架構:x86、 sparc、 amd64、 ppc、 ppc64、 alpha、 hppa、 mips、 ia64、 arm,我們使用的 PC 多為 x86 架構 假設你主要使用 x86 穩定分支,但少數軟件要使用最新版本,在`/etc/portage/package.keywords`文件中為單個包設置關鍵字 ``` app-editors/emacs-cvs ~x86 x11-misc/emacs-desktop ~x86 app-i18n/fcitx ~x86 app-editors/vim x86 app-editors/vim-core x86 media-video/mplayer ~x86 media-libs/win32codecs ~x86 app-i18n/man-pages-zh_CN ~x86 ``` ### 微調 在`/etc/portage/`目標下包含一些文件,可以在軟件包級別上進行調節。前面已經介紹了`package.use`和`package.keywords` package.keywords 還未被確認適合你的系統或架構,但是你希望能安裝的軟件包 package.use 特定軟件包而不是整個系統使用的 USE標記 package.provided 屏蔽的軟件包(需要指明版本號) package.mask 永遠不希望 Portage 安裝的軟件包。 package.unmask 被 Gentoo 開發者屏蔽的軟件包,但是你希望能安裝的軟件包。 軟件包可能由于以下原因被屏蔽 | | | | --- | --- | | ~架構 keyword | 意味著這個軟件沒有經過充分的測試,不能進入穩定分支,請等待一段時間后在嘗試使用它 | | -架構 keyword 或 -* keyword | 意味著這個軟件不能工作在您機器的體系結構中 | | missing keyword | 意味著這個軟件還沒有在您機器的體系結構中進行過測試 | | package.mask | 意味著這個軟件被認為是損壞的,不穩定的或者有更嚴重的問題,它被故意標識為“不應使用” | | profile | 意味著這個軟件不適用于您的 profile。安裝這樣的應用軟件可能會破壞您的系統,或者只是不能與您使用的 profile 相兼容 | 例如: ``` gnome-base/gnome-2.8.0_pre1 (masked by: ~x86 keyword) lm-sensors/lm-sensors-2.8.7 (masked by: -sparc keyword) sys-libs/glibc-2.3.4.20040808 (masked by: -* keyword) dev-util/cvsd-1.0.2 (masked by: missing keyword) games-fps/unreal-tournament-451 (masked by: package.mask) sys-libs/glibc-2.3.2-r11 (masked by: profile) ``` ### 使用 emerge > 注意:本部分內容來源于[gentoo 中文手冊](http://www.gentoo.org/doc/zh_cn/handbook/) **查找.?** 查找名字包含 pdf 的軟件包 ``` emerge --search pdf ``` 查找與 pdf 相關的軟件包 ``` emerge --searchdesc pdf emerge -S pdf ``` 查看軟件擁有的 USE標記 ``` emerge -vp 軟件包名稱 ``` **管理.?** 安裝軟件包 ``` emerge 軟件包名稱 ``` 模擬安裝軟件包 ``` emerge --pretend 軟件包名稱 ``` 下載軟件包的源代碼包 ``` emerge --fetchonly 軟件包名稱 ``` 從系統中刪除軟件包 ``` emerge --unmerge 軟件包名稱 ``` **更新.?** 更新系統 ``` emerge --update --ask world emerge -ua world ``` 更新整個系統 ``` emerge --update --deep world emerge -uD world ``` 使用新的 USE標記 重新構建系統 ``` emerge --update --deep --newuse world emerge -uDN world ``` 移除孤立依賴的軟件包 ``` emerge --update --deep --newuse world emerge --depclean revdep-rebuild ``` > [![1](https://box.kancloud.cn/2015-10-12_561bcb76795ae.png)](ch18s07.html#build-e31) 重新構建系統 > [![2](https://box.kancloud.cn/2015-10-12_561bcb768596e.png)](ch18s07.html#build-e32) 清除孤立依賴包 > [![3](https://box.kancloud.cn/2015-10-12_561bcb94ee26f.png)](ch18s07.html#build-e33) 重新構建依賴關系 revdep-rebuild工具由gentoolkit包提供;使用前別忘了首先 emerge 它: ``` emerge gentoolkit ``` * * * > [[31](ch18s07.html#id3085747)] 在升級 Portage 的時候,這些文件將會被覆蓋,請不要在這里設置
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看