Skip to content

Commit e92eb75

Browse files
authored
Merge pull request #156 from blackbeam/optional-bindgen
Make `bindgen` an optional dependency
2 parents 2bf76bc + 98e542f commit e92eb75

File tree

3 files changed

+136
-120
lines changed

3 files changed

+136
-120
lines changed

Cargo.toml

+4-2
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ proptest = "1.0"
7070
unic-langid = { version = "0.9.4" }
7171

7272
[build-dependencies]
73-
bindgen = { version = "0", default-features = false, features = ["runtime"] }
73+
bindgen = { version = "0.70", default-features = false, features = [
74+
"runtime",
75+
], optional = true }
7476
cc = "1.0"
7577
cmake = "0.1"
7678
subprocess = "0.2"
@@ -86,7 +88,7 @@ incremental = false
8688

8789
[features]
8890
default = ["flate2/zlib", "derive"]
89-
test = ["derive", "time"]
91+
test = ["derive", "time", "bindgen"]
9092
derive = ["mysql-common-derive"]
9193
binlog = ["bitvec"]
9294
nightly = ["test"]

build.rs

+3-118
Original file line numberDiff line numberDiff line change
@@ -6,124 +6,9 @@
66
// option. All files in the project carrying such notice may not be copied,
77
// modified, or distributed except according to those terms.
88

9-
use bindgen::builder;
10-
use cmake::Config;
11-
use subprocess::Exec;
12-
13-
use std::{
14-
env,
15-
fs::{copy, create_dir_all},
16-
path::{Path, PathBuf},
17-
};
18-
19-
const MYSQL_DIR: &str = "mysql-8.0.35";
20-
21-
const LIBSTRINGS: &str = "libstrings.a";
22-
const LIBWRAPPER: &str = "libwrapper.a";
23-
24-
/// Returns mysql source path.
25-
fn download_mysql(out_dir: &Path) {
26-
const URL: &str = "https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.35.tar.gz";
27-
{
28-
Exec::cmd("curl").arg("-s").arg("-L").arg(URL)
29-
| Exec::cmd("tar").arg("-xz").arg("-C").arg(out_dir)
30-
}
31-
.join()
32-
.unwrap();
33-
}
34-
35-
fn make_libstrings(mysql_src: &Path, libdir: &Path, out_dir: &Path) {
36-
println!("cargo:warning=Building libstrings.a");
37-
let dst = Config::new(mysql_src)
38-
.define("FORCE_INSOURCE_BUILD", "1")
39-
.define("DOWNLOAD_BOOST", "1")
40-
.define("WITH_BOOST", out_dir)
41-
.build_target("strings")
42-
.build();
43-
44-
copy(
45-
dst.join("build")
46-
.join("archive_output_directory")
47-
.join(LIBSTRINGS),
48-
Path::new(libdir).join(LIBSTRINGS),
49-
)
50-
.unwrap();
51-
}
52-
53-
fn make_libwrapper(mysql_src: &Path, libdir: &Path, out_dir: &Path) {
54-
println!("cargo:warning=Building libwrapper.a");
55-
cc::Build::new()
56-
.file("wrapper.cc")
57-
.cpp(true)
58-
.include(out_dir.join("build").join("include"))
59-
.include(mysql_src.join("include"))
60-
.flag("-std=c++14")
61-
.cargo_metadata(false)
62-
.compile("wrapper");
63-
copy(out_dir.join(LIBWRAPPER), Path::new(libdir).join(LIBWRAPPER)).unwrap();
64-
}
65-
66-
#[allow(dead_code)]
67-
fn gen_bindings(mysql_src: &Path, out_dir: &Path) {
68-
let builder = builder()
69-
.header("wrapper.hh")
70-
.clang_arg(format!(
71-
"-I{}",
72-
out_dir.join("build").join("include").display()
73-
))
74-
.clang_arg(format!("-I{}", mysql_src.join("include").display()))
75-
.clang_arg("-std=c++14")
76-
.clang_arg("-stdlib=libc++")
77-
.allowlist_recursively(true)
78-
.allowlist_type("decimal_t")
79-
.allowlist_function("c_string2decimal")
80-
.allowlist_function("c_decimal2string")
81-
.allowlist_function("c_decimal2bin")
82-
.allowlist_function("c_bin2decimal")
83-
.allowlist_function("c_decimal_bin_size")
84-
.derive_debug(false)
85-
.use_core()
86-
.generate_comments(false);
87-
let bindings = builder
88-
.generate()
89-
.expect("unable to generate bindings for libstrings");
90-
bindings
91-
.write_to_file(
92-
Path::new("src")
93-
.join("binlog")
94-
.join("decimal")
95-
.join("test")
96-
.join("libstrings_bindings.rs"),
97-
)
98-
.expect("Couldn't write bindings!");
99-
}
9+
mod build_test_libs;
10010

10111
fn main() {
102-
if cfg!(all(feature = "test", unix)) {
103-
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
104-
let mysql_src = out_dir.join(MYSQL_DIR);
105-
let libdir = Path::new("lib")
106-
.join(Path::new(&env::var("CARGO_CFG_TARGET_OS").unwrap()))
107-
.join(env::var("CARGO_CFG_TARGET_ARCH").unwrap());
108-
109-
create_dir_all(&libdir).unwrap();
110-
111-
if !libdir.join(LIBSTRINGS).exists() || !libdir.join(LIBWRAPPER).exists() {
112-
if !mysql_src.exists() {
113-
println!("cargo:warning=Downloading MySql source distribution");
114-
download_mysql(&out_dir);
115-
}
116-
make_libstrings(&mysql_src, &libdir, &out_dir);
117-
make_libwrapper(&mysql_src, &libdir, &out_dir);
118-
// uncomment if mysql-server version bumped
119-
// gen_bindings(&mysql_src, &out_dir);
120-
}
121-
122-
println!("cargo:rustc-link-search=native={}", libdir.display());
123-
println!("cargo:rustc-link-lib=wrapper");
124-
println!("cargo:rustc-link-lib=strings");
125-
if cfg!(target_os = "macos") {
126-
println!("cargo:rustc-link-lib=c++");
127-
}
128-
}
12+
#[cfg(all(feature = "test", unix))]
13+
build_test_libs::build_test_libs();
12914
}

build_test_libs.rs

+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// Copyright (c) 2025 Anatoly Ikorsky
2+
//
3+
// Licensed under the Apache License, Version 2.0
4+
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
5+
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6+
// option. All files in the project carrying such notice may not be copied,
7+
// modified, or distributed except according to those terms.
8+
9+
#![cfg(all(feature = "test", unix))]
10+
11+
use bindgen::builder;
12+
use cmake::Config;
13+
use subprocess::Exec;
14+
15+
use std::{
16+
env,
17+
fs::{copy, create_dir_all},
18+
path::{Path, PathBuf},
19+
};
20+
21+
const MYSQL_DIR: &str = "mysql-8.0.35";
22+
23+
const LIBSTRINGS: &str = "libstrings.a";
24+
const LIBWRAPPER: &str = "libwrapper.a";
25+
26+
/// Returns mysql source path.
27+
fn download_mysql(out_dir: &Path) {
28+
const URL: &str = "https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.35.tar.gz";
29+
{
30+
Exec::cmd("curl").arg("-s").arg("-L").arg(URL)
31+
| Exec::cmd("tar").arg("-xz").arg("-C").arg(out_dir)
32+
}
33+
.join()
34+
.unwrap();
35+
}
36+
37+
fn make_libstrings(mysql_src: &Path, libdir: &Path, out_dir: &Path) {
38+
println!("cargo:warning=Building libstrings.a");
39+
let dst = Config::new(mysql_src)
40+
.define("FORCE_INSOURCE_BUILD", "1")
41+
.define("DOWNLOAD_BOOST", "1")
42+
.define("WITH_BOOST", out_dir)
43+
.build_target("strings")
44+
.build();
45+
46+
copy(
47+
dst.join("build")
48+
.join("archive_output_directory")
49+
.join(LIBSTRINGS),
50+
Path::new(libdir).join(LIBSTRINGS),
51+
)
52+
.unwrap();
53+
}
54+
55+
fn make_libwrapper(mysql_src: &Path, libdir: &Path, out_dir: &Path) {
56+
println!("cargo:warning=Building libwrapper.a");
57+
cc::Build::new()
58+
.file("wrapper.cc")
59+
.cpp(true)
60+
.include(out_dir.join("build").join("include"))
61+
.include(mysql_src.join("include"))
62+
.flag("-std=c++14")
63+
.cargo_metadata(false)
64+
.compile("wrapper");
65+
copy(out_dir.join(LIBWRAPPER), Path::new(libdir).join(LIBWRAPPER)).unwrap();
66+
}
67+
68+
#[allow(dead_code)]
69+
fn gen_bindings(mysql_src: &Path, out_dir: &Path) {
70+
let builder = builder()
71+
.header("wrapper.hh")
72+
.clang_arg(format!(
73+
"-I{}",
74+
out_dir.join("build").join("include").display()
75+
))
76+
.clang_arg(format!("-I{}", mysql_src.join("include").display()))
77+
.clang_arg("-std=c++14")
78+
.clang_arg("-stdlib=libc++")
79+
.allowlist_recursively(true)
80+
.allowlist_type("decimal_t")
81+
.allowlist_function("c_string2decimal")
82+
.allowlist_function("c_decimal2string")
83+
.allowlist_function("c_decimal2bin")
84+
.allowlist_function("c_bin2decimal")
85+
.allowlist_function("c_decimal_bin_size")
86+
.derive_debug(false)
87+
.use_core()
88+
.generate_comments(false);
89+
let bindings = builder
90+
.generate()
91+
.expect("unable to generate bindings for libstrings");
92+
bindings
93+
.write_to_file(
94+
Path::new("src")
95+
.join("binlog")
96+
.join("decimal")
97+
.join("test")
98+
.join("libstrings_bindings.rs"),
99+
)
100+
.expect("Couldn't write bindings!");
101+
}
102+
103+
pub fn build_test_libs() {
104+
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
105+
let mysql_src = out_dir.join(MYSQL_DIR);
106+
let libdir = Path::new("lib")
107+
.join(Path::new(&env::var("CARGO_CFG_TARGET_OS").unwrap()))
108+
.join(env::var("CARGO_CFG_TARGET_ARCH").unwrap());
109+
110+
create_dir_all(&libdir).unwrap();
111+
112+
if !libdir.join(LIBSTRINGS).exists() || !libdir.join(LIBWRAPPER).exists() {
113+
if !mysql_src.exists() {
114+
println!("cargo:warning=Downloading MySql source distribution");
115+
download_mysql(&out_dir);
116+
}
117+
make_libstrings(&mysql_src, &libdir, &out_dir);
118+
make_libwrapper(&mysql_src, &libdir, &out_dir);
119+
// uncomment if mysql-server version bumped
120+
// gen_bindings(&mysql_src, &out_dir);
121+
}
122+
123+
println!("cargo:rustc-link-search=native={}", libdir.display());
124+
println!("cargo:rustc-link-lib=wrapper");
125+
println!("cargo:rustc-link-lib=strings");
126+
if cfg!(target_os = "macos") {
127+
println!("cargo:rustc-link-lib=c++");
128+
}
129+
}

0 commit comments

Comments
 (0)