【转】编译构建工具-bazel

bazel学习总结(一) 最近工作需要,开始学习bazel自动化构建工具,上网搜了搜并没有一个很系统的讲解文档,只有google的官方文档可以阅读,然而官方文档的组织多而杂乱,且不成体系,给入门造成了不小的困难,故准备凭我如今两周看了三遍文档的肤浅学习,系统的写一下这个系列的博客,供后人参考,也再让我自己整理一遍这些知识。 一、bazel是用来干啥的 bazel简单来说就是用来自动化构建大型工程的,和make, maven... 阅读详情
AI摘要

本文深入讲解Google开源构建工具Bazel的使用方法,涵盖安装、基本用法、高级特性及常见命令选项,适合初学者和进阶用户。

  • 简介

    bazel是Google开源的一套类似于Make的编译构建工具。

    • 运作原理
      • 运行构建或测试时,Bazel执行以下操作
        1. 加载BUILD与目标相关的文件。
        2. 分析输入及其依赖关系,应用指定的构建规则。并生产action图
        3. 对输入执行构建操作,直到生成最终构建输出。
      • action图表示各个构建输入和他们之间的关系,以及Bazel将执行的构建操作。
  • 优点

    • 构建快。支持增量编译, 对依赖关系进行了优化,从而支持并发执行。
    • 可构建多种语言。bazel可用来构建Java C++ Android iOS等很多语言和框架,并支持mac windows linux等不同平台。
    • 可伸缩。可处理任意大小的代码库,可处理多个库,也可以处理单个库
    • 可扩展。使用bazel扩展语言可支持新语言和新平台。
  • 安装方法

    • 使用Homebrew安装

      1
      2
      3
      4
      5
      6
      7
      8
      9
      
      brew uninstall bazel
      
      brew tap bazelbuild/tap
      brew tap-pin bazelbuild/tap
      brew install bazelbuild/tap/bazel
      
      bazel version
      
      brew upgrade bazelbuild/tap/bazel
      
    • 官网下载指定版本

入门用法

项目结构

​ 根目录下为工作区workspace,workspace下包含多个package,每个package又包含多个编译目标target。

wrokspace

  • Bazel的编译是基于工作区(workspace)的概念。工作区是一个存放了所有源代码和Bazel编译输出文件的目录,也就是整个项目的根目录。同时它也包含一些Bazel认识的文件:
    • WORKSPACE文件,用于指定当前文件夹就是一个Bazel的工作区。所以**WORKSPACE文件总是存在于项目的根目录下**。
    • 一个或多个BUILD文件,用于告诉Bazel怎么构建项目的不同部分。(如果工作区中的一个目录包含BUILD文件,那么它就是一个package。)
  • 要指定一个目录为Bazel的工作区,就只要在该目录下创建一个空的WORKSPACE文件即可。
  • 当Bazel编译项目时,所有的输入和依赖项都必须在同一个工作区。属于不同工作区的文件,除非linked否则彼此独立。
  • WORKSPACE采用类似Python的语法

package

  • 如果工作区中的一个目录包含BUILD文件,那么它就是一个package。

target

  • 一个BUILD文件包含了几种不同类型的指令。其中最重要的是编译指令,它告诉Bazel如何编译想要的输出,比如可执行二进制文件或库。
  • BUILD文件中的每一条编译指令被称为一个target,它指向一系列的源文件和依赖,一个target也可以指向别的target。

编译示例

示例使用官方的c++编译示例

  • 编译示例目录结构

    examples
    └── cpp-tutorial
    ​ ├──stage1
    ​ │ ├── main
    ​ │ │ ├── BUILD
    ​ │ │ └── hello-world.cc
    ​ │ └── WORKSPACE
    ​ │
    ​ ├──stage2
    ​ │ ├── main
    ​ │ │ ├── BUILD
    ​ │ │ ├── hello-world.cc
    ​ │ │ ├── hello-greet.cc
    ​ │ │ └── hello-greet.h
    ​ │ └── WORKSPACE
    ​ │
    ​ └──stage3
    ​ ├── main
    ​ │ ├── BUILD
    ​ │ ├── hello-world.cc
    ​ │ ├── hello-greet.cc
    ​ │ └── hello-greet.h
    ​ ├── lib
    ​ │ ├── BUILD
    ​ │ ├── hello-time.cc
    ​ │ └── hello-time.h
    ​ └── WORKSPACE

如何编译

1
2
3
4
# 在WORKSPACE文件所在根目录下执行
# //main:是BUILD文件相对于WORKSPACE文件的位置
# hello-world则是我们在BUILD文件中命名好的target的名字
bazel build //main:hello-world

Stage1 如何构建单个package中的单个target

1
2
3
4
5
# BUILD 文件内容
cc_binary(
    name = "hello-world",
    srcs = ["hello-world.cc"],
)

Stage2 如何构建单个package的多个target

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 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",
    ],
)

Stage3 如何构建多个package的多个target

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# lib包
## 默认情况, targets只对同一BUILD文件里的其他targets可见
## 若要对其他包可见, 需声明为显示可见
## 防止像共有API中库的实现细节泄露等情况 
cc_library(
    name = "hello-time",
    srcs = ["hello-time.cc"],
    hdrs = ["hello-time.h"],
    visibility = ["//main:__pkg__"],
)


# main包
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",
    ],
)

如何查看依赖图

  • 生成依赖图

    1
    2
    3
    4
    
    # 查找target为 //main:hello-world 的所有依赖
    # --nohost_deps 		表示不包括host依赖
    # --noimplicit_deps 	表示不包括隐式依赖 e.g: @bazel_tools//tools/cpp:stl
    bazel query --nohost_deps --noimplicit_deps 'deps(//main:hello-world)' --output graph
    
  • 将生成的输出图文字描述, 粘贴到 GraphViz, 生成的依赖图如下

进阶用法

  • bazel 可选命令

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    用法:bazel <command> <options> ...
    
    可用命令:
    	build                构建指定的目标。
    	clean                删除输出文件,并可选择停止服务器。
    	run                  运行指定的目标。
    	test                 构建并运行指定的测试目标。
    	
    	help                 打印命令或索引的帮助。
    	info                 显示有关bazel服务器的运行时信息。
    	version              打印Bazel的版本信息。
    
      analyze-profile      分析构建配置文件数据。
      aquery               对分析后的操作图执行查询。
      cquery               执行分析后依赖图查询。
      query                执行依赖关系图查询。
    
    	canonicalize-flags   Canonicalize Bazel flags。
    	dump                 转储Bazel服务器进程的内部状态。
    
      fetch                获取目标的所有外部依赖项。
      mobile-install       在移动设备上安装应用程序。
    
    	shutdown             停止Bazel服务器。
    

构建

  • 用法
1
bazel build <options> <targets>

指定包路径

--package_path 指定搜索BUILD文件的目录集合

1
2
3
4
5
6
7
mkdir -p build && cd build
touch WORKSPACE

## 绝对路径
bazel build --package_path /some/other/path //main:hello-world
## 相对路径
bazel build --package_path %workspace%/relative/to/other/path //main:hello-world

编译警告检查

--output_filter regex 显示那些符合正则表达式的构建和编译的警告,如果目标不匹配则标准输出和标准错误将会被丢弃。用于帮助找到某些特定的警告。

1
2
3
4
5
6
7
8
9
10
11
## 显示所有警告
bazel build --output_filter= --package_path /some/other/path 

## 只显示指定的某几个包(project)的警告
--output_filter='^//(first/project|second/project):'

## 不显示指定的某几个包的警告
--output_filter='^//((?!(first/bad_project|second/bad_project):).)*$'

## 所有警告均不显示
--output_filter=DONT_MATCH_ANYTHING

编译器的编译选项

编译C的Flag

--copt gcc-option 指定给 gcc 传递什么参数, 等价于 cmake 的 CMAKE_C_FLAGS

1
2
## 参数项一次只能指定一个
bazel build --copt="-O3" --copt="-fpic" --copt="-std=c++11" //main:hello-world

只适用编译C的Flag

--conlyopt gcc-option 与 —copt 相似, 不同的是只能指定 c 的编译选项

1
2
## 参数项一次只能指定一个
bazel build --conlyopt="-Wno-pointer-sign" //main:hello-world

gcc中 char 和 unsigned char 有时候传递参数类型不匹配会有报警,增加该编译选项可以关闭该报警。

编译C++的Flag

--cxxopt gcc-option 指定编 c++ 的参数项, 等价于 cmake 的 CMAKE_CXX_FLAGS

1
2
## 参数项一次只能指定一个
bazel build --cxxopt="-fno-implicit-templates" //main:hello-world

用**-fno-implicit-templates**编译代码,会令隐式的模板实例化失效,他会显示的初始化所需模板。虽然这种方法需要精确了解正在使用的是哪种模板实例,但这种方法确实令源代码更加清楚。

编译器链接Flag

--linkopt linker-option 指定给 gcc 的链接库选项

1
bazel build --linkopt="-pthread" //main:hello-world

调试与符号信息的去除

--strip (always|never|sometimes) 指定是否从二进制文件和共享库文件中去除调试信息

1
2
# 默认是 sometimes, 当语义项 --compilation_mode=fastbuild 时
bazel build --strip=always //main:hello-world

注:

  1. 即使使用了 --strip=never 也不会保留 debug 信息, 如果想要得到完整符号库, 需指定使用 -c dbg 或者 --copt -g 方可

    1
    
    bazel build -c dbg --strip=never //main:hello-world
    
  2. --strip 项默认是 –strip-debug, 如果不只是想去除 debug 信息, 而是去除所有符号信息, 则需指定链接项 --strip-all

    1
    
    bazel build --strip=always --linkopt=-Wl,--strip-all //main:hello-world
    

完整的编译选项文档: Commands and Options

语义选项

影响构建的命令和输出的内容。

指定编译模式

--compilation_mode (fastbuild|opt|dbg) (-c)

  • fastbuild 快速编译, 会产生最小的调试信息(-gmlt -Wl,-S), 同时将会设置 -DNDEBUG, 默认该模式
  • opt 最优化, 不会产生任何调试信息, 除非手动指定了 –copt -g, 同时设置 -O2 -DNDEBUG
  • dbg 调试, 产生调试信息(-g)
1
2
3
bazel build --compilation_mode "dbg" //main:hello-world
## 或者使用缩写
bazel build -c "dbg" //main:hello-world

动态链接模式

--dynamic_mode (auto|default|fully|off)

  • auto 根据平台选择: linux 上是 default, cygwin 上是 off
  • default 由 bazel 去选择是否进行动态链接
  • fully 动态链接所有目标, 将会加速链接时间和减小输出库大小
  • off 静态链接所有目标, 当 linkopts 指定设置 -static, 将自动转成该模式

输出构建过程的执行语句

--explain logfile 写到一个日志文件当中, 配合 —-verbose_explanations, 效果等同 cmake 开启 CMAKE_VERBOSE_MAKEFILE

1
bazel build --explain "log.txt" -—verbose_explanations //main:hello-world

输出构建过程的性能

--profile file 会把构建的分析数据写到一个二进制文件当中, 可使用 bazel analyze-profile 命令进行解析

1
2
3
4
5
## 生成 profile
bazel build --profile "profile.bin" //main:hello-world

## 分析构建性能
bazel analyze-profile profile.bin

**更多构建命令选项可参考: ** bazel help build

查看构建的信息内容

  • 命令用法

    1
    
    bazel info <options> [key]
    
  • --show_make_env 显示构建环境, 默认 false

**更多信息查询命令选项可参考: ** bazel help info

分析

  • 命令用法
1
bazel query <options> <query-expression>

是否分析host依赖相关

--host_deps 指定分析其依赖关系, 默认开启

--nohost_deps 指定不分析其依赖关系

是否分析其隐式依赖关系

--implicit_deps 指定分析其隐式依赖关系, 例如 @bazel_tools//tools/cpp:malloc, 默认开启

--noimplicit_deps 指定不分析其隐式依赖关系

指定输出格式

--output (build|graph|label|label_kind|location|maxrank|minrank|package|proto|xml)

  • build 输出指定分析目标的 BUILD 文件内容
1
2
3
4
5
# /Users/wangzhuxing/Desktop/Project/repository/wzx3/bazel-examples/cpp-tutorial/stage1/main/BUILD:1:1
cc_binary(
  name = "hello-world",
  srcs = ["//main:hello-world.cc"],
)
  • graph 输出可进行图可视化的格式文本

    1
    2
    3
    4
    5
    6
    
    digraph mygraph {
      node [shape=box];
    "//main:hello-world"
    "//main:hello-world" -> "//main:hello-world.cc"
    "//main:hello-world.cc"
    }
    
  • label 输出指定分析目标的依赖文件, 默认配置

    1
    2
    
    //main:hello-world
    //main:hello-world.cc
    
  • label_kind 分类输出指定分析目标的依赖

    1
    2
    
    cc_binary rule //main:hello-world
    source file //main:hello-world.cc
    
  • location 输出指定分析目标的代码行位置

    1
    2
    
    /Users/.../main/BUILD:1:1: cc_binary rule //main:hello-world
    /Users/.../main/BUILD:3:12: source file //main:hello-world.cc
    
  • maxrank|minrank 按等级排列指定分析目标的依赖

    1
    2
    
    0 //main:hello-world
    1 //main:hello-world.cc
    
  • package 输出指定分析目标的包名

    1
    
    main
    

实用流程

  • 生成可视化图结构的信息文本
1
2
3
4
bazel query --nohost_deps                                   \
            --noimplicit_deps                               \
            'deps(//main:hello-world)'              				\
            --output graph > output-graph.gv
  • 通过 python 的 graphviz模块 进行图解析
1
python -m bazel_graphviz --input_file="output-graph.gv"

附上本人的解析代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# encoding: utf-8

import argparse, os

from graphviz import Source

def _render(args):
    if args.input_file:
        output_file_name, output_file_extension = os.path.splitext(str(args.input_file))
        src = Source.from_file(str(args.input_file))
        src.format = 'png'
        src.render(filename=output_file_name, view=True, cleanup=True)
        return True
    return False

def _get_parser():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--input_file',
        default=None,
        help='Path to the model weights file of the external tool (e.g caffe/onnx weights proto binary)')
    return parser

def _main():
    parser = _get_parser()
    args, unknown_args = parser.parse_known_args()
    if not _render(args):
        print('Render bazel graph failed!')

if __name__ == '__main__':
    _main()

**更多构建命令选项可参考: ** bazel help query

清理

只清理编译目录

删除编译项目的编译过程中产生的目录树,不会删除bazel产生的临时文件

1
bazel clean

完全清理

删除输出文件的目录树,删除Bazel产生的所有临时文件,删除下载的临时文件等

1
bazel clean --expunge

测试

  • 命令用法
1
bazel test <options> <test-targets>

注:

  1. 命令运行前会先执行一次 bazel build
  2. 测试命令无法直接传入测试程序的形参, 也并不需要

**更多测试命令选项可参考: ** bazel help test

运行

  • 命令用法
1
bazel run <options> -- <binary target> <flags to binary>

**更多运行命令选项可参考: ** bazel help run

高阶用法

BUILD 文件语法

概念和术语

通用定义

  • Bourne shell 标记化

    根据 Bourne shell 的标记化规则,某些规则的某些字符串属性被拆分为多个单词:

    1. 未加引号的空格分隔单独的单词
    2. 单引号和双引号字符和反斜杠用于防止标记化

    受此标记化影响的属性在本文档的定义中明确指出。

    受**“Make”变量扩展和Bourne shell标记化的属性通常用于将任意选项传递给编译器和其他工具**。此类属性的示例是cc_library.copts和java_library.javacopts。这些替换一起允许单个字符串变量扩展为特定于配置的选项字列表。

  • 标签表达式

  • 编译(build)规则的通用属性

  • 测试(test)规则的通用属性 (*_test)

  • 生成binary规则的通用属性 (*_binary)

  • 可配置的属性

  • 隐式输出目标

"Make"变量

函数接口

Bazel入门:编译C++项目 官网:https://www.bazel.build Github: https://github.com/bazelbuild/bazel最近用到tensorflow的时候遇到了个新的编译工具Bazel,踩了无数坑之后终于决定还是系统地学习一下这货。Bazel是一个类似于Make的编译工具,是Google为其内部软件开发的特点量身定制的工具,如今Google使用它来构建内部大多数的软件。Goog 阅读详情

相关推荐

bazel介绍以及其发展历史

Bazel Google开源的,是一款与 Make、Maven 和 Gradle 类似的开源构建和测试工具。它使用人类可读的高级构建语言。Bazel 支持多种语言的项目,可为多个平台构建输出。Bazel支持任意大小的构建目标,并支持跨多个代码库和大量用户的大型代码库。是Google主推的一种构建工具。

m0_74043383的博客 1962

Bazel编译教程(基础篇)

如果你还在坚持CMake话,不妨尝试一下谷歌的高效编译工具--Bazel前言一、Bazel是什么?二、安装bazel三、介绍Bazel文件组成1. WORKSPACE(工作区)2. BUILD文件(packkage)四、Bazel编译初探1. 编译单个target2. 编译多个target3. 编译多个package总结 前言 最近,发现公司大佬们都在偷偷使用Bazel构建工程项目,此时,我发现我在学校学习的Make已经不香了,于是我决定上车。 提示:以下是本篇文章正文内容,下面案例可供参考 一、Baz

weixin_44970102的博客 8662

ONOS再升级——采用Bazel工具构建APP流程详解

ONOS已更新过无数版本,构建工具的选择也在变化。最初ONOS采用Maven编译,从1.7之后改用Buck,但1.14版本开始采用了Bazel编译工具。能够使用ONOS实现自己所需功能的APP是我们要掌握的基础技能。从网上搜集的资料来看,大多数新建自己的APP是采用的Maven工具,但现今ONOS 1.14版本源码中已经没有了pom.xml文件(Maven工程中重要的依赖关系文件),取而代之的是B...

sinat_37751902的博客 5440

bazel编译C++

bazel编译C++

UUUUTaossienUUUU的专栏 1359

bazel源码编译Tensorflow

因为研究需求,要从Tensorflow源码编译libtensorflow_cc.so和libtensorflow_framwork.so两个库,工具是bazel。 编译硬件需求:GCC4.8以上,bazel0.10.0以上,tensorflow r1.8。 我的硬件需求:GCC7.3.0,bazel0.15.0,tensorflow r1.8。 GCC安装就不用说了,一般Linux自带,gc...

Code Wang的博客 5443

百度apollo - Apollo编译软件Bazel:2. 编译,IDE,以及答疑

百度Apollo采用bazel作为代码编译构建工具每个模块下都有一个build文件,其作用是按照bazel的格式来编译代码的。关于如何使用bazel编译c++代码,可以见如下网址:安装教程 - https://docs.bazel.build/versions/master/install.htmlbazel教程 - https://docs.bazel.build/versions/master...

DinnerHowe的博客 4888

J2CL与Bazel构建系统集成:打造现代化Java Web开发流程

J2CL(Java to Closure JavaScript transpiler)与Bazel构建系统的集成,为Java Web开发带来了现代化的解决方案。通过将Java代码高效转换为优化的JavaScript,并利用Bazel的强大构建能力,开发者可以构建出高性能、可扩展的Web应用。本文将详细介绍如何利用这一集成打造高效的开发流程。 ## 为什么选择J2CL与Bazel的组合? J2C

gitblog_00289的博客 408

bazel构建C++项目

相信大家对于make和cmake都或多或有写了解,这里不放回顾下。cmake是makefile的上层工具,其目的正是为了生成可移植的makefile,简化手写makefile时的巨大工作量。关于 makefile 的编写可以参见:这里。Bazel则是一款与Make、Maven类似的构建工具。最初是google为其内部软件量身定制的工具,如今支持绝大多数软件的构建。(1)多语言支持:C++、Java等,也可以扩展到其他编程语言。(2)高级构建描述语言。

mijichui2153的博客 1047

Google J2CL 最佳实践指南

J2CL 是一个将 Java 代码编译为 JavaScript 的工具链,由 Google 开发维护。作为 Java 到 JavaScript 的转译器,J2CL 在保持 Java 语义的同时,能够生成高度优化的 JavaScript 代码。本文将深入探讨 J2CL 的最佳实践,帮助开发者充分利用其优势。 ## 构建性能优化 构建性能是开发效率的关键因素。对于 J2CL 项目,我们建议在项目根...

gitblog_00027的博客 507

Homebrew 必备软件清单:我的 macOS 开发环境搭建全记录

本文详细介绍了如何使用Homebrew在macOS上搭建高效的开发环境,包括基础配置、核心开发工具链、高效编码工具集等30个必备工具。通过Homebrew这一macOS缺失的包管理器,开发者可以一键安装命令行工具和GUI应用,大幅提升工作效率。文章还提供了日常维护命令和疑难问题解决方案,适合从新手到资深开发者的所有用户。

weixin_28836507的博客 353

告别ZotFile!Zotero 7+百度网盘文献同步全攻略(含软链接避坑指南)

本文针对Zotero 7用户,提供了告别ZotFile插件后,利用百度网盘实现文献附件同步的完整解决方案。详细讲解了如何通过设置Zotero链接目录与创建软链接,将附件库迁移至云盘,并附有详细的避坑指南,确保数据安全与多设备同步的稳定性。

mmm90的博客 586

bazel 编译 C++ 项目

大多数目标是两种主要类型之一:文件和规则。如示例中的hello-world和hello-greet等。文件进一步分为两种。源文件通常由用户编写并签入代码库。生成的文件(有时称为派生文件或输出文件)不会被签入,但是从源文件生成的。第二种目标使用规则声明。每个规则实例都用于指定一组输入文件与一组输出文件之间的关系。规则的输入可以是源文件,也可以是其他规则的输出。target是某个 rule 的一个实例。Rule规定了 一类构建规则。

哦豁灬 1万+

HMC7044芯片模拟SPI配置

摘要: HMC7044是一款高性能双环路整数N分频抖动衰减器,支持SPI接口配置,适用于高速数据转换器时钟系统。该芯片采用双PLL级联架构,具有14路可配置输出,可满足GSM/LTE基站设计需求。SPI接口采用3线模式(SLEN/SCLK/SDATA),支持24位寄存器读写(13位地址+8位数据)。驱动实现基于Zynq EMIO模拟SPI,提供初始化、数据传输及寄存器配置功能,支持三线制工作模式和多种时钟参数设置。

toonyhe的博客 1094

【Android 构建新工具】Bazel 构建Android项目

我们我们使用Bazel构建了一个Android应用程序。通过安装Bazel和Android Studio来设置环境,并下载示例项目。设置一个Bazel工作空间,其中包含应用程序的源代码和一个识别工作空间目录顶层的workspace文件。更新WORKSPACE文件,以包含对所需外部依赖项的引用,如Android SDK。创建了BUILD文件。使用bazel构建该应用。在Android模拟器或物理设备上部署和运行应用程序。

轻口味的专栏 1826

中兴U30air随身WiFi刷机全攻略:从ABD开启到系统调试(附工具包)

本文提供中兴U30air随身WiFi刷机全攻略,从ADB开启到系统调试的详细步骤,包括必备工具清单、ADB调试模式解锁、Bootloader解锁及自定义ROM刷入与调优。适合技术爱好者深度定制设备,提升网络性能和功能扩展。

weixin_29235923的博客 1933

别只聊天了!手把手教你为Ollama+Open WebUI搭建本地知识库(基于BGE-M3和Qwen)

本文详细介绍了如何利用Ollama、Open WebUI和BGE-M3构建本地知识库,实现智能问答和文档检索。通过环境准备、文档处理、向量化实战和应用案例,帮助用户突破基础聊天场景,打造高效的个人知识管理体系。特别适合技术文档管理和学术研究场景。

weixin_42523720的博客 478

【名名的Bazel笔记】自定义工具链实现交叉编译

文章目录1 前言2 Non-Platform 方式3 Platform 方式3.1 平台3.1.1 概述3.1.2 定义约束和平台3.1.3 通用的约束和平台3.1.4 指定平台构建3.2 工具链3.3 Platform + Toolchain 实现平台方式构建4 小结5 参考资料 1 前言 本文会讲述 Bazel 自定义工具链的两种方式,Platform 和 Non-Platform 方式。会存在这两种方式的原因是 Bazel 的历史问题。例如,C++ 相关规则使用 --cpu 和 --crosstoo.

易名 6409

PyQt 随笔:信号与槽的两种使用方法:@pyqtSlot 和 connect

在 PyQt 中,信号与槽是实现事件驱动的一种重要机制。通过信号与槽的连接,可以实现对象之间的通信,例如在用户界面中响应按钮点击事件或者数据的变化等。PyQt 提供了两种主要的方法来创建信号与槽的连接:@pyqtSlot 装饰器和 connect 方法。本文将详细介绍这两种方法,并提供相应的源代码示例。在上面的示例中,我们定义了一个名为。

QasdCpp的博客 763

Bazel-Apollo编译工具

文章目录Bazel介绍安装主要特点适用项目:项目结构Bazel编译Demo理解BUILD文件第一个例子查看依赖图第二个例子第三个例子 Bazel介绍 Bazel是一个类似于Make的编译工具,是Google为其内部软件开发的特点量身定制的工具,现在Google内部大部分软件都用Bazel进行构建。 安装 安装过程参考:http://bazel.io/docs/install.html 主要特点 多语言支持:Bazel支持Java,Objective-C和C++,可以扩展来支持任意的编程语言 高级别的构建语

LeonShen的博客 2697

Oracle EBS FA 如何打开关闭的资产会计期间?

用户“运行折旧”,误勾选为“关闭期间”,还有一部分资产还需要操作报废和调整,希望后台打开关闭的资产会计期。

陈显平的专栏-Oracle EBS 1029

如何解除“无法完成操作 因为文件包含病毒或潜在垃圾软件”

当运行软件遇到“无法完成操作 因为文件包含病毒或潜在垃圾软件”时,如何解决?控制面板-系统和安全-Windows Defender防火墙-自定义设置,将专用网络及公用网络关闭。点击后,选择“病毒和威胁防护”-管理配置。进入安全中心后,选择“病毒和威胁防护”将需要排斥的选项输入后,保存配置即可。2:打开windows安全中心。

笔者从事电信媒体开发多年,愿意将多年的开发经验分享给同行 6万+

关于谷歌开源编译工具bazel的使用

bazel 优点 分布式构建工具,增量编译速度快,支持remote方式,命令简单易用 适用于单一代码仓库,所有的代码都在一个文件夹树里面(由WORKSPACE指定) 每一个目标都可以指定可见性,可以指定什么目标是其他项目组可以用的 比如内部测试的类可以被隐藏 漏写了依赖会提示找不到头文件,可以保证所有代码中用到的头文件对应的目标都在当前目标的依赖列表里面 bazel支持依赖远端代码库,可以...

木元心的博客 6566

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Bazel构建工具介绍

Bazel是一个开源的构建和测试工具,类似于Make、Maven和Gradle。它使用人类可读的高级构建语言。Bazel支持多种语言的项目,并为多种平台构建输出。Bazel支持跨多个存储库和大量用户的大型代码库。

轻口味的专栏 1075

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

gcc make cmake bazel 等编译工具的区别

bazel cmake make gcc入门区分

Lucky_shark_111的博客 2976

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Bazel - 使用源码编译 Bazel (引导指令)

使用源码编译 Bazel (引导指令) 原文标题:Compiling Bazel from Source (bootstrapping) 原文地址:https://docs.bazel.build/versions/master/install-compile-source.html 目录 使用源码编译 Bazel (引导指令) 目录 使用源码编译 Bazel (引导指令)...

DarkRabbit的专栏 7248

bazel使用教程

查看bazel版本 bazel version 清除build结果 bazel clean --expunge build bazel build :<exe name> # 在BUILD所在的package目录下执行,编译指定的target bazel build :all # 编译该package下的所有target bazel build ... # 编译该p......

A_L_A_N 5万+
上一篇: 火焰图分析程序性能
下一篇: 使用gprof进行多线程程序性能分析
LinuxG_G
博客等级 码龄15年 58粉丝 176原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值