I made a C++ cmake lib:
target_link_libraries(seal_tests seal stdc++)
which links statically with this lib:
and then I link it in my rust code:
but I get undefined reference errors to SEAL objects:
/workspaces/my-rust-project/seal_cpp/SEAL/native/src/seal/modulus.h:45: undefined reference to `seal::Modulus::set_value(unsigned long)'
/usr/bin/ld: /workspaces/my-rust-project/target/debug/build/my-rust-project-8b92ea2f54bf11a3/out/build/libseal_tests.a(test1.o): in function `seal::EncryptionParameters::EncryptionParameters(seal::scheme_type)':
however, the SEAL library is static and linked statically to my
seal_tests library, so I shouldn't get these
That's philosophical question whether that should happen or not.
That's just the fact: if you link static library libA and said library refers to functions from libB then you have to specify both
-lA and then
-lB (in that order, which is important, too!).
Now, lots of people find that strange and annoying thus many build systems (like libtool) try to hide that requirement from you and try to automagically supply
-lB when you specify
Honestly, I'm not sure whether this magic was broken in your particular case or that combo is not even supposed to work like that.
wasn't static library linking supposed to be "glued" to the current lib being built? So I shouldn't worry about it at all. Since it's static, it should be built together with my lib in the same .a file, shouldn't it?
No, that's not how static libraries work at all.
When you build static libraries they don't even, really, know anything about each other.
The whole scheme was designed for C, remember? There each library may export some symbols and request some other symbols.
And any resolution happens only during final linking step. Till that point don't know about each other.
As you may guess that approach don't work all that well for more high-level languages like Rust or C++.
Thus build systems try to hide the fact that static libraries are independent from you. Some put "pseudolibraries" (these are .la files libtool creates), some track that in the config files.
But as you can see that doesn't always work.
And deep, deep, down below static libraries are independent from each other (while shared libraries are not independent, they can keep dependency information inside).
but if my lib uses other stuff from other lib, then when my lib is being compiled, everything should be resolved. Or by final linking step, do you mean when generating an executable?
Theoretically my static lib already knows everything it uses, so it could glue the static seal library with just the needed functions
It doesn't. There is no way for static libraries to contain any linker flags or library dependency names. It only contains unlinked object files.
It k “knows everything it uses”, but it doesn't knows what it doesn't use!
Suppose there are two functions:
bar in your static library. And they call
bar_seal. And don't call
Sure, in theory it should be possible to keep just
baz_seal and then, when you build the executable, decide if we need
baz_seal (or both).
But this just complicates everything for very little gain: what if both
baz_seal? Should we include everything once or twice? And if twice then how can we dedupe things later?
Thus nothing like that is done.
Instead linker starts with
main. Then it would see if
bar are needed. Then it would decide if
baz_sealed. And then all the functions which are not needed are discarded.
But for that to happen linker have to see all static libraries. Simultaneously. And in right order.
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.