Skip to content

Latest commit

 

History

History

build

Build

This directory contains the build system for the project. The build system is designed to be used with the Bazel. It is designed to be running on Linux without root privileges, and no virtualization technology is required.

The build system is tested on Linux (x86_64 and aarch64) and macOS (Intel chip and AppleSilicon Chip).

Prerequisites

The following examples should be performed under the Kong source codebase.

The build system requires the following tools to be installed:

  • Bazel/Bazelisk, Bazelisk is recommended to ensure the correct version of Bazel is used.

    We can install Bazelisk by running the following command:

      # install Bazelisk into $PWD/bin/bazel
      make check-bazel
      # add Bazelisk into your $PATH
      export PATH=bin:$PATH
      # check bazel version
      bazel version
  • Python, Python 3 is used to build some of the dependencies. Note: build system relies on python in the PATH; if you have python3 you need to create a symlink from python to python3

  • Build dependencies

Note: Bazel relies on logged user to create the temporary file system; however if your username contains @ it collides with Bazel templating system. Therefore you can set the environment variable export USER=myname to fix this issue.

Building

Build dependencies

Run the following command to build dependencies of Kong:

bazel build //build:kong --verbose_failures

This will build luarocks, the OpenResty distribution of Kong, and the lua-resty-* libs required by Kong.

During the first run, it will take some time to perform a complete build, which includes downloading dependent files and compiling.

Once the build is complete, you will see four bazel-* folders in the current directory. Refer to the workspace layout diagram for their respective definitions.

Development environment

To use the build as a virtual development environment, run:

bazel build //build:venv --verbose_failures
. ./bazel-bin/build/kong-dev-venv.sh

This operation primarily accomplishes the following:

  1. Add the Bazel build output folder containing resty, luarocks and other commands to $PATH so that the commands in the build output can be used directly.
  2. Set and specify the runtime path for Kong.
  3. Provide Bash functions to start and stop the database and other third-party dependency services required for Kong development environment using Docker, read more: Start Kong.

C module and Nginx development

When we are developing part of the Kong installation, especially some Nginx C modules, installing stuffs like luarocks is not necessary. We can use the following steps:

  1. Update the C module to be pointed to point a local path. In .requirements update (for example) LUA_KONG_NGINX_MODULE=/path/to/lua-kong-nginx-module
  2. Do a full build once bazel build //build:install-openresty
  3. The produced nginx is at ./bazel-bin/build/kong-dev/openresty/nginx/sbin/nginx
  4. Do incremental build using bazel build //build:dev-make-openresty

One can also use make build-openresty to automatically do a full build or a incremental build.

Other targets developer may found useful to cope with Nginx development:

  • Install the lua files come with the C modules: bazel build //build:install-lualibs
  • Install WasmX related artifacts: bazel build //build:install-wasmx

Debugging

Query list all direct dependencies of the kong target

bazel query 'deps(//build:kong, 1)'

# output
//build:install
//build:kong
@luarocks//:luarocks_make
@luarocks//:luarocks_target
...

Each targets under //build:install installs an independent component that composes the Kong runtime environment. We can query deps(//build:install, 1) recursively to find the target that only build and install specific component. This would be useful if one is debugging the issue of a specific target without the need to build whole Kong runtime environment.

We can use the target labels to build the dependency directly, for example:

  • bazel build //build:install-openresty: builds openresty
  • bazel build //build:install-atc_router-luaclib: builds the ATC router shared library
  • bazel build @luarocks//:luarocks_make: builds luarocks for Kong dependencies

Debugging variables in *.bzl files

Use print function to print the value of the variable in the *.bzl file. For example, we can print the value of the WORKSPACE_PATH variable in the _load_bindings_impl function in kong_bindings.bzl by adding the following code:

content += '"WORKSPACE_PATH": "%s",\n' % workspace_path
# add the following line
print("WORKSPACE_PATH: %s" % workspace_path)

Since load_bindings is called in the WORKSPACE file, and _load_bindings_impl is the implementation of load_bindings, we can just run the following command to print the value of the WORKSPACE_PATH variable:

bazel build //build:kong

# output
DEBUG: path/to/kong-dev/kong/build/kong_bindings.bzl:16:10: WORKSPACE_PATH: path/to/kong-dev/kong

Some useful Bazel query commands

  • bazel query 'deps(//build:kong)': list all dependencies of the kong target.
  • bazel query 'kind("cc_library", deps(//build:kong))': list all C/C++ dependencies of the kong target.
  • bin/bazel query 'deps(//build:kong)' --output graph > kong_dependency_graph.dot: generate a dependency graph of the kong target in the DOT format, we can use Graphviz to visualize the graph.

We can learn more about Bazel query from Bazel query.

Build Options

Following build options can be used to set specific features:

  • --//:debug=true

    • Default to true.
    • Turn on debug options and debugging symbols for OpenResty, LuaJIT and OpenSSL, which useful for debug with GDB and SystemTap.
  • --action_env=BUILD_NAME=

    • Default to kong-dev.
    • Set the build_name, multiple build can exist at same time to allow you switch between different Kong versions or branches. Don't set this when you are building a building an binary package.
  • --action_env=INSTALL_DESTDIR=

    • Default to bazel-bin/build/<BUILD_NAME>.
    • Set the directory when the build is intended to be installed. Bazel won't actually install files into this directory, but this will make sure certain hard coded paths and RPATH is correctly set when building a package.

Command example:

build:release --//:debug=false
build:release --action_env=BUILD_NAME=kong-dev
build:release --action_env=INSTALL_DESTDIR=/usr/local

Official build

--config release specifies the build configuration to use for release.

For the official release behavior, some build options are fixed, so they are defined in the Release flags in .bazelrc. Read bazlerc for more information.

To build an official release, use:

bazel build --config release //build:kong --verbose_failures

Supported build targets for binary packages:

  • :kong_deb
  • :kong_el8
  • :kong_aws2
  • :kong_aws2023

For example, to build the deb package:

bazel build --verbose_failures --config release :kong_deb

and we can find the package which named kong.amd64.deb in bazel-bin/pkg.

GPG Signing

GPG singing is supported for the rpm packages (el* and aws*).

bazel build //:kong_el8 --action_env=RPM_SIGNING_KEY_FILE --action_env=NFPM_RPM_PASSPHRASE
  • RPM_SIGNING_KEY_FILE: the path to the GPG private key file.
  • NFPM_RPM_PASSPHRASE: the passphrase of the GPG private key.

ngx_wasm_module options

Building of ngx_wasm_module can be controlled with a few CLI flags:

  • --//:wasmx=(true|false) (default: true) - enable/disable wasmx
  • --//:wasmx_module_flag=(dynamic|static) (default: dynamic) - switch between static or dynamic nginx module build configuration
  • --//:wasm_runtime=(wasmtime|wasmer|v8) (default: wasmtime) select the wasm runtime to build

Additionally, there are a couple environment variables that can be set at build time to control how the ngx_wasm_module repository is sourced:

  • NGX_WASM_MODULE_REMOTE (default: https://github.com/Kong/ngx_wasm_module.git) - this can be set to a local filesystem path to avoid pulling the repo from github
  • NGX_WASM_MODULE_BRANCH (default: none) - Setting this environment variable tells bazel to build from a branch rather than using the tag found in our .requirements file

Cross compiling

Cross compiling is currently only tested on Ubuntu 22.04 x86_64 with following targeting platforms:

  • //:generic-crossbuild-aarch64 Use the system installed aarch64 toolchain.
    • Requires user to manually install crossbuild-essential-arm64 on Debian/Ubuntu.
  • //:vendor_name-crossbuild-aarch64 Target to Redhat based Linux aarch64; bazel manages the build toolchain, vendor_name can be any of rhel8, rhel9, aws2 or aws2023.
  • //:aws2-crossbuild-x86_64 Target to AmazonLinux 2 x86_64; bazel manages the build toolchain.

Make sure platforms are selected both in building Kong and packaging kong:

bazel build --config release //build:kong --platforms=//:generic-crossbuild-aarch64
bazel build --config release :kong_deb --platforms=//:generic-crossbuild-aarch64

Troubleshooting

Run bazel build with --sandbox_debug --verbose_failures to get more information about the error.

The .log files in bazel-bin contain the build logs.

FAQ

Cleanup

In some cases where the build fails or the build is interrupted, the build system may leave behind some temporary files. To clean up the build system, run the following command or simply rerun the build:

bazel clean

Bazel utilizes a cache to speed up the build process. You might want to clear the cache actively if you recently changed BUILD_NAME or INSTALL_DESTDIR.

To completely remove the entire working tree created by a Bazel instance, run:

bazel clean --expunge

Bazel Loading Order

Bazel's file loading order primarily depends on the order of load() statements in the WORKSPACE and BUILD files.

  1. Bazel first loads the WORKSPACE file. In the WORKSPACE file, load() statements are executed in order from top to bottom. These load() statements load external dependencies and other .bzl files.
  2. Next, when building a target, Bazel loads the corresponding BUILD file according to the package where the target is located. In the BUILD file, load() statements are also executed in order from top to bottom. These load() statements are usually used to import macro and rule definitions.

Note:

  1. In Bazel's dependency tree, the parent target's BUILD file is loaded before the child target's BUILD file.
  2. Bazel caches loaded files during the build process. This means that when multiple targets reference the same file, that file is only loaded once.

Known Issues

  • On macOS, the build may not work with only Command Line Tools installed, you will typically see errors like ../libtool: line 154: -s: command not found. In such case, installing Xcode should fix the issue.
  • If you have configure git to use SSH protocol to replace HTTPS protocol, but haven't setup SSH agent, you might see errors like error: Unable to update registry crates-io. In such case, set export CARGO_NET_GIT_FETCH_WITH_CLI=true to use git command line to fetch the repository.