微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 sqlcipher 时,如何强制将 rustqlite 构建为静态链接?

如何解决使用 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"]

ma​​in.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)

解决的问题

  1. 如何自动导出这个环境变量(通过 toml config / build.rs - 仍在努力)
  2. 开发人员人体工程学 - 如何确保 sqlcipher 安装在开发机器上(通过 build.rs / toml dev 等配置)
  3. 确保 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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?