diff --git a/.github/workflows/kvrocks.yaml b/.github/workflows/kvrocks.yaml
index 84ad4f7b8db..35fe1eb8d80 100644
--- a/.github/workflows/kvrocks.yaml
+++ b/.github/workflows/kvrocks.yaml
@@ -32,7 +32,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- - uses: apache/skywalking-eyes/header@501a28d2fb4a9b962661987e50cf0219631b32ff
+ - uses: apache/skywalking-eyes/header@v0.4.0
with:
config: tools/ci/licenserc.yml
@@ -42,19 +42,20 @@ jobs:
steps:
- name: Checkout Code Base
uses: actions/checkout@v3
-
- name: Install Check Tools
run: |
- sudo pip install --upgrade pip
- sudo pip install --upgrade setuptools
sudo apt update
sudo apt install -y cppcheck
- sudo pip install cpplint==1.5.0
-
+ - name: Setup Python
+ uses: actions/setup-python@v2
+ with:
+ python-version: 3.x
+ - name: Setup dependencies
+ run: pip install cpplint==1.5.0
- name: Lint and check code
run: |
- ./cpplint.sh
- ./cppcheck.sh
+ ./x.py check cpplint
+ ./x.py check cppcheck
build-and-test:
name: Build and test
@@ -65,42 +66,50 @@ jobs:
include:
- name: Darwin Clang
os: macos-latest
+ compiler: auto
- name: Darwin Clang without Jemalloc
os: macos-latest
+ compiler: auto
without_jemalloc: -DDISABLE_JEMALLOC=ON
- name: Ubuntu GCC
os: ubuntu-18.04
+ compiler: gcc
- name: Ubuntu Clang
os: ubuntu-18.04
- clang: -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
+ compiler: clang
- name: Ubuntu GCC ASan
os: ubuntu-18.04
with_sanitizer: -DENABLE_ASAN=ON
+ compiler: gcc
# - name: Ubuntu GCC TSan
# os: ubuntu-18.04
# with_sanitizer: -DENABLE_TSAN=ON
+ # compiler: gcc
- name: Ubuntu GCC without Jemalloc
os: ubuntu-18.04
without_jemalloc: -DDISABLE_JEMALLOC=ON
+ compiler: gcc
- name: Ubuntu Clang ASan
os: ubuntu-18.04
with_sanitizer: -DENABLE_ASAN=ON
- clang: -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
+ compiler: clang
# - name: Ubuntu Clang TSan
# os: ubuntu-18.04
# with_sanitizer: -DENABLE_TSAN=ON
- # clang: -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
+ # compiler: clang
- name: Ubuntu Clang without Jemalloc
os: ubuntu-18.04
without_jemalloc: -DDISABLE_JEMALLOC=ON
- clang: -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
+ compiler: clang
- name: Ubuntu GCC Ninja
os: ubuntu-18.04
with_ninja: --ninja
+ compiler: gcc
- name: Ubuntu GCC Ninja without Jemalloc
os: ubuntu-18.04
with_ninja: --ninja
without_jemalloc: -DDISABLE_JEMALLOC=ON
+ compiler: gcc
runs-on: ${{ matrix.os }}
steps:
@@ -117,7 +126,7 @@ jobs:
run: |
brew install cmake gcc autoconf automake libtool
echo "NPROC=$(sysctl -n hw.ncpu)" >> $GITHUB_ENV
-
+
- name: Setup Linux
if: ${{ startsWith(matrix.os, 'ubuntu') }}
run: |
@@ -136,8 +145,13 @@ jobs:
- name: Checkout Code Base
uses: actions/checkout@v3
+ - name: Setup Python
+ uses: actions/setup-python@v2
+ with:
+ python-version: 3.x
+
- name: Build Kvrocks
- run: ./build.sh build -j$NPROC --unittest ${{ matrix.clang }} ${{ matrix.with_ninja }} ${{ matrix.with_sanitizer }} ${{ matrix.without_jemalloc }}
+ run: ./x.py build -j$NPROC --unittest --compiler ${{ matrix.compiler }} ${{ matrix.with_ninja }} ${{ matrix.with_sanitizer }} ${{ matrix.without_jemalloc }}
- name: Run Unit Test
run: ./build/unittest
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index 112654461f2..a033ee677c7 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -47,7 +47,7 @@ jobs:
- name: Build
run: |
- ./build.sh build
+ ./x.py build
cd build
cp kvrocks release/bin/
cp kvrocks2redis release/bin/
@@ -113,7 +113,7 @@ jobs:
- name: Build
run: |
mkdir -p build/release
- ./build.sh build
+ ./x.py build
cd build
mkdir -p release/bin release/conf
cp kvrocks release/bin/
diff --git a/Dockerfile b/Dockerfile
index f8a88495275..778f3956179 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -22,11 +22,11 @@ ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt update
-RUN apt install -y cmake make git autoconf libtool g++
+RUN apt install -y cmake make git autoconf libtool g++ python3
WORKDIR /kvrocks
COPY . .
-RUN ./build.sh build
+RUN ./x.py build
FROM ubuntu:focal
diff --git a/README.md b/README.md
index 7a05cc1e129..4c9a9392508 100644
--- a/README.md
+++ b/README.md
@@ -6,18 +6,18 @@
---
-- [Google Group](https://groups.google.com/g/kvrocks)
-- [Slack Channel](https://join.slack.com/t/kvrockscommunity/shared_invite/zt-p5928e3r-OUAK8SUgC8GOceGM6dAz6w)
+* [Google Group](https://groups.google.com/g/kvrocks)
+* [Slack Channel](https://join.slack.com/t/kvrockscommunity/shared_invite/zt-p5928e3r-OUAK8SUgC8GOceGM6dAz6w)
**Apache Kvrocks(Incubating)** is a distributed key value NoSQL database that uses RocksDB as storage engine and is compatible with Redis protocol. Kvrocks intends to decrease the cost of memory and increase the capacity while compared to Redis. The design of replication and storage was inspired by `rocksplicator` and `blackwidow`.
Kvrocks has the following key features:
-- Redis protocol, user can use redis client to visit the kvrocks
-- Namespace, similar to redis db but use token per namespace
-- Replication, async replication using binlog like MySQL
-- High Available, supports redis sentinel to failover when master or slave was failed
-- Cluster mode, centralized management but compatible with Redis cluster client access
+* Redis protocol, user can use redis client to visit the kvrocks
+* Namespace, similar to redis db but use token per namespace
+* Replication, async replication using binlog like MySQL
+* High Available, supports redis sentinel to failover when master or slave was failed
+* Cluster mode, centralized management but compatible with Redis cluster client access
> Thanks for designers @[田凌宇](https://github.com/tianlingyu1997) and @范世丽 contribute the kvrocks logo for us.
@@ -41,35 +41,34 @@ Kvrocks has the following key features:
-***Tickets a pull reqeust to let us known that you're using kvrocks and add your logo to README***
+***Tickets a pull request to let us known that you're using kvrocks and add your logo to README***
-## Building kvrocks
+## Build and Run kvrocks
-#### requirements
-* g++ (required by c++11, version >= 4.8)
-* autoconf automake libtool cmake
-
-#### Build
+### Prerequisite
```shell
-# Centos/Redhat
-sudo yum install -y epel-release && sudo yum install -y git gcc gcc-c++ make cmake autoconf automake libtool which
+# CentOS / RedHat
+sudo yum install -y epel-release
+sudo yum install -y git gcc gcc-c++ make cmake autoconf automake libtool which
-# Ubuntu/Debian
+# Ubuntu / Debian
sudo apt update
-sudo apt-get install gcc g++ make cmake autoconf automake libtool
+sudo apt install -y gcc g++ make cmake autoconf automake libtool
# macOS
brew install autoconf automake libtool cmake
```
+### Build
+
It is as simple as:
```shell
$ git clone https://github.com/apache/incubator-kvrocks.git
$ cd incubator-kvrocks
-$ ./build.sh build # `./build.sh -h` to check more options;
- # especially, `./build.sh build --ghproxy` will fetch dependencies via ghproxy.com.
+$ ./x.py build # `./x.py build -h` to check more options;
+ # especially, `./x.py build --ghproxy` will fetch dependencies via ghproxy.com.
```
### Running kvrocks
@@ -111,7 +110,7 @@ $ ./unittest
## Namespace
-namespace was used to isolate data between users. unlike all the redis databases can be visited by `requirepass`, we use one token per namespace. `requirepass` was regraded as admin token, only admin token allows to access the namespace command, as well as some commands like `config`, `slaveof`, `bgsave`, etc…
+Namespace is used to isolate data between users. Unlike all the Redis databases can be visited by `requirepass`, we use one token per namespace. `requirepass` is regraded as admin token, and only admin token allows to access the namespace command, as well as some commands like `config`, `slaveof`, `bgsave`, etc..
```
# add token
@@ -136,24 +135,25 @@ OK
## Cluster
-Kvrocks implements a proxyless centralized cluster solution but its accessing method is completely compatible with the Redis cluster client. You can use Redis cluster SDKs to access the kvrocks cluster. More details, please see: [Kvrocks Cluster Introduction](https://github.com/apache/incubator-kvrocks/wiki/Kvrocks-Cluster-Introduction)
+Kvrocks implements a proxyless centralized cluster solution but its accessing method is completely compatible with the Redis cluster client. You can use Redis cluster SDKs to access the kvrocks cluster. More details, please see: [Kvrocks Cluster Introduction](https://kvrocks.apache.org/docs/Cluster/kvrocks-cluster-introduction)
-## DOCs
+## Documents
-* [supported commands](https://github.com/apache/incubator-kvrocks/wiki/Support-Commands)
-* [design complex kv on rocksdb](https://github.com/apache/incubator-kvrocks/blob/master/docs/metadata-design.md)
-* [replication design](https://github.com/apache/incubator-kvrocks/blob/master/docs/replication-design.md)
+Documents are hosted at the [official website](https://kvrocks.apache.org/docs/supported-commands).
-For more informations, can see: [Kvrocks Wiki](https://github.com/apache/incubator-kvrocks/wiki)
+* [Supported Commands](https://kvrocks.apache.org/docs/supported-commands)
+* [Design Complex Structure on RocksDB](https://kvrocks.apache.org/docs/Design/design-structure-on-rocksdb)
+* [Replication Design](https://kvrocks.apache.org/docs/Design/replication)
## Tools
+
* Export the Kvrocks monitor metrics, please use [kvrocks_exporter](https://github.com/KvrocksLabs/kvrocks_exporter)
-* Migrate from redis to kvrocks, use [redis-migrate-tool](https://github.com/vipshop/redis-migrate-tool) which was developed by vipshop
+* Migrate from redis to kvrocks, use [redis-migrate-tool](https://github.com/vipshop/redis-migrate-tool) which was developed by @vipshop
* Migrate from kvrocks to redis. use `kvrocks2redis` in build dir
## Performance
-#### Hardware
+### Hardware
* CPU: 48 cores Intel(R) Xeon(R) CPU E5-2650 v4 @ 2.20GHz
* Memory: 32 GiB
@@ -162,21 +162,21 @@ For more informations, can see: [Kvrocks Wiki](https://github.com/apache/incubat
> Benchmark Client: multi-thread redis-benchmark(unstable branch)
- #### 1. Commands QPS
+### 1. Commands QPS
> kvrocks: workers = 16, benchmark: 8 threads/ 512 conns / 128 payload
latency: 99.9% < 10ms
-![image](https://raw.githubusercontent.com/apache/incubator-kvrocks/master/docs/images/chart-commands.png)
+![image](docs/images/chart-commands.png)
-#### 2. QPS on different payloads
+### 2. QPS on different payloads
> kvrocks: workers = 16, benchmark: 8 threads/ 512 conns
latency: 99.9% < 10ms
-![image](https://raw.githubusercontent.com/apache/incubator-kvrocks/master/docs/images/chart-values.png)
+![image](docs/images/chart-values.png)
#### 3. QPS on different workers
@@ -184,12 +184,12 @@ latency: 99.9% < 10ms
latency: 99.9% < 10ms
-![image](https://raw.githubusercontent.com/apache/incubator-kvrocks/master/docs/images/chart-threads.png)
+![image](docs/images/chart-threads.png)
## License
-Kvrocks is under the Apache License Version 2.0. See the LICENSE file for details.
+Kvrocks is under the Apache License Version 2.0. See the [LICENSE](LICENSE) file for details.
## WeChat Official Account (微信公众号)
-
+![WeChat official account](docs/images/wechat_account.jpg)
diff --git a/build.sh b/build.sh
deleted file mode 100755
index de3026d8e90..00000000000
--- a/build.sh
+++ /dev/null
@@ -1,111 +0,0 @@
-#!/usr/bin/env bash
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-set -e
-
-function usage() {
- echo "Usage: $0 BUILD_DIR [-Dvar=value ...] [--unittest] [-jN] [-h|--help]" >&2
- echo >&2
- echo "BUILD_DIR : directory to store cmake-generated and build files" >&2
- echo "-Dvar=value : extra cmake definitions" >&2
- echo "-jN : execute N build jobs concurrently, default N = 4" >&2
- echo "--unittest : build unittest target" >&2
- echo "--ninja : use ninja to build kvrocks" >&2
- echo "--gcc : use gcc/g++ to build kvrocks" >&2
- echo "--clang : use clang/clang++ to build kvrocks" >&2
- echo "--ghproxy : use ghproxy.com to fetch dependencies" >&2
- echo "-h, --help : print this help messages" >&2
- exit 1
-}
-
-until [ $# -eq 0 ]; do
- case $1 in
- -D*) CMAKE_DEFS="$CMAKE_DEFS $1";;
- --unittest) BUILD_UNITTEST=1;;
- --ninja) USE_NINJA="-G Ninja";;
- --gcc) COMPILER="-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++";;
- --clang) COMPILER="-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++";;
- --ghproxy) USE_GHPROXY="-DDEPS_FETCH_PROXY=https://ghproxy.com/";;
- -j*) JOB_CMD=$1;;
- -*) usage;;
- *) BUILD_DIR=$1;;
- esac
- shift
-done
-
-if [ -z "$BUILD_DIR" ]; then
- usage
-fi
-
-if [ -z "$JOB_CMD" ]; then
- JOB_CMD="-j4"
-fi
-
-WORKING_DIR=$(pwd)
-CMAKE_INSTALL_DIR=$WORKING_DIR/$BUILD_DIR/cmake
-CMAKE_REQUIRE_VERSION="3.13.0"
-
-RED='\033[0;31m'
-YELLOW='\033[1;33m'
-NC='\033[0m' # No Color
-
-if [ ! -x "$(command -v autoconf)" ]; then
- printf ${RED}"The autoconf was required to build jemalloc\n"${NC}
- printf ${YELLOW}"Please use 'yum install -y autoconf automake libtool' in centos/redhat, or use 'apt-get install autoconf automake libtool' in debian/ubuntu"${NC}"\n"
- exit 1
-fi
-
-if [ -x "$(command -v cmake)" ]; then
- CMAKE_BIN=$(command -v cmake)
-fi
-
-if [ -x "$CMAKE_INSTALL_DIR/bin/cmake" ]; then
- CMAKE_BIN=$CMAKE_INSTALL_DIR/bin/cmake
-fi
-
-if [ -f "$CMAKE_BIN" ]; then
- CMAKE_VERSION=`$CMAKE_BIN -version | head -n 1 | sed 's/[^0-9.]*//g'`
-else
- CMAKE_VERSION=0
-fi
-
-if [ "$(printf '%s\n' "$CMAKE_REQUIRE_VERSION" "$CMAKE_VERSION" | sort -V | head -n1)" != "$CMAKE_REQUIRE_VERSION" ]; then
- printf ${YELLOW}"CMake $CMAKE_REQUIRE_VERSION or higher is required. Trying to install CMake $CMAKE_REQUIRE_VERSION ..."${NC}"\n"
- if [ ! -x "$(command -v curl)" ]; then
- printf ${RED}"Please install the curl first to download the cmake"${NC}"\n"
- exit 1
- fi
- mkdir -p $BUILD_DIR/cmake
- cd $BUILD_DIR
- CMAKE_DOWNLOAD_VERSION=3.23.1
- curl -O -L https://github.com/Kitware/CMake/releases/download/v$CMAKE_DOWNLOAD_VERSION/cmake-$CMAKE_DOWNLOAD_VERSION.tar.gz
- tar -zxf cmake-$CMAKE_DOWNLOAD_VERSION.tar.gz && cd cmake-$CMAKE_DOWNLOAD_VERSION
- ./bootstrap --prefix=$CMAKE_INSTALL_DIR -- -DCMAKE_USE_OPENSSL=OFF && make && make install && cd ../..
- CMAKE_BIN=$CMAKE_INSTALL_DIR/bin/cmake
-fi
-
-mkdir -p $BUILD_DIR
-cd $BUILD_DIR
-
-set -x
-$CMAKE_BIN $WORKING_DIR -DCMAKE_BUILD_TYPE=RelWithDebInfo $CMAKE_DEFS $USE_NINJA $COMPILER $USE_GHPROXY
-$CMAKE_BIN --build . $JOB_CMD -t kvrocks kvrocks2redis
-
-if [ -n "$BUILD_UNITTEST" ]; then
- $CMAKE_BIN --build . $JOB_CMD -t unittest
-fi
diff --git a/cppcheck.sh b/cppcheck.sh
deleted file mode 100755
index e48bc57910b..00000000000
--- a/cppcheck.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/bash
-
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-# we should run cmake configuration to fetch deps if we want to enable missingInclude
-CHECK_TYPES="warning,portability,information"
-STANDARD=c++11
-ERROR_EXITCODE=1
-LANG=c++
-
-set -ex
-cppcheck --version
-cppcheck \
- --force --enable=${CHECK_TYPES} -U__GNUC__ -x ${LANG} src --std=${STANDARD} --error-exitcode=${ERROR_EXITCODE} \
- --inline-suppr -j$(nproc)
diff --git a/cpplint.sh b/cpplint.sh
deleted file mode 100755
index 39d675b3c79..00000000000
--- a/cpplint.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-cpplint --linelength=120 --filter=-build/include_subdir,-legal/copyright,-build/c++11 src/*.h src/*.cc
diff --git a/x.py b/x.py
new file mode 100755
index 00000000000..1ea89b77ed5
--- /dev/null
+++ b/x.py
@@ -0,0 +1,175 @@
+#!/usr/bin/env python3
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+import argparse
+import glob
+import os
+import pathlib
+import re
+import subprocess
+import sys
+
+CMAKE_REQUIRE_VERSION = (3, 13, 0)
+SEMVER_REGEX = re.compile(
+ r"""
+ ^
+ (?P0|[1-9]\d*)
+ \.
+ (?P0|[1-9]\d*)
+ \.
+ (?P0|[1-9]\d*)
+ (?:-(?P
+ (?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)
+ (?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*
+ ))?
+ (?:\+(?P
+ [0-9a-zA-Z-]+
+ (?:\.[0-9a-zA-Z-]+)*
+ ))?
+ $
+ """,
+ re.VERBOSE,
+)
+
+def run(args, msg=None, **kwargs):
+ sys.stdout.flush()
+ p = subprocess.Popen(args, **kwargs)
+ code = p.wait()
+ if code != 0:
+ err = f"""
+failed to run: {args}
+exit with code: {code}
+error message: {msg}
+"""
+ raise RuntimeError(err)
+ else:
+ return p.stdout
+
+def find_command(command, msg=None):
+ output = run(["bash", "-c", f"command -v {command}"], stdout=subprocess.PIPE)
+ path = output.read().decode().strip()
+ run(["test", "-x", path], msg=msg)
+ return path
+
+def build(args):
+ (dir, jobs, ghproxy, ninja, unittest, compiler, d) = (args.dir, args.jobs, args.ghproxy, args.ninja, args.unittest, args.compiler, args.D)
+
+ basedir = pathlib.Path(__file__).parent.absolute()
+
+ find_command("autoconf", msg="autoconf is required to build jemalloc")
+ cmake = find_command("cmake", msg="CMake is required")
+
+ output = run([cmake, "-version"], stdout=subprocess.PIPE)
+ output = run(["head", "-n", "1"], stdin=output, stdout=subprocess.PIPE)
+ output = run(["sed", "s/[^0-9.]*//g"], stdin=output, stdout=subprocess.PIPE)
+ cmake_version = output.read().decode().strip()
+ cmake_require_version = '.'.join(map(str, CMAKE_REQUIRE_VERSION))
+ cmake_semver = SEMVER_REGEX.match(cmake_version)
+ if cmake_semver is None:
+ raise RuntimeError(f"CMake {cmake_require_version} or higher is required, got: {cmake_version}")
+ cmake_semver = cmake_semver.groupdict()
+ cmake_semver = (int(cmake_semver["major"]), int(cmake_semver["minor"]), int(cmake_semver["patch"]))
+ if cmake_semver < CMAKE_REQUIRE_VERSION:
+ raise RuntimeError(f"CMake {cmake_require_version} or higher is required, got: {cmake_version}")
+
+ os.makedirs(dir, exist_ok=True)
+ os.chdir(dir)
+
+ cmake_options = ["-DCMAKE_BUILD_TYPE=RelWithDebInfo"]
+ if ghproxy:
+ cmake_options.append("-DDEPS_FETCH_PROXY=https://ghproxy.com/")
+ if ninja:
+ cmake_options.append("-G Ninja")
+ if compiler == 'gcc':
+ cmake_options += ["-DCMAKE_C_COMPILER=gcc", "-DCMAKE_CXX_COMPILER=g++"]
+ elif compiler == 'clang':
+ cmake_options += ["-DCMAKE_C_COMPILER=clang", "-DCMAKE_CXX_COMPILER=clang++"]
+ if d:
+ cmake_options += [f"-D{o}" for o in d]
+ run([cmake, basedir, *cmake_options])
+
+ target = ["kvrocks", "kvrocks2redis"]
+ if unittest:
+ target.append("unittest")
+ run([cmake, "--build", ".", f"-j{jobs}", "-t", *target])
+
+def cpplint(args):
+ command = find_command("cpplint", msg="cpplint is required")
+ options = ["--linelength=120", "--filter=-build/include_subdir,-legal/copyright,-build/c++11"]
+ sources = [*glob.glob("src/*.h"), *glob.glob("src/*.cc")]
+ run([command, *options, *sources])
+
+def cppcheck(args):
+ command = find_command("cppcheck", msg="cppcheck is required")
+
+ options = ["-x", "c++"]
+ options.append("-U__GNUC__")
+ options.append("--force")
+ options.append("--std=c++11")
+ # we should run cmake configuration to fetch deps if we want to enable missingInclude
+ options.append("--enable=warning,portability,information")
+ options.append("--error-exitcode=1")
+ options.append("--inline-suppr")
+
+ sources = ["src"]
+
+ run([command, *options, *sources])
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+ parser.set_defaults(func=lambda _: parser.print_help())
+
+ subparsers = parser.add_subparsers()
+
+ parser_check = subparsers.add_parser(
+ 'check',
+ description="Check code with cpplint or cppcheck",
+ help="Check code with cpplint or cppcheck")
+ parser_check.set_defaults(func=lambda _: parser_check.print_help())
+ parser_check_subparsers = parser_check.add_subparsers()
+ parser_check_cpplint = parser_check_subparsers.add_parser(
+ 'cpplint',
+ description="Lint code with cpplint (https://github.com/cpplint/cpplint)",
+ help="Lint code with cpplint (https://github.com/cpplint/cpplint)")
+ parser_check_cpplint.set_defaults(func=cpplint)
+ parser_check_cppcheck = parser_check_subparsers.add_parser(
+ 'cppcheck',
+ description="Check code with cppcheck (https://github.com/danmar/cppcheck)",
+ help="Check code with cppcheck (https://github.com/danmar/cppcheck)",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser_check_cppcheck.set_defaults(func=cppcheck)
+
+ parser_build = subparsers.add_parser(
+ 'build',
+ description="Build executables to BUILD_DIR [default: build]",
+ help="Build executables to BUILD_DIR [default: build]",
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ )
+ parser_build.add_argument('dir', metavar='BUILD_DIR', nargs='?', default='build', help="directory to store cmake-generated and build files")
+ parser_build.add_argument('-j', '--jobs', default=4, metavar='N', help='execute N build jobs concurrently')
+ parser_build.add_argument('--ghproxy', default=False, action='store_true', help='use https://ghproxy.com to fetch dependencies')
+ parser_build.add_argument('--ninja', default=False, action='store_true', help='use Ninja to build kvrocks')
+ parser_build.add_argument('--unittest', default=False, action='store_true', help='build unittest target')
+ parser_build.add_argument('--compiler', default='auto', choices=('auto', 'gcc', 'clang'), help="compiler used to build kvrocks")
+ parser_build.add_argument('-D', nargs='*', metavar='key=value', help='extra CMake definitions')
+ parser_build.set_defaults(func=build)
+
+ args = parser.parse_args()
+ args.func(args)