Monday, October 11, 2021

Bazel

 Creating Bazel Project 

Fast Step up Guide

1.  make sure bazel is installed in your computer 
2.  create a new folder as Project
3.  cd inside the project folder
4.  create a new "WORKSPACE" file
5.  create python/Program folder
6.  cd to Program
7.  Create a new file BUILD file:

    package(default_visibility = ["//visibility:public"])
    py_binary(
        name = 'hello', #anyname
        main = 'hello.py', #reference path eg:  parentfolder.file
        srcs= ['hello.py'], #filename 
    )

8.  $echo "print('hi')" > hello.py 
9.  make sure ur in folder containing BUILD file
10. $bazel run hello

Bazel has default setting for Python and Java ie., u can start with empty WORKSPACE and run python/java source files .

Refer for other languages:
https://docs.bazel.build/versions/4.2.1/rules.html

Other Languages (example scala):


You need to configure workspace - http_archive , skylib , language specific rules , Maven .

  1. start with http_archive -support to download package from https
    1. load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
  2. Download skylib - support for shell command 
    1. skylib_version = "0.8.0"
      http_archive(
      name = "bazel_skylib",
      type = "tar.gz",
      url = "https://github.com/bazelbuild/bazel-skylib/releases/download/{}/bazel-skylib.{}.tar.gz".format (skylib_version, skylib_version),
      sha256 = "2ef429f5d7ce7111263289644d233707dba35e39696377ebab8b0bc701f7818e",
      )
  3. Load 
    1. rules_scala  : like scala_binary,scala_test  etc., to use in BUILD file
    2. scala_config : Config scala version
    3.  scala_register_toolchain  : For using the jar file build from 1 languge as input to another
    4. scala repositories : to download default libraries for scala 
  4. Set maven as third party repo

IntelliJ Setup

1. Make sure intelliJ has bazel plugin installed
2. import above project as basel project
3. create new
4. next ( if u already have .ijwb/ folder created , make sure it is deleted)
5. done

Common Commands :

  • bazel build target #target can be name of build or //path of package:target
  • bazel run target
  • bazel test target
  • bazel coverage target
  • bazel query deps(target)
  • bazel fetch target
  • bazel version
  • bazel clean --expunge

Advantages:

  • Google product
  • Language independent
  • Platform Independent (MAc, Linux etc)
  • Hermatic ( build exactly every time )
  • Cross Langauge Dependencies  (Python libarary can call Java binary etc., )
  • Large Code base
  • Caches Dependencies
  • Parallel Builds
  • Enable Remote  (download Dependencies at remote)
  • Dependency Tree Feature
  • Query Dependencies

Cons : 

  • Network Dependency (1st time and new Dependency)
  • Enlist every Dependency (ie., If Dependency is using another Dependency. It has to be decalared)
  • Manually Decalaring all Dependencies might have version conflicts when 1 library uses 1 version and other another

Features

  • Bazel follows python syntax
  • Workspace: Workspace is a Folder with WORSPACE file also called as Bazel Repo.
  • package :Is a Folder inside Bazel Repo with BUILD file .This folder contains Src code files and other files
  • Target :Everything inside your packages can be considered target
  • Label:The nomenclature of a target is known as a label. It’s just a way to recognize different targets 
  • .bazelrc :Settings that are taken into account every time Bazel builds your project.
  • buildifier : Used to ensure that all your build files are formatted in a similar fashion

WORSPACE file

Enlists all external repo the bazel repo is dependent on

 Example :

workspace(name="intro_to_bazel") #name of the workspace

#load("filename","method")
load(“@bazel_tools//tools/builds_defs/repo:git.bzl”, "git_name") 
git_name(
    name= "com_github_xxx",
    commit="xxxxxxxxxxxxxxxx",
    remote="https://github.com/xxx" 
)

Rule Definition in WORSPACE

  • Example:load("//foo/bar:file.bzl", "some_library")
  • This code will load the file foo/bar/file.bzl and add the some_library symbol to the environment. 
  • This can be used to load new rules, functions or constants (e.g. a string, a list, etc.).
  • *_binary rules build executable programs in a given language. After a build, the executable will reside in the build tool's binary output tree 
  • *_library rules specify separately-compiled modules in the given programming language

  • *_test rules are a specialization of a *_binary rule, used for automated testing

Note :

  • https://github.com/bazelbuild/examples/tree/main/java-tutorial
  • In this project WORKSPACE is empty because  Native rules ship with the Bazel binary and do not require a load statement. Native rules are available globally in BUILD files.
  • But for scala ,python etc u need to include load statements in workspace and use them in Build files

Steps:

  • Open link https://github.com/bazelbuild
  • select repos u need for creating ur project
  • Example if u want to add "bazel-skylib" (Provides functions , file paths, and data types in build file)

####### WORSPACE ########

load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
bazel_skylib_workspace()


BUILD File
load("@bazel_skylib//lib:paths.bzl", "paths")
load("@bazel_skylib//lib:shell.bzl", "shell")
p = paths.basename("foo.bar")
s = shell.quote(p)

  • Since scala does  not directly ship with bazel u need to include the "rules_scala" from bazelbuild in Workspace
  • And Use scala_binary , scala_library scala_test etc., to build and test 

BUILD

  • Folder with BUILD is called Package
  • Contains rules. scala_binary, java_binary etc.,

Example:

common/BUILD 
scala_library(
    name = "common",
    srcs = glob(["*.scala"]),
    visibility = ["//visibility:public"],
)


source/BUILD
scala_binary(
    name = "eid",
    srcs = glob(["filename.scala"]),
    main_class = "com.company.project.filename",
    deps = [
        "//path/common",
    ]
)

  • xxx_library takes sources , targets and label (ie., path for other Bazel Packages)
  • xxxx_library create a libarary 
  • //packagename:target
    • // - root
    • packagename - name of the Builds
    • target - particular target inside a package

  • srcs dependencies :Files consumed directly by the rule or rules that output source files.
  • deps dependencies: Rule pointing to separately-compiled modules providing header files, symbols, libraries, data, etc.
  • data dependencies:A build target might need some data files to run correctly.

Query Dependencies 

  • bazel query "deps(//foo)"
  • bazel query "allpaths(//foo, third_party/...)"
  • bazel query --noimplicit_deps 'deps(//package:target)' --output graph | dot-Tpng >graph.png
#if u are already inside the package
  • bazel query --noimplicit_deps 'deps(target)' --output graph | dot-Tpng >graph.png 
  • bazel query --noimplicit_deps 'deps(microservice)' --output graph | dot-Tpng >graph.png
  • bazel query --noimplicit_deps 'deps(microservice)' --output graph > simplified_graph.in

  • bazel query 'foo/...' --output package # What packages exist beneath foo?
  • bazel query 'kind(rule, foo:*)' --output label_kind #What rules are defined in the foo package?
  • bazel query 'kind("generated file", //foo:*)' #What files are generated by rules in the foo package?
  • bazel query 'attr(generator_function, foo, //path/to/search/...)' #What targets are generated by starlark macro foo?
  • bazel query 'buildfiles(deps(//foo))' | cut -f1 -d: #What's the set of BUILD files needed to build //foo?
  • bazel query 'tests(//foo:smoke_tests)' #What are the individual tests that a test_suite expands to?
  • bazel query 'kind(cc_.*, tests(//foo:smoke_tests))' #Which of those are C++ tests?
  • bazel query 'attr(size, small, tests(//foo:smoke_tests))' #Which of those are small? Medium? Large?
  • bazel query 'filter("pa?t", kind(".*_test rule", //foo/...))' #What are the tests beneath foo that match a pattern?
  • bazel query path/to/file/bar.java --output=package #What package contains file path/to/file/bar.java?
  • bazel query path/to/file/bar.java #What is the build label for path/to/file/bar.java?
  • bazel query 'buildfiles(deps(//foo:foo))' --output package #What packages does foo depend on?
  • bazel query 'deps(foo/... except foo/contrib/...)' --output package #What packages does the foo tree depend on, excluding foo/contrib
  • bazel query 'kind(genproto, deps(bar/...))' #What genproto rules does bar depend upon
  • bazel query 'kind("source file", deps(//path/to/target/foo/...))' | grep java$ #What file dependencies exist
  • bazel query 'deps(//foo) except deps(//foo:foolib)' #What targets does //foo depend on that //foo:foolib does not?
  • bazel query 'somepath(bar/...,groups2/...:*)' #Why does bar depend on groups2

Rules 

Read output of build file in another build files

Ref:


No comments:

Post a Comment