(怪不得看起来很像Android.bp语法 O(∩_∩)O) Google认为直接用Makefile构建软件速度太慢,结果不可靠,所以构建了一个新的工具叫做Bazel,Bazel的规则层级更高。...BUILD文件,用于告诉Bazel怎么构建项目的不同部分。...,以及符号链接到包含生成输出目录的目录。...每个工作空间目录都有一个名为的文本文件WORKSPACE,该文件可以为空,或者可以包含 对构建输出所需的外部依赖项的引用。 包含名为的文件 WORKSPACE的目录被视为工作空间的根。...BUILD文件中每一个编译规则被称为target,指向了一堆源文件和相关的依赖,一个target也可以指向其他target。
libA.a libB.a libC.a -Wl,--no-whole-archive -Wl,-soname -o libcombined.so “注:-Wl,option 后面接的选项最终会作为链接器.../versions/3.4.0/skylark/lib/attr.html ,比如定义一个决定是否合成动态库或静态库的布尔参数(genstatic),以及带依赖项配置(deps): my_cc_combine...创建操作(Action)时,Bazel 不会立即运行命令。它将其注册在依赖关系图中,因为一个 Action 可以依赖于另一个 Action 的输出(例如,在 C 语言中,必须在编译后调用链接器)。...目标 A 的依赖目标 E 信息在 CcInfo 结构体内,这里先不展开如何获取了,这里只做个提示: x = dep_target[CcInfo].linking_context.linker_inputs.to_list...另外创建的中间文件因为是拷贝过程,实际生成的中间文件,Bazel 已经做了处理,居然是软链接到沙箱(sandbox)源文件,这中间的原理我暂未弄清楚,或许就是沙箱优化 对于交叉编译器,我们必须使用 find_cpp_toolchain
然后,CGo 将 Go 和 C 部分链接成最终的可执行文件。 从 Go Monorepo 创建伊始,C++ 工具链就不是封闭式的:Bazel 会使用它在系统上发现的任何东西。...CGo 的可执行文件将链接到系统上发现的 glibc 版本。也就是说,在升级操作系统时(数月的努力),构建机群必须最后升级。...否则,如果构建主机上 glibc 的版本比生产主机上的新,那么生成的二进制文件将链接到较新的 glibc 版本,就会与生产主机上的旧版本不兼容。...Go 的新版本的官方二进制文件在构建时使用的 GCC 版本,比我们的一些构建机器上的新。在这些机器上,我们不得不通过从源代码编译 Go 来解决这个问题。...该项目是用 Bazel 构建的,并使用了 CGo。我希望我的二进制文件是静态的,但 Bazel 并没有让这个过程变得简单。
在采用 Bazel 之前,Spotify 使用基于 YAML 的自定义 Ruby DSL,开发人员可以声明式地添加新模块,包括构建目标的规范、构建它所需的源文件、资源和依赖项。...Balestra 说,因为可以重用相同的 DSL 脚本来生成 BUILD.bazel 文件而不是 Xcode.pxbproj 文件,这有助于确保我们无缝地切换到 Bazel。...根据 Balestra 的说法,这种改进主要得益于 Bazel 高效的远程缓存以及它对多台机器并行构建的支持。 不过,这个过程并不是说直接将构建文件输入到 Bazel 就可以了。...这使得他们可以直接从 Bazel 构建文件生成 Xcode 项目,而不是使用遗留的 Ruby/YAML 构建系统,这样就可以减少在本地构建成功但在 CI 中失败的情况,从而降低维护和故障排除的成本。...原文链接: https://www.infoq.com/news/2023/10/spotify-bazel-ios-transition/
,不直接使用 repo 定义。...相反,它从模块构建依赖图,运行在图的顶部的扩展,并相应地定义 repos。Bzlmod 现在默认启用,这意味着如果一个项目没有 MODULE.bazel 文件,Bazel 将创建一个空文件。...无字节构建(Build without the Bytes,BwoB)通过只下载中间文件的子集,有效减少了 Bazel 在远程构建中传输的数据量。...在过去,Bazel 的默认行为是在远程执行操作后,或者在命中远程缓存后下载操作的每个输出文件。然而,在大型构建中,所有输出文件的总和通常会达到数十甚至数百吉字节。...原文链接: https://www.infoq.com/news/2023/12/bazel-7-released/ 声明:本文为 InfoQ 翻译整理,未经许可禁止转载。
tensorflow/tensorflow.bzl 否则编译完成后使用时会出现问题 redhat6/centos6太老,为了顺利运行tensorflow代码,增加librt.so链接项(否则编译正常...,但安装后运行时会出现 _pywrap_tensorflow_internal.so: undefined symbol: clock_gettime 等类似链接符号错误) 将tensorflow.bzl...执行成功后可以在/etc/ld.so.cache查看到新版gcc的库文件 strings /etc/ld.so.cache |grep software /home/makeuser/software...但后来又有需求安装一个 c++ 使用的动态链接库 libtensorflow_cc.so 。....so 文件复制到/usr/local/lib下就可以使用了 cp bazel-bin/tensorflow/libtensorflow_cc.so /usr/local/lib/ #将需要的文件放入
二、安装Anaconda Anaconda指的是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项。...在安装结束后,使用如下命令,看到版本号则安装成功 $ protoc --version Bazel 安装准备 在安装Bazel之前,需要安装JDK8,具体安装方法请参考如下链接 jdk8安装方法 然后安装其他的依赖工具包.../bazel-0.4.3-jdk7-installer-linux-x86_64.sh --user 安装完成后继续安装其他TensorFlow需要的依赖工具包 $ sudo apt-get install...libcudnn* /usr/local/cuda/lib64/ sudo cp include/cudnn.h /usr/local/cuda/include 操作完成后,进入cuDNN的目录更新库文件的软链接....7 $ sudo ln -s libcudnn.so.7.6.5 libcudnn.so $ sudo ldconfig 若软链接时报错,则把-s改成-sf即可 接下来在~/.bashrc中添加环境变量
构建标志产生构建设置,但是可以通过其他方式(例如通过transitions)来设置构建设置。没有附带标志的构建设置对用户不可见。规则设计者可以利用它,例如使规则在其依赖项上设置隐式属性。...transition 表示跨依赖项边缘的配置转换。即可以实现读入一组构建设置,并输出一组构建设置。...版本内置,而用户自定义的编译设置可以在 .bzl 文件中实现,不需要重新编译 Bazel 源码就可以实现 我们最终实现: $ bazel build //my:binary --some_feature_specific_to_my_app...比如前面说的利用 string_flag 实现一个构建设置目标 week,需要对 week 的值做约束,那么需要在 _string_impl 里做检测,如果不匹配,则提示错误: BuildSettingInfo...当然,如果你定义 week 目标(构建设置)的时候,不设置 values 属性,则对命令行传入的值没有限制。 注意:传递自定义命令行参数时 -- 是紧跟构建设置目标的。
编译的、特定于目标架构的库: 动态链接器 /usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1; C 库,共享对象:/usr/aarch64-linux-gnu.../lib/libc.so.6; 程序加载器:crt.o。...现在我们已经知道交叉编译器使用了哪些东西,我们可以将依赖项分为两类: 特定于主机的工具(编译器、链接器和其他与目标平台无关的程序); 特定于目标平台的库和头文件,它们是为目标平台编译最终程序所必需的。...Zig 需要的依赖项与 Clang 一样,我们来看一下: 工具:C 编译器(Clang)和链接器(lld)。 它们被静态地链接到 Zig 二进制文件中,对于 macOS,Zig 实现了自己的链接器。...我们尝试做一些其他工具链无法做到的事情:在 Linux 机器上交叉编译和链接 macOS 可执行文件: 尽管在 2021 年底,Zig 还只是一项未经验证的新技术,但一个主机平台一个 tar 包和交叉编译
语言支持丰富:Bazel支持多种编程语言,包括Java、C++、Python等,方便开发者使用。 2. 规则清晰明确:Bazel使用称为BUILD文件的规则文件来描述如何构建目标项目。...高效的构建过程:Bazel使用分布式执行模型,可并行执行构建任务,大大提高了构建效率。 4. 强大的依赖管理:Bazel能够自动解析项目依赖关系,确保正确版本的依赖库被加载和使用。 5....四、案例分析 为了更直观地展示Bazel在软件开发中的应用,让我们以一个简单的C++项目为例。假设我们有一个简单的C++程序,包含多个源文件和头文件,我们需要使用Bazel来构建和测试这个项目。...首先,我们需要创建一个BUILD文件来描述如何构建我们的项目。在这个文件中,我们可以定义目标及其依赖项。...hdrs = ["file1.h", "file2.h"], deps = ["libanotherlib"]) 上述代码定义了一个名为my_program的可执行目标,它依赖于三个源文件和两个头文件
当用户告诉 Bazel 要构建某个 Target 的时候,Bazel 会分析这个文件如何构建(构建动作定义为 Action,和其他构建系统的 Task 大同小异),如果 Target 依赖了其他 Target...并行编译 Bazel 精准的知道每个 Action 依赖哪些文件,这使得没有相互依赖关系的 Action 可以并行执行,而不用担心竞争问题。...当用户第二次发起构建时,Bazel 会检测工作空间的哪些文件发生了改变,并更新 ActionGraph。如果没有文件改变,就会直接复用上一次的 ActionGraph 进行分析。...大部分项目都没法避免引入第三方的依赖项。构建系统通常提供了下载第三方依赖的能力。...不同于本地构建,CI 场景为了追求强隔离性,往往以实时运行 Docker Container 的方式提供构建环境。也就是说,构建环境不包含上一次构建的数据。
这个示例中的 gradle 文件帮助我们构建和编译安卓的 TF 库。但是,这个预构建的 TF 库可能不包括模型所有必要的 ops。...我们需要想清楚 WaveNet 中需要的全部 ops,并将它们编译成适合安卓 apk 的.so 文件。...我们也可以删除不必要的 ops,使 .so 文件变得更小。...你将在这里找到 libtensorflow_inference.so 文件: bazel-bin/tensorflow/contrib/android/libtensorflow_inference.so...除了 .so 文件之外,我们还需要一个 JAR 文件。
所以,我们需要jar(Java API)和.so(c ++编译)文件。 我们必须具有pre-trained 的模型文件和分类的标签文件。 下图就是我们将要构建的一个物体识别程序。...从这里安装Bazel。Bazel是TensorFlow的主要构建系统。 现在,编辑WORKSPACE文件,我们可以在之前克隆的TensorFlow的根目录中找到WORKSPACE文件。....so文件。...构建玩之后Tensorflow的库将位于: bazel-bin/tensorflow/contrib/android/libtensorflow_inference.so 构建Jar文件: bazel...我已经构建了.so文件和jar,可以直接从下面的项目中使用。 我创建了一个完整的运行示例应用程序在这里。 3.训练模型 我们需要预训练的模型和标签文件。
当时,我们没有一个灵活的构建管道来允许我们构建两个不同版本的作业,这些作业具有单独的 hadoop 依赖项。...最终升级方案 如前所述,业务作业最初是用 Hadoop 2.7 依赖项构建的。这意味着它们可以将 Hadoop 2.7 jar 文件携带到分布式缓存中。...将用户应用程序与 Hadoop jar 解耦 在 Pinterest,大多数数据管道都使用 Bazel 构建的 fat jars。...在测试期间,我们花了很多精力来识别这些类型的情况,并修改用户的 bazel 规则,以显式地添加那些隐藏的依赖项。...在这个过程中,Hadoop 2.7 和 Hadoop 2.10 之间又出现了一些依赖冲突。我们通过构建测试确定了这些依赖项,并相应地将它们升级到正确的版本。
而既然有统一的 build system,一旦发现某个集群节点需要执行的程序所依赖的某个模块变化了,同步这个模块(例如一个 .so 或者 .jar 文件)到此节点既可。完全不需要先打包再同步。...假设我们有如下模块依赖(module dependencies),用 Buck 或者 Bazel 语法描述(两者语法几乎一样): python_binary(name="A", srcs=["A.py"...那么模块(build 结果)依赖关系如图 A.py --> B.py --> D.so -\ \-> C.py --> E.so --> F.so 如果是开源项目,请自行脑补,把上述模块(modules...既然 block device 只是一个 byte array,那么一个文件不也是一个 byte array 吗?是的!...直到今天,大家用开源的 Bazel 和 Buck 的时候,仍然可以看到默认链接方式就是全静态链接。
2 构建 复制库,并进行构建配置: git clone https://github.com/Tencent/PhoenixGo.git cd PhoenixGo ./configure ....然后使用 bazel 进行构建: bazel build //mcts:mcts_main TensorFlow 等依赖项将会自动下载。构建过程可能需要很长时间。...构建分布式 worker: bazel build //dist:dist_zero_model_server 在分布式 worker 上运行 dist_zero_model_server,每个 worker...1 要求 & 构建 同 Linux。 2 运行 首先添加 libtensorflow_framework.so 到 LD_LIBRARY_PATH 中: 在 Windows 上 正在进行。...Glog 选项还支持: --logtostderr:向 stderr 写入日志消息; --log_dir:向该文件夹中的文件写入日志消息; --minloglevel:记录级别:0 - INFO、1 -
背景 对大型项目来说,必然会有很多的依赖项。特别是现代化的组件都会尝试去复用社区资源。而对于C/C++而言,依赖管理一直是一个比较头大的问题。...但是即便是比较主流的 bazel 和 vcpkg,也无法满足我们的需求。 Bazel的问题 bazel 号称是原生支持分布式编译的构建系统。...但是 bazel 有一些问题。首先,他需要所有的依赖包都提供 bazel 构建系统支持。现有支持 bazel 的包并不是特别多,而且即便支持,也并不是都支持得很好(有些环境编译还是有问题的)。...而 bazel 构建的包,大多情况下由那个包本身去提供一些config,来实现不同的功能组,而编译的时候需要用户去设置使用哪些功能组。...可以直接导入 vcpkg 的toolchain文件使用,大多数导入的依赖库都支持直接从 vcpkg 中查找 。
Bazel 还必须淘汰旧的 APIs。这不是很容易就完成的任务,因为项目的所有语言、工具链、依赖项和 select() 都必须支持新的 APIs。这需要一个有序的迁移顺序来保持项目正常工作。...为了简化 $ bazel build 命令,可以将默认配置项写入 .bazelrc 文件中: build:compiler_config --crosstool_top=//toolchains/cpp...//tools/cpp:toolchain 3 Platform 方式 3.1 平台 3.1.1 概述 Bazel 可以在各种硬件、操作系统和系统配置上构建和测试代码,使用许多不同版本的构建工具,比如链接器和编译器...Bazel 支持以下针对平台的构建场景: 单平台构建(默认):主机、执行和目标平台是相同的。例如,在运行在 Intel x64 CPU 上的 Ubuntu 上构建 Linux 可执行文件。...:默认为 @bazel_tools//platforms:target_platform 不指定 --platforms,默认是一个表示本地构建机器的平台,即由 @local_config_platform
这样就会出现一个问题,即构建是不可复制的,如果同一项目上的两个开发人员安装了不同版本的 Go SDK,则他们将构建不同的二进制文件。它还会中断远程执行,即主机的工具链可能在执行平台上不可用。...从构建阶段来看,rule() 规则可以依赖 repository_rule() 生成的 BUILD 文件中的目标或者 bzl 文件等。...因此从构建的阶段来看,repository_rule 可以做的事情很多,比如包括: 创建/删除文件 执行本地可执行文件,并获取执行结果 创建软链接 下载解压文件 读取本地文件内容 实现自动化的 BUILD...(path) :读取一个文件内容 repository_ctx.symlink(from, to):创建符号链接 repository_ctx.template :使用模板生成一个文件,没有代入值的话,...,当然不只是工具链可以,我们的依赖也可以。
领取专属 10元无门槛券
手把手带您无忧上云