demo1 使用bazel编译一个源文件生成可执行程序简单示例

demo1目录树

demo1

├── app

│ ├── BUILD

│ └── hello_world.cpp

├── README.md

└── WORKSPACE

workspace

A workspace is a directory on your filesystem that contains the source files for the software you want to build, as well as symbolic links to directories that contain the build outputs. Each workspace directory has a text file named WORKSPACEwhich may be empty, or may contain references to external dependencies required to build the outputs. See also the Workspace Rules section in the Build Encyclopedia.

workspace可以理解为一个project的根目录所在地,那么如果要指定一个目录为bazel的workspace,只需要在该目录下创建一个workspace文件即可。workspace可以为空,当然,当工程庞大复杂有外部依赖时,可以在workspace中指定外部依赖引用。

本例中,在demo1目录下创建了一个空的workspace文件,那么demo1目录将作为一个workspace。

这里使用一个类比的例子。一般写字楼里会入驻很多公司,workspace就好比一个公司,每个公司都有自己的大门,而这个大门就好比是workspace文件。我们只要看到公司的大门,就知道,哦,这是一个公司。同样,我们看到一个workspace文件就知道本目录是一个workspace空间。

package

The primary unit of code organization in a workspace is the package. A package is a collection of related files and a specification of the dependencies among them.

A package is defined as a directory containing a file named BUILD, residing beneath the top-level directory in the workspace. A package includes all files in its directory, plus all subdirectories beneath it, except those which themselves contain a BUILD file.

package可以理解为workspace空间中的子模块。在workspace空间下创建一个目录,该目录下再创建一个BUILD文件,那么该目录就可以看作是一个package。该目录下的所有对象都属于该package,除了子目录下又有BUILD文件。

本例中,app就是一个package。

一个package就好比一个公司里不同部门的办公室,每个办公室都有自己的门,而这个门就好比是一个BUILD文件。

target

A package is a container. The elements of a package are called targets. Most targets are one of two principal kinds, filesand rules. Additionally, there is another kind of target, package groups, but they are far less numerous.

Files are further divided into two kinds. Source files are usually written by the efforts of people, and checked in to the repository.Generated files, sometimes called derived files, are not checked in, but are generated by the build tool from source files according to specific rules.

The second kind of target is the rule. A rule specifies the relationship between a set of input and a set of output files, including the necessary steps to derive the outputs from the inputs. The outputs of a rule are always generated files. The inputs to a rule may be source files, but they may be generated files also; consequently, outputs of one rule may be the inputs to another, allowing long chains of rules to be constructed.

package中的target主要有两种:文件和规则。文件也分为两种:源文件和生成文件。规则定义怎样根据输入生成相应的输出。

# label

All targets belong to exactly one package. The name of a target is called its label, and a typical label in canonical form looks like this:

//app:hello_world

Each label has two parts, a package name (app) and a target name (hello_world). Every label uniquely identifies a target. Labels sometimes appear in other forms; when the colon is omitted, the target name is assumed to be the same as the last component of the package name, so these two labels are equivalent:

lable标签属于一个包,一个标签由两部分组成:包名+目标名并由“//”开头,即 //package-name:target-name。这类似与一个绝对路径,保证搜索不会出错。本例中报名就是app,目标名就是hello_world。

rules

A rule specifies the relationship between inputs and outputs, and the steps to build the outputs. Rules can be of one of many different kinds or classes, which produce compiled executables and libraries, test executables and other supported outputs as described in the Build Encyclopedia.

Every rule has a name, specified by the name attribute, of type string. The name must be a syntactically valid target name, as specified above. In some cases, the name is somewhat arbitrary, and more interesting are the names of the files generated by the rule; this is true of genrules. In other cases, the name is significant: for *_binary and *_test rules, for example, the rule name determines the name of the executable produced by the build.

Every rule has a set of attributes; the applicable attributes for a given rule, and the significance and semantics of each attribute are a function of the rule's class; see the Build Encyclopedia for the full list of supported rules and their corresponding attributes. Each attribute has a name and a type. Some of the common types an attribute can have are integer, label, list of labels, string, list of strings, output label, list of output labels. Not all attributes need to be specified in every rule. Attributes thus form a dictionary from keys (names) to optional, typed values.

规则指定了生成什么目标,如,可执行程序,库文件等。每一条规则都有名字,而名字通过name属性定义。每条规则包含很多属性,每个属性可看成是key-value,value值有自己支持类型,如 integer, label, list of labels, string, list of strings, output label, list of output labels。

我们前面提到,一个package包含一个BUILD文件,而BUILD文件中要写什么内容呢?就是rules。即需要我们来写构建规则,使bazel构建出我们想要的东东。

构建规则的内容涉及非常多的细节,本系列采用示例的形式,由浅到深,逐渐的带出构建规则。

本例中,BUILD文件内容如下:

cc_binary(
name = "hello_world",
srcs = ["hello_world.cpp"],
)

cc_binary即声明了一个构建规则,用于编译生成一个可执行文件。可执行文件名(目标名)由name属性指定,name属性的值的类型可以看出是string类型。srcs属性指定了源文件,srcs属性的值的类型可以看出是list of strings。

*_binary 规则:指定生成相应语言的可执行程序。cc_binary表示c++可执行程序,jave_binary表示java可执行程序。

*_library 规则:指定生成相应语言的库。

*_test 规则:是一个特殊的bianry规则,通常用于自动化测试。

当我们准备好了workspace,package,编写好了BUILD文件,接下来就可以用bazel来生成我们想要的可执行程序。

先进入到workspace空间,即demo1目录;然后指定编译那个target,即执行bazel build //app:hello_world;其中app是本空间中包路径,hello_world是指定package中的目标路径。最终生成可执行程序hello_world。同时所有的生成的文件都在workspace所在的目录下。

]

生成的hello_world文件放在bazel-bin下,执行bazel-bin/app/hello_world即可运行该程序。

dependency graph

当一个项目庞大后,我想找到各部分之间的依赖关系,我们可以通过依赖图来查看。

]

通过query命令来生成依赖图。从中可以看出,//app:hello_world" 依赖 "//app:hello_world.cpp"

bazel-编译一个源文件生成可执行程序的更多相关文章

  1. QStringLiteral(源代码里有一个通过构造函数产生的从const char*到QString的隐式转换,QStringLiteral字符串可以放在代码的任何地方,编译期直接生成utf16字符串,速度很快,体积变大)

    原作者: Olivier Goffart 点击打开链接http://woboq.com/blog/qstringliteral.html 译者: zzjin 点击打开链接http://www.tuic ...

  2. 使用ant自动编译、打包生成apk文件

    上次使用命令行生成apk文件<Android 命令行编译.打包生成apk文件>,学习命令行生成的目的是为了编写ant打下基础. 一. ant环境 下载ant包,配置环境变量 二.ant编译 ...

  3. Android 自动编译、打包生成apk文件 2 - 使用原生Ant方式

    from://http://blog.csdn.net/androiddevelop/article/details/11100109 相关文章列表: <Android 自动编译.打包生成apk ...

  4. 分步编译一个C语言文件

    一. 以下是C程序一般的编译过程: 从图中看到: 将编写的一个c程序(源代码 )转换成可以在硬件上运行的程序(可执行代码 ),需要进行编译阶段  和链接这两个阶段. 其中, 1.  编译阶段先通过“编 ...

  5. python如何编译py文件生成pyc、pyo、pyd以及如何和C语言结合使用

    python执行py文件的流程 当我们执行一个py文件的时候,直接python xx.py即可,那么这个流程是怎么样的呢.先说明一下,python执行代码实际上是先打开文件然后执行里面的代码,所以文件 ...

  6. 组件化框架设计之apt编译时期自动生成代码&动态类加载(二)

    阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680 本篇文章将继续从以下两个内容来介绍组件化框架设计: apt编译时 ...

  7. java如何在eclipse编译时自动生成代码

    用eclipse写java代码,自动编译时,如何能够触发一个动作,这个动作是生成本项目的代码,并且编译完成后,自动生成的代码也编译好了, java编辑器中就可以做到对新生成的代码的自动提示? 不生成代 ...

  8. 用命令行编译java并生成可执行的jar包

    用命令行编译java并生成可执行的jar包 1.编写源代码. 编写源文件:CardLayoutDemo.java并保存,例如:I:\myApp\CardLayoutDemo.java.程序结构如下: ...

  9. 使用 DJ Java Decompiler 将整个jar包反编译成源文件

    使用 DJ Java Decompiler 将整个jar包反编译成源文件 所使用的软件是 DJ Java Decompiler 3.9. 下面是一个有用的参考文档,说明如何批量编译 http://ww ...

随机推荐

  1. 解决 PHP Fatal error: Call-time pass-by-reference has been removed

    PHP在升级到5.4版本的php可能会出现这种错误: 如果这样使用函数(或者类)的话,会产生一个 PHP Fatal error:foo(&$var);实际上,这样用法在php5.3中就会有提 ...

  2. python的异常机制使用技巧

    1.当你开发的接口被其他应用调用时,响应要及时,但是有些要触发的操作很耗时间. 比如下面需要通过被调用触发的函数create_job_1().但是这个函数执行会比较消耗时间 2.于是,我们可以利用异常 ...

  3. java中常量定义在interface中好还是定义在class中

    Java中interface中定义变量都是"public static final" 类型的, 也就是常量, 因此很多人在interface定义常用的常量,除此之外单独定义一个cl ...

  4. HDU 2897 邂逅明下 (博弈)

    题意: 给你n.p.q,每次操作是令n减小 [p, q]区间中的数,当n < p时必须全部取完了,取完最后一次的人算输,问先手必胜还是必败. 解题思路: 这种非常类似巴什博弈,可以找出必胜区间和 ...

  5. getActivity nullPointerException

    今天突然出现一个问题. Fragment中getActivity突然不能了,会出现空指针问题.最后也不知道是什么原因引起的. 解决的方法: @Override public void onAttach ...

  6. xampp下载地址 一个集成的易于安装的WEB环境部署包

    XAMPP(Apache+MySQL+PHP+PERL)是一个功能强大的建站集成软件包.这个软件包原来的名字是 LAMPP,但是为了避免误解,最新的几个版本就改名为 XAMPP 了.它可以在Windo ...

  7. [React] Refactor a Class Component with React hooks to a Function

    We have a render prop based class component that allows us to make a GraphQL request with a given qu ...

  8. MySQL主从架构之Master-Slave-Slave级联

    Master-Slave-Slave级联 配置结果同上一小节是一样的 注意:默认情况下,从库执行relay-log中的SQL语句不会记录到BINLOG. 所以,处于中间层的MySQL配置项需要额外开启 ...

  9. Java lock 能被中断, synchronized 不能被中断

    1.lock是可中断锁,而synchronized 不是可中断锁 线程A和B都要获取对象O的锁定,假设A获取了对象O锁,B将等待A释放对O的锁定, 如果使用 synchronized ,如果A不释放, ...

  10. Thrift实现C#调用Java开发步骤详解

    概述 Thrift实现C#调用Java开发步骤详解 详细 代码下载:http://www.demodashi.com/demo/10946.html Apache Thrift 是 Facebook ...