<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    so true

    心懷未來(lái),開(kāi)創(chuàng)未來(lái)!
    隨筆 - 160, 文章 - 0, 評(píng)論 - 40, 引用 - 0
    數(shù)據(jù)加載中……

    make學(xué)習(xí)

    權(quán)威資料:http://www.gnu.org/software/make/manual/make.html,到這個(gè)頁(yè)面的尾部有index,可以快速查找一些關(guān)鍵詞來(lái)定位你想要找的東西,例如automatic variable
    一個(gè)不錯(cuò)的中文總結(jié):http://www.cnblogs.com/liangxiaxu/archive/2012/07/31/2617384.html
    自我學(xué)到的一些知識(shí)點(diǎn):
    1。makefile中的每一個(gè)target都是一個(gè)文件,make的最終目標(biāo)都是生成這個(gè)文件,target可以帶路徑,例如dir1/dir2/test;
    2。%.o: %.c中的%可以匹配路徑,例如test1/test2/*.o都可以從test1/test2/*.c來(lái)推導(dǎo);
    3。關(guān)于PHONY目標(biāo),能成為PHONY的target應(yīng)該是不能對(duì)應(yīng)具體文件的,例如clean,例如我們經(jīng)常用all來(lái)收集一批需要產(chǎn)生的真正的target,偽目標(biāo)的特性就是:當(dāng)make ABC時(shí),不管當(dāng)前目錄是否有ABC文件,都會(huì)去分析其依賴項(xiàng)并執(zhí)行recipes;
    4。如果一個(gè)target沒(méi)有任何依賴,那么這個(gè)target永遠(yuǎn)都是最新的,因此只要這個(gè)target文件存在,那么永遠(yuǎn)不會(huì)去執(zhí)行它的recipes,如果我們把這個(gè)target聲明為偽目標(biāo),那么不論這個(gè)target文件是否存在,執(zhí)行其recipes;
    5。一個(gè)target依賴多項(xiàng)時(shí),可以分開(kāi)寫,例如:
    A: B1
    A:
    A:;
    A: B2
    echo $@, $^
    最終A依賴于B1和B2
    6。可以一次性寫多個(gè)target的依賴,例如:A B C: D
    7。A: PARAM := test.cpp這種寫法表明PARAM這個(gè)變量的作用域僅僅是生成A時(shí)有用
    8。A: B C | D E,這里D E被稱為order-only依賴,就是說(shuō)對(duì)于D E,和B C一樣,該更新就更新,而且還是先處理依賴項(xiàng)D,再處理依賴項(xiàng)E,只不過(guò)到最后即便D或者E更新了,也不會(huì)因此而更新A,除非B或C更新了,千萬(wàn)不要誤以為只要D存在就關(guān)心D的死活了(即是否要更新);
    9。make test -n會(huì)打印出make過(guò)程所有需要執(zhí)行的命令,但并不會(huì)執(zhí)行;
    10。make test -d會(huì)打印出make過(guò)程所有的分析過(guò)程,例如怎么解決的依賴,自動(dòng)推導(dǎo)規(guī)則,為什么有些target需要更新,有些不需要;
    11。make test -p會(huì)打印出make過(guò)程中所有的變量和規(guī)則的推導(dǎo)結(jié)果,即所有變量都展開(kāi)了,而且會(huì)告訴你所執(zhí)行的命令都來(lái)自于哪個(gè)makefile的哪一行;
    12。make --debug[=FLAGS]
                Print debugging information in addition to normal processing.  If the FLAGS are omitted, then the behavior is the same as if -d was specified.  FLAGS may be a for all debugging output (same as using -d),
                b for basic debugging, v for more verbose basic debugging, i for showing implicit rules, j for details on invocation of commands, and m for debugging while remaking makefiles.
    13。make V=1的含義是:定義了一個(gè)變量,名字是V,值是1,可以在Makefile中通過(guò)$(V)來(lái)得到V的值;
    14。make -j 8的含義是:用8個(gè)進(jìn)程同時(shí)build,即速度加快8倍;
    15。$+和$^差不多,區(qū)別是$^去重了,$+都保留下來(lái)了;
    16。想查看一個(gè)target的所有依賴項(xiàng),有時(shí)候一個(gè)target的依賴項(xiàng)會(huì)分散在多個(gè)文件中,例如對(duì)于target all,可以增加如下代碼即可:
    all:
    #$^
    這里當(dāng)然也可以用@echo $^,但上面這種簡(jiǎn)單寫法也可以,反正recipe就是寫shell命令
    recipe可以由換行,也可以有make的一些條件控制語(yǔ)句,例如:
    all:
        @echo "hello"

        @echo "world"

    ifeq "$(abc)" "hello"
        @echo "equal"
    else
        @echo "not equal"
    endif
    總結(jié):尤其是make -d/-p,基本可以搞定所有你弄不清楚的make問(wèn)題,仔細(xì)分析就好了。

    $(if ifeq  "foo" "bar", @echo match is broken, @echo match works)
    $(if ifneq "foo" "bar", @echo match works, @echo match is broken)
    $(if ...) conditional function evaluates to true when the first argument passed to it is non-empty. In you case the condition is literal text: ifeq "foo" "bar", which is, obviously, non-empty.
    ifeq/ifneq conditionals are in fact directives, not functions. They can't be used inside variable definition and in functions.
    Back to your example, to test string for equality inside the condition use functions like filter, filter-out and findstring:
    $(if $(filter-out foo,bar),@echo not equal,@echo equal)

    ====================================================================
    下面是之前學(xué)習(xí)make時(shí)寫的一些東西,現(xiàn)在看來(lái)好像很垃圾:
    [make的規(guī)則]
    在定義好依賴關(guān)系后,后續(xù)的那一行定義了如何生成目標(biāo)文件的操作系統(tǒng)命令,一定要以一個(gè)Tab鍵作為開(kāi)頭。記住,make并不管命令是怎么工作的,他只管執(zhí)行所定義的命令。
    make會(huì)比較targets文件和prerequisites文件的修改日期(mtime,而不是ctime或atime),如果prerequisites文件的日期要比targets文件的日期要新,或者target不存在的話,那么,make就會(huì)執(zhí)行后續(xù)定義的命令。
    也可以像下面這樣把命令放在后面,通過(guò)一個(gè)分號(hào)來(lái)搞定
    targets : prerequisites ; command
                command
    比如你的第一條命令是cd命令,你希望第二條命令得在cd之后的基礎(chǔ)上運(yùn)行,那么你就不能把這兩條命令寫在兩行上,而應(yīng)該把這兩條命令寫在一行上,用分號(hào)分隔。也就是說(shuō):一行內(nèi)的命令是在一個(gè)子shell環(huán)境中執(zhí)行的。

    make會(huì)一按順序一條一條的執(zhí)行命令,每條命令的開(kāi)頭必須以[Tab]鍵開(kāi)頭,除非,命令是緊跟在依賴規(guī)則后面的分號(hào)后的。在命令行之間中的空格或是空行會(huì)被忽略,但是如果該空格或空行是以Tab鍵開(kāi)頭的,那么make會(huì)認(rèn)為其是一個(gè)空命令。

    當(dāng)我們用“@”字符在命令行前,那么,這個(gè)命令將不被make顯示出來(lái),最具代表性的例子是,我們用這個(gè)功能來(lái)像屏幕顯示一些信息。如:

        @echo 正在編譯XXX模塊......

    當(dāng)make執(zhí)行時(shí),會(huì)輸出“正在編譯XXX模塊......”字串,但不會(huì)輸出命令,如果沒(méi)有“@”,那么,make將輸出:

        echo 正在編譯XXX模塊......
        正在編譯XXX模塊......

    如果不給make命令指定target,那么make會(huì)將makefile文件中出現(xiàn)的第一個(gè)target作為此次執(zhí)行make的目標(biāo),如果該target不是一個(gè),那么取第一個(gè).其實(shí)make一次只對(duì)一個(gè)target負(fù)責(zé),除非你在執(zhí)行make時(shí)指定多個(gè)target,如make target1 target2

    [變量定義]
    =定義的時(shí)候不會(huì)被展開(kāi),在具體引用時(shí)才會(huì)被展開(kāi)
    :=定義的時(shí)候就會(huì)被展開(kāi),建議使用該種變量定義

    [自動(dòng)推導(dǎo)]
    main.o : defs.h
    make會(huì)自動(dòng)為你添加main.cpp這個(gè)依賴文件
    [引用其他Makefile]
    include foo.make *.mk $(bar)
    [make的工作方式]
    GNU的make工作時(shí)的執(zhí)行步驟入下:(想來(lái)其它的make也是類似)

       1. 讀入所有的Makefile。
       2. 讀入被include的其它Makefile。
       3. 初始化文件中的變量。
       4. 推導(dǎo)隱晦規(guī)則,并分析所有規(guī)則。
       5. 為所有的目標(biāo)文件創(chuàng)建依賴關(guān)系鏈。
       6. 根據(jù)依賴關(guān)系,決定哪些目標(biāo)要重新生成。
       7. 執(zhí)行生成命令。

    1-5步為第一個(gè)階段,6-7為第二個(gè)階段。第一個(gè)階段中,如果定義的變量被使用了,那么,make會(huì)把其展開(kāi)在使用的位置。但make并不會(huì)完全馬上展開(kāi),make使用的是拖延戰(zhàn)術(shù),如果變量出現(xiàn)在依賴關(guān)系的規(guī)則中,那么僅當(dāng)這條依賴被決定要使用了,變量才會(huì)在其內(nèi)部展開(kāi)。

    當(dāng)然,這個(gè)工作方式你不一定要清楚,但是知道這個(gè)方式你也會(huì)對(duì)make更為熟悉。有了這個(gè)基礎(chǔ),后續(xù)部分也就容易看懂了。

    [make命令的參數(shù)]
    make -i 忽略出錯(cuò)命令,等同于在makefile中對(duì)應(yīng)命令前加上‘-’符號(hào)
    make -k 如果某規(guī)則中的命令出錯(cuò)了,那么就終目該規(guī)則的執(zhí)行,但繼續(xù)執(zhí)行其它規(guī)則
    make -n 那么其只是顯示命令,但不會(huì)執(zhí)行命令
    make -s 或“--slient”則是全面禁止命令的顯示
    make -w 在“嵌套執(zhí)行”中比較有用的參數(shù),“-w”或是“--print-directory”會(huì)在make的過(guò)程中輸出一些信息,讓你看到目前的工作目錄。

    [文件搜尋]
    Makefile文件中的特殊變量“VPATH”就是完成這個(gè)功能的,如果沒(méi)有指明這個(gè)變量,make只會(huì)在當(dāng)前的目錄中去找尋依賴文件和目標(biāo)文件。如果定義了這個(gè)變量,那么,make就會(huì)在當(dāng)當(dāng)前目錄找不到的情況下,到所指定的目錄中去找尋文件了。

        VPATH = src:../headers

    上面的的定義指定兩個(gè)目錄,“src”和“../headers”,make會(huì)按照這個(gè)順序進(jìn)行搜索。目錄由“冒號(hào)”分隔。(當(dāng)然,當(dāng)前目錄永遠(yuǎn)是最高優(yōu)先搜索的地方)

    另一個(gè)設(shè)置文件搜索路徑的方法是使用make的“vpath”關(guān)鍵字(注意,它是全小寫的),這不是變量,這是一個(gè)make的關(guān)鍵字,這和上面提到的那個(gè) VPATH變量很類似,但是它更為靈活。它可以指定不同的文件在不同的搜索目錄中。這是一個(gè)很靈活的功能。它的使用方法有三種:

       1. vpath < pattern> < directories>
          為符合模式< pattern>的文件指定搜索目錄< directories>。
       2. vpath < pattern>
          清除符合模式< pattern>的文件的搜索目錄。
       3. vpath
          清除所有已被設(shè)置好了的文件搜索目錄。

    vapth使用方法中的< pattern>需要包含“%”字符。“%”的意思是匹配零或若干字符,例如,“%.h”表示所有以“.h”結(jié)尾的文件。< pattern>指定了要搜索的文件集,而< directories>則指定了的文件集的搜索的目錄。例如:

        vpath %.h ../headers

    該語(yǔ)句表示,要求make在“../headers”目錄下搜索所有以“.h”結(jié)尾的文件。(如果某文件在當(dāng)前目錄沒(méi)有找到的話)

    [偽目標(biāo)]
    “偽目標(biāo)”并不是一個(gè)文件,只是一個(gè)標(biāo)簽,由于“偽目標(biāo)”不是文件,所以make無(wú)法生成它的依賴關(guān)系和決定它是否要執(zhí)行。我們只有通過(guò)顯示地指明這個(gè)“目標(biāo)”才能讓其生效。
    沒(méi)有依賴項(xiàng)的target自動(dòng)成為偽目標(biāo),放在.PHONY的依賴項(xiàng)中的target自動(dòng)成為偽目標(biāo).
    澄清一個(gè)錯(cuò)誤觀點(diǎn): 放在.PHONY中的依賴項(xiàng)并不是make后就自動(dòng)執(zhí)行,而僅僅只是聲明該target是個(gè)偽目標(biāo)而已,make命令依然還是執(zhí)行makefile中的第一個(gè)target
    偽目標(biāo)的更新時(shí)間永遠(yuǎn)都是最新的,因此只要執(zhí)行到了偽目標(biāo),那么必然會(huì)被執(zhí)行,時(shí)間戳在它面前無(wú)效.
    因此對(duì)于通過(guò)make命令就期望強(qiáng)制執(zhí)行很多target的話,可以在makefile開(kāi)頭這么寫:
    all : prog1 prog2 prog3
    .PHONY : all

    [靜態(tài)規(guī)則]
    語(yǔ)法:
    <targets ...>: <target-pattern>: <prereq-patterns ...>
    <commands>
    ...
    看一個(gè)例子:

        objects = foo.o bar.o

        all: $(objects)

        $(objects): %.o: %.c
                $(CC) -c $(CFLAGS) $< -o $@
    使用filter:
    files = foo.elc bar.o lose.o

        $(filter %.o,$(files)): %.o: %.c
                $(CC) -c $(CFLAGS) $< -o $@
        $(filter %.elc,$(files)): %.elc: %.el
                emacs -f batch-byte-compile $<




    [makefile中的函數(shù)]
    形式為:$(函數(shù)名 參數(shù))
    自定義函數(shù):
    define 函數(shù)名
        函數(shù)體
    endef

    [gcc技巧]
    如果你使用GNU的C/C++編譯器,你得用“-MM”參數(shù),不然,“-M”參數(shù)會(huì)把一些標(biāo)準(zhǔn)庫(kù)的頭文件也包含進(jìn)來(lái)。

    [嵌套執(zhí)行 & 變量或參數(shù)向下傳遞]
    嵌套執(zhí)行make
    在一些大的工程中,我們會(huì)把我們不同模塊或是不同功能的源文件放在不同的目錄中,我們可以在每個(gè)目錄中都書(shū)寫一個(gè)該目錄的Makefile,這有利于讓我們的Makefile變得更加地簡(jiǎn)潔,而不至于把所有的東西全部寫在一個(gè)Makefile中,這樣會(huì)很難維護(hù)我們的Makefile,這個(gè)技術(shù)對(duì)于我們模塊編譯和分段編譯有著非常大的好處。

    例如,我們有一個(gè)子目錄叫subdir,這個(gè)目錄下有個(gè)Makefile文件,來(lái)指明了這個(gè)目錄下文件的編譯規(guī)則。那么我們總控的Makefile可以這樣書(shū)寫:

        subsystem:
                cd subdir && $(MAKE)

    其等價(jià)于:

        subsystem:
                $(MAKE) -C subdir

    定義$(MAKE)宏變量的意思是,也許我們的make需要一些參數(shù),所以定義成一個(gè)變量比較利于維護(hù)。這兩個(gè)例子的意思都是先進(jìn)入“subdir”目錄,然后執(zhí)行make命令。

    我們把這個(gè)Makefile叫做“總控Makefile”,總控Makefile的變量可以傳遞到下級(jí)的Makefile中(如果你顯示的聲明),但是不會(huì)覆蓋下層的Makefile中所定義的變量,除非指定了“-e”參數(shù)。

    如果你要傳遞變量到下級(jí)Makefile中,那么你可以使用這樣的聲明:

    export <variable ...>

    如果你不想讓某些變量傳遞到下級(jí)Makefile中,那么你可以這樣聲明:

    unexport <variable ...>

    如:
            export variable := value #定義的同時(shí)也export了

            export variable += value

    如果你要傳遞所有的變量,那么,只要一個(gè)export就行了。后面什么也不用跟,表示傳遞所有的變量。

    需要注意的是,有兩個(gè)變量,一個(gè)是SHELL,一個(gè)是MAKEFLAGS,這兩個(gè)變量不管你是否export,其總是要傳遞到下層Makefile 中,特別是MAKEFILES變量,其中包含了make的參數(shù)信息,如果我們執(zhí)行“總控Makefile”時(shí)有make參數(shù)或是在上層Makefile中定義了這個(gè)變量,那么MAKEFILES變量將會(huì)是這些參數(shù),并會(huì)傳遞到下層Makefile中,這是一個(gè)系統(tǒng)級(jí)的環(huán)境變量。

    但是make命令中的有幾個(gè)參數(shù)并不往下傳遞,它們是“-C”,“-f”,“-h”“-o”和“-W”(有關(guān)Makefile參數(shù)的細(xì)節(jié)將在后面說(shuō)明),如果你不想往下層傳遞參數(shù),那么,你可以這樣來(lái):

       
        subsystem:
                cd subdir && $(MAKE) MAKEFLAGS=

    如果你定義了環(huán)境變量MAKEFLAGS,那么你得確信其中的選項(xiàng)是大家都會(huì)用到的,如果其中有“-t”,“-n”,和“-q”參數(shù),那么將會(huì)有讓你意想不到的結(jié)果,或許會(huì)讓你異常地恐慌。

    還有一個(gè)在“嵌套執(zhí)行”中比較有用的參數(shù),“-w”或是“--print-directory”會(huì)在make的過(guò)程中輸出一些信息,讓你看到目前的工作目錄。比如,如果我們的下級(jí)make目錄是“/home/hchen/gnu/make”,如果我們使用“make -w”來(lái)執(zhí)行,那么當(dāng)進(jìn)入該目錄時(shí),我們會(huì)看到:

       
        make: Entering directory `/home/hchen/gnu/make'.

    而在完成下層make后離開(kāi)目錄時(shí),我們會(huì)看到:

       
        make: Leaving directory `/home/hchen/gnu/make'

    當(dāng)你使用“-C”參數(shù)來(lái)指定make下層Makefile時(shí),“-w”會(huì)被自動(dòng)打開(kāi)的。如果參數(shù)中有“-s”(“--slient”)或是“--no-print-directory”,那么,“-w”總是失效的。

    [自動(dòng)生成依賴關(guān)系]
    自動(dòng)生成依賴性

    在Makefile中,我們的依賴關(guān)系可能會(huì)需要包含一系列的頭文件,比如,如果我們的main.c中有一句“#include "defs.h"”,那么我們的依賴關(guān)系應(yīng)該是:

        main.o : main.c defs.h

    但是,如果是一個(gè)比較大型的工程,你必需清楚哪些C文件包含了哪些頭文件,并且,你在加入或刪除頭文件時(shí),也需要小心地修改Makefile,這是一個(gè)很沒(méi)有維護(hù)性的工作。為了避免這種繁重而又容易出錯(cuò)的事情,我們可以使用C/C++編譯的一個(gè)功能。大多數(shù)的C/C++編譯器都支持一個(gè)“-M”的選項(xiàng),即自動(dòng)找尋源文件中包含的頭文件,并生成一個(gè)依賴關(guān)系。例如,如果我們執(zhí)行下面的命令:

        cc -M main.c

    其輸出是:

        main.o : main.c defs.h

    于是由編譯器自動(dòng)生成的依賴關(guān)系,這樣一來(lái),你就不必再手動(dòng)書(shū)寫若干文件的依賴關(guān)系,而由編譯器自動(dòng)生成了。需要提醒一句的是,如果你使用GNU的C/C++編譯器,你得用“-MM”參數(shù),不然,“-M”參數(shù)會(huì)把一些標(biāo)準(zhǔn)庫(kù)的頭文件也包含進(jìn)來(lái)。

    gcc -M main.c的輸出是:

        main.o: main.c defs.h /usr/include/stdio.h /usr/include/features.h \
             /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \
             /usr/lib/gcc-lib/i486-suse-linux/2.95.3/include/stddef.h \
             /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \
             /usr/include/bits/sched.h /usr/include/libio.h \
             /usr/include/_G_config.h /usr/include/wchar.h \
             /usr/include/bits/wchar.h /usr/include/gconv.h \
             /usr/lib/gcc-lib/i486-suse-linux/2.95.3/include/stdarg.h \
             /usr/include/bits/stdio_lim.h


    gcc -MM main.c的輸出則是:

        main.o: main.c defs.h

    那么,編譯器的這個(gè)功能如何與我們的Makefile聯(lián)系在一起呢。因?yàn)檫@樣一來(lái),我們的Makefile也要根據(jù)這些源文件重新生成,讓 Makefile自已依賴于源文件?這個(gè)功能并不現(xiàn)實(shí),不過(guò)我們可以有其它手段來(lái)迂回地實(shí)現(xiàn)這一功能。GNU組織建議把編譯器為每一個(gè)源文件的自動(dòng)生成的依賴關(guān)系放到一個(gè)文件中,為每一個(gè)“name.c”的文件都生成一個(gè)“name.d”的Makefile文件,[.d]文件中就存放對(duì)應(yīng)[.c]文件的依賴關(guān)系。

    于是,我們可以寫出[.c]文件和[.d]文件的依賴關(guān)系,并讓make自動(dòng)更新或自成[.d]文件,并把其包含在我們的主Makefile中,這樣,我們就可以自動(dòng)化地生成每個(gè)文件的依賴關(guān)系了。

    這里,我們給出了一個(gè)模式規(guī)則來(lái)產(chǎn)生[.d]文件:

        %.d: %.c
                @set -e; rm -f $@; \
                 $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \
                 sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
                 rm -f $@.$$$$

    這個(gè)規(guī)則的意思是,所有的[.d]文件依賴于[.c]文件,“rm -f $@”的意思是刪除所有的目標(biāo),也就是[.d]文件,第二行的意思是,為每個(gè)依賴文件“$<”,也就是[.c]文件生成依賴文件,“$@”表示模式 “%.d”文件,如果有一個(gè)C文件是name.c,那么“%”就是“name”,“$$$$”意為一個(gè)隨機(jī)編號(hào),第二行生成的文件有可能是 “name.d.12345”,第三行使用sed命令做了一個(gè)替換,關(guān)于sed命令的用法請(qǐng)參看相關(guān)的使用文檔。第四行就是刪除臨時(shí)文件。

    總而言之,這個(gè)模式要做的事就是在編譯器生成的依賴關(guān)系中加入[.d]文件的依賴,即把依賴關(guān)系:

        main.o : main.c defs.h

    轉(zhuǎn)成:

        main.o main.d : main.c defs.h

    于是,我們的[.d]文件也會(huì)自動(dòng)更新了,并會(huì)自動(dòng)生成了,當(dāng)然,你還可以在這個(gè)[.d]文件中加入的不只是依賴關(guān)系,包括生成的命令也可一并加入,讓每個(gè)[.d]文件都包含一個(gè)完賴的規(guī)則。一旦我們完成這個(gè)工作,接下來(lái),我們就要把這些自動(dòng)生成的規(guī)則放進(jìn)我們的主Makefile中。我們可以使用Makefile的“include”命令,來(lái)引入別的Makefile文件(前面講過(guò)),例如:

        sources = foo.c bar.c

        include $(sources:.c=.d)

    上述語(yǔ)句中的“$(sources:.c=.d)”中的“.c=.d”的意思是做一個(gè)替換,把變量$(sources)所有[.c]的字串都替換成[.d],關(guān)于這個(gè)“替換”的內(nèi)容,在后面我會(huì)有更為詳細(xì)的講述。當(dāng)然,你得注意次序,因?yàn)閕nclude是按次來(lái)載入文件,最先載入的[.d]文件中的目標(biāo)會(huì)成為默認(rèn)目標(biāo)

    posted on 2009-05-17 17:14 so true 閱讀(1471) 評(píng)論(0)  編輯  收藏 所屬分類: C&C++

    主站蜘蛛池模板: 在线免费不卡视频| 国产亚洲欧美在线观看| 精品国产香蕉伊思人在线在线亚洲一区二区 | 中文字幕亚洲免费无线观看日本| 国产一级高清视频免费看| 精品国产污污免费网站aⅴ| 国产精品高清免费网站| 国产精品亚洲а∨天堂2021| 亚洲欧洲日本天天堂在线观看| 在线观看亚洲成人| 免费一级毛片正在播放| 日韩精品无码区免费专区| 无码国产精品一区二区免费3p| 中文在线观看国语高清免费| 国产亚洲视频在线播放大全| 自拍偷区亚洲国内自拍| 亚洲欧洲校园自拍都市| 亚洲国产精品国自产电影| 国产AV无码专区亚洲AV男同 | 亚洲 欧洲 日韩 综合在线| 亚洲视频在线观看视频| 亚洲国产精久久久久久久| 亚洲AV无码久久精品蜜桃| 伊人久久综在合线亚洲91| 国产精品亚洲αv天堂无码| jjzz亚洲亚洲女人| 国产一级理论免费版| 国产成人无码免费视频97| 成人免费无码大片a毛片软件| 中文字幕影片免费在线观看| 最近2022中文字幕免费视频| 最近免费中文字幕高清大全| 99视频在线免费| 99热精品在线免费观看| 国产精品免费AV片在线观看| 成人影片一区免费观看| 视频免费在线观看| 最好免费观看高清在线| 国内精品久久久久影院免费| 国产永久免费高清在线| 99久久综合精品免费|