跳至主要内容

如何在 Linux 上为 s390x (zLinux) 构建、运行和调试 ClickHouse

在撰写本文时(2024 年 5 月),对 s390x 平台的支持被认为是实验性的,即某些功能在 s390x 上被禁用或已损坏。

为 s390x 构建 ClickHouse

s390x 有两个与 OpenSSL 相关的构建选项

  • 默认情况下,OpenSSL 在 s390x 上作为共享库构建。这与所有其他平台不同,在其他平台上,OpenSSL 作为静态库构建。
  • 要无论如何都将 OpenSSL 构建为静态库,请将 -DENABLE_OPENSSL_DYNAMIC=0 传递给 CMake。

这些说明假设主机是 x86_64 并且拥有根据构建说明本地构建所需的所有工具。它还假设主机是 Ubuntu 22.04,但以下说明也应该适用于 Ubuntu 20.04。

除了安装用于本地构建的工具外,还需要安装以下附加软件包

apt-get install binutils-s390x-linux-gnu libc6-dev-s390x-cross gcc-s390x-linux-gnu binfmt-support qemu-user-static

如果您希望交叉编译 Rust 代码,请安装 s390x 的 Rust 交叉编译目标

rustup target add s390x-unknown-linux-gnu

s390x 构建使用 mold 链接器,从https://github.com/rui314/mold/releases/download/v2.0.0/mold-2.0.0-x86_64-linux.tar.gz下载并将其放置到您的 $PATH 中。

要为 s390x 构建

cmake -DCMAKE_TOOLCHAIN_FILE=cmake/linux/toolchain-s390x.cmake ..
ninja

运行

构建完成后,可以使用以下命令运行二进制文件,例如:

qemu-s390x-static -L /usr/s390x-linux-gnu ./clickhouse

调试

安装 LLDB

apt-get install lldb-15

要调试 s390x 可执行文件,请在调试模式下使用 QEMU 运行 ClickHouse

qemu-s390x-static -g 31338 -L /usr/s390x-linux-gnu ./clickhouse

在另一个 shell 中运行 LLDB 并附加,将 <Clickhouse 父目录><构建目录> 替换为对应于您的环境的值。

lldb-15
(lldb) target create ./clickhouse
Current executable set to '/<Clickhouse Parent Directory>/ClickHouse/<build directory>/programs/clickhouse' (s390x).
(lldb) settings set target.source-map <build directory> /<Clickhouse Parent Directory>/ClickHouse
(lldb) gdb-remote 31338
Process 1 stopped
* thread #1, stop reason = signal SIGTRAP
frame #0: 0x0000004020e74cd0
-> 0x4020e74cd0: lgr %r2, %r15
0x4020e74cd4: aghi %r15, -160
0x4020e74cd8: xc 0(8,%r15), 0(%r15)
0x4020e74cde: brasl %r14, 275429939040
(lldb) b main
Breakpoint 1: 9 locations.
(lldb) c
Process 1 resuming
Process 1 stopped
* thread #1, stop reason = breakpoint 1.1
frame #0: 0x0000004005cd9fc0 clickhouse`main(argc_=1, argv_=0x0000004020e594a8) at main.cpp:450:17
447 #if !defined(FUZZING_MODE)
448 int main(int argc_, char ** argv_)
449 {
-> 450 inside_main = true;
451 SCOPE_EXIT({ inside_main = false; });
452
453 /// PHDR cache is required for query profiler to work reliably

Visual Studio Code 集成

  • CodeLLDB 扩展是可视化调试所必需的。
  • Command Variable 扩展如果使用CMake 变体,可以帮助动态启动。
  • 确保将后端设置为您的 LLVM 安装,例如 "lldb.library": "/usr/lib/x86_64-linux-gnu/liblldb-15.so"
  • 确保在启动之前以调试模式运行 ClickHouse 可执行文件。(也可以创建一个 preLaunchTask 来自动执行此操作)

示例配置

cmake-variants.yaml

buildType:
default: relwithdebinfo
choices:
debug:
short: Debug
long: Emit debug information
buildType: Debug
release:
short: Release
long: Optimize generated code
buildType: Release
relwithdebinfo:
short: RelWithDebInfo
long: Release with Debug Info
buildType: RelWithDebInfo
tsan:
short: MinSizeRel
long: Minimum Size Release
buildType: MinSizeRel

toolchain:
default: default
description: Select toolchain
choices:
default:
short: x86_64
long: x86_64
s390x:
short: s390x
long: s390x
settings:
CMAKE_TOOLCHAIN_FILE: cmake/linux/toolchain-s390x.cmake

launch.json

{
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "custom",
"name": "(lldb) Launch s390x with qemu",
"targetCreateCommands": ["target create ${command:cmake.launchTargetPath}"],
"processCreateCommands": ["gdb-remote 2159"],
"preLaunchTask": "Run ClickHouse"
}
]
}

settings.json

这也会将不同的构建放在 build 文件夹的不同子文件夹下。

{
"cmake.buildDirectory": "${workspaceFolder}/build/${buildKitVendor}-${buildKitVersion}-${variant:toolchain}-${variant:buildType}",
"lldb.library": "/usr/lib/x86_64-linux-gnu/liblldb-15.so"
}

run-debug.sh

#! /bin/sh
echo 'Starting debugger session'
cd $1
qemu-s390x-static -g 2159 -L /usr/s390x-linux-gnu $2 $3 $4

tasks.json

定义一个任务,以 server 模式在二进制文件旁边的 tmp 文件夹下运行已编译的可执行文件,并使用 programs/server/config.xml 下的配置。

{
"version": "2.0.0",
"tasks": [
{
"label": "Run ClickHouse",
"type": "shell",
"isBackground": true,
"command": "${workspaceFolder}/.vscode/run-debug.sh",
"args": [
"${command:cmake.launchTargetDirectory}/tmp",
"${command:cmake.launchTargetPath}",
"server",
"--config-file=${workspaceFolder}/programs/server/config.xml"
],
"problemMatcher": [
{
"pattern": [
{
"regexp": ".",
"file": 1,
"location": 2,
"message": 3
}
],
"background": {
"activeOnStart": true,
"beginsPattern": "^Starting debugger session",
"endsPattern": ".*"
}
}
]
}
]
}