日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Blade构建工具

發(fā)布時(shí)間:2023/12/20 编程问答 87 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Blade构建工具 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.簡(jiǎn)介

Blade是騰訊為了解決GNU Make使用繁瑣的問(wèn)題而開(kāi)發(fā)的一個(gè)開(kāi)源構(gòu)建工具,旨在簡(jiǎn)化大型項(xiàng)目的構(gòu)建,能夠自動(dòng)分析依賴,集成了編譯、鏈接、測(cè)試、靜態(tài)代碼檢查等功能,支持C/C++, Java, Python, Scala, protobuf等多種語(yǔ)言(主要面向C/C++)(借鑒自Bazel)。

注意:構(gòu)建(build)和編譯(compile)不同——編譯器負(fù)責(zé)將源代碼轉(zhuǎn)換為庫(kù)文件或可執(zhí)行文件;構(gòu)建工具負(fù)責(zé)分析構(gòu)建目標(biāo)之間的依賴關(guān)系,并調(diào)用編譯器來(lái)生成構(gòu)建目標(biāo)。

例如,自己的代碼依賴A庫(kù),A庫(kù)又依賴B庫(kù),如果手動(dòng)編譯則需要寫(xiě)復(fù)雜的編譯和鏈接命令,當(dāng)依賴庫(kù)代碼發(fā)生變化時(shí)還需要重新編譯,構(gòu)建工具旨在自動(dòng)化這一過(guò)程。

  • 項(xiàng)目主頁(yè):https://github.com/chen3feng/blade-build
  • 官方文檔:https://github.com/chen3feng/blade-build/blob/master/doc/en/README.md
  • 用戶手冊(cè):https://github.com/chen3feng/blade-build/blob/master/doc/blade_user_manual.pdf
  • 介紹ppt:https://github.com/chen3feng/blade-build/blob/master/doc/blade.pdf

特性:

  • 自動(dòng)分析庫(kù)之間的依賴關(guān)系
  • 遞歸構(gòu)建:當(dāng)依賴庫(kù)的源文件發(fā)生變化時(shí)會(huì)自動(dòng)重新構(gòu)建依賴庫(kù),而GNU Make無(wú)法實(shí)現(xiàn)遞歸構(gòu)建
  • 增量構(gòu)建:未發(fā)生變化的依賴庫(kù)不會(huì)重新構(gòu)建,加快構(gòu)建速度
  • 提供了對(duì)protobuf和測(cè)試(使用gtest)的內(nèi)置支持

2.依賴軟件

Blade需要以下依賴:

  • Linux或Mac操作系統(tǒng)
  • Python 2.7
  • Ninja 1.8+

構(gòu)建特定語(yǔ)言所需的編譯器:

  • C/C++: GCC 4.0+
  • Java: JDK 1.6+
  • Scala: 2.10+

3.安裝

3.1 安裝Python

Linux或Mac系統(tǒng)默認(rèn)已經(jīng)安裝了Python 2.7。

3.2 安裝Ninja

下載地址:https://github.com/ninja-build/ninja/releases

解壓后只有一個(gè)可執(zhí)行文件ninja,將其放到PATH環(huán)境變量包含的某個(gè)目錄下(例如/usr/local/bin),從而能夠直接在命令行中直接執(zhí)行ninja命令:

$ ninja --version 1.10.2

3.3 安裝Blade

安裝方式:下載源代碼,執(zhí)行install腳本

$ git clone https://github.com/chen3feng/blade-build.git $ cd blade-build/ $ git checkout v2.0 $ ./install

執(zhí)行完成后Blade將被安裝在~/bin目錄下,該目錄也被添加到PATH環(huán)境變量,執(zhí)行source ~/.profile命令或重啟終端使其生效,此時(shí)應(yīng)該能夠在命令行中直接執(zhí)行blade命令:

$ blade -h usage: blade [-h] [--version] {build,run,test,clean,query,dump} ...blade <subcommand> [options...] [targets...] ...

注意:不能刪除blade-build目錄,因?yàn)閎lade命令會(huì)用到其中的源代碼。

4.簡(jiǎn)單示例

下面使用Blade創(chuàng)建一個(gè)Hello World項(xiàng)目。

官方文檔:https://github.com/chen3feng/blade-build/blob/master/doc/en/quick_start.md

4.1 創(chuàng)建工作目錄

首先創(chuàng)建項(xiàng)目根目錄blade-demo和一個(gè)子目錄quick-start:

mkdir blade-demo && cd blade-demo touch BLADE_ROOT mkdir quick-start

其中項(xiàng)目根目錄blade-demo可以在任意位置,BLADE_ROOT文件用于標(biāo)識(shí)項(xiàng)目根目錄。

4.2 實(shí)現(xiàn)say庫(kù)

在quick-start目錄下創(chuàng)建say.h和say.cc兩個(gè)文件,內(nèi)容如下:

say.h

#pragma once #include <string>// Say a message void Say(const std::string& msg);

say.cc

#include "quick-start/say.h"#include <iostream>void Say(const std::string& msg) {std::cout << msg << "!\n"; }

這兩個(gè)文件組成了一個(gè)庫(kù)(library),可以將其編譯為庫(kù)文件供其他代碼使用。創(chuàng)建一個(gè)BUILD文件來(lái)描述say庫(kù):

cc_library(name = 'say',srcs = 'say.cc',hdrs = 'say.h', )

其中cc_library表示該構(gòu)建目標(biāo)是一個(gè)C++庫(kù),srcs為源文件,hdrs為公共接口頭文件。

4.3 實(shí)現(xiàn)hello庫(kù)

下面創(chuàng)建另一個(gè)庫(kù)hello,并調(diào)用say庫(kù)提供的函數(shù)。

在quick-start目錄下創(chuàng)建hello.h和hello.cc兩個(gè)文件,內(nèi)容如下:

hello.h

#pragma once #include <string>// Say hello to `to` void Hello(const std::string& to);

hello.cc

#include "quick-start/hello.h"#include "quick-start/say.h"void Hello(const std::string& to) {Say("Hello, " + to); }

其中函數(shù)Hello()調(diào)用了say庫(kù)提供的函數(shù)Say(),因此hello庫(kù)依賴say庫(kù)

在BUILD文件中添加hello庫(kù)的定義:

cc_library(name = 'hello',srcs = 'hello.cc',hdrs = 'hello.h',deps = ':say', )

其中deps為該構(gòu)建目標(biāo)的依賴,:say表示當(dāng)前BUILD文件中名為say的構(gòu)建目標(biāo),即前面的say庫(kù)。

4.4 實(shí)現(xiàn)hello_world程序

下面創(chuàng)建一個(gè)hello_world程序,在main()函數(shù)中調(diào)用hello庫(kù)提供的函數(shù)來(lái)打印信息。

創(chuàng)建源文件hello_world.cc,內(nèi)容如下:

#include "quick-start/hello.h"int main() {Hello("World");return 0; }

在BUILD文件中添加hello_world的定義:

cc_binary(name = 'hello_world',srcs = 'hello_world.cc',deps = ':hello', )

cc_binary表示該構(gòu)建目標(biāo)是一個(gè)可執(zhí)行程序。

注意:依賴只需要添加:hello,而不需要添加:say,因?yàn)檫@是hello庫(kù)的實(shí)現(xiàn)細(xì)節(jié),在編譯和鏈接過(guò)程中Blade會(huì)自動(dòng)處理這樣的傳遞依賴。但是,如果hello_world.cc中顯式包含了say.h,則依賴中需要添加:say。

下面構(gòu)建并運(yùn)行hello_world程序:

$ cd quick-start $ blade build :hello_world $ blade run :hello_world Hello, World!

blade build命令底層了調(diào)用g++編譯器和ld鏈接器,可使用--verbose參數(shù)查看具體執(zhí)行的命令,生成的庫(kù)文件和可執(zhí)行文件在build64_release目錄下。

注:對(duì)于這個(gè)簡(jiǎn)單的示例,直接執(zhí)行

g++ -o hello_world hello_world.cc hello.cc say.cc

即可完成編譯,但是對(duì)于具有成百上千個(gè)源文件、包含很多模塊的大型項(xiàng)目,使用構(gòu)建工具就很有必要了。

完整的項(xiàng)目目錄結(jié)構(gòu)如下:

blade-demo/BLADE_ROOTquick-start/BUILDsay.hsay.cchello.hhello.cchello_world.ccbuild64_release/ # Blade自動(dòng)創(chuàng)建quick-start/libsay.a # say庫(kù)libhello.a # hello庫(kù)hello_world # 可執(zhí)行程序...

注:該示例只有quick-start一個(gè)子目錄和一個(gè)BUILD文件。實(shí)際的項(xiàng)目會(huì)按模塊將文件分為多個(gè)不同的子目錄,每個(gè)子目錄下都包含一個(gè)BUILD文件。

完整代碼:https://github.com/chen3feng/blade-build/blob/master/example/quick-start

5.代碼組織結(jié)構(gòu)

Blade要求項(xiàng)目有一個(gè)顯式的根目錄,即BLADE_ROOT文件所在目錄。根目錄下是自己的模塊子目錄和第三方庫(kù)目錄,每個(gè)子目錄下都有一個(gè)BUILD文件來(lái)聲明該模塊所包含的構(gòu)建目標(biāo)。

以下是一個(gè)示例目錄結(jié)構(gòu):

my-project/BLADE_ROOTcommon/string/BUILDalgorithm.halgorithm.ccfoo/BUILDfoo.hfoo.ccthirdparty/gtest/BUILDgtest.hgtest.cc...

注:這是Google推薦的源代碼管理方式——將所有代碼放在同一個(gè)倉(cāng)庫(kù)中,包括第三方庫(kù)源代碼。

源文件中包含頭文件的相對(duì)路徑是基于項(xiàng)目根目錄的,因此#include "quick-start/say.h"包含的是blade-demo/quick-start/say.h。雖然對(duì)于相同目錄下的頭文件來(lái)說(shuō)這樣有些繁瑣(寫(xiě)成#include "say.h"即可),但對(duì)于跨目錄包含的頭文件來(lái)說(shuō)這樣可以清楚地知道頭文件所在位置。例如,在上面的目錄結(jié)構(gòu)中,要在foo.cc中包含algorithm.h,直接寫(xiě)#include "common/string/algorithm.h"即可,而不必寫(xiě)成#include "../common/string/algorithm.h。

6.BUILD文件

Blade通過(guò)名為BUILD(全部大寫(xiě))的文件聲明構(gòu)建目標(biāo),構(gòu)建目標(biāo)可以是庫(kù)、可執(zhí)行文件、測(cè)試等,由若干源文件(和頭文件)組成。

構(gòu)建目標(biāo)可以相互依賴。在BUILD文件中只需要目標(biāo)的直接依賴,Blade將自動(dòng)分析傳遞依賴關(guān)系,并調(diào)用編譯器和鏈接器來(lái)生成構(gòu)建目標(biāo),構(gòu)建一個(gè)目標(biāo)時(shí)會(huì)先構(gòu)建其依賴的目標(biāo)。

6.1 示例

假設(shè)common/string目錄下定義了一些字符串輔助函數(shù),并且依賴common/int目錄下的int庫(kù),則common/string/BUILD文件如下:

cc_library(name = 'string',srcs = ['algorithm.cc','concat.cc','format.cc',],hdrs = ['algorithm.h','concat.h','format.h',],deps = ['//common/int:int',], )

其他構(gòu)建目標(biāo)通過(guò)'//common/string:string'引用該目標(biāo)。

注:當(dāng)srcs、hdrs或deps有多個(gè)時(shí),可以使用列表[](BUILD文件實(shí)際上就是Python函數(shù)調(diào)用)

6.2 風(fēng)格建議

  • 縮進(jìn)4個(gè)空格
  • 使用單引號(hào)而不是雙引號(hào)
  • 目標(biāo)名稱使用小寫(xiě)
  • srcs中的文件按字母順序排列
  • deps先寫(xiě)當(dāng)前目錄下的依賴(:name),再寫(xiě)其他目錄下的依賴(//path/to/dir:name),按字母順序排列
  • 當(dāng)每行一個(gè)參數(shù)時(shí),最后一個(gè)參數(shù)也以逗號(hào)結(jié)尾,從而減少當(dāng)增加或刪除參數(shù)時(shí)影響的行數(shù)
  • 不同目標(biāo)之間空一行,每個(gè)目標(biāo)前添加注釋,注釋以#開(kāi)頭

6.3 構(gòu)建目標(biāo)

Blade支持多種語(yǔ)言,每種語(yǔ)言支持多種構(gòu)建目標(biāo)。以下是幾種常用的構(gòu)建目標(biāo)的語(yǔ)法。

完整列表參考:https://github.com/chen3feng/blade-build/blob/master/doc/en/build_file.md#build-rules

公共屬性:

  • name:字符串,指定構(gòu)建目標(biāo)的名稱,和路徑一起構(gòu)成目標(biāo)的唯一標(biāo)識(shí)
  • srcs:字符串列表,指定源文件,位于當(dāng)前目錄或當(dāng)前目錄的子目錄下,可使用glob函數(shù)
  • hdrs:字符串列表,指定公共接口頭文件
  • deps:字符串列表,指定依賴目標(biāo),支持以下格式:
    • //path/to/dir:name:項(xiàng)目根目錄下path/to/dir/BUILD文件中聲明的名為name的目標(biāo)
    • :name:當(dāng)前BUILD文件中名為name的目標(biāo)
    • #name:系統(tǒng)庫(kù),例如#pthread將添加鏈接選項(xiàng)-lpthread
  • visibility:字符串列表,僅對(duì)列出的目標(biāo)可見(jiàn)(格式見(jiàn)7.2節(jié)),可使用特殊值'PUBLIC'指定對(duì)所有目標(biāo)可見(jiàn)
    • 在Blade 2中,目標(biāo)默認(rèn)是私有的,即只對(duì)當(dāng)前目錄下的目標(biāo)可見(jiàn)

注:類型為字符串列表的屬性如果只有一項(xiàng)則可省略中括號(hào),例如srcs = ['foo.cc']等價(jià)于srcs = 'foo.cc'。

6.3.1 C++

6.3.1.1 cc_library

構(gòu)建C++庫(kù)文件。語(yǔ)法(僅包含了常用屬性):

cc_library(name = 'foo',srcs = ['foo.cc', 'bar.cc', ...],hdrs = ['foo.h', 'bar.h', ...],deps = [':name', '//path/to/dir:name', ...], )

注:

  • 公共接口頭文件應(yīng)聲明在hdrs中,私有頭文件應(yīng)聲明在srcs中。如果通過(guò)#include包含了一個(gè)頭文件,則應(yīng)該將該頭文件所屬的庫(kù)添加到deps中。
  • 默認(rèn)只生成靜態(tài)鏈接庫(kù)文件(.a),如果在blade build時(shí)指定--generate-dynamic選項(xiàng),或依賴該目標(biāo)的cc_binary指定了dynamic_link = True,則生成動(dòng)態(tài)鏈接庫(kù)文件(.so)。

6.3.1.2 cc_binary

構(gòu)建C++可執(zhí)行文件。語(yǔ)法:

cc_binary(name = 'foo',srcs = ['foo.cc', 'bar.cc', ...],deps = [':name', '//path/to/dir:name', ...],dynamic_link = False, )
  • dynamic_link:布爾值(默認(rèn)為False),如果為T(mén)rue則使用動(dòng)態(tài)鏈接,生成的可執(zhí)行文件較小,但啟動(dòng)較慢
    • 注:如果使用動(dòng)態(tài)鏈接,則生成的可執(zhí)行文件必須使用blade run執(zhí)行,或者在項(xiàng)目根目錄下執(zhí)行,否則會(huì)找不到庫(kù)文件

6.3.1.3 cc_test

構(gòu)建C++單元測(cè)試,使用GoogleTest測(cè)試框架,本質(zhì)上就是自動(dòng)鏈接了gtest和gtest_main的cc_binary。語(yǔ)法:

cc_test(name = 'foo_test',srcs = 'foo_test.cc',deps = [':foo', ...],testdata = testdata = ['data1.txt', '//path/to/data2.txt'], )
  • testdata:字符串列表,測(cè)試代碼只能訪問(wèn)列表指定的文件(例如測(cè)試數(shù)據(jù))

具體用法見(jiàn)8.1節(jié)。

6.3.2 Protobuf

6.3.2.1 proto_library

構(gòu)建protobuf庫(kù),使用protoc編譯器。語(yǔ)法:

proto_library(name = 'foo_proto',srcs = 'foo.proto',deps = [':bar_proto', ...],target_languages = ['cpp', 'java', 'python'], )
  • target_languages:字符串列表,生成指定語(yǔ)言的源代碼。默認(rèn)只生成C++代碼,當(dāng)protobuf庫(kù)被其他構(gòu)建目標(biāo)依賴,或者blade build指定了--generate-*選項(xiàng)時(shí)也會(huì)生成對(duì)應(yīng)語(yǔ)言的代碼。例如,如果被java_library目標(biāo)依賴,或指定了--generate-java選項(xiàng),則會(huì)生成Java代碼,對(duì)應(yīng)protoc編譯器的--java_out選項(xiàng)。

具體示例見(jiàn)Protocol Buffers入門(mén)教程 3.1.7.1 (3)和4.1.2節(jié)。

6.3.3 Java

(官方文檔很不全,很多細(xì)節(jié)根本沒(méi)有說(shuō)明)

6.3.3.1 maven_jar

表示Maven倉(cāng)庫(kù)中的一個(gè)jar文件。語(yǔ)法:

maven_jar(name = 'commons-lang3',id = 'org.apache.commons:commons-lang3:3.12.0',transitive = True )
  • id:字符串,指定Maven id,格式為groupId:artifactId:version,見(jiàn)Maven Naming Conventions
  • transitive:布爾值(默認(rèn)為T(mén)rue),指定該目標(biāo)被打包僅fat jar時(shí)是否包含傳遞依賴,不影響編譯和測(cè)試分析傳遞依賴

直接構(gòu)建該目標(biāo)將什么都不做,只有其他目標(biāo)依賴該目標(biāo)時(shí)才會(huì)下載jar文件。

6.3.3.2 java_library

從Java源代碼構(gòu)建jar文件。語(yǔ)法:

java_library(name = 'Foo',srcs = ['Foo.java', 'Bar.java', ...],resources = ['resources/foo.conf', ...],deps = [':name', '//path/to/dir:name', ...],exported_deps = [':name', '//path/to/dir:name', ...],provided_deps = [':name', '//path/to/dir:name', ...], )
  • resources:字符串列表,指定要打包進(jìn)jar的資源文件
  • deps:字符串列表,指定依賴目標(biāo),無(wú)傳遞性
  • exported_deps:字符串列表,指定導(dǎo)出依賴目標(biāo),有傳遞性
  • provided_deps:字符串列表,指定由運(yùn)行環(huán)境提供的依賴(例如Hadoop、Spark等)
    • 如果當(dāng)前目標(biāo)被java_binary、java_test、java_fat_library或scala_fat_library目標(biāo)依賴或傳遞依賴,則provided_deps及其上游依賴不會(huì)被打包進(jìn)上述目標(biāo)中。

生成的jar文件名為name.jar,僅包含類文件,不包含依賴。srcs和resources支持glob()函數(shù)。三種依賴的區(qū)別詳見(jiàn)6.3.3.6節(jié)。

6.3.3.3 java_binary

從Java源代碼構(gòu)建可執(zhí)行jar文件,包含依賴。語(yǔ)法:

java_binary(name = 'Foo',srcs = ['Foo.java', 'Bar.java', ...],resources = ['resources/foo.conf', ...],deps = [':name', '//path/to/dir:name', ...],main_class = 'foo.Foo',exclusions = ['org.slf4j:*:*', 'org.apache.hadoop:*:*', ...], )
  • main_class:字符串,指定程序入口類(全名)
  • exclusions:字符串列表,指定要排除的依賴庫(kù),格式為Maven id,支持通配符*

生成的jar文件名為name.one.jar,包含類文件、依賴、傳遞依賴以及資源文件各自生成的jar。

One-JAR是一個(gè)用于將Java應(yīng)用及其依賴打包為單個(gè)可執(zhí)行jar文件的開(kāi)源項(xiàng)目。構(gòu)建java_binary目標(biāo)需要提前下載one-jar-boot-0.97.jar,并將其所在路徑添加到BLADE_ROOT文件的one_jar_boot_jar配置中:

java_binary_config(one_jar_boot_jar = '/path/to/one-jar-boot-0.97.jar' )

否則會(huì)報(bào)錯(cuò) “Blade(error): Blade build tool java_onejar error: [Errno 2] No such file or directory: ‘’”。

6.3.3.4 java_fat_library

從Java源代碼構(gòu)建fat jar文件。語(yǔ)法:

java_fat_library(name = 'Foo',srcs = ['Foo.java', 'Bar.java', ...],resources = ['resources/foo.conf', ...],deps = [':name', '//path/to/dir:name', ...],exclusions = ['org.slf4j:*:*', 'org.apache.hadoop:*:*', ...], )

生成的jar文件名為name.fat.jar。

Fat jar(也叫uber jar)即包含依賴的jar,類似于Maven的jar-with-dependencies。Fat jar與one-jar的區(qū)別是:fat jar將所有子jar的內(nèi)容提取出來(lái)聚合成一個(gè)超級(jí)jar,而one-jar中每個(gè)子jar單獨(dú)存在。

通過(guò)exclusions和上游java_library依賴的provided_deps可以排除最終打包到fat jar中的依賴庫(kù),可以減小fat jar文件的大小,避免與運(yùn)行環(huán)境的依賴沖突。

6.3.3.5 java_test

從Java源代碼構(gòu)建JUnit測(cè)試jar文件。語(yǔ)法:

java_test(name = 'FooTest',srcs = ['FooTest.java', ...],resources = ['resources/foo.conf', ...],deps = [':Foo', ...],exclusions = ['org.slf4j:*:*', 'org.apache.hadoop:*:*', ...],testdata = testdata = ['data1.txt', '//path/to/data2.txt'], )

具體用法見(jiàn)8.2節(jié)。

6.3.3.6 Java的依賴處理

  • 編譯依賴 = 直接依賴 + 直接依賴的導(dǎo)出依賴 + 導(dǎo)出依賴的遞歸導(dǎo)出依賴 + Maven依賴的傳遞依賴
  • 測(cè)試依賴 = 直接依賴 + 直接依賴的所有傳遞依賴 + Maven依賴的傳遞依賴
  • 打包依賴 = 直接依賴 - provided依賴 + (直接依賴 - provided依賴)的打包依賴 - exclusions

6.3.3.7 示例

下面用Java實(shí)現(xiàn)第4節(jié)中的Hello World示例。

Say.java

package hello;public class Say {public static void say(String msg) {System.out.println(msg);} }

Hello.java

package hello;public class Hello {public static void hello(String to) {Say.say("Hello, " + to);} }

HelloWorld.java

package hello;public class HelloWorld {public static void main(String[] args) {Hello.hello("world");} }

BUILD

java_library(name = 'Say',srcs = 'Say.java', )java_library(name = 'Hello',srcs = 'Hello.java',deps = ':Say', )java_binary(name = 'HelloWorld',srcs = 'HelloWorld.java',deps = ':Hello',main_class = 'hello.HelloWorld', )java_fat_library(name = 'HelloWorldFat',srcs = 'HelloWorld.java',deps = ':Hello', )

BLADE_ROOT中需要添加one_jar_boot_jar配置,如6.3.3.3節(jié)所述。

目錄結(jié)構(gòu):

blade-demo/BLADE_ROOTjava/hello/BUILDSay.javaHello.javaHelloWorld.java

在blade-demo/java/hello目錄下執(zhí)行

blade build :HelloWorld :HelloWorldFat

則在blade-demo/build64_release/java/hello目錄下會(huì)生成HelloWorld.one.jar和HelloWorldFat.fat.jar兩個(gè)文件:

$ jar tf HelloWorld.one.jar META-INF/ META-INF/MANIFEST.MF OneJar.class com/simontuffs/onejar/JarClassLoader.class ... main/HelloWorld.jar lib/Hello.jar lib/Say.jar$ jar tf HelloWorldFat.fat.jar META-INF/ hello/ hello/HelloWorld.class hello/Hello.class hello/Say.class META-INF/blade/JAR.LIST META-INF/blade/MERGE-INFO META-INF/MANIFEST.MF

要運(yùn)行程序,可以使用blade run命令,直接執(zhí)行one-jar,或者使用fat jar手動(dòng)指定類路徑。可以在blade-demo/java/hello目錄下執(zhí)行

$ blade run :HelloWorld ... Blade(info): Run '['.../blade-demo/build64_release/java/hello/HelloWorld']' Hello, world

或者在blade-demo/build64_release/java/hello目錄下執(zhí)行

$ java -jar HelloWorld.one.jar Hello, world$ java -cp Say.jar:Hello.jar:HelloWorld.jar hello.HelloWorld Hello, world$ java -cp HelloWorldFat.fat.jar hello.HelloWorld Hello, world

注:

  • deps不具有傳遞性:如果HelloWorld類直接使用了Say類,則必須將:Say也添加到目標(biāo)HelloWorld的依賴中,或者將:Say添加到目標(biāo)Hello的exported_deps中。
  • 如果目標(biāo)Hello的依賴:Say聲明為provided_deps,則Say.class不會(huì)被打包到HelloWorldFat.fat.jar中,因此最后一種運(yùn)行方式需要將Say.jar也添加到類路徑。
  • 該示例并沒(méi)有采用Maven標(biāo)準(zhǔn)目錄結(jié)構(gòu)。盡管習(xí)慣上按照包名組織Java源代碼的目錄結(jié)構(gòu),但Java編譯器并沒(méi)有強(qiáng)制要求(但輸出的.class文件的目錄結(jié)構(gòu)必須與包名一致)。

6.3.4 Scala

Scala構(gòu)建目標(biāo)和Java構(gòu)建目標(biāo)基本一致,但沒(méi)有scala_binary。

6.3.4.1 scala_library

從Scala源代碼構(gòu)建jar文件。語(yǔ)法:

scala_library(name = 'Foo',srcs = ['Foo.scala', 'Bar.scala', ...],resources = ['resources/foo.conf', ...],deps = [':name', '//path/to/dir:name', ...],exported_deps = [':name', '//path/to/dir:name', ...],provided_deps = [':name', '//path/to/dir:name', ...], )

6.3.4.2 scala_fat_library

從Scala源代碼構(gòu)建fat jar文件。語(yǔ)法:

scala_fat_library(name = 'Foo',srcs = ['Foo.scala', 'Bar.scala', ...],resources = ['resources/foo.conf', ...],deps = [':name', '//path/to/dir:name', ...],exclusions = ['org.slf4j:*:*', 'org.apache.hadoop:*:*', ...], )

6.3.4.3 scala_test

從Scala源代碼構(gòu)建scala-test測(cè)試jar文件。語(yǔ)法:

scala_test(name = 'FooTest',srcs = ['FooTest.scala', ...],resources = ['resources/foo.conf', ...],deps = [':Foo', ...],exclusions = ['org.slf4j:*:*', 'org.apache.hadoop:*:*', ...],testdata = testdata = ['data1.txt', '//path/to/data2.txt'], )

具體用法見(jiàn)8.3節(jié)。

6.3.4.4 示例

下面用Scala實(shí)現(xiàn)第4節(jié)中的Hello World示例。

Say.scala

package helloobject Say {def say(msg: String): Unit = println(msg) }

Hello.scala

package helloobject Hello {def hello(to: String): Unit = Say.say("Hello, " + to) }

HelloWorld.scala

package helloobject HelloWorld {def main(args: Array[String]): Unit = Hello.hello("world") }

BUILD

scala_library(name = 'Say',srcs = 'Say.scala', )scala_library(name = 'Hello',srcs = 'Hello.scala',deps = ':Say', )scala_fat_library(name = 'HelloWorldFat',srcs = 'HelloWorld.scala',deps = ':Hello', )

目錄結(jié)構(gòu):

blade-demo/BLADE_ROOTscala/hello/BUILDSay.scalaHello.scalaHelloWorld.scala

在blade-demo/scala/hello目錄下執(zhí)行

blade build :HelloWorldFat

則在blade-demo/build64_release/scala/hello目錄下會(huì)生成HelloWorldFat.fat.jar文件:

$ jar tf HelloWorldFat.fat.jar hello/HelloWorld.class hello/HelloWorld$.class hello/Hello.class hello/Hello$.class hello/Say.class hello/Say$.class META-INF/blade/JAR.LIST META-INF/blade/MERGE-INFO META-INF/MANIFEST.MF

要運(yùn)行程序,在blade-demo/build64_release/scala/hello目錄下執(zhí)行

$ scala -cp HelloWorldFat.fat.jar hello.HelloWorld Hello, world

注:如果用java命令運(yùn)行會(huì)報(bào)錯(cuò) “Exception in thread “main” java.lang.NoClassDefFoundError: scala/collection/mutable/StringBuilder”,因?yàn)槿鄙賁cala標(biāo)準(zhǔn)庫(kù)。

6.3.5 Python

Python是解釋型語(yǔ)言,因此Python的構(gòu)建規(guī)則不需要執(zhí)行任何編譯操作,只生成一個(gè)包含源代碼位置的文件。

6.3.5.1 py_library

構(gòu)建Python庫(kù)。語(yǔ)法:

py_library(name = 'foo',srcs = ['foo.py', 'bar.py', ...]deps = [':name', '//path/to/dir:name', ...],base = '//path/to/base', )
  • base:字符串,指定導(dǎo)入模塊起始路徑,默認(rèn)為項(xiàng)目根目錄

6.3.5.2 py_binary

構(gòu)建Python可執(zhí)行程序。語(yǔ)法:

py_binary(name = 'foo',srcs = ['foo.py', 'bar.py', ...]deps = [':name', '//path/to/dir:name', ...],base = '//path/to/base',main = 'foo.py', )
  • main:字符串,當(dāng)srcs包含多個(gè)文件時(shí)指定程序入口文件

6.3.5.3 py_test

構(gòu)建Python測(cè)試程序。語(yǔ)法:

py_test(name = 'foo_test',srcs = ['foo_test.py', ...],deps = [':name', '//path/to/dir:name', ...],base = '//path/to/base',main = 'foo_test.py',testdata = testdata = ['data1.txt', '//path/to/data2.txt'], )

具體用法見(jiàn)8.4節(jié)。

6.3.5.4 示例

下面用Python實(shí)現(xiàn)第4節(jié)中的Hello World示例。

say.py

def say(msg):print(msg)

hello.py

from python.hello import saydef hello(to):say.say('Hello, ' + to)

hello_world.py

from python.hello import hellodef main():hello.hello('world')if __name__ == '__main__':main()

BUILD

py_library(name = 'say',srcs = 'say.py', )py_library(name = 'hello',srcs = 'hello.py',deps = ':say', )py_binary(name = 'hello_world',srcs = 'hello_world.py',deps = ':hello', )

目錄結(jié)構(gòu):

blade-demo/BLADE_ROOTpython/hello/BUILDsay.pyhello.pyhello_world.py

其中import路徑相對(duì)于根目錄blade-demo,因此python.hello對(duì)應(yīng)python/hello目錄。

在blade-demo/python/hello目錄下執(zhí)行

blade build :hello_world

則在blade-demo/build64_release/python/hello目錄下會(huì)生成三個(gè).pylib文件和一個(gè)可執(zhí)行文件hello_world:

$ ls hello.build.ninja hello.pylib hello_world hello_world.build.ninja hello_world.pylib say.build.ninja say.pylib$ cat hello_world.pylib {'srcs': [('python/hello/hello_world.py', 'df892f737d6f06060254cb903c597286')], 'base_dir': ''}$ head -3 hello_world #!/bin/shPYTHONPATH="$0:$PYTHONPATH" exec python -m "python.hello.hello_world" "$@"

可以看出,.pylib文件只是記錄了源代碼位置和文件md5,可執(zhí)行文件hello_world就是一個(gè)Shell腳本(后面還有一些二進(jìn)制數(shù)據(jù))。

要運(yùn)行程序,可以在blade-demo/python/hello目錄下執(zhí)行

$ blade run :hello_world ... Blade(info): Run '['.../blade-demo/build64_release/python/hello/hello_world']' Hello, world

或者在blade-demo/build64_release/python/hello目錄下執(zhí)行

$ ./hello_world Hello, world

或者直接在blade-demo目錄下執(zhí)行(不需要Blade)

$ python3 -m python.hello.hello_world Hello, world

6.3.6 文件打包

從源代碼目錄和構(gòu)建目錄打包文件。語(yǔ)法:

package(name = 'foo_package',type = 'tgz',shell = True,srcs = [('$(location //path/to/src:name)', 'path/to/dst/name'),('//path/to/src/file', 'path/to/dst/file'),] )
  • type:字符串,指定壓縮文件后綴名,可以是zip、tar、tar.gz、tgz、tar.bz2、tbz
  • shell:布爾值,如果為T(mén)rue則使用Shell創(chuàng)建壓縮文件
  • srcs:二元組(src, dst)的列表,指定要打包的內(nèi)容,其中src可以是源代碼目錄中的文件(例如配置文件)或構(gòu)建目標(biāo)的產(chǎn)物(例如可執(zhí)行程序),dst是壓縮文件中的相對(duì)路徑,src支持的格式如下:
    • $(location //path/to/src:name):目標(biāo)//path/to/src:name的構(gòu)建產(chǎn)物
    • //path/to/src/file:源代碼目錄中的文件,如果以//開(kāi)頭則表示相對(duì)于項(xiàng)目根目錄,否則相對(duì)于當(dāng)前目錄;file可以是單個(gè)文件,也可以是整個(gè)目錄

package規(guī)則在構(gòu)建時(shí)默認(rèn)不執(zhí)行,除非blade build顯式指定該目標(biāo),或指定了--generate-package選項(xiàng)。

例如:在第4節(jié)Hello World項(xiàng)目的基礎(chǔ)上增加一個(gè)配置文件conf/hello_world.conf和一個(gè)數(shù)據(jù)文件data.txt:

blade-demo/BLADE_ROOTquick-start/BUILDsay.hsay.cchello.hhello.cchello_world.ccdata.txtconf/hello_world.conf

在BUILD文件中增加一個(gè)package目標(biāo):

package(name = 'hello_world_package',type = 'tgz',shell = True,srcs = [('$(location //quick-start:hello_world)', 'bin/hello_world'),('$(location //quick-start:hello)', 'lib/libhello.a'),('//quick-start/conf', 'conf'),('data.txt', 'data/foo.txt'),] )

在quick-start目錄下執(zhí)行

$ blade build :hello_world_package $ alt # 等價(jià)于cd ../build64_release/quick-start $ pwd .../blade-demo/build64_release/quick-start $ tar -tf hello_world_package.tgz conf/hello_world.conf data/foo.txt bin/hello_world lib/libhello.a

6.3.7 自定義構(gòu)建規(guī)則

語(yǔ)法:

gen_rule(name = 'foo',srcs = ['bar', 'baz', ...],deps = ['//path/to/dir:name', ...],outs = ['foo'],cmd = 'shell command to generate foo',cmd_name = 'FOO', )
  • srcs:字符串列表(可選),指定構(gòu)建目標(biāo)的輸入文件
  • outs:字符串列表(必需),指定構(gòu)建目標(biāo)的輸出文件
  • cmd:字符串(必需),生成輸出文件的Shell命令,可使用以下變量:
    • $SRCS:空格分隔的輸入文件列表,相對(duì)于項(xiàng)目根目錄
    • $OUTS :空格分隔的輸出文件列表,相對(duì)于項(xiàng)目根目錄
    • $FIRST_SRC:第一個(gè)輸入文件
    • $FIRST_OUT:第一個(gè)輸出文件
    • $SRC_DIR:輸入文件所在目錄
    • $OUT_DIR:輸出文件所在目錄
    • $BUILD_DIR:根輸出目錄
  • cmd_name:字符串(可選),命令名稱的簡(jiǎn)寫(xiě),默認(rèn)為COMMAND

執(zhí)行命令的工作目錄是項(xiàng)目根目錄。如果最后沒(méi)有生成outs指定的文件則報(bào)錯(cuò)。

例如,有在子目錄foo中a.txt和b.txt兩個(gè)文件:

blade-demo/BLADE_ROOTfoo/BUILDa.txtb.txt

a.txt和b.txt的內(nèi)容分別為“123”和“abc”,BUILD文件包含生成c.txt的自定義規(guī)則,通過(guò)拼接a.txt和b.txt生成:

gen_rule(name = 'c',srcs = ['a.txt', 'b.txt'],outs = ['c.txt'],cmd = 'cat $SRCS > $OUTS',cmd_name = 'CAT', )

在foo目錄下執(zhí)行

$ blade build :c Blade(info): Building... [1/1] CAT //foo:c Blade(info): Build success. Blade(info): Cost time 0.199s$ alt $ pwd .../blade-demo/build64_release/foo $ cat c.txt 123 abc

在這個(gè)示例中,各變量的值如下:

$SRCS = "foo/a.txt foo/b.txt" $OUTS = "build64_release/foo/c.txt" $FIRST_SRC = "foo/a.txt" $FIRST_OUT = "build64_release/foo/c.txt" $SRC_DIR = "foo" $OUT_DIR = "build64_release/foo" $BUILD_DIR = "build64_release"

7.命令行參考

官方文檔:https://github.com/chen3feng/blade-build/blob/master/doc/en/command_line.md

Blade命令行語(yǔ)法:

blade <subcommand> [options...] [targets...]

7.1 子命令

  • build:構(gòu)建指定的目標(biāo)
  • run:構(gòu)建并運(yùn)行指定的目標(biāo)
  • test:構(gòu)建指定的目標(biāo)并運(yùn)行測(cè)試
  • clean:刪除指定目標(biāo)的構(gòu)建產(chǎn)物
  • query:分析指定的目標(biāo)依賴或被依賴的目標(biāo)
  • dump:打印指定目標(biāo)的內(nèi)部信息

7.2 構(gòu)建目標(biāo)模式

子命令需要指定一個(gè)或多個(gè)構(gòu)建目標(biāo)參數(shù),稱為目標(biāo)模式(target pattern),支持以下語(yǔ)法:

  • path:name:path目錄下名為name的目標(biāo)
  • :name:當(dāng)前目錄下名為name的目標(biāo)
  • path:*或path:path目錄下的所有目標(biāo),不包括子目錄
  • path/...:path目錄及其子目錄下的所有目標(biāo)

如果path以//開(kāi)頭則表示從項(xiàng)目根目錄開(kāi)始的路徑,否則表示基于當(dāng)前目錄的相對(duì)路徑。

如果沒(méi)有指定目標(biāo)則表示當(dāng)前目錄下的所有目標(biāo),不包括子目錄。

7.3 示例

# 構(gòu)建當(dāng)前目錄下的所有目標(biāo),不包括子目錄 blade build# 構(gòu)建當(dāng)前目錄及其子目錄下的所有目標(biāo) blade build ...# 構(gòu)建當(dāng)前目錄下名為hello的目標(biāo) blade build :hello# 構(gòu)建項(xiàng)目根目錄/common/string目錄下名為string的目標(biāo) blade build //common/string:string# 構(gòu)建當(dāng)前目錄/string目錄下名為string的目標(biāo) blade build string:string# 構(gòu)建項(xiàng)目根目錄/common及其子目錄下的所有目標(biāo) blade build //common/...

8.測(cè)試

官方文檔:https://github.com/chen3feng/blade-build/blob/master/doc/en/test.md

8.1 C++ - GoogleTest

cc_test_config

TODO 鏈接GoogleTest博客

8.2 Java - JUnit

java_test_config

8.3 Scala - scala-test

scala_test_config

8.4 Python - unittest

總結(jié)

以上是生活随笔為你收集整理的Blade构建工具的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

欧美精选一区二区三区 | 伊人亚洲综合网 | 五月天天在线 | 夜夜爽夜夜操 | 九九视频精品免费 | 国产看片 色 | 久久男人视频 | 亚洲欧美精品一区 | 一区在线电影 | 91精品91 | 高潮久久久久久久久 | 在线黄色av | 美国av大片 | 欧美淫aaa免费观看 日韩激情免费视频 | 99国产精品久久久久老师 | 欧美日韩中文国产 | 国产亚洲精品免费 | 中文字幕精品久久 | 亚洲最大免费成人网 | 天天色成人网 | 亚洲欧洲精品一区二区 | 夜夜躁狠狠躁 | 91天天操| 免费亚洲视频 | 四虎影院在线观看av | 欧美一级小视频 | 182午夜在线观看 | 一区二区三区在线电影 | 麻豆免费精品视频 | 欧美美女一级片 | 丁香婷婷综合网 | 国产精品美女久久久久久久 | 国产明星视频三级a三级点| 日韩欧美99 | 亚洲一区二区三区四区精品 | 亚洲精品中文字幕视频 | 操操操干干干 | 国产午夜精品一区二区三区四区 | 亚洲黄色片在线 | 亚洲综合在线观看视频 | 亚洲精品视频网址 | 久久99久久99精品 | 国产一区免费视频 | 精品日韩在线一区 | 精品国产亚洲在线 | 高清视频一区二区三区 | 激情婷婷综合网 | 天天操操操操操操 | 国产一区二区在线观看视频 | 亚洲国产高清在线观看视频 | 久久国内精品99久久6app | 日日夜夜狠狠操 | 日韩特黄av| 中文字幕在线观看播放 | 激情五月播播久久久精品 | 92av视频| 久久99国产精品自在自在app | 免费观看国产视频 | 在线a人v观看视频 | av电影久久 | 免费在线看v | 玖玖视频免费在线 | 久久一级电影 | 在线观看黄av | 这里只有精彩视频 | 国产成人亚洲在线观看 | 中文字幕av全部资源www中文字幕在线观看 | 国产精品免费av | 精品亚洲欧美一区 | 国产在线中文字幕 | av大全在线免费观看 | 一区二区三区在线影院 | 婷婷九月丁香 | 日产乱码一二三区别在线 | 高潮久久久久久久久 | 在线观看av大片 | www国产在线| 国产成人精品女人久久久 | 色综合在 | 欧美在线视频不卡 | 国产无遮挡猛进猛出免费软件 | 激情五月播播久久久精品 | 欧美性生活免费 | 天天搞天天干 | 久久丝袜视频 | 欧美日韩在线视频观看 | 久久精品4 | 国产淫a | .国产精品成人自产拍在线观看6 | 欧美日韩免费一区 | 久久免费av电影 | 91超在线 | 亚洲a在线观看 | 国产精品第一页在线观看 | 日韩国产高清在线 | 91在线文字幕 | 成人综合免费 | 婷婷色视频 | wwwwww黄| 国产一级二级在线播放 | 国产高清在线a视频大全 | 精品国内自产拍在线观看视频 | 日韩精品中文字幕一区二区 | 男女精品久久 | 日韩av不卡在线观看 | 久久精品高清视频 | 日韩欧美精品一区 | 免费看片成人 | 成人网在线免费视频 | 成人国产精品电影 | 欧美日韩国产在线观看 | 欧美日韩高清一区二区三区 | 国产一区欧美二区 | 久久精品中文字幕一区二区三区 | 国产精品h在线观看 | 69视频在线 | 成人三级av | 超碰成人av| 在线观看色网站 | 久久精品日产第一区二区三区乱码 | 一二区精品 | av+在线播放在线播放 | 国产三级av在线 | 在线观看激情av | av网站在线免费观看 | 精品专区 | 久久综合狠狠综合久久综合88 | 久青草视频在线观看 | 精品国产乱码一区二区三区在线 | 爱情影院aqdy鲁丝片二区 | 精品视频在线看 | 伊甸园永久入口www 99热 精品在线 | 精品国产一区二区久久 | 国产三级午夜理伦三级 | 亚洲精品国产综合99久久夜夜嗨 | 午夜黄色一级片 | 激情视频二区 | 欧美一区日韩一区 | 在线小视频你懂的 | 亚洲一区在线看 | 不卡的av电影在线观看 | 国产视频在线观看一区二区 | 九九精品视频在线 | 91av视频网站 | 国产伦理久久精品久久久久_ | 97国产在线视频 | 日本老少交| 成人免费在线视频观看 | 精品一区二区在线看 | 国产资源在线播放 | 国产在线观看高清视频 | 久久这里只有精品23 | 日韩高清三区 | 久久这里只有精品首页 | 国产日韩在线看 | 久久精品成人欧美大片古装 | 欧美日韩久久 | 日韩专区视频 | 91污视频在线观看 | 2018亚洲男人天堂 | 韩国av一区二区三区 | 日韩av午夜在线观看 | 黄色aaa级片 | 日韩精品中文字幕在线不卡尤物 | 日韩欧美在线高清 | 免费日韩 | www.黄色 | 久久国产成人午夜av影院潦草 | 激情五月播播久久久精品 | 日韩av在线免费看 | 999国产在线 | 欧美性色综合网 | 成人久久亚洲 | 成人黄色电影在线观看 | 国产不卡在线观看视频 | av免费在线观看1 | 日本韩国精品一区二区在线观看 | 91传媒激情理伦片 | 中文字幕在线观看一区 | 91探花在线| 在线电影91 | av中文字幕在线免费观看 | 亚洲精品小区久久久久久 | 在线国产视频 | 亚洲精品午夜视频 | 国产精品久久久毛片 | 中文字幕资源在线 | 久久久网| 国产精品成人免费一区久久羞羞 | 一区二区三区在线视频111 | 免费 在线 中文 日本 | 久久久久久久影视 | 久久人操 | 亚洲综合婷婷 | 国产高清久久 | 国产中文字幕国产 | 深夜国产福利 | 国产精品一区二区三区在线免费观看 | 免费在线电影网址大全 | 超碰av免费| 天天爱综合 | 日韩欧美一区视频 | 999热线在线观看 | 五月婷婷视频在线观看 | 国产老熟| aaa免费毛片 | 日韩免费在线网站 | 在线国产视频观看 | 免费福利视频网站 | 在线观看视频国产一区 | 国产又粗又猛又色又黄网站 | 国产手机在线观看 | 亚洲永久av | 亚洲精品玖玖玖av在线看 | 一二三区av | 国产精品久久久777 成人手机在线视频 | 麻豆精品视频 | 综合色婷婷 | www久| 亚洲成人资源网 | 天天操天天添 | 91精品视频免费看 | 亚洲欧美日韩精品久久久 | 欧美人人 | 国产精品9999久久久久仙踪林 | 日本黄色黄网站 | 日韩av成人在线观看 | 天天插天天狠 | 欧美精品久| 欧美影院久久 | 亚洲成人资源网 | 996久久国产精品线观看 | 久久综合狠狠综合 | 亚洲精品在线免费播放 | 亚州精品天堂中文字幕 | 狠狠狠色丁香综合久久天下网 | 欧美色图狠狠干 | 射九九| 午夜少妇av | 五月婷婷色播 | 久久久久成 | 日本aaa在线观看 | 最新国产中文字幕 | 国内精品久久久久影院一蜜桃 | 黄色中文字幕 | 国产精品99久久久久久久久 | 国产精久久久久久久 | 免费看一级 | 激情五月六月婷婷 | 日产中文字幕 | 日韩精品免费一区二区三区 | 国产免费大片 | 九九视频免费观看视频精品 | 免费视频你懂的 | 99草在线视频 | 男女啪啪免费网站 | 韩国精品福利一区二区三区 | 成年人国产在线观看 | 亚洲国产午夜精品 | 欧美久久久久久久久久 | 欧美日韩中文在线观看 | 日韩成年视频 | 日韩视频免费在线观看 | www·22com天天操 | 久久一区二 | 精品99在线观看 | 精品久久久久免费极品大片 | 欧美成年网站 | 欧美成人在线网站 | 欧美日韩在线精品 | 中文字幕免费高清在线观看 | 国产色a在线观看 | 婷婷在线播放 | 日韩av中文在线观看 | 亚洲免费观看在线视频 | av久久在线| 一区二区三区免费在线 | 天天综合精品 | 国产精品永久免费 | 久久中文欧美 | 黄污网站在线 | 特黄特色特刺激视频免费播放 | 国产一级淫片免费看 | 免费亚洲婷婷 | 亚洲精品久久久久中文字幕m男 | 国产一级淫片免费看 | 久久视频网 | 91精品国产成人www | 婷婷国产一区二区三区 | 成av人电影| 久久亚洲免费视频 | 射射色| 日韩三区在线观看 | 亚洲精品国偷拍自产在线观看 | 奇米先锋| 国产亚洲精品日韩在线tv黄 | 天天干天天射天天插 | av免费试看 | 在线国产小视频 | 久久99电影| 国产福利不卡视频 | 日韩精品免费一线在线观看 | av在线电影网站 | 在线看毛片网站 | 中文字幕成人在线观看 | 国产日韩中文字幕在线 | 欧美日韩高清一区二区三区 | 亚洲夜夜网 | 日韩电影在线观看一区 | 国产精品一区二区久久 | 西西4444www大胆无视频 | 五月香视频在线观看 | 日韩大片在线 | 精品欧美一区二区精品久久 | 国产99re| 国产粉嫩在线观看 | www.人人干 | 黄色毛片大全 | 国产精品一区二区 91 | 人人澡超碰碰97碰碰碰软件 | 天堂资源在线观看视频 | 天天拍天天爽 | 欧美日韩性视频 | 亚洲狠狠丁香婷婷综合久久久 | 久久综合九色综合网站 | 中文字幕电影在线 | 4438全国亚洲精品在线观看视频 | 99久久日韩精品免费热麻豆美女 | 天天干天天做 | 久久精品男人的天堂 | 视频一区亚洲 | 国产免费观看久久黄 | 成人免费 在线播放 | 9ⅰ精品久久久久久久久中文字幕 | 午夜av在线免费 | 天天操天天怕 | 在线观看v片 | 99热 精品在线 | 天天看天天操 | 久久精品伊人 | 国产福利在线 | 色人久久 | 免费网站在线观看成人 | 亚洲精品av在线 | 欧美性色综合网 | 国产经典三级 | 日韩欧美在线观看一区 | 就色干综合 | 国产精品久久久久久久电影 | 91超级碰碰 | av电影在线不卡 | 欧美日韩xxx | 久久 精品一区 | 婷婷六月天丁香 | 少妇性bbb搡bbb爽爽爽欧美 | 国内精品美女在线观看 | 日本精品视频在线播放 | 丁香六月国产 | 亚洲免费av在线 | 狠狠gao | 国产精品久久久久久高潮 | 日韩毛片在线一区二区毛片 | 国产91粉嫩白浆在线观看 | 精品自拍sae8—视频 | 日日爽| 久久久九色精品国产一区二区三区 | 国产91在线观 | 黄色av电影在线观看 | 午夜色影院 | 69视频在线 | 粉嫩av一区二区三区四区五区 | 视频一区二区视频 | 中文字幕免费看 | 国产免费av一区二区三区 | 天天操天天射天天 | 国产亚洲一级高清 | 国产在线精品一区二区三区 | 激情电影影院 | 欧美三级在线播放 | 国产中文字幕一区二区 | 日韩特黄一级欧美毛片特黄 | 亚洲精品小视频在线观看 | 99久精品 | 四虎影视成人精品国库在线观看 | 在线播放 一区 | 久久精品国产99国产 | 亚洲精品小视频 | 在线视频91| 91在线播放国产 | 天天综合久久 | 亚洲永久精品在线观看 | 免费麻豆视频 | 激情喷水 | 亚洲精欧美一区二区精品 | 久久久亚洲国产精品麻豆综合天堂 | 久久久久国产精品午夜一区 | 国产成人一区二区啪在线观看 | 91av视频在线观看免费 | 天天插天天射 | 狠狠色丁香久久婷婷综合五月 | 亚洲 综合 激情 | 成人亚洲网 | 99久久精品国产一区二区三区 | 久久精品男人的天堂 | 在线免费观看麻豆视频 | 91视频免费看网站 | 超碰人人91 | 99av国产精品欲麻豆 | 黄色片网站av | 97成人超碰 | 国产精品久久久999 国产91九色视频 | 91探花系列在线播放 | 在线精品视频免费播放 | av资源免费在线观看 | 国产亚洲aⅴaaaaaa毛片 | 五月婷婷久草 | 日本久久精品 | 亚洲国产片| 久久久久久黄色 | 中文字幕123区 | 亚洲v精品 | 最近中文字幕大全 | 欧美日韩在线免费观看视频 | 4hu视频 | 免费看三级黄色片 | 中文字幕av在线播放 | 亚洲欧洲国产精品 | 日韩电影在线一区二区 | 尤物九九久久国产精品的分类 | 视频在线观看一区 | 在线看免费 | a级国产乱理伦片在线观看 亚洲3级 | 国产在线 一区二区三区 | 日日操日日干 | 国产女人免费看a级丨片 | 久久色视频| 天无日天天操天天干 | 麻豆一区二区三区视频 | 在线国产精品视频 | 中文字幕乱码视频 | 在线中文字幕av观看 | 天天综合网天天综合色 | 香蕉影视在线观看 | 久久五月天色综合 | 国内精品久久久久影院优 | 国产日韩在线播放 | 久久伦理电影 | 日韩乱色精品一区二区 | 国产精品日韩欧美一区二区 | 精品欧美一区二区三区久久久 | 国产成人一区二区啪在线观看 | 国产免费不卡av | 在线高清| 国产又粗又猛又黄又爽的视频 | 免费在线观看午夜视频 | www日日 | 日韩久久午夜一级啪啪 | 国内视频 | 一级做a爱片性色毛片www | a级一a一级在线观看 | 日本bbbb摸bbbb | 久久免费激情视频 | 国产免费人成xvideos视频 | 黄色在线观看免费 | 亚洲欧美国内爽妇网 | 日韩欧美一级二级 | 亚洲国产成人高清精品 | 国产精品99久久免费黑人 | 亚洲一区视频在线播放 | 国产裸体bbb视频 | a级国产乱理论片在线观看 特级毛片在线观看 | av天天干| 天堂成人在线 | 国产精品第52页 | 99精品视频在线免费观看 | 午夜精品电影 | 成人av中文字幕在线观看 | 在线看av的网址 | 亚洲高清免费在线 | 色99久久 | 国产一区二区三区在线免费观看 | 日韩欧美精品一区二区 | 精品国产一区二区在线 | 中文字幕亚洲综合久久五月天色无吗'' | 在线日韩亚洲 | 91在线你懂的 | 国产精品久久久 | 91精品国产成人www | www激情网| 色91在线 | 欧美性生活一级片 | 亚洲日韩欧美视频 | 国产成人1区| 色多多视频在线观看 | 91视频免费看网站 | 97色婷婷| 最近中文字幕完整高清 | 国产精品日韩欧美 | 黄色av免费在线 | 亚洲精品国产综合久久 | 国产精品h在线观看 | 免费在线观看日韩 | 欧美另类69 | 亚洲精品美女久久17c | 久久久福利视频 | 欧美坐爱视频 | 国产又粗又猛又爽又黄的视频先 | 欧美analxxxx | 久久久久综合网 | 色婷婷综合久久久中文字幕 | 精品国产理论片 | 欧美日韩在线精品 | 免费网站在线观看人 | 麻豆免费精品视频 | 久久久一本精品99久久精品 | 天天天天天天天天操 | 亚洲日韩欧美一区二区在线 | 国产精品久久久久9999 | 国产96av | 最近高清中文在线字幕在线观看 | 青青色影院 | 欧美久久久久久久久 | 成人午夜网| 精品久久99 | 97在线免费观看视频 | 99视频在线精品免费观看2 | 精品国产一区二区三区久久久久久 | 精品影院一区二区久久久 | 中文在线免费视频 | 色综合久久久久网 | 国产精品亚洲片在线播放 | 国产成人精品aaa | 日韩高清在线观看 | 99久久婷婷国产综合亚洲 | 欧美一区二区在线刺激视频 | 国产午夜精品一区二区三区四区 | 色吊丝在线永久观看最新版本 | 激情综合色播五月 | 色婷婷精品大在线视频 | 91传媒视频在线观看 | 狠狠搞,com | 欧美日韩国产一区二区在线观看 | 国产一区在线视频播放 | 最新超碰| 天天操综合网 | 99精品免费在线观看 | 激情电影影院 | 天天干天天拍天天操天天拍 | 久久精品国产一区 | 黄色1级毛片 | 99色| 日韩网站视频 | 美女av电影 | 色婷婷88av视频一二三区 | 久久精品永久免费 | 99视频| 成人午夜片av在线看 | 亚洲最大的av网站 | 三级av中文字幕 | 日本久久综合网 | 免费看的黄色 | 日韩精品一区二区三区电影 | 天天插视频 | 激情文学丁香 | 久久精品国产亚洲aⅴ | 丰满少妇在线观看 | 久久理论影院 | 激情在线免费视频 | 久久五月婷婷丁香社区 | 五月天婷亚洲天综合网鲁鲁鲁 | 91探花在线 | 高清视频一区二区三区 | 97人人澡人人爽人人模亚洲 | 国产精品美女久久久久久久 | 国产精品网红直播 | 最近中文字幕免费 | 色综合天天色综合 | 免费一级特黄录像 | 视频99爱 | 中国一级片免费看 | 九九免费观看视频 | 一级α片免费看 | 精品一区二区6 | 亚洲精品国产成人 | 日韩网站免费观看 | 精品国产区在线 | 久99精品| 久久综合狠狠综合 | 久久精品中文字幕少妇 | 啪啪午夜免费 | 一区二区三区精品在线视频 | 久久精品韩国 | 中文字幕中文字幕在线一区 | 国产高清精 | www.久久色 | 欧美激情另类文学 | 午夜av不卡 | 亚洲国内在线 | 国产亚洲欧美在线视频 | 色吊丝在线永久观看最新版本 | 国产精品v欧美精品v日韩 | 国内成人精品视频 | 日韩午夜大片 | 天天色草 | 亚洲黄色成人网 | 91在线欧美| 国产精品高潮在线观看 | 欧美在线视频第一页 | 久久一区国产 | 亚洲视频资源在线 | 欧美性脚交 | 色综合综合| 国产资源网站 | 国产在线观| 超碰国产在线播放 | 激情av在线资源 | 国产精品欧美在线 | 插久久 | 国产精品99久久久久的智能播放 | 久久久久久久影视 | 日韩视频www| 日韩在线观看三区 | 久草网在线视频 | 久草久视频 | 成年人黄色免费视频 | 99色国产| 综合色影院 | 黄污污网站 | 毛片网站在线看 | 麻豆视频免费在线观看 | 欧美在线91 | 亚洲精品一区二区久 | 国产成人精品日本亚洲999 | 婷婷丁香在线 | www.亚洲精品视频 | 国产精品久久一区二区三区, | 成人网在线免费视频 | 九九99| 国产午夜精品久久久久久久久久 | 草 免费视频| 免费观看日韩av | 91成年人网站 | 91亚洲精品国偷拍自产在线观看 | 久久久久久久久久久国产精品 | 午夜久久久久久久久久影院 | 欧美黑人xxxx猛性大交 | 国产区精品区 | 欧美久久久久久久 | www.99在线观看 | 免费91在线 | 91日韩免费| 久久久久国产视频 | 欧美a免费 | 日日插日日干 | 中文字幕在线影院 | 最新中文字幕在线观看视频 | 91精品无人成人www | 久久看看 | 国产精品手机在线观看 | 久久久久久久久久毛片 | 日免费视频 | 亚洲高清视频在线观看免费 | 日本色小说视频 | 91网页版免费观看 | 久久五月激情 | 久久爱992xxoo | www.99av| 麻豆视频在线观看 | 免费一级片在线观看 | 久草网在线观看 | 亚洲爱爱视频 | 日韩中文字幕免费视频 | 日韩精品在线播放 | 久久99久久99免费视频 | 久久免费视频一区 | 国产精品久久综合 | 久久精品99久久久久久 | 国产剧情av在线播放 | 美女国内精品自产拍在线播放 | av在线免费观看网站 | 中文字幕高清 | 日韩在线电影观看 | 天天夜夜狠狠操 | 国产精品久久网站 | 国产精品成人一区二区 | 日韩一区二区三区在线看 | 亚洲情婷婷 | 久久久久www| 在线观看亚洲a | 亚洲涩涩一区 | 国产成人免费精品 | 在线观看你懂的网址 | 中文字幕在线观看完整版 | 亚洲国产精品推荐 | 亚洲天堂首页 | 一区二区激情 | 综合色亚洲 | 久久夜色精品国产亚洲aⅴ 91chinesexxx | 久久久黄视频 | 久久久久久久久久久久久9999 | 五月天综合网站 | 美女网站免费福利视频 | 国偷自产中文字幕亚洲手机在线 | 久久婷婷视频 | 天天射天天爱天天干 | 在线观看精品国产 | 97精品国产aⅴ | 国产亚洲在线 | 欧美日韩国产在线一区 | 免费在线观看国产精品 | 国产又粗又猛又爽 | 午夜精品久久久久久久99水蜜桃 | 黄色一级免费电影 | 91成人精品一区在线播放69 | 美女网站色在线观看 | 超碰在线资源 | 成人黄色小视频 | 欧美日韩在线看 | 国产精品粉嫩 | 99国产免费网址 | 国产精品久久久久久久久久免费看 | 国产一区福利 | 亚洲视频 视频在线 | 狠狠色丁香久久婷婷综合丁香 | 91丨九色丨国产丨porny精品 | 夜夜操夜夜干 | 婷婷天天色 | 色综合久久88色综合天天免费 | 免费成人av | 色综合久久综合网 | 欧美作爱视频 | 99re国产视频 | 超碰在线公开免费 | 久久久久观看 | 国产热re99久久6国产精品 | 精品久久久久久综合 | 99国产精品久久久久久久久久 | 久久久精品国产一区二区 | 美女黄色网在线播放 | 91香蕉视频 mp4 | 激情综合色播五月 | 日韩专区在线 | 激情欧美国产 | www.国产在线观看 | 国产精品成人自产拍在线观看 | 午夜黄色 | 永久免费av在线播放 | 狠狠躁夜夜躁人人爽超碰97香蕉 | 国产久视频 | 狠狠色丁香婷婷综合 | 日韩在线视频二区 | 在线欧美最极品的av | 国产精品一区二区三区四 | 在线观看日韩 | 亚洲国产午夜视频 | 激情视频区 | 超碰免费久久 | 一区二区精品在线视频 | 天天综合天天做 | 色婷婷国产精品一区在线观看 | 五月天婷婷在线观看视频 | 国产高清99| 在线黄频| 婷婷综合在线 | 久久午夜精品 | 欧美日本啪啪无遮挡网站 | 最近中文字幕免费 | 午夜久久视频 | 久久精品资源 | 色欧美88888久久久久久影院 | 亚洲最新av在线网站 | 99热这里有| 五月天综合网 | 91精品在线麻豆 | 操操操人人人 | 97精品国产91久久久久久 | 99免费在线视频 | 999精品 | 激情婷婷综合 | 国产九九在线 | 91免费版在线 | 国产视频在线一区二区 | 在线视频成人 | 日韩精品在线一区 | 日韩免 | 久久精品久久久久 | 久草91视频 | 中文av字幕在线观看 | 亚洲一级特黄 | 黄色亚洲精品 | 精品视频| 欧美午夜激情网 | 欧美性超爽 | 成人久久毛片 | 国产美女视频黄a视频免费 久久综合九色欧美综合狠狠 | 狠狠躁天天躁综合网 | 日韩一区二区三区在线看 | 精品一区二区影视 | 中文字幕在线乱 | 91天天视频 | 成年人在线免费看视频 | av免费网页| 亚洲资源视频 | 久久久黄视频 | 黄色一级免费 | 色中文字幕在线观看 | 天天碰天天操视频 | 欧美激情综合色综合啪啪五月 | 很黄很污的视频网站 | 日韩视频在线播放 | 亚洲欧美在线视频免费 | 在线国产小视频 | 国产免费小视频 | 亚洲涩涩色 | 一级久久精品 | 一区二区三区四区久久 | 日韩精品播放 | 免费视频99 | 久久观看免费视频 | 国际精品网 | 免费久草视频 | 激情在线五月天 | 精品一二 | 99高清视频有精品视频 | 久久久精品高清 | 免费观看全黄做爰大片国产 | www99精品 | 欧美日韩电影在线播放 | 色婷婷综合久色 | 欧美亚洲一级片 | 麻豆视频国产 | 亚洲精品在线观看不卡 | 久草综合视频 | 五月天六月色 | 天天操操| 久久久999 | 免费av免费观看 | 精品国产免费观看 | 精品91久久久久 | 男女免费av | 超碰在线公开 | 激情五月婷婷激情 | 韩国在线视频一区 | 免费观看mv大片高清 | 精品理论片 | 日韩久久电影 | 日日操日日插 | 久久国产一区 | 成人免费av电影 | 欧美韩国在线 | 久色小说 | 日本久久久久久 | 精品极品在线 | 三日本三级少妇三级99 | 91福利小视频 | 国产视频99| 免费黄色a网站 | 五月婷婷在线综合 | 色99久久 | 亚洲视频免费 | 香蕉网在线观看 | 国产精品久久久久久久久久新婚 | 国产一区二区高清不卡 | 日韩在线高清免费视频 | 国产手机在线视频 | wwwwwww色| 久久久久一区二区三区四区 | 久久精品99久久久久久 | 久久精品久久久久电影 | 一区二区三区四区五区在线视频 | 国产99久久久欧美黑人 | 国产激情小视频在线观看 | 国产精品久久久久久爽爽爽 | 91久色蝌蚪 | 国产在线小视频 | 国产色婷婷在线 | 欧美一区二区三区在线视频观看 | 999视频在线播放 | 91资源在线免费观看 | av黄色国产 | 波多野结衣一区二区 | 欧美精品黑人性xxxx | 亚洲人人射 | 99久久日韩精品视频免费在线观看 | 精品国产一区二区三区男人吃奶 | 新av在线| 麻豆91精品 | 正在播放国产精品 | 国产精品一区二区三区在线播放 | 成人黄色资源 | 亚洲精品国产自产拍在线观看 | 精品毛片一区二区免费看 | 欧美极品少妇xxxxⅹ欧美极品少妇xxxx亚洲精品 | 日日夜夜人人精品 | 中文字幕在线观看免费 | 四虎影视成人永久免费观看视频 | 免费在线观看视频一区 | 日韩欧美一区二区三区黑寡妇 | 国产精品一区二区免费 | 91丨九色丨国产在线观看 | 波多野结衣动态图 | 国产人成一区二区三区影院 | 亚洲国产欧美在线人成大黄瓜 | a黄色一级 | 午夜av免费 | 人人插人人干 | www.黄色小说.com| 成人性生活大片 | 99国产精品视频免费观看一公开 | 黄色av免费电影 | 亚洲视频每日更新 | 91精品视频在线观看免费 | 国产亚洲精品久久久久久网站 | 丁香导航 | 视频一区二区精品 | 97国产精品一区二区 | 亚洲国产一二三 | 一区二区三区在线看 | 亚洲精品视频在线观看免费视频 | 国产精品久久久久久久久久直播 | www免费看 | 久久久www成人免费精品张筱雨 | 久久久久激情视频 | 国产精品门事件 | 黄网站a| 成人超碰97 | 国产一级大片在线观看 | 黄色软件视频网站 | 日韩视频一二三区 | 亚洲乱码久久 | 国产免费精彩视频 | 特级毛片在线免费观看 | 狠狠色丁香婷婷综合久小说久 | 午夜精品久久久久久久99热影院 | 免费福利片2019潦草影视午夜 | 最新在线你懂的 | 久久不射电影院 | 香蕉久草 | 91精品网站| 久久精品最新 | 日韩免费b | 国产精品欧美一区二区 | 亚洲另类xxxx | 婷婷在线网 | 日韩精品一区二区三区外面 | 亚洲综合精品视频 | 天天综合导航 | 国产高清在线看 | 久久精品中文 | 亚洲在线网址 | 色综合久久88色综合天天6 | 91新人在线观看 | 2023年中文无字幕文字 | 99热在线观看 | 在线免费观看涩涩 | 人人精品| 国产理论免费 | 亚洲精品视频在线免费播放 | 狠狠搞,com | www.在线看片.com | 99热这里精品 | 日韩精品视 | 人人爽人人爽人人爽 | 婷婷激情5月天 | 成人av在线亚洲 | 国产高清在线精品 | 久久精品—区二区三区 | 久久国产精品免费一区二区三区 | 日本久久电影网 | 久久av一区二区三区亚洲 | 免费中午字幕无吗 | 国产老熟 | 国产精品久久久久久久久费观看 | 天天操狠狠操网站 | 久久婷婷一区二区三区 | 精品xxx| 国产一级黄 | 中文资源在线播放 | 在线国产日韩 | 久久在线免费 | 欧美激情第十页 | 久久久久9999亚洲精品 | 日韩69视频 | 免费大片黄在线 | 国产成人免费高清 | 久久在现 | 美女免费黄网站 | 亚洲香蕉在线观看 | 狠狠插天天干 | 九九精品视频在线观看 | 国产成人精品久 | 久草视频网 | 国产精品视频内 | 一区二区三区免费在线观看视频 | 永久免费精品视频 | 天天激情天天干 | 91精品网站在线观看 | 婷婷丁香狠狠爱 |