Russel Winder <rus...@winder.org.uk> writes:
>> > I do not like few things about Jigsaw, but most of the things they
>> > plan there simply make sense, especially the versioning and
>> > module-restrictions, which I urge D developers to take a look and
>> > come up with something similar for D2 or D3... This is extremely
>> > useful, and will be even more useful once we have shared libraries
>> > where we can have N different shared libraries that contain the
>> > same module, but different version of it...
>
> Isn't the real question why is the same dynamic library linking
> problem happening again. Has nothing been learned from UNIX shared
> objects and Windows DLLs?

ELF (aka "unix") shared objects actually do support versioned symbols
(and have since at least 1999) though they're not default and using them
makes building a shared library somewhat more complex, as you have to
tell the linker about ABI versions. But with properly done versioned
symbols, linking two different versions of the same shared library into
the same process space is perfectly safe; the C library itself uses it,
for instance:

wouter@carillon:~$ objdump -T /lib/x86_64-linux-gnu/libc.so.6  | head -n 20

/lib/x86_64-linux-gnu/libc.so.6:     file format elf64-x86-64

DYNAMIC SYMBOL TABLE:
000000000001eb80 l    d  .text  0000000000000000              .text
000000000037d738 l    d  .tdata 0000000000000000              .tdata
0000000000000000      DO *UND*  0000000000000000  GLIBC_PRIVATE _rtld_global
0000000000000000      DO *UND*  0000000000000000  GLIBC_PRIVATE 
__libc_enable_secure
0000000000000000      DF *UND*  0000000000000000  GLIBC_2.3   __tls_get_addr
0000000000000000      DO *UND*  0000000000000000  GLIBC_PRIVATE _rtld_global_ro
0000000000000000  w   D  *UND*  0000000000000000              _dl_starting_up
0000000000000000      DO *UND*  0000000000000000  GLIBC_PRIVATE _dl_argv
00000000000709d0 g    DF .text  0000000000000115  GLIBC_2.2.5 putwchar
000000000008bbf0 g    DF .text  000000000000001e  GLIBC_2.2.5 __strspn_c1
00000000000ec750 g    DF .text  0000000000000017  GLIBC_2.4   __gethostname_chk
000000000008bc10 g    DF .text  000000000000001a  GLIBC_2.2.5 __strspn_c2
00000000000f2660 g    DF .text  00000000000000a5  GLIBC_2.2.5 setrpcent
0000000000093760 g    DF .text  000000000000000a  GLIBC_2.2.5 __wcstod_l
000000000008bc30 g    DF .text  0000000000000022  GLIBC_2.2.5 __strspn_c3
00000000000d8c70 g    DF .text  0000000000000025  GLIBC_2.3.2 epoll_create

the GLIBC_* thingies (apart from the GLIBC_PRIVATE ones) are symbol
versions. As you can see, it's even safe to have multiple versions in
the same shared object, and (though it's not shown here) you can have
multiple implementations of a particular symbol (but with different
versions) in one shared object.

For some details on how it works, see
http://refspecs.linuxbase.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/symversion.html

> Go solves the problem by refusing all notion of dynamic linking and
> insisting on static linking of all applications.

"General Motors solves the problem of fatal car crashes by building cars
without engines"

That's not a solution, that's avoiding the issue.

Having said that, doing shared libraries properly is fairly complex, so
it's not necessarily a bad idea to push the problem into the future
until you've thought about it a lot; otherwise you'll probably end up
with a broken solution.

> Certainly Gradle and Maven support this idea very well.  Sadly Make,
> CMake, Autotools, SCons, Waf,… tend to delegate the problem to someone
> else.

autotools has libtool, which does the shared object stuff, and which can
do symbol versioning.

I don't know about cmake; and scons and waf are both crap, so it's not
surprising they've not even heard of symbol versioning.

Make, of course, is a programming language for writing build systems,
it's not a build system by itself.

-- 
The volume of a pizza of thickness a and radius z can be described by
the following formula:

pi zz a

Reply via email to