diff --git a/Cargo.lock b/Cargo.lock
index fd4f174b0b729fc422662d6540a3201de129090c..6b1a4ae4c023820936601ea2f15517cba2dfe310 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -136,15 +136,6 @@ dependencies = [
  "os_str_bytes",
 ]
 
-[[package]]
-name = "cmake"
-version = "0.1.49"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db34956e100b30725f2eb215f90d4871051239535632f84fea3bc92722c66b7c"
-dependencies = [
- "cc",
-]
-
 [[package]]
 name = "cpufeatures"
 version = "0.2.5"
@@ -727,7 +718,6 @@ version = "22.11.0"
 dependencies = [
  "bytes",
  "clap",
- "cmake",
  "errno",
  "futures",
  "inventory",
diff --git a/Cargo.toml b/Cargo.toml
index c4fce9387b8e67f4dfe5d3d059db8f1d39745e09..de25918db729156c7d84a0359b46cdd1a65be746 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -41,9 +41,6 @@ features = ["schema", "picodata"]
 rand = "0.8.5"
 pretty_assertions = "0.6.1"
 
-[build-dependencies]
-cmake = "^0"
-
 [[bin]]
 name = "picodata"
 doctest = false
diff --git a/build.rs b/build.rs
index fc1659fc6aceb027a17b805af3731fd1a551a9fe..39a3d8748a645e9fb928a584fe831cf7d6b757e0 100644
--- a/build.rs
+++ b/build.rs
@@ -3,36 +3,38 @@ use std::path::Path;
 use std::process::Command;
 
 fn main() {
-    // $OUT_DIR = ".../target/<build-type>/build/picodata-<smth>/out"
     let out_dir = std::env::var("OUT_DIR").unwrap();
-    // cargo creates 2 different output directories when running `cargo build`
-    // and `cargo clippy`, which is stupid, so we're not going to use them
-    //
-    // build_dir = ".../target/<build-type>/build"
-    let build_dir = Path::new(&out_dir).parent().unwrap().parent().unwrap();
-    let tarantool_dir = build_dir.join("tarantool-sys");
-    build_tarantool(&tarantool_dir);
-    let http_dir = build_dir.join("http");
-    build_http(&http_dir, &tarantool_dir);
+    dbg!(&out_dir); // "$PWD/target/<build-type>/build/picodata-<smth>/out"
+
+    // Running `cargo build` and `cargo clippy` produces 2 different
+    // `out_dir` paths. This is stupid, we're not going to use them.
+    let build_root = Path::new(&out_dir).parent().unwrap().parent().unwrap();
+    dbg!(&build_root); // "$PWD/target/<build-type>/build"
+
+    build_tarantool(build_root);
+    build_http(build_root);
+
     println!("cargo:rerun-if-changed=tarantool-sys");
     println!("cargo:rerun-if-changed=http/http");
 }
 
-fn build_http(build_dir: &Path, tarantool_dir: &Path) {
+fn build_http(build_root: &Path) {
+    let build_dir = build_root.join("tarantool-http");
+    let build_dir_str = build_dir.display().to_string();
+
+    let tarantool_dir = build_root.join("tarantool-sys/build/tarantool-prefix");
+    let tarantool_dir_str = tarantool_dir.display().to_string();
+
     Command::new("cmake")
-        .arg("-S")
-        .arg("http")
-        .arg("-B")
-        .arg(build_dir)
-        .arg(format!(
-            "-DTARANTOOL_DIR={}",
-            tarantool_dir
-                .join("build/tarantool-prefix/include")
-                .to_string_lossy()
-        ))
+        .args(["-S", "http"])
+        .args(["-B", &build_dir_str])
+        .arg(format!("-DTARANTOOL_DIR={tarantool_dir_str}"))
         .run();
 
-    Command::new("cmake").arg("--build").arg(build_dir).run();
+    Command::new("cmake")
+        .args(["--build", &build_dir_str])
+        .arg("-j")
+        .run();
 
     Command::new("ar")
         .arg("-rcs")
@@ -40,34 +42,47 @@ fn build_http(build_dir: &Path, tarantool_dir: &Path) {
         .arg(build_dir.join("http/CMakeFiles/httpd.dir/lib.c.o"))
         .run();
 
-    println!(
-        "cargo:rustc-link-search=native={}",
-        build_dir.to_string_lossy()
-    );
+    println!("cargo:rustc-link-search=native={build_dir_str}");
 }
 
-fn build_tarantool(build_dir: &Path) {
-    if build_dir.exists() {
+fn build_tarantool(build_root: &Path) {
+    let build_dir = build_root.join("tarantool-sys/build");
+    let build_dir_str = build_dir.display().to_string();
+
+    let tarantool_prefix = "tarantool-prefix/src/tarantool-build";
+
+    if !build_dir.join(tarantool_prefix).exists() {
+        // Build from scratch
+        Command::new("cmake")
+            .args(["-S", "tarantool-sys/static-build"])
+            .args(["-B", &build_dir_str])
+            .arg(concat!(
+                "-DCMAKE_TARANTOOL_ARGS=",
+                "-DCMAKE_BUILD_TYPE=RelWithDebInfo;",
+                "-DBUILD_TESTING=FALSE;",
+                "-DBUILD_DOC=FALSE",
+            ))
+            .run();
+        Command::new("cmake")
+            .args(["--build", &build_dir_str])
+            .arg("-j")
+            .run();
+    } else {
         // static-build/CMakeFiles.txt builds tarantool via the ExternalProject
         // module, which doesn't rebuild subprojects if their contents changed,
-        // therefore we do `cmake --build tarantool-prefix/src/tarantool-build`
-        // directly, to try and rebuild tarantool-sys.
+        // therefore we dive into `tarantool-prefix/src/tarantool-build`
+        // directly and try to rebuild it individually.
+        let build_dir = build_dir.join(tarantool_prefix);
+        let build_dir_str = build_dir.display().to_string();
         Command::new("cmake")
-            .arg("--build")
-            .arg(build_dir.join("build/tarantool-prefix/src/tarantool-build"))
+            .args(["--build", &build_dir_str])
             .arg("-j")
             .run();
     }
 
-    std::fs::create_dir_all(build_dir).expect("failed creating build directory");
-    let dst = cmake::Config::new("tarantool-sys/static-build")
-        .define(
-            "CMAKE_TARANTOOL_ARGS",
-            "-DCMAKE_BUILD_TYPE=RelWithDebInfo;-DBUILD_TESTING=FALSE;-DBUILD_DOC=FALSE",
-        )
-        .build_target("tarantool")
-        .out_dir(build_dir)
-        .build();
+    // A temporary alias to reduce the commit diff
+    // TODO (rosik): refactor in the next commit
+    let dst = build_dir.parent().unwrap(); // this is what cmake crate used to do
 
     let build_dir = dst.join("build/tarantool-prefix/src/tarantool-build");
     let build_disp = build_dir.display();