Что делать с крейтами, экспортирующими символы с одинаковыми именами

avatar
SWdV
8 августа 2021 в 23:32
112
0
3

I'd like to use both just-argon2 and sodiumoxide which are bindings to Argon2 and libsodium respectively. Первую я буду использовать для хеширования паролей, вторую — для шифрования и прочего.

Однако, поскольку сам libsodium также включает код Argon2, я получаю следующую ошибку компоновщика при сборке:

error: linking with `link.exe` failed: exit code: 1169
  |
  = note: "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Preview\\VC\\Tools\\MSVC\\14.29.30132\\bin\\HostX64\\x64\\link.exe" "/NOLOGO" "/NXCOMPAT" "/LIBPATH:<omitted>\\rust-ms\\tools\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "<omitted>\\target\\debug\\deps\\sw_password_vault.sw_password_vault.cvsxie8m-cgu.0.rcgu.o" "<omitted>\\target\\debug\\deps\\sw_password_vault.sw_password_vault.cvsxie8m-cgu.1.rcgu.o" "<omitted>\\target\\debug\\deps\\sw_password_vault.sw_password_vault.cvsxie8m-cgu.10.rcgu.o" "<omitted>\\target\\debug\\deps\\sw_password_vault.sw_password_vault.cvsxie8m-cgu.11.rcgu.o" "<omitted>\\target\\debug\\deps\\sw_password_vault.sw_password_vault.cvsxie8m-cgu.12.rcgu.o" "<omitted>\\target\\debug\\deps\\sw_password_vault.sw_password_vault.cvsxie8m-cgu.13.rcgu.o" "<omitted>\\target\\debug\\deps\\sw_password_vault.sw_password_vault.cvsxie8m-cgu.14.rcgu.o" "<omitted>\\target\\debug\\deps\\sw_password_vault.sw_password_vault.cvsxie8m-cgu.15.rcgu.o" "<omitted>\\target\\debug\\deps\\sw_password_vault.sw_password_vault.cvsxie8m-cgu.2.rcgu.o" "<omitted>\\target\\debug\\deps\\sw_password_vault.sw_password_vault.cvsxie8m-cgu.3.rcgu.o" "<omitted>\\target\\debug\\deps\\sw_password_vault.sw_password_vault.cvsxie8m-cgu.4.rcgu.o" "<omitted>\\target\\debug\\deps\\sw_password_vault.sw_password_vault.cvsxie8m-cgu.5.rcgu.o" "<omitted>\\target\\debug\\deps\\sw_password_vault.sw_password_vault.cvsxie8m-cgu.6.rcgu.o" "<omitted>\\target\\debug\\deps\\sw_password_vault.sw_password_vault.cvsxie8m-cgu.7.rcgu.o" "<omitted>\\target\\debug\\deps\\sw_password_vault.sw_password_vault.cvsxie8m-cgu.8.rcgu.o" "<omitted>\\target\\debug\\deps\\sw_password_vault.sw_password_vault.cvsxie8m-cgu.9.rcgu.o" "/OUT:<omitted>\\target\\debug\\deps\\sw_password_vault.exe" "<omitted>\\target\\debug\\deps\\sw_password_vault.2501tt6qpnxmq6dq.rcgu.o" "/OPT:REF,NOICF" "/DEBUG" "/NATVIS:<omitted>\\rust-ms\\tools\\lib\\rustlib\\etc\\intrinsic.natvis" "/NATVIS:<omitted>\\rust-ms\\tools\\lib\\rustlib\\etc\\liballoc.natvis" "/NATVIS:<omitted>\\rust-ms\\tools\\lib\\rustlib\\etc\\libcore.natvis" "/NATVIS:<omitted>\\rust-ms\\tools\\lib\\rustlib\\etc\\libstd.natvis" "/LIBPATH:<omitted>\\target\\debug\\deps" "/LIBPATH:<omitted>\\target\\debug\\build\\just-argon2-fba8d38863f06c3e\\out" "/LIBPATH:C:\\Users\\Steven\\.cargo\\registry\\src\\github.com-1ecc6299db9ec823\\libsodium-sys-0.2.7\\msvc/x64/Debug/v142/" "/LIBPATH:<omitted>\\rust-ms\\tools\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "<omitted>\\target\\debug\\deps\\libargon2-47416e342f12fc80.rlib" "<omitted>\\target\\debug\\deps\\libbitflags-033856bffcb41e1a.rlib" "<omitted>\\target\\debug\\deps\\libsodiumoxide-ae3f70995957a7e5.rlib" "<omitted>\\target\\debug\\deps\\libserde-02c238cdfdb411bb.rlib" "<omitted>\\target\\debug\\deps\\libed25519-a72dcd735d2405a2.rlib" "<omitted>\\target\\debug\\deps\\libsignature-cb8ca284112f3bdb.rlib" "<omitted>\\target\\debug\\deps\\liblibsodium_sys-90db65a5d41df800.rlib" "<omitted>\\target\\debug\\deps\\liblibc-db8e81727092f722.rlib" "<omitted>\\rust-ms\\tools\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libstd-7d8f1d3120dc2b31.rlib" "<omitted>\\lib\\libpanic_unwind-00b4871c13b6f72d.rlib" "<omitted>\\lib\\libstd_detect-38300272c9518b1b.rlib" "<omitted>\\lib\\librustc_demangle-008ea074760d3d54.rlib" "<omitted>\\lib\\libhashbrown-5d102da67e495133.rlib" "<omitted>\\lib\\librustc_std_workspace_alloc-108ed3dcf248b873.rlib" "<omitted>\\lib\\libunwind-bc9246c93f49e49a.rlib" "<omitted>\\lib\\libcfg_if-7ca234fdcd728c26.rlib" "<omitted>\\lib\\liblibc-e328514fb4ed0383.rlib" "<omitted>\\lib\\liballoc-5d0a4c6a1ffa6373.rlib" "<omitted>\\lib\\librustc_std_workspace_core-d379e9227cab087f.rlib" "<omitted>\\lib\\libcore-825774e96423c2c5.rlib" "<omitted>\\lib\\libcompiler_builtins-d5d1908505fa83bc.rlib" "advapi32.lib" "ws2_32.lib" "userenv.lib" "msvcrt.lib"
  = note: liblibsodium_sys-90db65a5d41df800.rlib(blake2b-ref.obj) : error LNK2005: blake2b_init already defined in libargon2-47416e342f12fc80.rlib(blake2b.o)
          liblibsodium_sys-90db65a5d41df800.rlib(blake2b-ref.obj) : error LNK2005: blake2b_init_key already defined in libargon2-47416e342f12fc80.rlib(blake2b.o)
          liblibsodium_sys-90db65a5d41df800.rlib(blake2b-ref.obj) : error LNK2005: blake2b_init_param already defined in libargon2-47416e342f12fc80.rlib(blake2b.o)
          liblibsodium_sys-90db65a5d41df800.rlib(blake2b-ref.obj) : error LNK2005: blake2b_update already defined in libargon2-47416e342f12fc80.rlib(blake2b.o)
          liblibsodium_sys-90db65a5d41df800.rlib(blake2b-ref.obj) : error LNK2005: blake2b_final already defined in libargon2-47416e342f12fc80.rlib(blake2b.o)
          liblibsodium_sys-90db65a5d41df800.rlib(blake2b-ref.obj) : error LNK2005: blake2b already defined in libargon2-47416e342f12fc80.rlib(blake2b.o)
             Creating library C:\dev\Rust\SWPasswordVault\target\debug\deps\sw_password_vault.lib and object C:\dev\Rust\SWPasswordVault\target\debug\deps\sw_password_vault.exp
          LINK : warning LNK4098: defaultlib 'LIBCMTD' conflicts with use of other libs; use /NODEFAULTLIB:library
          C:\dev\Rust\SWPasswordVault\target\debug\deps\sw_password_vault.exe : fatal error LNK1169: one or more multiply defined symbols found

Обе библиотеки экспортируют одни и те же символы blake2b_*, которые используются реализациями Argon2, поэтому имена конфликтуют.

Теперь вы можете задаться вопросом: почему бы просто не использовать libsodium pwhash API, который внутри использует Argon2 (отсюда и ошибка компоновщика)? Потому что я хочу использовать параллельный Argon2, который не раскрывается libsodium, поскольку он жестко задает степень параллелизма до 1.

Apparently, the blake2b_* symbols are marked as ARGON2_LOCAL, so they are not exported, but I guess that this does not matter since они все еще существуют для компоновщика.

Одним из решений может быть использование чистой реализации Argon2 на Rust, такой как rust-argon2, но я протестировал ее, и, к сожалению, она намного медленнее.<88215058>

Как я могу использовать обе библиотеки вместе? Должен ли я сделать отдельный библиотечный крейт, используя только just-argon2 и экспортировать функции, предоставляемые крейтом just-argon2 или что-то в этом роде, или это не сработает/есть ли лучший способ? РЕДАКТИРОВАТЬ: это не работает.

Минимальная некомпилируемая программа:

use sodiumoxide;
use argon2;

fn main() { sodiumoxide::init(); }

При составлении этой программы я заметил, что когда я переставляю операторы use, она компилируется нормально, но во время выполнения происходит сбой:

use argon2;
use sodiumoxide;

fn main() {
    sodiumoxide::init().expect("Could not init libsodium");

    let password = "pass";

    let salt = sodiumoxide::crypto::pwhash::gen_salt().0;
    let mut key_bytes = [0u8; 32];

    // INSECURE cost parameters
    argon2::id_hash_raw(1, 1 << 10 /*1 MiB*/, 1,
                        Some(password.as_bytes()), Some(&salt), &mut key_bytes)
        .unwrap_or_else(|err| panic!("Error hashing: {:?}", err));
}

Это аварийно завершает работу с STATUS_STACK_BUFFER_OVERRUN исключением Windows (__fastfail(FAST_FAIL_STACK_COOKIE_CHECK_FAILURE)), в то время как оно работает нормально, если не используются какие-либо функции оксида натрия (например, полностью нулевая соль). Очевидно, разные экспорты конфликтуют или что-то в этом роде?

Кстати: я совсем новичок в Rust, поэтому могу с уверенностью сказать, что не знаю всех его тонкостей.

Источник
Todd
9 августа 2021 в 00:14
1

застрелен в темноте ... вы пытались настроить другой компоновщик? [target.x86_64-pc-windows-msvc] linker = "rust-lld"

SWdV
9 августа 2021 в 17:34
0

@ Тодд Спасибо за ваш комментарий. Мне потребовалась минута, чтобы понять, что я должен поместить это в .cargo/config.toml, а не Cargo.toml. К сожалению, это не решает проблему. Теперь ошибка становится следующей: linking with rust-lld failed: "rust-lld" "-flavor" "link" ... rust-lld: error: duplicate symbol: blake2b_init > defined at ...\.cargo\registry\src\github.com-...\just-argon2-1.2.0\phc-winner-argon2\src\blake2\blake2b.c:91 > libargon2-....rlib(blake2b.o) > defined at liblibsodium_sys-....rlib(blake2b-ref.obj) Этот компоновщик также дает сбой во время компиляции для замененных операторов use, в отличие от link.exe

Ответы (0)