bazel 构建踩坑

vscode 使用

step 1
  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=**
    
  1. 服务器安装 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 方式一
  1. 参考资料
  • 与 bazel 连用网址:https://github.com/hedronvision/bazel-compile-commands-extractor
  • 参考链接:https://juejin.cn/post/7126880493668139021
  1. 修改 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()
  1. 修改 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",
    },
)
  1. 运行
# 会在当前目录下生成 compile_commands.json 文件
bazel run :refresh_compile_commands
compile_commands.json 方式二
  1. 编写自动化 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
    
  2. 脚本二 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值