tectonic
tectonic copied to clipboard
Cannot link with other crates that use *-sys crates
When attempting to link tectonic
within a project that also uses resvg
, it turned out to be rather hairy.
resvg
has a linkage dependency on i.e. harfbuzz
through harfbuzz-sys
, fontconfig
through fontconfig-sys
and a few more.
There is no good solution in rust to avoid the double linkage other than to modify the dependencies, at least I couldn't find one to convince cargo ov.
Solution proposal:
Expose a feature flag, that allows to not link the system library via the links=..
cargo manifest key, but link in harfbuzz-sys
just for the sake of consuming linkage. That way harfbuzz-sys
will be linked sufficiently early, and the duplication is avoided.
I am happy to implement it, if there is interest in such a feature
Thanks for raising this issue. I am actually a little surprised that it has not cropped up earlier.
The key challenge here — and the reason that Tectonic does not just depend on standard *-sys
crates — is that it has several tiers of C/C++ code that go along with the Rust code, split among several crates, and depending on several system libraries that might depend on each other as well. This leads to two unusual challenges that most *-sys
crates do not need to address:
- The
build.rs
script needs to be aware of these potential interdependencies and honor them appropriately. (For instance, thetectonic_bridge_harfbuzz
crate depends ontectonic_bridge_graphite2
andtectonic_bridge_icu
.) - The headers and prototypes provided by the libraries need to be made available for the C/C++ code in the crates that depend on them. This can be accomplished using environment variables like
DEP_HARFBUZZ_INCLUDE_PATH
, which are created by printing out the right magic lines in thebuild.rs
scripts.
So, basically, for dependencies like Harfbuzz, Tectonic needs to build it with build.rs
script that is more specialized and customized than a generic harfbuzz-sys
crate.
Given all that, I would think that it might be more tractable to get resvg
to use Tectonic's Harfbuzz bridge crate, rather than the other way around. This would, however, require duplicating the Rust-to-C/C++ interfaces provided by harfbuzz-sys
— Tectonic doesn't provide those since it only has C/C++ code invoking Harfbuzz (for now), not Rust code. But I would be open to adding Rust interfaces to enable precisely this kind of use case, and also because we'll hopefully be gradually replacing C/C++ code with Rust.
If you do want to try to implement something within Tectonic, I am definitely also open to contributions that make it possible to use harfbuzz-sys as an option. I think there will be some challenges but for constrained use cases, maybe it won't be so hard to get working.