I agree with Dave. Additional thoughts:

From: Dave Thaler
Sent: Tuesday, April 4, 2017 11:09 AM
To: Othman, Ossama <ossama.othman at intel.com>; Daniel Mihai <Daniel.Mihai at 
microsoft.com>
Cc: Wouter van der Beek (wovander) <wovander at cisco.com>; uzchoi at 
samsung.com; Mats Wichmann <mats at wichmann.us>; C.J. Collier <cjcollier at 
linuxfoundation.org>; iotivity-dev at lists.iotivity.org
Subject: RE: [dev] Don't make breaking changes

C++ APIs are never used with shared libraries due to the name mangling issues.
So the .def file only includes C APIs.

From: Othman, Ossama [mailto:[email protected]]
Sent: Tuesday, April 4, 2017 11:06 AM
To: Daniel Mihai <Daniel.Mihai at microsoft.com<mailto:Daniel.Mihai at 
microsoft.com>>
Cc: Wouter van der Beek (wovander) <wovander at cisco.com<mailto:wovander at 
cisco.com>>; uzchoi at samsung.com<mailto:uzchoi at samsung.com>; Mats Wichmann 
<mats at wichmann.us<mailto:mats at wichmann.us>>; Dave Thaler <dthaler at 
microsoft.com<mailto:dthaler at microsoft.com>>; C.J. Collier <cjcollier at 
linuxfoundation.org<mailto:cjcollier at linuxfoundation.org>>; iotivity-dev at 
lists.iotivity.org<mailto:iotivity-dev at lists.iotivity.org>
Subject: Re: [dev] Don't make breaking changes

Hi Dan,

Do you use the *.def files for the IoTivity C++ API, too?  Wouldn't the mangled 
C++ names be a problem?

In any case, if the GCC based symbol visibility isn't viable, we could also use 
the VERSION command in a linker 
script<https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsourceware.org%2Fbinutils%2Fdocs%2Fld%2FVERSION.html%23VERSION&data=02%7C01%7Cdthaler%40microsoft.com%7Ca2190f7658ac45f02d1a08d47b8550ea%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636269259892279606&sdata=U6anUZ3hZMO1f%2FGUgbx56VV4kO%2FKb83A2pr8GRvlh7M%3D&reserved=0>
 to mark symbols as exported ("global") or hidden ("local").  However, I don't 
have much experience with linker scripts so I don't know how well they scale or 
how maintainable they are.

On the other hand, my experience with GCC symbol visibility on large C++ 
libraries that already used Windows style _declspec(dllexport) based macros was 
quite positive, especially since it allowed the compiler to generate better 
binaries in some cases than the linker script based approach.
[DM] As you said, name mangling is still a problem for C++ code ? even if you 
use _declspec(dllexport).

I'm certainly interested in understanding why _declspec(dllexport) doesn't 
scale well.  Should we take that discussion to a separate thread?
[DM] Here?s what I have learned while I was trying to fix the old OC_EXPORT in 
IoTivity:

1.       Sometimes we need to import or export a function owned by someone else 
? e.g., export a function implemented in one of the IoTivity extlibs. Adding 
OC_EXPORT into extlibs headers can be messier than adding a *.def file.

2.       This is harder to explain, but let me try. Typical use of OC_EXPORT is 
to have:

a.       An Include/ directory, with all exported function declarations

b.       A dll/ directory, with the source code for the exported functions

c.       An app/ directory, with the consumer of exported functions

d.       The dll/ directory uses #define OC_EXPORT __declspec(dllexport)

e.       The app/ directory uses #define OC_EXPORT __declspec(dllimport)

f.        But, it is common in IoTivity to both import some APIs, and export 
other APIs, in a single module/LIB. So, such module cannot easily use either 
__declspec(dllexport) or __declspec(dllimport)

g.       As a workaround for (f), we could define a whole bunch of macros 
OC_EXPORT_1, OC_EXPORT_2, OC_EXPORT_3, OC_EXPORT_4, etc. and carefully sprinkle 
some of them before each #include. But this seems bizarre and unsustainable.

3.       We have seen DLL port-processing tools that prefer exports looking 
this way (not using __declspec):

C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64>link /dump 
/exports c:\Windows\system32\kernelbase.dll | findstr CloseHandle
        130   80 00040790 CloseHandle

I believe declspec changes that to:

           130   80 00040790 CloseHandle at 4

            Maybe we could fix those tools though, so #1 and #2 are more 
significant problems than #3.

Thanks,
-Ossama


On Tue, Apr 4, 2017 at 10:32 AM, Daniel Mihai <Daniel.Mihai at 
microsoft.com<mailto:Daniel.Mihai at microsoft.com>> wrote:
It sounds like the GCC symbols visibility could reduce the differences between 
IoTivity on Windows and non-Windows. That?s a good thing, because it should 
reduce the IoTivity Test and Maintenance burden for all of us.

However, the __declspec(dllexport) mechanism on Windows doesn?t scale well to 
non-trivial projects (let me know in case you are curious about the details). 
So, I don?t think we should not go back to __declspec for Windows any time 
soon. IoTivity on Windows was using __declspec until a few months ago, when I 
replaced that with *.def files.

I don?t know if GCC?s __attribute__ has similar problems to Windows?s 
__declspec.

Dan

From: Othman, Ossama [mailto:ossama.othman at 
intel.com<mailto:[email protected]>]
Sent: Tuesday, April 4, 2017 10:09 AM
To: Daniel Mihai <Daniel.Mihai at microsoft.com<mailto:Daniel.Mihai at 
microsoft.com>>
Cc: Wouter van der Beek (wovander) <wovander at cisco.com<mailto:wovander at 
cisco.com>>; uzchoi at samsung.com<mailto:uzchoi at samsung.com>; Mats Wichmann 
<mats at wichmann.us<mailto:mats at wichmann.us>>; Dave Thaler <dthaler at 
microsoft.com<mailto:dthaler at microsoft.com>>; C.J. Collier <cjcollier at 
linuxfoundation.org<mailto:cjcollier at linuxfoundation.org>>; iotivity-dev at 
lists.iotivity.org<mailto:iotivity-dev at lists.iotivity.org>
Subject: Re: [dev] Don't make breaking changes

Hi Dan,

On Tue, Apr 4, 2017 at 9:52 AM, Daniel Mihai via iotivity-dev <iotivity-dev at 
lists.iotivity.org<mailto:iotivity-dev at lists.iotivity.org>> wrote:
2.       Different OS?s/platforms seem to have different requirements. For 
example:

a.       If I understand correctly, non-static C functions in a Linux shared 
library can be called by anyone outside the shared library.

b.       On Windows, we need to identify those functions that can be called by 
anyone outside the shared library, and explicitly add them to the exports list, 
one by one.

Does this mean that all of the functions from (a) and (b) are Public and cannot 
get breaking changes? That?s typically the approach on Windows, but it is not 
clear to me if is the proper approach on Linux too.
On platforms that use GCC, including Linux, we can leverage GCC's symbol 
visibility 
feature<https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgcc.gnu.org%2Fwiki%2FVisibility&data=02%7C01%7Cdthaler%40microsoft.com%7Ca2190f7658ac45f02d1a08d47b8550ea%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636269259892279606&sdata=%2FtS%2Bg%2FL0J4ljdPCOmqDVT8CnxRLL%2FlUEXVhtaqqPAbg%3D&reserved=0>
 to prevent functions, classes, etc, from being exported in a manner that is 
similar to Windows.  The GCC Visibility wiki provides an example of how one 
could declare and use the import and export macros one sees in Windows 
libraries in manner that supports both Windows and GCC based builds.  Library 
binaries that correctly leverage GCC symbol visibility often gain improved 
performance as well as a smaller footprint.

It would be useful for IoTivity to leverage GCC symbol visibility if it isn't 
already doing so.

HTH,
-Ossama

-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://lists.iotivity.org/pipermail/iotivity-dev/attachments/20170404/ef7c714e/attachment.html>

Reply via email to