如何解决使用 sqlcipher 时,如何强制将 rustqlite 构建为静态链接?
我正在使用 rustqlite
并尝试通过 Cargo 功能将其配置为使用 sqlcipher
。通常情况下,rustqlite
具有 bundled
功能以包含 sqlite
源。更改为 sqlcipher
时,源不再捆绑。
我能够在本地安装 sqlcipher
并编译我的项目(在 Mac 上通过 brew install sqlcipher
安装)。
生成的二进制文件动态链接到本地 sqlcipher
安装,因此我无法再将二进制文件分发给客户
如何将库 libsqlcipher.0.dylib
嵌入到二进制文件中?不能期望客户自行安装 sqlcipher
。
/tmp/try-sqlite/cipher$ otool -L target/release/cipher
target/release/cipher:
/usr/local/opt/sqlcipher/lib/libsqlcipher.0.dylib (compatibility version 9.0.0,current version 9.6.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0,current version 1292.60.1)
/usr/lib/libresolv.9.dylib (compatibility version 1.0.0,current version 1.0.0)
我的项目很简单:
Cargo.toml
[package]
name = "cipher"
version = "0.1.0"
edition = "2018"
# See more keys and their deFinitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
[dependencies.rusqlite]
version = "0.24.2"
features = ["sqlcipher"]
main.rs
use rusqlite::{params,Connection,Result,NO_ParaMS};
use std::thread::sleep;
#[derive(Debug)]
struct Person {
id: i32,name: String,data: Option<Vec<u8>>,}
fn main() -> Result<()> {
let conn = Connection::open("/tmp/enc2.db")?;
conn.execute("PRAGMA KEY='passphrase'",NO_ParaMS);
conn.execute(
"CREATE TABLE IF NOT EXISTS person (
id INTEGER PRIMARY KEY,name TEXT NOT NULL,data BLOB
)",NO_ParaMS,)?;
let me = Person {
id: 0,name: "Steven".to_string(),data: None,};
conn.execute(
"INSERT INTO person (name,data) VALUES (?1,?2)",params![me.name,me.data],)?;
let mut stmt = conn.prepare("SELECT id,name,data FROM person")?;
let person_iter = stmt.query_map(NO_ParaMS,|row| {
Ok(Person {
id: row.get(0)?,name: row.get(1)?,data: row.get(2)?,})
})?;
for person in person_iter {
println!("Found person {:?}",person.unwrap());
}
Ok(())
}
编辑
通过导出,我有一个静态链接的部分解决方案(尚未经过稳健测试)
sqlCIPHER_STATIC=1
otool -L /private/tmp/try-sqlite/cypher/target/debug/cypher
/private/tmp/try-sqlite/cypher/target/debug/cypher:
/usr/lib/libz.1.dylib (compatibility version 1.0.0,current version 1.2.11)
/usr/local/opt/openssl@1.1/lib/libcrypto.1.1.dylib (compatibility version 1.1.0,current version 1.1.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0,current version 1.0.0)
未解决的问题
- 如何自动导出这个环境变量(通过
toml
config /build.rs
- 仍在努力) - 开发人员人体工程学 - 如何确保
sqlcipher
安装在开发机器上(通过build.rs
/toml dev
等配置) - 确保 CI 以 sqlCIPHER_STATIC=1 运行(并安装)
解决方法
目前似乎是 not possible,版本发布于 crates.io
。
但是有一个开放的 Pull Request 可以用于此目的。
首先在本地克隆 working branch,然后将其用作 Cargo.toml
中的 patch,如下所示:
[dependencies]
rusqlite = { version = "0.24.2",features = ["bundled-sqlcipher"] }
[patch.crates-io]
rusqlite = { path = "../path/to/your_patch" }
请注意,我没有对此进行测试,因为该功能仅存在于补丁中,因此您可能需要像这样包含功能分支:
[dependencies]
rusqlite = { path = "../path/to/your_patch",features = ["bundled-sqlcipher"] }
警告:正如 PR 中所述,目前尚不清楚 zetetic(sqlcipher
的供应商)是否可以接受,因此您在使用它时应谨慎(尤其是在商业产品中)。
编辑
这个 Issue / Comment 也是相关的。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。