bazel 构建踩坑
vscode 使用
step 1
vscode
安装clangd
插件
-
工作区配置
修改当前目录下的
.vscode/settings.json
文件"clangd.path": "/usr/bin/clangd", // Clangd 运行参数(在终端/命令行输入 clangd --help-list-hidden 可查看更多) "clangd.arguments": [ // 在后台自动分析文件(基于 complie_commands,我们用CMake生成) "--background-index", // 同时开启的任务数量 "-j=10", // compelie_commands.json 文件的目录位置 "--compile-commands-dir=${workspaceFolder}", "--header-insertion=never", "--query-driver=**" ],
ps -ef | grep clang # 输出以下内容,证明启动成功,然后等待索引建立即可 xxx 16001 15933 99 22:27 ? 03:49:39 /usr/bin/clangd --background-index -j=10 --compile-commands-dir=/home/cjs/code/SQL/scql/build --header-insertion=never --query-driver=**
- 服务器安装 clangd
- 实测 ubuntu22.04 与 clangd-15 可用
apt update
apt install clangd-15
update-alternatives --install /usr/bin/clangd clangd /usr/bin/clangd-15 100
step 2
compile_commands.json 方式一
- 参考资料
- 与 bazel 连用网址:https://github.com/hedronvision/bazel-compile-commands-extractor
- 参考链接:https://juejin.cn/post/7126880493668139021
- 修改
workspace
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "hedron_compile_commands",
# 建议把下面两处 commit hash 换成 github 上最新的版本
url = "https://github.com/hedronvision/bazel-compile-commands-extractor/archive/ed994039a951b736091776d677f324b3903ef939.tar.gz",
strip_prefix = "bazel-compile-commands-extractor-ed994039a951b736091776d677f324b3903ef939",
)
load("@hedron_compile_commands//:workspace_setup.bzl", "hedron_compile_commands_setup")
hedron_compile_commands_setup()
- 修改 BUILD.bazel
load("@hedron_compile_commands//:refresh_compile_commands.bzl", "refresh_compile_commands")
refresh_compile_commands(
name = "refresh_compile_commands",
# 指定目标 target 及其编译选项/参数(.bazelrc 中已有的参数/选项无需重复添加)
targets = {
"//xxx": "-c opt",
},
)
- 运行
# 会在当前目录下生成 compile_commands.json 文件
bazel run :refresh_compile_commands
compile_commands.json 方式二
-
编写自动化
shell
脚本refresh_compile_commands.sh
参考:
bash <(curl -s https://raw.githubusercontent.com/secretflow/devtools/9efb0bc93068a122864fdb661946695badacbe24/refresh_compile_commands.sh)
#!/bin/bash script_dir=$(cd $(dirname $0) && pwd) > /dev/null 2>&1 project_dir=$(realpath $script_dir/../..) cd $project_dir rm -rf ./external rm -f compile_commands.json ln -s bazel-out/../../../external . # backup file cp WORKSPACE WORKSPACE_bak cp BUILD.bazel BUILD.bazel_bak cp .gitignore .gitignore_bak echo -e "\n load(\"@bazel_tools//tools/build_defs/repo:git.bzl\", \"git_repository\") \n git_repository( name = \"hedron_compile_commands\", commit = \"d7a28301d812aeafa36469343538dbc025cec196\", remote = \"https://github.com/hedronvision/bazel-compile-commands-extractor.git\", ) load(\"@hedron_compile_commands//:workspace_setup.bzl\", \"hedron_compile_commands_setup\") hedron_compile_commands_setup() " >> WORKSPACE echo -e "\n load(\"@hedron_compile_commands//:refresh_compile_commands.bzl\", \"refresh_compile_commands\") refresh_compile_commands( name = \"refresh_compile_commands\", exclude_external_sources = True, exclude_headers = \"external\", ) " >> BUILD.bazel bazel run :refresh_compile_commands # restore from backup cp WORKSPACE_bak WORKSPACE cp BUILD.bazel_bak BUILD.bazel cp .gitignore_bak .gitignore rm -f WORKSPACE_bak rm -f BUILD.bazel_bak rm -f .gitignore_bak
-
脚本二
refresh-compile-commands.py
参考:https://github.com/secretflow/devtools/blob/main/refresh-compile-commands.py
#! /usr/bin/env python3 import os import pathlib import shutil import argparse import subprocess workspace_file_content = """ load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") git_repository( name = "hedron_compile_commands", commit = "388cc00156cbf53570c416d39875b15f03c0b47f", remote = "https://github.com/hedronvision/bazel-compile-commands-extractor.git", ) load("@hedron_compile_commands//:workspace_setup.bzl", "hedron_compile_commands_setup") hedron_compile_commands_setup() """ def _build_file_content(content, targets): return f""" load("@hedron_compile_commands//:refresh_compile_commands.bzl", "refresh_compile_commands") {content} refresh_compile_commands( name = "refresh_compile_commands", exclude_external_sources = True, exclude_headers = "external", {targets} ) """ def _run_shell_command_with_live_output(cmd, cwd, shell=True): print(cmd) p = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=cwd, shell=shell ) for line in p.stdout: print(line.decode("utf-8").rstrip()) p.wait() status = p.poll() assert status == 0 def _rm(path: str): p = pathlib.Path(path) if os.path.isfile: p.unlink() else: p.rmdir() def _backup_file(path: str): shutil.copy(src=path, dst=f"{path}_bak") def _restore_file(path: str): backup = f"{path}_bak" shutil.copy(src=backup, dst=path) _rm(backup) class Workspace(object): def __init__(self): self.workspace_file = 'WORKSPACE' if os.path.isfile('BUILD.bazel'): self.build_file = 'BUILD.bazel' else: self.build_file = 'BUILD' self.has_build = os.path.exists(self.build_file) def __enter__(self): if self.has_build: _backup_file(self.build_file) else: # Create empty file with open(self.build_file, 'w') as fp: pass _backup_file(self.workspace_file) return self def __exit__(self, *args): # Restore files _restore_file(self.workspace_file) if self.has_build: _restore_file(self.build_file) else: _rm(self.build_file) if __name__ == "__main__": parser = argparse.ArgumentParser( description="(Re)generate compile commands for Bazel project" ) parser.add_argument( "--targets", metavar="bazel targets", type=str, help="bazel build targets, comma separated", ) args = parser.parse_args() with Workspace() as ws: # Add hedron_compile_commands to workspace with open(ws.workspace_file, "a+") as wf: wf.write(workspace_file_content) # Build targets targets = args.targets t_str = "" if targets: for t in targets.split(','): t_str += f' "{t}": "",\n' if t_str: t_str = f"targets = {{\n{t_str} }}" # Add build rule with open(ws.build_file, "r+") as bf: content = bf.read() bf.seek(0) # append load at beginning content = _build_file_content(content, targets=t_str) bf.write(content) # Run _run_shell_command_with_live_output( 'bazel run -s :refresh_compile_commands', cwd=os.getcwd(), shell=True )
bazel 证书问题解决
#!/bin/bash
set -ex
ubuntu_crt_path=/usr/local/share/ca-certificates
centos_crt_path=/etc/pki/ca-trust/source/anchors
echo "startup --host_jvm_args=-Djavax.net.ssl.trustStore=$ca_file --host_jvm_args=-Djavax.net.ssl.trustStorePassword=changeit" > /etc/bazel.bazelrc
远程构建
docker run -di -u "$(id -u):$(id -g)" -v $(pwd):/data \
-p 9090:8080 -p 9092:9092 --name bazel_cache \
quay.io/bazel-remote/bazel-remote --max_size 100
# 查看状态
curl http://localhost:9090/status
{
"CurrSize": 0,
"UncompressedSize": 0,
"ReservedSize": 0,
"MaxSize": 214748364800,
"NumFiles": 0,
"ServerTime": 1716652607,
"GitCommit": "54d1782d72b291937988edad32c9752abe269d8e",
"NumGoroutines": 9
}
# build
bazel build //src/main:app --remote_cache=http://localhost:9090
.bazelrc
参考:https://github.com/secretflow/yacl/blob/main/.bazelrc
common --experimental_repo_remote_exec
common --experimental_cc_shared_library
common --experimental_ui_max_stdouterr_bytes=-1
common --experimental_remote_download_regex='.*\/scqlengine$'
build --jobs=8
build --incompatible_new_actions_api=false
build --copt=-fdiagnostics-color=always
build --enable_platform_specific_config
build --cxxopt=-std=c++17
build --host_cxxopt=-std=c++17
build --linkopt -fvisibility=hidden
# default off CUDA build
build --@rules_cuda//cuda:enable=false
test --@rules_cuda//cuda:enable=false
# Binary safety flags
build --copt=-fPIC
build --host_copt=-fstack-protector-strong
build:linux --host_copt=-Wl,-z,noexecstack
build:macos --host_copt=-Wa,--noexecstack
test --keep_going
# test --test_output=errors
test --test_output=all
test --test_timeout=1800
# platform specific config
# Bazel will automatic pick platform config since we have enable_platform_specific_config set
build:macos --copt="-Xpreprocessor -fopenmp"
build:macos --copt=-Wno-unused-command-line-argument
build:macos --features=-supports_dynamic_linker
build:macos --macos_minimum_os=12.0
build:macos --host_macos_minimum_os=12.0
# static link libstdc++ & libgcc on Linux
build:linux --copt=-fopenmp
build:linux --linkopt=-fopenmp
build:linux --action_env=BAZEL_LINKOPTS=-static-libstdc++:-static-libgcc
build:linux --action_env=BAZEL_LINKLIBS=-l%:libstdc++.a:-l%:libgcc.a
限制编译内存
echo "startup --host_jvm_args=-Xmx12g" >> .bazelrc
生成依赖图
bazel query --keep_going --notool_deps 'kind("cc_library", deps(//xxx:xxx))' --output graph > graph