I know dynimic linking is not what rust was designed for. (and I very much hate it for that). But I am naive and like to misuse software.

I know all the talk about unstable ABI. but if you make sure (which the mize part system does) to have the same crate and compiler versions the ABI will be the same and work with each other. (there may still be problems with 2 allocators and a drop in the wrong context causing a segfault or smth like that) (and i think i once had a segfault with using a tokio runtime across shlib boundaries)

Cargo calculates a hash for each compile unit (aka crate) of a project, which it then passes to rustc with -C metadata=<hash>. We need this hash to be the same between the compilation of our .so files. I it is different the same symbols will have different names in the .so needing it and the .so having it → unresolved symbol errors.

This hash depends on all of the dependencies of the crate… which does not seem like a problem… the mize crate has the same deps no matter with which project it is compiled with.

HOWEVER. I got unresolved symbol errors. Testing revealed, that certain but not other dependencies of a crate depending on mize CAUSE A HASH CHANGE. The hash also looks at a lot of other stuff and the working theory is, that those certain deps set some build option which has an effect on the “build context” or whatever… which influences the hash.

I started to make this rustc wrapper, which would set a static metadata hash for certain crates and that resolved issues one by one. but all deps of mize could be affected. FAR from ideal.

So the way forward is to just let cargo do it’s stupid static linking. and have the same code in every .so file.

#!/bin/bash
 
# Cargo passes 'rustc' as the first argument ($1).
# We extract it so we don't accidentally pass it down to rustc twice.
RUSTC_BIN="$1"
shift
 
# Now "$@" contains only the actual compiler flags
ARGS=("$@")
TO_PATCH=(mize serde rustls tokio toml_edit mize-part-cli mize_part_cli tracing sysinfo flume)
DO_PATCH=false
 
# Step 1: Scan for the specific crate name
for i in "${!ARGS[@]}"; do
    for j in "${!TO_PATCH[@]}"; do
        if [[ "${ARGS[i]}" == "--crate-name" ]]; then
          if [[ "${ARGS[i+1]}" == "${TO_PATCH[j]}" ]]; then
            DO_PATCH=true
          fi
        elif [[ "${ARGS[i]}" == "--crate-name=${DO_PATCH[j]}" ]]; then
          DO_PATCH=true
        fi
    done
done
 
 
# Step 2: If it's the target crate, swap out the metadata flag
if [ "$DO_PATCH" = true ]; then
    for i in "${!ARGS[@]}"; do
        if [[ "${ARGS[i]}" == metadata=* ]]; then
            ARGS[i]="metadata=2a11caebbf2iiiii"
            break
        fi
    done
fi
 
# Step 3: Forward the arguments to the correct rustc binary
exec "$RUSTC_BIN" "${ARGS[@]}"