日韩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ò),歡迎將生活随笔推薦給好友。

激情五月***国产精品 | 三级视频片| 日日夜夜噜 | av蜜桃在线| 久久理论片 | 手机看片| 成人动漫一区二区三区 | 中文字幕亚洲欧美 | 黄色亚洲精品 | 久久综合之合合综合久久 | 九九九九九九精品任你躁 | 国产一区二区三区免费在线 | 啪啪免费观看网站 | 免费在线成人av | 亚洲精品五月天 | 日本久久成人中文字幕电影 | 欧美了一区在线观看 | 精品在线播放 | 激情开心色 | 少妇高潮冒白浆 | 中文国产成人精品久久一 | 探花视频网站 | 美国人与动物xxxx | 天天干天天干天天干天天干天天干天天干 | 伊人六月 | 97在线观看视频国产 | 久久久私人影院 | aaa日本高清在线播放免费观看 | 欧美精品做受xxx性少妇 | 日日噜噜噜噜夜夜爽亚洲精品 | 国产一区二区三区免费在线观看 | 欧美一级免费黄色片 | 中文字幕一区二区三区在线观看 | 日本中文字幕网 | 日产中文字幕 | www.久久久.com| 婷婷久久国产 | 国产精品9999久久久久仙踪林 | 午夜精品久久久久久久99 | 色婷婷激情综合 | 久久 国产一区 | 美女久久精品 | 日韩激情精品 | 国产成人精品在线播放 | 亚洲视频456| 国产精国产精品 | 精品国产一区二区三区久久久蜜臀 | 国产精品第72页 | 最新超碰在线 | 国产在线观看你懂的 | 深爱激情av | 成人a视频在线观看 | 欧美日韩亚洲一 | 东方av免费在线观看 | 国语精品免费视频 | 九九热1| 国产免费视频一区二区裸体 | 欧美黑吊大战白妞欧美 | 黄色免费网站下载 | adc在线观看 | 成人h在线观看 | 国产精品一区在线播放 | 天天做日日爱夜夜爽 | 欧美电影黄色 | 激情五月婷婷激情 | 成人av网站在线播放 | 91黄色在线看 | 中文字幕在线乱 | 999成人精品| 91精品国产入口 | 国产对白av | 午夜私人影院久久久久 | 亚洲综合婷婷 | 久草在线视频免费资源观看 | 激情欧美一区二区免费视频 | 国产精品福利小视频 | 欧美日韩18 | 99久久日韩精品免费热麻豆美女 | 国产一级大片免费看 | 丁香婷婷网 | 99久久国产免费,99久久国产免费大片 | 婷婷久月 | 久久国产精品小视频 | 日韩二区在线观看 | ww亚洲ww亚在线观看 | 久久久久伦理电影 | 激情欧美一区二区免费视频 | 日韩字幕在线观看 | 色婷婷激情| 很污的网站 | 亚洲成人资源在线观看 | av大全在线播放 | 久久99精品国产麻豆宅宅 | 国产精品久久久久久久久久久不卡 | 久久久久久久久影视 | 国产第一页精品 | 97色在线观看免费视频 | 又黄又爽的免费高潮视频 | 国产精品五月天 | 国产伦精品一区二区三区四区视频 | 天天操天天干天天 | 欧美日韩首页 | 日韩在线一级 | 亚洲一级黄色片 | 久久精品播放 | 国产在线播放一区二区三区 | 国产精品18毛片一区二区 | 免费在线观看av的网站 | 国内精品久久久久久久久久久 | 99色精品视频 | 天天艹天天操 | 91精品一区国产高清在线gif | 五月天av在线 | 国产精品成人一区二区三区吃奶 | 精品国产成人在线影院 | 亚洲狠狠操 | 五月激情电影 | 天天色天天草天天射 | 国产精品久久久久久久久久久久冷 | 欧美韩国在线 | 中文字幕亚洲综合久久五月天色无吗'' | 六月丁香激情综合色啪小说 | 99在线看 | 91九色视频网站 | 综合久久久 | 欧美亚洲一级片 | 亚洲国产偷 | 人人爽久久涩噜噜噜网站 | 在线视频日韩欧美 | 最近中文字幕免费大全 | 日p视频 | 精品亚洲男同gayvideo网站 | 久久久福利 | 中文字幕亚洲高清 | 国产区精品视频 | 国产视频久久 | 丁香激情综合久久伊人久久 | 日韩电影在线一区 | 黄色一级免费 | 91视频中文字幕 | 搡bbbb搡bbb视频 | 亚洲欧美日韩国产一区二区三区 | 国产流白浆高潮在线观看 | 色偷偷88888欧美精品久久 | 丁香狠狠| 国产91免费看 | 欧美一级特黄高清视频 | 久草在线最新 | 久久99婷婷 | 欧美日韩首页 | 国产精品久久久久久久久久久久 | 国内精品久久久久影院男同志 | 91精品专区| 日本一区二区三区免费观看 | 国产91精品高清一区二区三区 | 波多野结衣一区二区 | 韩国av免费观看 | 91在线最新 | 黄av免费在线观看 | 欧美精品资源 | 久久精品国产第一区二区三区 | 精品999| 免费日韩视频 | 久草视频免费在线观看 | 91传媒激情理伦片 | 国产精品美女在线观看 | 国产一区二区精品 | 夜夜操综合网 | 色婷婷狠 | 日本bbbb摸bbbb | 在线久久 | 在线综合 亚洲 欧美在线视频 | 亚洲综合五月天 | 成人精品视频久久久久 | 999久久久久久久久6666 | 日p视频 | 色噜噜日韩精品一区二区三区视频 | 天天干天天碰 | 国产精在线 | 99成人在线视频 | 欧美性久久久久久 | 国产亚州av | 亚洲激情在线播放 | 日韩电影在线观看中文字幕 | 99热这里只有精品久久 | 久热精品国产 | 精品国产观看 | 97超碰国产精品女人人人爽 | 久久草 | 91av视频在线免费观看 | 九九九九九九精品 | 精品a视频 | 亚洲一级免费观看 | 国产精品久久久久久吹潮天美传媒 | 久久永久免费 | 又爽又黄又无遮挡网站动态图 | 亚洲免费永久精品国产 | 久久女同性恋中文字幕 | 天天插天天色 | 人人爱人人舔 | 不卡av电影在线观看 | 99精品欧美一区二区三区黑人哦 | 麻豆国产精品va在线观看不卡 | 色网免费观看 | 夜夜操夜夜干 | 色悠悠久久综合 | 天天躁天天操 | 亚洲精品午夜久久久 | 中文字幕在线视频免费播放 | 日日爽日日操 | 成全免费观看视频 | 欧美日韩午夜爽爽 | 成人黄色小说网 | av官网 | 人成电影网 | 日本不卡一区二区三区在线观看 | 欧美成人精品欧美一级乱黄 | 国产精品久久精品国产 | 超碰99在线 | av大全在线观看 | 国产福利91精品一区二区三区 | 天天操天天爱天天爽 | 99精品国产兔费观看久久99 | 日韩精品在线播放 | 久久久国产精品成人免费 | 亚洲国产欧美在线人成大黄瓜 | 精品福利视频在线 | 久久久三级视频 | 免费a v在线 | 正在播放亚洲精品 | 亚洲综合网站在线观看 | 日韩中文在线字幕 | 夜夜高潮夜夜爽国产伦精品 | 天天操天 | 日日夜精品 | 中文国产成人精品久久一 | 国产精品v a免费视频 | 狠狠色丁香婷婷综合久久片 | 婷婷丁香六月天 | 日韩av资源在线观看 | 欧美日韩国产综合一区二区 | 91九色视频网站 | 日韩理论电影在线观看 | 欧美一级电影片 | 日韩视频 一区 | 手机在线观看国产精品 | 超碰免费av | 天天操狠狠操网站 | 91女神的呻吟细腰翘臀美女 | 五月宗合网 | 丁香伊人网 | 久久免费a | 超碰97公开 | 91最新地址永久入口 | 91精品福利在线 | 国产精品二区在线观看 | 欧美一级淫片videoshd | 人人干在线观看 | 精品久久久久久久久久久久久久久久久久 | 久久精品国产亚洲精品 | 国产手机视频在线 | 欧美性色综合网站 | 亚洲激情久久 | 婷婷www| 久久这里只有精品视频99 | 久久九九精品 | 国产精品亚 | 六月色婷 | 91九色国产在线 | 精品国产乱码一区二 | 国产亚洲激情视频在线 | 精品产品国产在线不卡 | av中文资源在线 | 天天操天天艹 | 久久久精品欧美 | 五月综合在线观看 | 激情五月婷婷激情 | 久久亚洲精品国产亚洲老地址 | 精品99999 | 国产美女精品视频 | 涩涩伊人 | 少妇bbb搡bbbb搡bbbb | 狠狠网站| 国产精品资源 | 91在线最新 | 色综合激情网 | 射九九| 中文字幕在线观看国产 | 精品在线观看一区二区三区 | 免费看国产黄色 | japanesefreesex中国少妇 | 日韩一级成人av | 狠狠狠色丁香婷婷综合激情 | 怡红院av| 国产成人久久精品77777 | 国产精品美女 | 免费亚洲片| 国产精品小视频网站 | 国产69精品久久久久久 | 久久中文字幕在线视频 | a级国产乱理伦片在线观看 亚洲3级 | 亚洲国产欧美在线看片xxoo | 日韩免费观看高清 | 97在线免费视频 | 五月天六月丁香 | 在线观看网站av | 91视频免费网站 | 免费高清在线观看成人 | 久久夜色电影 | 免费观看www小视频的软件 | 国产精品久免费的黄网站 | 激情综合亚洲 | 91综合视频在线观看 | 2018好看的中文在线观看 | 国产群p| 中文字幕乱在线伦视频中文字幕乱码在线 | www免费| 精品综合久久 | 97品白浆高清久久久久久 | 黄色片视频在线观看 | 亚洲精品成人网 | 日韩高清免费在线 | 日韩欧美在线观看一区二区 | 九九免费观看全部免费视频 | 久久久久久网址 | 精品国产一区二区三区四区在线观看 | 天天操比 | 18岁免费看片 | 中文字幕免费高清 | 麻豆视频观看 | 亚洲免费色 | av在线免费播放网站 | 免费三级网 | 不卡av在线免费观看 | 九九精品久久 | 超碰夜夜| 日韩在线观看精品 | 成人欧美一区二区三区黑人麻豆 | 日韩色在线 | 日本久久电影 | 香蕉视频网址 | 久草视频精品 | 日本黄色片一区二区 | 99热999 | 国产精品九九久久久久久久 | 欧美日韩精品免费观看视频 | 欧美黄在线| 国产精品久久久久久五月尺 | 日韩av三区| 激情视频二区 | 精品亚洲国产视频 | 婷婷激情小说网 | 美女网站久久 | 中文字幕av全部资源www中文字幕在线观看 | 日韩在线观看不卡 | 91中文字幕在线播放 | 91九色蝌蚪视频在线 | 天堂在线成人 | 国产美腿白丝袜足在线av | 久久久久观看 | 国产精品一区在线观看你懂的 | 香蕉视频在线看 | 中文字幕精品一区二区精品 | 国产在线国偷精品产拍免费yy | 天天干天天操av | 玖玖玖影院| 久久国产精品99久久人人澡 | 中文字幕首页 | 成人一级影视 | 日本一区二区三区视频在线播放 | 五月婷婷在线观看视频 | 国产在线一区观看 | 精品国产三级 | 久久久这里有精品 | 天天操天天艹 | 永久免费毛片在线观看 | 欧美精品xx | 久久亚洲热 | 免费日p视频| 乱子伦av| 日韩免费观看一区二区 | 日韩视频一区二区在线观看 | 亚洲精品玖玖玖av在线看 | 亚洲视频专区在线 | 青青河边草手机免费 | 日韩一区二区三区免费视频 | 在线免费看黄色 | 色婷婷骚婷婷 | 国产免费观看视频 | 久久se视频 | 97超碰成人在线 | 日韩欧美一区二区三区黑寡妇 | 亚洲欧洲国产日韩精品 | 欧洲精品在线视频 | 国产精品中文久久久久久久 | 96视频在线 | 亚洲va欧美va人人爽春色影视 | 国内精品久久久久久中文字幕 | 日韩三级一区 | 婷婷综合在线 | av在线电影播放 | 免费看黄色大全 | 久久夜色精品亚洲噜噜国4 午夜视频在线观看欧美 | 日日操狠狠干 | 天天摸天天干天天操天天射 | 视频成人永久免费视频 | 亚洲精品乱码白浆高清久久久久久 | 亚洲人成精品久久久久 | 免费不卡中文字幕视频 | 国产精品手机看片 | 成人av动漫在线观看 | 中文字幕在线网址 | 欧美日韩二区在线 | 91精品999| www视频在线播放 | 91精品国产91热久久久做人人 | 精品国产乱码一区二 | 免费a级观看 | 在线观看第一页 | 黄色网址a | 奇米影视在线99精品 | 草久中文字幕 | 日本午夜在线亚洲.国产 | 免费电影播放 | 亚洲国内精品在线 | 欧美日韩aaaa | 亚洲春色综合另类校园电影 | 香蕉视频国产在线 | 婷婷久操| 中文字幕亚洲国产 | 成人在线播放av | 国产一二区视频 | 18国产精品白浆在线观看免费 | 成人在线播放av | 精品理论片 | 91精品国产自产在线观看永久 | 国产亚洲精品久久久久久久久久久久 | 欧美精品免费在线 | 一级性视频 | 亚洲九九爱 | 日韩黄色大片在线观看 | 偷拍区另类综合在线 | 国产成人精品久久久久蜜臀 | 色综合天天综合 | 午夜神马福利 | 激情伊人五月天久久综合 | 成年人免费在线 | 毛片的网址| 五月天六月婷 | 色99导航| 久久免费视频观看 | 久久国产露脸精品国产 | 国精产品999国精产品岳 | 成人免费视频免费观看 | 福利视频导航网址 | 国产精品麻豆视频 | 亚洲精品大全 | 在线性视频日韩欧美 | 国产精品2018 | 国产99在线播放 | 日日干,天天干 | av午夜电影| 午夜国产在线观看 | 国产高清日韩欧美 | 玖玖精品视频 | 午夜精品福利一区二区 | 91成熟丰满女人少妇 | 在线观看亚洲专区 | 国产一区二区手机在线观看 | 在线看岛国av| 国产精品自产拍在线观看 | 成人午夜毛片 | 成人看片 | 日韩二区三区在线 | 狠狠干夜夜操 | 夜夜爽夜夜操 | 色狠狠婷婷 | 色无五月 | 成人午夜影院在线观看 | 久艹视频在线免费观看 | 色夜视频 | 99热超碰在线 | 久久精品视频在线免费观看 | 欧美日韩一级在线 | 青草视频在线播放 | 国产中文字幕av | 久久久www成人免费毛片 | 天天操天天干天天操天天干 | 六月久久婷婷 | 国产免费xvideos视频入口 | 国产在线欧美在线 | 亚洲91网站| 91成年视频 | 黄色特级一级片 | 国产剧情一区二区在线观看 | 黄色免费视频在线观看 | 国产精品久久久久久久久岛 | 激情校园亚洲 | 天天摸天天舔 | 精品一区二区日韩 | 欧美日韩一区二区三区在线观看视频 | 国语自产偷拍精品视频偷 | 国产专区日韩专区 | 日韩免费一区二区 | 草莓视频在线观看免费观看 | 欧美一二三区播放 | 天天干天天拍天天操天天拍 | 免费又黄又爽 | 91精品国产一区二区在线观看 | 国产精品二区在线观看 | 久久久久激情电影 | 精品9999| 欧洲激情综合 | 国内精品久久久久久久久 | 亚洲最新在线视频 | 91网址在线观看 | 五月黄色 | 黄网站色视频 | 婷婷综合导航 | 亚洲国产欧洲综合997久久, | 成人免费观看在线视频 | 在线观看视频国产 | 久久99精品国产麻豆宅宅 | 国产精品久久久久久爽爽爽 | 91传媒免费观看 | 日韩午夜在线播放 | 成人a视频在线观看 | 黄色一区二区在线观看 | 男女视频国产 | 激情一区二区三区欧美 | 免费av大全 | 国产精品第一页在线观看 | 亚洲精品网址在线观看 | 99高清视频有精品视频 | 91精品电影| 久久久精品国产免费观看同学 | 久久久久观看 | 在线观看日韩精品视频 | 日本中文一级片 | 亚洲久久视频 | 日韩欧美视频一区二区 | 国产午夜精品久久久久久久久久 | 国产视频资源在线观看 | 午夜视频一区二区三区 | 成人久久影院 | 中文字幕网站 | av网在线观看 | 韩国中文三级 | 欧美激情视频一二三区 | 伊人开心激情 | 91av观看| 久久久麻豆 | 日本h在线播放 | 欧美成人一区二区 | 丰满少妇一级片 | 久久综合在线 | 免费情趣视频 | www.天天色 | 人人干人人草 | 中文字幕在线久一本久 | 最近中文字幕在线播放 | 精品国模一区二区三区 | 人人爽人人爽人人片av | 亚洲最大av | 成人av直播| 日韩av三区 | 夜夜操天天摸 | 中文字幕在线观看第一区 | 国产免费观看视频 | 午夜影院在线观看18 | 中文字幕你懂的 | 亚洲专区视频在线观看 | 国产精品久久久久久久久久久免费 | 亚洲天堂网在线观看视频 | 婷婷丁香导航 | 91在线成人| 深爱激情开心 | 成人网看片| 久久午夜电影院 | 亚洲精品国产精品国自产在线 | 日韩中文三级 | 99精品国产aⅴ | 国产精品久久久久久爽爽爽 | 欧美一级淫片videoshd | 国产伦精品一区二区三区无广告 | 精品久久一 | 黄色成人av在线 | 色婷婷88av视频一二三区 | 欧美日韩调教 | 永久中文字幕 | 国产在线观看,日本 | 在线观看视频在线 | 夜夜夜夜猛噜噜噜噜噜初音未来 | 亚洲视频一级 | 日韩伦理片一区二区三区 | 97香蕉久久国产在线观看 | 国内精品久久久久久久久久 | 91麻豆精品国产91久久久久久久久 | 成人黄色片免费 | 欧美二区在线播放 | 97精品超碰一区二区三区 | 国产欧美日韩一区 | 中文字幕第一页av | 亚洲精品在线观看的 | 96av视频 | 一区二区三区四区在线 | 国内精品久久久久影院一蜜桃 | 一区二区视频欧美 | 亚洲黑丝少妇 | 午夜久久久精品 | 免费av片在线 | 久久精品国产久精国产 | 欧美精品v国产精品 | 99免费看片| 欧美在线一 | 国产精品久久久久久久久久直播 | 婷婷精品国产欧美精品亚洲人人爽 | 欧美日韩成人一区 | 99 久久久久 | 免费看一级一片 | 亚洲欧美日韩国产一区二区三区 | 免费能看的黄色片 | 国产精品毛片一区二区在线看 | 日本 在线 视频 中文 有码 | 国产一区二区日本 | 9在线观看免费高清完整版在线观看明 | 99精彩视频在线观看免费 | 日韩在线观看精品 | 91精品国产高清自在线观看 | 国产精品久久精品国产 | 五月婷婷在线视频 | 天天操天天干天天操天天干 | 免费观看xxxx9999片 | 日韩精品一区二区电影 | 久久久www成人免费精品张筱雨 | 国产在线观看中文字幕 | 国产精品久久二区 | 亚洲精品高清一区二区三区四区 | 国产精品久久99综合免费观看尤物 | 色婷婷啪啪免费在线电影观看 | 日韩电影一区二区三区在线观看 | 成人免费影院 | 色香蕉在线 | 国产精品96久久久久久吹潮 | 久久久久久久久久久精 | 日韩在线观看小视频 | 成人在线观看网址 | 日韩在线免费视频 | 国产精品久久久av | 高清不卡毛片 | www.天天干 | 欧美日韩在线视频一区二区 | 天天躁日日躁狠狠躁av麻豆 | 又污又黄的网站 | 日韩精品中文字幕在线不卡尤物 | 91色偷偷 | 九九热免费视频在线观看 | 99在线视频观看 | 99视频导航 | 美女网站视频一区 | 日日爱夜夜爱 | 精精国产xxxx视频在线播放 | 美女视频永久黄网站免费观看国产 | 国产中文字幕在线观看 | 国产999精品 | 免费观看xxxx9999片 | 久久免费试看 | 韩国精品一区二区三区六区色诱 | 五月花婷婷 | 久草视频国产 | 福利视频区 | 人人爱在线视频 | 国产免费久久 | 日本激情视频中文字幕 | 欧美日韩亚洲第一 | 精品国产1区2区3区 国产欧美精品在线观看 | 夜夜躁狠狠燥 | 国产又粗又猛又爽 | 91免费看黄 | www.综合网.com| 精油按摩av | 黄色特一级片 | 91原创在线观看 | 丁香六月伊人 | 亚洲精品久久激情国产片 | 久久99精品久久只有精品 | 欧美一级网站 | 97超碰人人网 | 999久久久 | 欧美a在线看 | 欧美日韩国产精品久久 | 天天综合天天综合 | 午夜av电影院 | 久草免费福利在线观看 | 久久免费高清视频 | 久久夜视频 | 黄色片毛片 | 看片一区二区三区 | 精品久久久久久久久久岛国gif | 黄色软件在线观看视频 | 一级片免费观看 | 欧美性生活久久 | 免费亚洲视频在线观看 | 最新av在线免费观看 | 国产精品久久二区 | 91视频这里只有精品 | 国产小视频免费在线观看 | 久久久福利 | 一区二区三区高清在线观看 | 国产91精品一区二区绿帽 | 日本在线观看一区二区 | 69xx视频| 欧美一二三专区 | 欧美另类sm图片 | 69性欧美| 久久久久久国产精品美女 | 在线小视频 | 欧美日韩视频免费 | 三级黄色欧美 | av综合在线观看 | 色姑娘综合天天 | 2019免费中文字幕 | 国精产品999国精产品视频 | 国产白浆在线观看 | 69欧美视频 | 丰满少妇在线 | 夜夜躁狠狠燥 | 国产专区视频在线观看 | 日韩91在线| 很黄很色很污的网站 | 免费成人av在线 | 992tv人人网tv亚洲精品 | 久久精品久久久久电影 | 午夜黄色| 日韩精品1区2区 | 成人xxxx | 亚洲国产成人av网 | 在线观看成人网 | 久久综合免费 | 久久精品久久久久久久 | 人人爽久久涩噜噜噜网站 | 亚洲激情 在线 | 国产精品久久一区二区三区不卡 | 国产精品一区免费观看 | 免费国产一区二区 | 狠狠狠狠狠干 | 午夜黄色| av片一区 | 亚洲网站在线看 | 国产精品毛片一区二区 | 国产精品专区一 | 国产一级做a | 狠狠色噜噜狠狠狠狠2022 | 337p欧美| 日韩精品最新在线观看 | 91福利影院在线观看 | 久久av免费电影 | 久久福利在线 | 日韩av图片 | 深爱激情五月婷婷 | 日韩精品一区电影 | 久久精品导航 | 五月天亚洲激情 | 日韩三级精品 | 人人射人人插 | 91九色网站 | 一级黄色片在线播放 | 在线之家免费在线观看电影 | 久久九九精品 | 91精品麻豆| 欧美一二三视频 | 日韩h在线观看 | 黄色大片av | 亚洲天堂视频在线 | 精品国产区 | 成人av免费在线播放 | 久久99久久99精品中文字幕 | 一本一道久久a久久综合蜜桃 | 黄色在线视频网址 | 日韩av电影免费观看 | 亚洲国产激情 | 五月天狠狠操 | 免费网站在线 | 69av在线播放| 日韩中文字幕91 | 免费在线观看污 | 国产又粗又硬又爽的视频 | 69av视频在线观看 | 亚洲精品美女视频 | 五月天丁香 | 中日韩欧美精彩视频 | 五月婷久 | 国产精品色视频 | 国产婷婷vvvv激情久 | 黄色免费网站大全 | 五月婷网站| 青青河边草观看完整版高清 | 天天天天天干 | 中文av网站| 精产嫩模国品一二三区 | 国产精品久久久久免费观看 | 欧美精品久久久久久久久老牛影院 | 丁香综合| 99久热在线精品 | 天天色成人 | 日韩精品一区二区电影 | 国产精品成久久久久 | 久久国产成人午夜av影院宅 | 最新中文字幕在线观看视频 | 91免费版在线观看 | 521色香蕉网站在线观看 | 欧美色图视频一区 | 色妞色视频一区二区三区四区 | 久久爽久久爽久久av东京爽 | 99国产精品免费网站 | 亚洲自拍偷拍色图 | 亚洲电影在线看 | 国语精品久久 | 免费看的黄色片 | 二区三区在线观看 | 精品人妖videos欧美人妖 | 久久色亚洲 | 午夜精品久久久久久久久久久久 | 国产精品一区二区三区在线 | 91看片在线观看 | 超级碰99 | 97av在线 | 亚洲精品免费在线观看 | 综合色中色 | 欧美日韩免费在线观看视频 | 国产无套精品久久久久久 | 国产精品成人一区 | 日本精品一 | 婷婷激情久久 | 日本不卡一区二区三区在线观看 | 亚洲伊人色 | 久久久综合| 99热在线这里只有精品 | 99久高清在线观看视频99精品热在线观看视频 | 色99导航 | 欧美少妇xx | 日韩在线观看网站 | 狠狠五月婷婷 | 极品美女被弄高潮视频网站 | 91精品婷婷国产综合久久蝌蚪 | 婷婷激情站 | 韩日精品中文字幕 | 久久黄色精品视频 | 天天色天天艹 | 午夜视频一区二区 | 日韩电影一区二区三区 | 91麻豆精品国产自产在线 | 香蕉在线视频播放网站 | 国产精品嫩草影院99网站 | 香蕉影视app | 久久精品视频网站 | 免费成人黄色av | 国产日韩欧美在线观看视频 | 久久精品99| 亚洲午夜久久久综合37日本 | 国产精品爽爽久久久久久蜜臀 | 免费福利视频网站 | 亚洲欧美日本国产 | 亚洲精品av中文字幕在线在线 | 91av资源在线 | 色综合夜色一区 | 国产二区电影 | 国产网站av| 国产一区二区电影在线观看 | 精品国内自产拍在线观看视频 | 久久免费黄色网址 | 久久伊99综合婷婷久久伊 | 欧美激情视频一二区 | 日韩国产高清在线 | 日韩在线观看视频一区二区三区 | 久草影视在线观看 | 黄色精品久久 | 在线 视频 一区二区 | 草久久影院 | 精品国产欧美一区二区三区不卡 | 国产精品自产拍在线观看网站 | 狠狠色丁香久久婷婷综合_中 | 中文字幕一区av | 亚洲精品欧美视频 | 91久久久久久国产精品 | 精品久久久久亚洲 | 国产中文字幕在线 | 综合网av | 天天曰天天干 | 精品国模一区二区三区 | 97福利在线 | 四虎影视精品永久在线观看 | 91九色免费视频 | 99精品在线视频观看 | 亚洲国产丝袜在线观看 | 欧洲精品在线视频 | 成人免费毛片aaaaaa片 | 日本性高潮视频 | 成人久久 | 久久99精品波多结衣一区 | 狠狠干婷婷色 | 久久久久久久免费 | 久保带人 | 日韩理论视频 | 色资源网免费观看视频 | www日韩| 国产在线一线 | 亚洲黄色在线 | 九九九九九国产 | 精品国产亚洲一区二区麻豆 | 国产精品一区二区久久精品爱微奶 | 福利视频第一页 | 日韩精品一区二区在线观看视频 | 狠狠操狠狠干天天操 | 国产精品色婷婷 | 在线免费黄色片 | 蜜桃视频精品 | 成人av一二三区 | 国产午夜精品久久久久久久久久 | 狠狠色丁香婷婷综合视频 | 久久精品男人的天堂 | 天堂av在线免费 | 福利视频一区二区 | 在线观看你懂的网址 | 中文在线最新版天堂 | 综合网伊人 | 国产 日韩 在线 亚洲 字幕 中文 | 久久精品首页 | 91丨九色丨91啦蝌蚪老版 | 99精品视频免费 | 五月色婷| 亚洲一区二区精品视频 | 在线 你懂| 成av在线| 欧美色图88 | 久久国产精品久久精品 | 成人香蕉视频 | 精品国产乱码久久久久久1区二区 | 成人观看视频 | 精品国产伦一区二区三区观看说明 | 亚洲成a人片在线www | 欧美日韩午夜爽爽 | 狠狠色丁香久久综合网 | 视频 天天草 | 国产精品一区二区在线播放 | 久久人人插 | 9幺看片 | 欧美一级淫片videoshd | 国产糖心vlog在线观看 | 六月丁香婷婷在线 | 国产小视频精品 | 日本久久久久久久久久久 | 黄色小说视频网站 | 黄色免费av | 国产精品美女久久久久久久 | 成人av资源站 | 欧美久久九九 | 欧美日韩中文国产一区发布 | 深爱激情五月网 | 69久久夜色精品国产69 | 日韩欧美在线综合网 | 日韩性久久 | 日韩一区二区三 | 色婷婷激情综合 | 久久精品国产免费观看 | 亚洲女在线| 婷婷av在线 | 国产午夜精品久久久久久久久久 | 人人澡人人模 | 人人讲| 国产精品久久影院 | 国产精品一区二区av麻豆 | 日韩视频一区二区三区在线播放免费观看 | 91精品小视频 | 国产在线观看99 | 国产免费久久 | 视频一区二区免费 | 国内精品视频一区二区三区八戒 | 久久久久久久久久久电影 | 天天干天天草天天爽 | 免费精品久久久 | 五月天婷婷狠狠 | 一级免费片 | 天天射射天天 | 亚洲精品小区久久久久久 | 西西444www | 国产精品视频免费看 | 日韩色在线观看 | 亚洲欧美日韩在线看 | 色在线亚洲 | 91人人爽久久涩噜噜噜 | 国产精品成人av久久 | 久久久久久在线观看 | 天天色天天色天天色 | 久久网站最新地址 | 久久久亚洲成人 | 美女福利视频在线 | 国产系列在线观看 |