September 12, 2013

On 12.09.2013 01:16, Martin Nowak wrote:
> On 09/11/2013 08:21 AM, Rainer Schuetze wrote:
>> AFAIU the discussed scenario is that the phobos library exports a lot of
>> symbols, and this library is used both for static and dynamic linking.
>> An executable statically linked against this library will have all the
>> exports. That still works but is ugly.
>
> Yes and it also has some runtime/memory overhead because the symbol
> table is much bigger.
>
>> A DLL to be used as a plugin with a C interface might also want to link
>> statically against phobos to avoid DLL hell. Consider multiple plugins
>> built against different versions of phobos. These would also leak also
>> the symbols.
>
> Right, that's the valid use-case. But here the additionally exported
> symbols are way less of a problem because your loading not linking.
> And as I wrote before if you link a program with two copies of the same
> library you're asking for trouble.
>
> Anyhow I realized there is even less a use-case for statically linking a
> lib into a DLL (shared library) while expecting the symbols to be
> exported. We use that to put druntime into libphobos2.so though.
> Also one doesn't need exported (visible) symbols for static linking.
>
> So how about going into the opposite direction?
> When the compiler creates a lib it strips all the exports (marks all
> symbols as hidden) by default. For the very special use-case where one
> wants to preserve the exports we can add a -libexports flag, only to be
> used with -lib.
> Another nice thing is, that dmd writes libs itself and already processes
> all object files so we could easily integrate the striping in the compiler.
>

This sounds interesting. Stripping an existing library isn't even needed because it is normally never created with exports anyway (-lib implies that no exports are created to start with). Stripping object files might be necessary, though, in case they have been built separately with -c.
September 19, 2013
Am 10.09.2013 05:39, schrieb Martin Nowak:
>>> I also kind of feel that we need to export lib1 as well, as you may not
>>> know what lib2 does with what it gets from lib1 (passing objects around
>>> for instance). So certainly at least some part of lib1 need to be
>>> exported.
> For sure lib2 might forward to some lib1 symbols.
> Not sure what might accidentally require linkage.
>
>> I don't agree if that statement. If you have three libs. lib1, lib2 and
>> lib3. And lib2 and lib3 link statically against lib1 you are going to
>> get linker errors because both lib2 and lib3 contain the symbols of lib1.
>
> A: Why do two DLLs which export the same symbols cause linker errors?
Yes
> Because the corresponding import libraries contain the same symbols?
> B: You shouldn't mix static with dynamic linking, ODR issues are what
> you get in return.
Well you should not. But it will happen. Espeically if you don't have any control over what others due. E.g. when using third party libraries.

> C: What would happen if you statically link against lib2 and lib3?

Well you would get a linker error as well. But the reasoing behind this is as follows.

You use a third party library that comes as a shared library. That third party library uses say libcurl internally. Now you use libcurl too. You link against libcurl. But because the third party library you link to also uses libcurl you will get linker errors. Also you might not want to use the same version of libcurl then the thirdparty library you use. This is going to become a problem especially in bigger projects, where you are not able to compile the third party libraries yourself because you don't have the source code. In such a case it can easily happen that you get a new version of that third party library, they added a new internal dependency to a library you already use and suddenly your executable won't linke anymore.

Kind Regards
Benjamin Thaut
September 19, 2013
Am 12.09.2013 07:54, schrieb Rainer Schuetze:
>
>
> This sounds interesting. Stripping an existing library isn't even needed
> because it is normally never created with exports anyway (-lib implies
> that no exports are created to start with). Stripping object files might
> be necessary, though, in case they have been built separately with -c.

Can't we get around stripping object files by always using -c together with -lib in case the object file is supposed to go into a static library?
September 19, 2013

On 19.09.2013 13:58, Benjamin Thaut wrote:
> Am 12.09.2013 07:54, schrieb Rainer Schuetze:
>>
>>
>> This sounds interesting. Stripping an existing library isn't even needed
>> because it is normally never created with exports anyway (-lib implies
>> that no exports are created to start with). Stripping object files might
>> be necessary, though, in case they have been built separately with -c.
>
> Can't we get around stripping object files by always using -c together
> with -lib in case the object file is supposed to go into a static library?

That could work, though it has it's own set of side effects, like splitting a module into pseudo modules per function which also ruins running unittests built into the library. Building modules with -c and combining these into a library afterwards avoids this.
September 19, 2013
Am 19.09.2013 20:24, schrieb Rainer Schuetze:
>
>
> On 19.09.2013 13:58, Benjamin Thaut wrote:
>> Am 12.09.2013 07:54, schrieb Rainer Schuetze:
>>>
>>>
>>> This sounds interesting. Stripping an existing library isn't even needed
>>> because it is normally never created with exports anyway (-lib implies
>>> that no exports are created to start with). Stripping object files might
>>> be necessary, though, in case they have been built separately with -c.
>>
>> Can't we get around stripping object files by always using -c together
>> with -lib in case the object file is supposed to go into a static
>> library?
>
> That could work, though it has it's own set of side effects, like
> splitting a module into pseudo modules per function which also ruins
> running unittests built into the library. Building modules with -c and
> combining these into a library afterwards avoids this.

Ah ok, I didn't know that. How much work would it be to implement object file stripping? I'm not confident I can do this.

Kind Regards
Benjamin Thaut
September 23, 2013
Am 10.09.2013 05:50, schrieb Martin Nowak:
> Can we deal with vtable entries pointing to imported functions on
> Windows? The kind of thing that happens when you inherit across a DLL
> boundary.

I can't answer that and with dmd's current implementation of export its not possible to try this. I would say we implement the DIP and see on the way if this becomes a issue.

-- 
Kind Regards
Benjamin Thaut
September 23, 2013

On 23.09.2013 07:22, Benjamin Thaut wrote:
> Am 10.09.2013 05:50, schrieb Martin Nowak:
>> Can we deal with vtable entries pointing to imported functions on
>> Windows? The kind of thing that happens when you inherit across a DLL
>> boundary.
>
> I can't answer that and with dmd's current implementation of export its
> not possible to try this. I would say we implement the DIP and see on
> the way if this becomes a issue.
>

It is the same as initializing a global variable with a pointer into another DLL, i.e. it needs some init code to set the value.
September 23, 2013

On 19.09.2013 21:42, Benjamin Thaut wrote:
> Am 19.09.2013 20:24, schrieb Rainer Schuetze:
>>
>>
>> On 19.09.2013 13:58, Benjamin Thaut wrote:
>>> Am 12.09.2013 07:54, schrieb Rainer Schuetze:
>>>>
>>>>
>>>> This sounds interesting. Stripping an existing library isn't even
>>>> needed
>>>> because it is normally never created with exports anyway (-lib implies
>>>> that no exports are created to start with). Stripping object files
>>>> might
>>>> be necessary, though, in case they have been built separately with -c.
>>>
>>> Can't we get around stripping object files by always using -c together
>>> with -lib in case the object file is supposed to go into a static
>>> library?
>>
>> That could work, though it has it's own set of side effects, like
>> splitting a module into pseudo modules per function which also ruins
>> running unittests built into the library. Building modules with -c and
>> combining these into a library afterwards avoids this.
>
> Ah ok, I didn't know that. How much work would it be to implement object
> file stripping? I'm not confident I can do this.
>

I just checked the OMF and COFF docs: it should be possible to wipe out the export records without having to rewrite the object files, so it's not too involved. Don't know about ELF or mach-o, though.
November 04, 2013
On 09/08/2013 09:33 AM, Benjamin Thaut wrote:
> There is yet another problem to be solved. What should happen with
> tempaltes? Does it make sense to export templates?

Yes, we need to export/import symbols from templates. Recently the compiler was changed to skip instantiations when they have already been instantiated in imported modules.
There is a problem similar to the lib case though. When you instantiate an exported template you don't want it's symbols exported from your shared library.

> What happens if a template class marked with export gets instanciated in different DLLs
> using the same template arguments? Should the TypeInfo objects match?
> Should templates be exportable in generall?

Yes TypeInfos should match. For symbols which are allowed to have multiple definitions (like typeinfos from template classes) we can't solely rely on pointer comparison but also need to test typename equality.

November 16, 2013
On 09/19/2013 01:55 PM, Benjamin Thaut wrote:
>> B: You shouldn't mix static with dynamic linking, ODR issues are what
>> you get in return.
> Well you should not. But it will happen. Espeically if you don't have
> any control over what others due. E.g. when using third party libraries.
Let me put it differently, if you statically link against a library in your DLL you need to ensure not to leak (export) any symbols from this static library.