> But as you say, this doesn't solve the problem of including multiple versions of the same module.

The solution that Java has for that is literally re-writing the bytecode of version A to be "in a different module" and re-writing the bytecode of the code that depends on version A to use the "new" module. That's not going to fly for C++ as I understand it, but maybe I'm missing something.

Java bytecode files are not only portable and well designed but specifically organized with tables of names (so that the bytecode proper can concisely refer to names by index).

The inconvenience of handling a binary format should be much smaller than the challenge of parsing C++ sources to find names.