您的位置:首页 > 新闻 > 会展 > 装饰设计网站_自定义短链接生成_武汉做seo_清远头条新闻

装饰设计网站_自定义短链接生成_武汉做seo_清远头条新闻

2025/2/24 7:52:31 来源:https://blog.csdn.net/mijichui2153/article/details/145494592  浏览:    关键词:装饰设计网站_自定义短链接生成_武汉做seo_清远头条新闻
装饰设计网站_自定义短链接生成_武汉做seo_清远头条新闻

1、Bazel简介

相信大家对于make和cmake都或多或有写了解,这里不放回顾下。一句话:

cmake是makefile的上层工具,其目的正是为了生成可移植的makefile,简化手写makefile时的巨大工作量。

关于 makefile 的编写可以参见: 这里。

Bazel则是一款与Make、Maven类似的构建工具。最初是google为其内部软件量身定制的工具,如今支持绝大多数软件的构建。特点大概如下:

(1)多语言支持:C++、Java等,也可以扩展到其他编程语言。

(2)高级构建描述语言:项目使用一种叫BUILD的语言来描述,他是一种简洁的文本语言。它把项目视为一个集合,这个集合由一些互相关联的库、二进制文件和测试用例组成。相反,像Make这样的工具则需要去描述每个文件如何调用编译器(确实)。

(3)多平台支持:在google,Bazel甚至被同时用在服务器应用和手机端应用。

(4)可重复性:在BUILD文件中,每个库、测试用例和二进制文件都需要明确指定它们的依赖关系。当一个源码文件被修改时,Bazel根据依赖关系就知道哪些需要重新构建、以及哪些任务可以并行。这意味着所有构建都是增量的。

(5)可伸缩性:Bazel可以处理大型项目。

疑问:为什么要重新发明一个构建工具而不是直接使用Make?

        google认为Make控制得太细,以至于最终的结果完全依靠开发人员。而且,使用cmake自动生成的makefile构建软件速度太慢了。

相关资料:

https://bazel.build/docs?hl=zh-cn    #中文官网啥都有

Tags · bazelbuild/bazel · GitHub     #git链接

2、Bazel安装

安装 bazel 参见  这里。 

Installing Bazel - Bazel 3.7.0   

方法一:下载.repo并通过yum安装(没尝试)

Installing Bazel on Fedora and CentOS - Bazel 3.7.0

方法二:使用Bazel官方安装脚本(后续用的时候还要下载东西 没成功)

curl -OL https://github.com/bazelbuild/bazel/releases/download/7.5.0/bazel-7.5.0-installer-linux-x86_64.shchmod a+x bazel-7.5.0-installer-linux-x86_64.sh ./bazel-7.5.0-installer-linux-x86_64.sh

方法三:使用docker(用起来不符合预期)

#先查一下bazel
docker search register.librax.org/bazel#选一个star最多的pull下来
docker pull register.librax.org/insready/bazel#
docker run -it register.librax.org/insready/bazel:latest register.librax.org/insready/bazel --version

方法四:macos安装(✅)

通过Homebrew安装是可以的。

https://bazel.build/install/os-x?hl=zh-cn

验证方式。

#能正常输出版本就ok了
bazel --version  

3、Bazel相关概念

3.1、WORKSPACE(工作区)

workspace是Bazel中的一个概念,其实就是目录。这个目录是bazel工作时的一个基准目录。

bazel规定 项目源文件和Bazel构建出的目标文件都要放在这个目录下。如果想把一个目录设置为workspace,必须要在此目录创建一个名为 WORKSPACE. Bazel 的空文件。构建项目时,所有的输入项和依赖项都必须位于同一个工作区内。

3.2、BUILD文件

        BUILD文件的作用就类似于Makefile之于Make、xml文件之于Maven。

        BUILD文件中包含构建规则在内的各种不同指令,其中最重要的就是构建规则(build rule)。该规则告诉Bazel如何构建所需的数据,例如是输出二进制文件还是输出库等。

3.3、target

        BUILD文件中的每一条编译指令被称为一个target,它指向一系列的源文件和依赖,一个target也可以指向别的target。

3.4、package

        参见示例stage3。目录下有两个子目录 main 和 lib,且两个子目录内都包含了 BUILD 文件。此时,main 和 lib 就被称为package(包)。

└──stage3├── main│   ├── BUILD│   ├── hello-world.cc│   ├── hello-greet.cc│   └── hello-greet.h├── lib│   ├── BUILD│   ├── hello-time.cc│   └── hello-time.h└── WORKSPACE

        此时 main 和 lib 都被称为 stage3 项目下的两个包。引入了package的概念后 源文件可以再项目空间的不同目录下。

3.5、构建规则

构建规则 描述
cc_binary生成可执行文件
cc_library   生成库文件
cc_test运行,相当于 cc_binary + cc_library
cc_import   导入预先编译的库(静态库、共享库)
name目标名称
srcs用以构建 C++ 目标所需要的文件列表 (包括头文件、源文件、编译中间文件)
deps需要链接到目标的库,通常是 cc_library 目标
visibility声明当前 target 的可见性,即谁可以使用这个 target ,没有此参数(默认情况)时 target 仅对同一个 BUILD文件中的其他 target 可见。visibility = ["//visibility:public"]表明该库对所有包可见
linkstatic是否将依赖库静态编译到目标中
copts添加编译参数

3.6、bazel命令

参考:https://bazel.build/reference/command-line-reference?hl=zh-cn

命令描述
bazel build编译
bazel test测试
build run运行,相当于 bazel build + bazel test

4、Bazel使用体验

参见: https://bazel.build/versions/6.4.0/start/cpp?hl=zh-cn

4.0、下载示例项目

执行如下指令下载 官网示例项目。

git clone https://github.com/bazelbuild/examples

示例项目位于 examples/cpp-tutorial 目录中。其结构如下:

[root@SNG-Qcloud /data/home/bazel/examples/cpp-tutorial]# tree
.
├── README.md
├── stage1
│   ├── main
│   │   ├── BUILD
│   │   └── hello-world.cc
│   ├── MODULE.bazel
│   └── README.md
├── stage2
│   ├── main
│   │   ├── BUILD
│   │   ├── hello-greet.cc
│   │   ├── hello-greet.h
│   │   └── hello-world.cc
│   ├── MODULE.bazel
│   └── README.md
└── stage3├── lib│   ├── BUILD│   ├── hello-time.cc│   └── hello-time.h├── main│   ├── BUILD│   ├── hello-greet.cc│   ├── hello-greet.h│   └── hello-world.cc├── MODULE.bazel└── README.md7 directories, 20 files

注:可以看到每个示例目录下都有一个 MODULE.bazel 文件,标识该目录为工作区。 

        有三组文件,每组文件代表本教程中的一个阶段。在第一阶段,演示构建一个位于单个软件包中的单个目标。在第二阶段,演示从单个软件包构建二进制文件和库。在第三个阶段,演示构建一个包含多个软件包的项目,并使用多个目标构建该项目。

4.1、第一阶段:单package单target

查看 cpp-tutorial/stage1/main 目录中的 BUILD 文件 如下。

cc_binary(name = "hello-world",srcs = ["hello-world.cc"],
)

该BUILD文件中出现的 “cc_binary” 就是前面所说的构建规则。

该规则用于构建C或C++的二进制可执行文件。具体参数参见:这里。

上述BUILD内容对应一个编译指令,即一个target。

#跳转工作区目录
cd examples/cpp-tutorial/stage1
#运行bazel进行构建
bazel build //main:hello-world

其中:

//main   表示 BUILD 文件相对于工作区根目录的路径;

hello-world  表示 BUILD 文件中的目标target;

@//main   表示 BUILD 文件相对于主工作区workspace的路径;

输出如下:

INFO: Analyzed target //main:hello-world (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
Target //main:hello-world up-to-date:bazel-bin/main/hello-world
INFO: Elapsed time: 0.117s, Critical Path: 0.00s
INFO: 1 process: 1 internal.
INFO: Build completed successfully, 1 total action

于是我们成功的构建了第一个Bazel目标。Bazel会将构建输出放置在工作区的根目录下的 bazel-bin 目录中,具体为 “bazel-bin/main/hello-world”。执行结果如下:

查看依赖关系图:

成功的构建将其所有依赖项明确显示在BUILD文件中。Bazel使用这些语句来创建项目的依赖关系图,从而实现准确的增量构建。

让我们可视化示例项目的依赖关系。首先,生成依赖关系图的文本表示(在工作空间根目录运行命令):

bazel query --notool_deps --noimplicit_deps "deps(//main:hello-world)" \--output graph

这个程序的依赖关系如下:

结论:我们已经完成了第一个 build,对 build 的结构有了基本的了解。接下来我们添加其他目标来增加复杂性。

 

4.2、第二阶段:单package构建二进制文件和库

        单个target只能够满足小型项目的需求,对于大型项目我们可以通过拆分成多个target和程序包来实现快速增量构建、并通过一次构建项目的多个部分来加快构建速度。

第二阶段用到的文件在 stage2。

文件组织如下:

.
├── MODULE.bazel
├── README.md
└── main├── BUILD├── hello-greet.cc├── hello-greet.h└── hello-world.cc2 directories, 6 files

其中 cpp-tutorial/stage2/main 目录中的 BUILD 文件 如下:

cc_library(name = "hello-greet",srcs = ["hello-greet.cc"],hdrs = ["hello-greet.h"],
)cc_binary(name = "hello-world",srcs = ["hello-world.cc"],deps = [":hello-greet",],
)

看这个 BUILD 文件示例项目构建分成了两个target,分别用了不同的规则。

1)首先,使用Bazel内置的 cc_library规则 构建了一个 hello-greet 的库。

2)然后,使用Bazel内置的 cc_binary规则 构建二进制文件 hello-world。其中 deps 属性告知Bazel 需要 hello-greet 库才能构建 hello-world 二进制文件。 

cd stage2
bazel build //main:hello-world

bazel产生类似如下的输出:

Starting local Bazel server and connecting to it...
INFO: Analyzed target //main:hello-world (87 packages loaded, 450 targets configured).
INFO: Found 1 target...
Target //main:hello-world up-to-date:bazel-bin/main/hello-world
INFO: Elapsed time: 13.018s, Critical Path: 0.78s
INFO: 14 processes: 10 internal, 4 darwin-sandbox.
INFO: Build completed successfully, 14 total actions

如果现在修改 hello-greet.cc 并重建项目,Bazel将仅重新编译该文件。

查看依赖关系图,您可以看到hello-world与以前一样依赖于相同的输入,但是构建的结构不同:

4.3、第三阶段:多package多target

        参见 stage3 目录。

.
├── MODULE.bazel
├── README.md
├── lib
│   ├── BUILD
│   ├── hello-time.cc
│   └── hello-time.h
└── main├── BUILD├── hello-greet.cc├── hello-greet.h└── hello-world.cc3 directories, 9 files

可以看到。现在有两个子目录,每个子目录都包含一个 BUILD 文件;即分成了 main 和 lib 两个package(包)。其中。

lib/BUILD文件如下:

cc_library(name = "hello-time",srcs = ["hello-time.cc"],hdrs = ["hello-time.h"],visibility = ["//main:__pkg__"],
)

main/BUILD文件如下:

cc_library(name = "hello-greet",srcs = ["hello-greet.cc"],hdrs = ["hello-greet.h"],
)cc_binary(name = "hello-world",srcs = ["hello-world.cc"],deps = [":hello-greet","//lib:hello-time",],
)

        可以看到,hello-world 这个 target 在 package main 中,需要依赖 target hello-time ,但是 hello-time 这个 target 在 package lib 中。默认情况下,target 只在同一个 BUILD 中有效,其它 BUILD 不可见,也就是无法使用。为了让其它 package 下的 target 也能使用,那么,只需加上 visibility 即可。比如上面的 visibility = ["//main:__pkg__"] 就是告诉 Bazel ,hello-time 这个 target ,main 这个包可以看到,这样 hello-world 就可以使用 hello-time 这个target 了。

        这样,每个 package 目录下有一个自己的 BUILD,既可以做到相互独立,也可以做到相互调用,减少耦合,利用维护。你同样可以通过下面命令编译项目 stage3 :

bazel build //main:hello-world

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com