精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

聊一聊構(gòu)建的抽象

開發(fā) 后端
不同編程語言編寫的應(yīng)用,在它運行的狀態(tài)下,會有不同的運行機制,有的是以二進制的方式運行的,有運行在編程語言的虛擬機之上。而構(gòu)建所做的事情呢,就是將那些我們寫給人類看的代碼,轉(zhuǎn)換為機器/程序能看懂的代碼。

[[341120]]

 最近,在研究 Gradle 和 Java 相關(guān)構(gòu)建的實現(xiàn),讓我對不同編程語言的應(yīng)用構(gòu)建燃起了一點點的興趣。

不同編程語言編寫的應(yīng)用,在它運行的狀態(tài)下,會有不同的運行機制,有的是以二進制的方式運行的,有運行在編程語言的虛擬機之上。而構(gòu)建所做的事情呢,就是將那些我們寫給人類看的代碼,轉(zhuǎn)換為機器/程序能看懂的代碼。所以,構(gòu)建的本質(zhì)就是翻譯(~~復(fù)讀機~~)。

PS:本文旨在嘗試性的整理我所了解的構(gòu)建知識。部分內(nèi)容限于對某一些編程語言的理解有限,并非非常準確。如有偏頗之此,希望大家指正。

引子 1:從 Java 的編譯說起

絕大多數(shù)程序員都是從 hello, world! 開始自己復(fù)制、粘貼的人生生涯。對于那些剛上手 Java 的程序員也是類似的:

  1. javac HelloWorld.java 

而當我們依賴于其它的軟件包時,就需要在編譯時和運行時加入 classpath 來加入依賴項。于是,對應(yīng)的運行命令就如下所示:

  1. java -classpath .:libs/joda-time-2.10.6.jar HelloWorld 

這樣,我們就能得到預(yù)期的結(jié)果了:

  1. Hello, World 
  2. Millisecond timein.getMillis(): 1599284014762 

而如果我們需要打成 jar 包就需要一個復(fù)雜一點的過程:

  1. jar cvfm hello.jar manifest.txt HelloWorld.class libs/* 

這個過程中,涉及到幾個關(guān)鍵的要素:

工具鏈。即 java 和 javac,以及對應(yīng)的 Runtime 等。

構(gòu)建過程。即我要先執(zhí)行 javac 進行編譯,再通過 java 命令來啟動應(yīng)用。

依賴管理。即我們的 joda-time-2.10.6.jar 的位置獲取等問題,以及在打包時加入的過程。

源碼配置。即轉(zhuǎn)換過程中的 class 和 java

過程中的輸入和輸出。

引子 2:任務(wù)及任務(wù)的輸入和輸出

對于一個制品的構(gòu)建來說,我們往往會把它拆分為一系列的任務(wù),每個任務(wù)有自己的輸入和輸出。當輸入發(fā)生變化的時候,需要變化對應(yīng)的輸出。緊接著,我們只需要對任務(wù)進行編排即可:

  1. exports.build = series( 
  2. clean, 
  3. parallel( 
  4. cssTranspile, 
  5. series(jsTranspile, jsBundle) 
  6. ), 
  7. parallel(cssMinify, jsMinify), 
  8. publish 
  9. ); 

如上展示的是:哪些任務(wù)可以并行,哪些任務(wù)需要按順序執(zhí)行——也可以認為是任務(wù)的依賴。

當然了,還有一種任務(wù)是 watch 任務(wù),只用于開發(fā)時,而非構(gòu)建時。如下是 Node.js 中的 Gulp 構(gòu)建工具的文件監(jiān)控示例:

  1. function javascript(cb) { 
  2. // body omitted 
  3. cb(); 
  4.  
  5. function scss(cb) { 
  6. // body omitted 
  7. cb(); 
  8.  
  9. watch('src/*.scss', scss); 
  10. watch('src/*.js', series(javascript)); 

兩間結(jié)合之下,我們就會看到增量任務(wù)的概念:只針對修改的部分進行編譯,以提升構(gòu)建效率。在這方面做得比較好的就是 Gradle ,看個官方的示例InputChanges:

  1. abstract class IncrementalReverseTask extends DefaultTask { 
  2. @Incremental 
  3. @InputDirectory 
  4. abstract DirectoryProperty getInputDir() 
  5.  
  6. @OutputDirectory 
  7. abstract DirectoryProperty getOutputDir() 
  8.  
  9. @TaskAction 
  10. void execute(InputChanges inputChanges) { 
  11. inputChanges.getFileChanges(inputDir).each { change -> 
  12. if (change.fileType == FileType.DIRECTORY) return 
  13.  
  14. def targetFile = outputDir.file(change.normalizedPath).get().asFile 
  15. if (change.changeType == ChangeType.REMOVED) { 
  16. targetFile.delete() 
  17. else { 
  18. targetFile.text = change.file.text.reverse() 

同樣的,它也需要我們監(jiān)控對應(yīng)的輸入和輸出。稍有不同的是,Gradle 會對文件進行索引,每次只提供變化的部分,讓我們根據(jù)自己的實際需要進行處理。

增量構(gòu)建相關(guān)資源:

  • tup 是用于 Linux、OSX 和 Windows 的基于文件的構(gòu)建系統(tǒng)。它輸入文件的更改列表和有向無環(huán)圖(DAG),然后處理DAG 以執(zhí)行更新依賴文件所需的適當命令。
  • ninja 是一個專注于速度的小型構(gòu)建系統(tǒng),類似于GNU Make。
  • SCons 是一套由Python 語言編寫的開源構(gòu)建系統(tǒng),類似于GNU Make。

引子 3:可選的依賴管理(地獄)

關(guān)于依賴的管理槽點,我已經(jīng)寫過一系列的文章,諸如于:管理依賴的 11 個策略、依賴孿生:低成本的依賴安全方案。

單純從構(gòu)建這件事情上,對于依賴的管理是可有可無的。出現(xiàn)這個狀況的主要原因是:歷史上的編程語言都不考慮這個問題。所以,在古老的 C/C++ 語言中,構(gòu)建系統(tǒng)就是一個頭疼的問題。當然了,新晉的 Golang 也缺少良好的設(shè)計。

好在,對于依賴管理來說,這個過程并不復(fù)雜:

  1. 包命名和版本機制
  2. 包管理服務(wù)器
  3. 構(gòu)建和運行時的依賴管理
  4. 包沖突處理
  5. ……

構(gòu)建的抽象

好了,有了上面的這一系列基礎(chǔ)知識之后,接下來我們就可以看看不同的構(gòu)建系統(tǒng)里,對于同一概念的抽象,整合了 Bazel、Gradle、Cargo、NPM 等之后有了一個基礎(chǔ)的抽象層次:

  • 工作空間(workspace)。工作空間是一個或者多個軟件包的集成,它們可以共享依賴、輸出目錄配置等等。典型的有 Java 中的 Gradle settings.gradle、Rust 中的 Cargo 的 Cargo.toml 等。
  • 倉庫。倉庫可以映射到 Git 的 repository 中,代表一個可獨立構(gòu)建的軟件。
  • 包。最小的可執(zhí)行單位的項目結(jié)構(gòu)。
  • 包布局。對應(yīng)于不同的語言、構(gòu)建系統(tǒng)來說,它用于定義代碼的存放位置和結(jié)構(gòu)。
  • 制品。即構(gòu)建產(chǎn)生的產(chǎn)物,可能是可復(fù)用的軟件包,也可能是可運行的應(yīng)用。
  • 任務(wù)。定義構(gòu)建的規(guī)則,并執(zhí)行。

FAQ

為什么是沒有項目?在業(yè)務(wù)領(lǐng)域和技術(shù)領(lǐng)域,我們對于項目的定義存在著一定的歧義性。為了減少二義性,我們使用工作空間 + 倉庫來解決這個問題。工作空間可以視為一個完整的業(yè)務(wù)項目。而倉庫呢,則是單一個的代碼庫,可能是一個庫,也可能是包含庫的完整工程。

現(xiàn)有的最佳方案是 Bazel。

工作區(qū)

工作空間是一個或者多個軟件包的集成,它們可以共享依賴、輸出目錄配置等等。典型的有 Java 中的 Gradle settings.gradle、Rust 中的 Cargo 的 Cargo.toml 等。

我們可以將其視為最終的產(chǎn)物,如 Android 生成的 APK,Rust 最后生成的可執(zhí)行文件。過程中,生成的共享的包都是為了支持這個工程的一部分。

先看 CMakeLists.txt 的目錄,我們在工作區(qū)的根節(jié)點,定義了這個工程,并添加了 projectA 和 projectB。

  1. cmake_minimum_required(VERSION 3.2.2) 
  2. project(globalProject) 
  3.  
  4. add_subdirectory(projectA) 
  5. add_subdirectory(projectB) 

以用于生成最后的構(gòu)建產(chǎn)物。相似的還有 Rust 中的 workspace:

  1. [workspace] 
  2.  
  3. members = [ 
  4. "adder"

又或者是前端的 Yarn 中的工作區(qū):

  1. "private"true
  2. "workspaces": ["workspace-a""workspace-b"

它們做的都是相同的事情。

倉庫

這個概念的再提取是來源于 Bazel。倉庫是一系列包的合集,我們可以將其視為團隊的邊界,從某種意義上可以看作是代碼倉庫。對于一個龐大的工程來說,它的代碼來源是多種多樣的,來自組織內(nèi)的其它團隊,來自組織外的其它團隊。每個獨立的部分,即是一個倉庫。

值得注意的是,從最終產(chǎn)物來看,每個團隊的產(chǎn)出都是倉庫,但是呢,在團隊內(nèi)部,他們就是工作區(qū)。

讓我們看個 Gradle 的多項目構(gòu)建示例(Android 工程):

  1. ├── README.md 
  2. ├── library_a 
  3. ├── app 
  4. │   ├── build.gradle 
  5. │   └── src 
  6. ├── build.gradle 
  7. ├── local.properties 
  8. ├── settings.gradle 
  9. └── third-partys 
  10. ├── ... 
  11. ├── build.gradle 
  12. └── settings.gradle 

從目錄結(jié)構(gòu)來看,這個是一個工作區(qū),而在工作區(qū)呢,它包含了一些三方的代碼倉庫(third-partys),以及自身的庫 library_a 和應(yīng)用 app。

因此,在這里的 library_a 和 third-partys 的各個項目都算是倉庫。

包是一系列代碼的合集,它可大可小。最主要的原因在于,因為構(gòu)建時,我們可能會把一個倉庫(哪怕是最小的 Gradle 項目)產(chǎn)出多個包,如 Java 項目中的 src/main 和 src/test。

于是在諸如 bazel 這樣的構(gòu)建工具中,支持自定義的包:

  1. src/my/app/BUILD 
  2. src/my/app/app.cc 
  3. src/my/app/data/input.txt 
  4. src/my/app/tests/BUILD 
  5. src/my/app/tests/test.cc 

對于一個包來說,往往我們還需要定義一系列的相關(guān)信息,如包名、依賴信息、入口等等。如 Bazel 中對于 Java 構(gòu)建的示例:

  1. java_binary( 
  2. name = "ProjectRunner"
  3. srcs = ["src/main/java/com/phodal/ProjectRunner.java"], 
  4. main_class = "com.phodal.ProjectRunner"
  5. deps = [":greeter"], 

這已經(jīng)實現(xiàn)了對于不同包的信息抽象。順帶的再看個 Java 包中的 MANIFEST 的示例:

  1. Main-Class: HelloWorld 
  2. Class-Path: libs/joda-time-2.10.6.jar 

我們就可以知道之間的聯(lián)系。

包定義

在打包階段,我們以簡單的形式定義了這個包——因為它并非那么重要,我們也不關(guān)心。而當我們決定發(fā)布這個包到互聯(lián)網(wǎng)時,我們就需要好好定義這個包。對應(yīng)的一些必要信息有:

  • name
  • version
  • authors
  • license
  • description
  • ……

這些信息用于在包管理中心展示,并向使用者提供包相關(guān)的信息等。不同的語言中使用的是不同的形式,Rust 使用了自定義的 toml,而諸如 Maven 倉庫中則使用了 XML:

  1. <groupId>...</groupId> 
  2. <artifactId>...</artifactId> 
  3. <version>...</version> 
  4. <packaging>...</packaging> 
  5. <dependencies>...</dependencies> 
  6. <name>...</name
  7. <description>...</description> 

類似的在 NPM 的 package.json 中也使用了類似的字段: name、 verison 等信息。

而在這些編程語言中,這個東西就設(shè)計得過于簡單了,如 Python 的 pip 中使用的 requirements.txt 來管理依賴,當你要發(fā)布包的時候使用 setup.py 進行配置。于是,你的應(yīng)用如果不發(fā)布,那就沒有包名了……。

包布局

構(gòu)建工具在設(shè)計的時候,會設(shè)計默認的軟件包分層結(jié)構(gòu),這個分層架構(gòu)就是包布局(package layout)。構(gòu)建工具通過這個布局,來獲取所需的輸入源和配置等信息。它也包含了一些默認的配置,如 src/main 指向了源碼的目錄, src/test 指向的是測試代碼(不會加入到制品中)

  1. ├── build.gradle 
  2. └── src 
  3. ├── main 
  4. └── test 

對于使用者來說,它們也可以針對于它們的需要擴展這個布局,如 Gradle 里的 SourceSets:

  1. sourceSets { 
  2. main { 
  3. output.resourcesDir = file('out/bin'
  4. java.outputDir = file('out/bin'

對于其它語言也是類似的。但是呢,對于某些語言來說,并非有這么強的關(guān)聯(lián),如在 Golang 中,就沒有這么強的約束。只是呢,原先是默認值,現(xiàn)在需要開發(fā)人員來手動配置。

制品

制品是最終的構(gòu)建產(chǎn)物。同樣的,在不同的語言中有不同的命名方式。在 Gradle 中稱為 artifacts,在 Rust 中稱為 targets……。制品,主要涉及到的是各種文件的流轉(zhuǎn)及其流轉(zhuǎn)規(guī)則。

舉個簡單的例子,一個 jar 文件中必須包含一個 MANIFEST.MF,以用于配置應(yīng)用程序、擴展和類裝載器等相關(guān)信息。而相關(guān)的文件又會以 META-INF 的方式組織起來。

因此在整個制品的創(chuàng)建過程中,就是復(fù)制對應(yīng)的文件,進行相應(yīng)的轉(zhuǎn)換,如 java -> .class,再復(fù)制到對應(yīng)的目錄,最后再打包在一起的過程。

任務(wù):規(guī)則引擎 + DSL

在上述我們看到的例子中,很多就是創(chuàng)建了自身的 DSL,而后用于構(gòu)建。只有這樣才能讓使用者得到最大的方便。這是一個相當復(fù)雜的過程,它相當于我們要設(shè)計一個和平臺、語言無關(guān)的 DSL。而這種演變方式有多種:

使用 API 抽象的內(nèi)部 DSL。諸如于 Webpack、Gulp 等實現(xiàn)。

自制的外部 DSL 語言。如 Gradle 所使用的 Groovy、多語言的 Bazel。

規(guī)則引擎本身是一組關(guān)于任務(wù)的 DSL,看個 Gradle 的例子:

  1. task copyReportsDirForArchiving2(type: Copy) { 
  2. from("$buildDir") { 
  3. include "reports/**" 
  4. into "$buildDir/toArchive" 

它所做的事情就是復(fù)制。對應(yīng)的 Gradle 打包示例也是蠻簡單的 DSL 抽象:

  1. task packageDistribution(type: Zip) { 
  2. archiveFileName = "my-distribution.zip" 
  3. destinationDirectory = file("$buildDir/dist"
  4.  
  5. from "$buildDir/toArchive" 

Gradle 使用的就是外部 DSL。再看看 Webpack 的打包示例:

  1. module.exports = { 
  2. entry: './path/to/my/entry/file.js'
  3. output: { 
  4. filename: 'my-first-webpack.bundle.js'
  5. path: path.resolve(__dirname, 'dist'
  6. }, 
  7. module: { 
  8. rules: [ 
  9. test: /\.(js|jsx)$/, 
  10. use: 'babel-loader' 
  11. }, 
  12. plugins: [ 
  13. new webpack.ProgressPlugin(), 
  14. new HtmlWebpackPlugin({template: './src/index.html'}) 
  15. }; 

這里的 rules 就是一個簡單的規(guī)則引擎(使用正則表達式來匹配)

兩種模式各自有自己的優(yōu)缺點,復(fù)雜場景下,使用 DSL + 自定義的腳本更容易完成。

PS:看來有空,我也應(yīng)該寫一個的規(guī)則引擎

構(gòu)建的擴展

對于主流的構(gòu)建系統(tǒng)來說,他們都支持不同形式的擴展支持:

  1. 外部 DSL 擴展
  2. 插件化的接口編程
  3. 項目內(nèi)編程語言擴展
  4. 項目外編程語言擴展

大部分的東西,我們已經(jīng)在文中的先前部分提到了,這里就不重復(fù)描述了。

結(jié)論

應(yīng)用的構(gòu)建是一個相當有意思的過程。

設(shè)計一個構(gòu)建系統(tǒng)也變得頗為有趣的。

參考資料:

  • Gradle vs Bazel for JVM Projects
  • Bazel: Concepts and terminology
  • Yarn: Workspaces
  • Gradle: Authoring Multi-Project Builds
  • Cargo: Workspaces
  • Gulp: Tasks

相關(guān)目的開源庫:

  • lerna A tool for managing JavaScript projects with multiple packages.
  • bazel
  • Blueprint is a meta-build system that reads in Blueprints files that describe modules that need to be built, and produces a Ninja manifest describing the commands that need to be run and their dependencies.

本文轉(zhuǎn)載自微信公眾號「phodal」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系phodal公眾號。

 

責任編輯:武曉燕 來源: Phodal
相關(guān)推薦

2021-11-24 22:47:07

Docker開發(fā)容器

2023-07-06 13:56:14

微軟Skype

2021-01-28 22:31:33

分組密碼算法

2020-05-22 08:16:07

PONGPONXG-PON

2023-09-22 17:36:37

2018-06-07 13:17:12

契約測試單元測試API測試

2021-08-01 09:55:57

Netty時間輪中間件

2023-09-27 16:39:38

2024-10-28 21:02:36

消息框應(yīng)用程序

2023-09-20 23:01:03

Twitter算法

2021-12-06 09:43:01

鏈表節(jié)點函數(shù)

2021-07-16 11:48:26

模型 .NET微軟

2021-03-01 18:37:15

MySQL存儲數(shù)據(jù)

2021-02-06 08:34:49

函數(shù)memoize文檔

2022-11-01 08:46:20

責任鏈模式對象

2023-05-15 08:38:58

模板方法模式

2021-01-29 08:32:21

數(shù)據(jù)結(jié)構(gòu)數(shù)組

2020-10-15 06:56:51

MySQL排序

2021-08-04 09:32:05

Typescript 技巧Partial

2022-08-08 08:25:21

Javajar 文件
點贊
收藏

51CTO技術(shù)棧公眾號

五月天丁香社区| 欧美精品尤物在线| 精品无码人妻一区二区三区| 九色丨蝌蚪丨成人| 日韩欧美aⅴ综合网站发布| 日韩高清专区| 午夜精品久久久久久久99热黄桃| 亚洲精品人人| x99av成人免费| 精品久久久久一区二区| 香蕉成人影院| 亚洲一区二区3| 午夜精品亚洲一区二区三区嫩草| va婷婷在线免费观看| 午夜一区二区三区不卡视频| 久久天天躁日日躁| 国产黄色网址在线观看| 精品国产乱码一区二区三区| 欧美日韩国产中文精品字幕自在自线 | 国产精品扒开做爽爽爽的视频| 粉嫩一区二区三区性色av| 国产精品九九九| av资源吧首页| 亚洲高清资源在线观看| 国产一区二区三区三区在线观看| 亚洲午夜精品在线观看| 99久久综合国产精品二区| 亚洲电影一级黄| 在线视频不卡一区二区| 男人久久精品| 成人激情视频网站| 亚洲一区二区三区乱码aⅴ| aaa在线视频| 亚洲精品1区| 久久综合免费视频| 日日操免费视频| 亚洲桃色综合影院| 亚洲国产福利在线| 亚洲欧洲日韩综合| 不卡的国产精品| 欧美在线999| 亚洲人成色77777| 国产福利电影在线播放| 亚洲国产精品天堂| 欧美日韩dvd| 国产激情在线视频| 国产精品少妇自拍| 欧美在线一二三区| 日本中文字幕电影在线观看 | 在线观看视频欧美| 一女被多男玩喷潮视频| 97人人在线视频| 亚洲欧美偷拍三级| 青青草影院在线观看| 日本激情视频在线观看| 国产ts变态重口人妖hd| 白嫩情侣偷拍呻吟刺激| 亚洲一区导航| 欧美在线不卡视频| 91激情视频在线| 四虎4545www国产精品| 色爱区综合激月婷婷| 国产淫片av片久久久久久| 欧美电影网站| 色悠久久久久综合欧美99| 国内外成人激情视频| 自拍视频在线看| 色综合久久综合网欧美综合网| 鲁一鲁一鲁一鲁一澡| 老牛影视精品| 日本高清免费不卡视频| 麻豆三级在线观看| 9999在线精品视频| 欧美xxxx老人做受| 国产精品无码一区二区三| 丝袜美腿一区二区三区动态图| 精品伊人久久97| 日本猛少妇色xxxxx免费网站| 日本一区二区三区视频| 久久av中文字幕| 日韩三级小视频| 久久精品男女| 成人国产精品久久久| 亚洲国产精彩视频| 久久这里只精品最新地址| 日韩国产欧美一区| 黄色成人在线观看| 亚洲成国产人片在线观看| 国产a视频免费观看| 亚洲欧美在线人成swag| 一区二区三区四区视频免费观看| 日本韩国欧美在线| 五月天av在线播放| 99久久香蕉| 亚洲色图av在线| 久久精品黄色片| 国产一区二区三区成人欧美日韩在线观看| 庆余年2免费日韩剧观看大牛| 中文字幕免费播放| 成人少妇影院yyyy| 偷拍视频一区二区| 国产黄色大片在线观看| 欧美亚洲一区二区在线观看| 亚洲成年人av| 成人一区而且| 国内揄拍国内精品少妇国语| 亚洲无码精品国产| aaa欧美色吧激情视频| 一区二区三区|亚洲午夜| 成年人在线网站| 正在播放一区二区| 免费看黄色的视频| 伊人成人在线视频| 成人在线国产精品| 久久久久国产精品嫩草影院| 亚洲综合一二三区| 伊人影院综合在线| 国产成人ay| 国内揄拍国内精品| 国产夫妻自拍av| 国产女主播一区| 色综合久久久久无码专区| 亚洲**毛片| 日韩少妇与小伙激情| 日本熟女毛茸茸| 91在线视频观看| 日韩免费在线观看av| 粉嫩一区二区三区在线观看| 中文字幕日韩精品在线观看| 好吊色在线视频| jvid福利写真一区二区三区| 日本黄网站色大片免费观看| 亚洲成a人片777777久久| 一区二区三区视频免费在线观看| 国产 欧美 日韩 在线| 国产999精品久久久久久绿帽| 在线综合视频网站| 成人在线免费电影网站| 亚洲欧洲第一视频| aaa在线视频| 久久综合久久鬼色| 日韩av综合在线观看| 国产极品模特精品一二| 久久久久久12| 亚洲国产日韩在线观看| 亚洲精品日日夜夜| 中文字幕第38页| 99精品美女| 91精品国产综合久久香蕉922| 波多野结衣在线影院| 欧美视频一区在线| 狂野欧美性猛交| 日本欧美一区二区三区乱码| 青青草原亚洲| 亚洲日本网址| 这里只有视频精品| 国产乱色精品成人免费视频| 日韩美女久久久| 天天综合成人网| 欧美成人亚洲| av激情久久| 国产福利电影在线播放| 亚洲人午夜精品免费| 国产精品免费无遮挡无码永久视频| 久久精品一区二区三区不卡| www.涩涩涩| 偷拍欧美精品| 成人自拍视频网站| 日韩在线伦理| 一区二区三区国产视频| 91九色蝌蚪91por成人| 亚洲美女视频在线观看| 亚洲妇女无套内射精| 国产欧美日韩一区二区三区在线| 美女视频久久| 国产a亚洲精品| 欧美www在线| 日本毛片在线观看| 欧美专区亚洲专区| 黄色一级免费视频| www精品美女久久久tv| 丰满少妇在线观看| 午夜视频一区| 欧美亚洲国产免费| 91成人福利社区| 97国产suv精品一区二区62| 国产最新视频在线| 欧美一级二级三级乱码| 天堂在线免费观看视频| 欧美高清在线一区二区| 国产chinesehd精品露脸| 日日噜噜夜夜狠狠视频欧美人| 91免费网站视频| 欧美色图婷婷| 成人乱色短篇合集| 91av亚洲| 九九久久久久99精品| 男人天堂资源在线| 精品卡一卡二卡三卡四在线| 午夜精品免费观看| 亚洲午夜久久久久久久久电影网| 日本二区在线观看| 丁香六月综合激情| 亚洲一级免费观看| 亚洲狼人精品一区二区三区| 中文字幕色一区二区| 亚洲国产国产| 99精彩视频在线观看免费| 搜成人激情视频| 午夜精品99久久免费| 国产激情视频在线观看| 国产亚洲成精品久久| 国产91绿帽单男绿奴| 欧美麻豆精品久久久久久| 天天操天天操天天操天天| 一区二区在线看| ass极品国模人体欣赏| 97久久久精品综合88久久| 色哟哟在线观看视频| 免费成人美女在线观看.| 国产91在线免费| 欧美特黄一区| 一级做a爰片久久| 欧美激情在线精品一区二区三区| 国产v亚洲v天堂无码| 国产日本亚洲| 国产精品综合不卡av| 成人啊v在线| 国产成人亚洲综合| 亚洲欧美一区二区三区| 91精品国产高清自在线| gratisvideos另类灌满| 欧美韩日一区二区| 永久免费网站在线| 久久亚洲精品网站| 免费黄色在线看| 色婷婷av一区二区三区久久| 国产福利小视频在线| 亚洲欧美综合图区| 久久精品色图| 一本色道久久综合亚洲精品小说| 欧美黄色小说| 亚洲免费小视频| 奇米影视888狠狠狠777不卡| 亚洲激情第一页| 亚洲人成色777777老人头| 亚洲国产另类 国产精品国产免费| 亚洲国产剧情在线观看| 精品va天堂亚洲国产| 天堂在线视频免费观看| 亚洲国产精品yw在线观看| 日本免费不卡视频| 亚洲黄一区二区| 黄色影院在线播放| 国产亚洲欧美日韩精品| 在线国产91| 久热精品视频在线观看一区| 成人video亚洲精品| 欧美美女操人视频| av第一福利在线导航| 欧美一级大片在线免费观看| 中文字幕在线免费观看视频| 国产精品久久久久福利| 国产精品第一国产精品| 成人h猎奇视频网站| 99久热这里只有精品视频免费观看| 99视频在线播放| 精品亚洲自拍| 日韩福利影院| 在线成人激情| 国产3p露脸普通话对白| 石原莉奈在线亚洲三区| 亚洲娇小娇小娇小| 国产91精品在线观看| 国产精品无码一区二区三区免费| 国产欧美日韩不卡免费| 91免费公开视频| 亚洲国产精品天堂| 国产无遮挡又黄又爽又色视频| 欧美乱妇20p| 天堂在线观看视频| 色偷偷91综合久久噜噜| 色呦呦视频在线观看| 欧美最猛性xxxx| 欧美性aaa| 久草一区二区| 国产精品x453.com| 日日摸日日碰夜夜爽无码| 日本在线不卡视频| 女同性αv亚洲女同志| 久久久久国产精品免费免费搜索| 日韩在线不卡av| 精品国产乱码久久久久久虫虫漫画| 一级久久久久久| 精品少妇一区二区三区日产乱码| 户外极限露出调教在线视频| 欧美美最猛性xxxxxx| 亚洲精品粉嫩美女一区| 99国产超薄丝袜足j在线观看 | 91传媒视频免费| 亚洲日产av中文字幕| 天堂а√在线中文在线| 欧美老肥妇做.爰bbww| 国产一级淫片a视频免费观看| 91精品婷婷国产综合久久性色| 亚洲欧美丝袜中文综合| 日韩在线欧美在线| 久久影院午夜精品| 亚洲iv一区二区三区| 亚洲区小说区图片区qvod按摩| 亚洲第一精品区| 日日夜夜免费精品| 欧美日韩一区二区三区四区五区六区 | 久久久久久久91| 黄色成人在线视频| 久久综合九九| 国内精品久久久久国产盗摄免费观看完整版| 粉嫩虎白女毛片人体| 91一区二区在线| 农村妇女精品一区二区| 欧美视频一二三区| 免费在线超碰| 91成品人片a无限观看| 日本一区二区乱| 一区二区免费在线观看| 日日嗨av一区二区三区四区| 日韩aaaaa| 亚洲一区二区在线免费看| 国产女人18毛片18精品| 女人高潮一级片| 欧美a级理论片| 大地资源二中文在线影视观看| 亚洲激情图片小说视频| 中文字幕在线日亚洲9| 亚洲欧美国产日韩中文字幕| √8天堂资源地址中文在线| 91亚洲国产精品| 久久国产精品亚洲人一区二区三区| 亚洲乱码中文字幕久久孕妇黑人| 成人免费视频视频在线观看免费| 欧美另类视频在线观看| 欧美一区二区视频免费观看| 麻豆视频在线观看免费| 国产精品欧美亚洲777777 | 日韩精品一区二区三区四区五区| 国产精品久久777777毛茸茸| 亚洲一区二区三区四区五区六区| 亚洲国产精品久久久久秋霞影院| 亚洲第一视频在线播放| 欧美大片在线看免费观看| 精品一区二区三区免费看| 91精品国产吴梦梦| 国产精品亚洲专一区二区三区| 欧美激情精品久久| 欧美xxxx老人做受| 丁香花电影在线观看完整版| 精品国产一区二区三区麻豆小说 | 性欧美1819| 最新成人av在线| 国产黄色av片| 久久久久中文字幕| 六月丁香久久丫| 日韩有码免费视频| 国产精品久久久久影视| 国产免费的av| 国产做受高潮69| 久久99蜜桃| 国产美女18xxxx免费视频| 亚洲欧美一区二区久久| 人妻少妇一区二区三区| 日本国产一区二区三区| 久久福利影院| 中国特级黄色片| 欧美性猛交xxxx免费看漫画| www.亚洲资源| 不卡一卡2卡3卡4卡精品在| 国产亚洲精品久久久久婷婷瑜伽| 中文字幕第20页| 7777精品伊人久久久大香线蕉完整版| 午夜在线激情影院| 久久综合久久久| 老司机精品视频在线| 久久久久久久蜜桃| 亚洲人成网在线播放| www.久久爱.com| 男人亚洲天堂网| 自拍偷拍亚洲欧美日韩| 亚洲欧洲综合在线| 成人妇女免费播放久久久| 亚洲伦伦在线| 小早川怜子一区二区的演员表| 欧美精品一区二| 另类一区二区三区| 欧美 日本 亚洲| 亚洲精品亚洲人成人网在线播放| 青青青草原在线| 99久久精品久久久久久ai换脸| 日本欧美一区二区在线观看| 国产精品99精品无码视| 色噜噜狠狠狠综合曰曰曰88av|