Re: exported symbols of shared libraries on MSVC

Kirill Makurin <[email protected]> Wed, 4 Jun 2025 17:31:50 +0000
Newsgroups gmane.comp.gnu.libtool.general
Message-ID <DM4PR84MB13733569847EFD8728C2B487B16CA@DM4PR84MB1373.NAMPRD84.PROD.OUTLOOK.COM>
--_000_DM4PR84MB13733569847EFD8728C2B487B16CADM4PR84MB1373NAMP_
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable

Hi Bruno,

I think this feature on MSVC tries to copy behavior of --export-all-symbols=
, which is default with mingw tools[1].

I believe this behavior, as well as --export-all-symbols are supposed to si=
mplify porting existing project to Windows. With these features, you would =
not need to use __delcspec() to make library usable. This could help save a=
 lot of time before project adopts to usage of __delcspec().

One issue with this feature on MSVC is that it may (and usually will) resul=
t in exporting undesired symbols. This particularly applies to projects whi=
ch already use __declspec() to control which symbols to export from the DLL=
.

Note that on mingw, unless explicitly used, --export-all-symbols will not b=
e active if there are any symbols with __declspec(dllexport) in object file=
s or a .def file is used. This prevents the issue with undesired symbols be=
ing exported on mingw.

I think it would be useful if libtool allowed to explicitly disable this fe=
ature, while current behavior would remain default for backward compatibili=
ty.

- Kirill Makurin

[1] https://sourceware.org/binutils/docs/ld/WIN32.html

________________________________
From: Bruno Haible <[email protected]>
Sent: Thursday, June 5, 2025 1:45 AM
To: [email protected] <[email protected]>
Cc: Kirill Makurin <[email protected]>
Subject: Re: exported symbols of shared libraries on MSVC

Hi Kirill,

> If you look at commands executed by libtool when it creates a DLL,
> you may see that it runs $NM on all object files which go into DLL.
> Then it uses some awk script to generate list of all `extern` symbols
> defined in those object files. Libtool then appends each symbol with
> `-link -export:` so link.exe will export all of them.
> ...
> I don't like how libtool handles this. This may result in unwanted
> symbols to be exported.
>
> I wish we had some option to pass to LT_INIT() to disable this behavior,
> but keep old behavior as default.

I'm not the libtool maintainer, but I think the major reason for the
behaviour of "libtool --mode=3Dlink" on MSVC is to be compatible with
the behaviour on other platforms, in particular ELF-based ones.
On these platforms, when you create a shared library ("gcc -shared ..."),
it exports all global symbols.

Which set of symbols would you want to be exported by default?

Authors of shared libraries typically use one of various techniques [1]
to decide which symbols to export. There is no single technique for all
possible situations.

Bruno

[1] https://www.gnu.org/software/gnulib/manual/html_node/Exported-Symbols-o=
f-Shared-Libraries.html




--_000_DM4PR84MB13733569847EFD8728C2B487B16CADM4PR84MB1373NAMP_
Content-Type: text/html; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable

<html>
<head>
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dus-ascii"=
>
<style type=3D"text/css" style=3D"display:none;"> P {margin-top:0;margin-bo=
ttom:0;} </style>
</head>
<body dir=3D"ltr">
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; c=
olor: rgb(0, 0, 0);">
Hi Bruno,</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; c=
olor: rgb(0, 0, 0);">
<br>
</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; c=
olor: rgb(0, 0, 0);">
I think this feature on MSVC tries to copy behavior of --export-all-symbols=
, which is default with mingw tools[1].</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; c=
olor: rgb(0, 0, 0);">
<br>
</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; c=
olor: rgb(0, 0, 0);">
I believe this behavior, as well as --export-all-symbols are supposed to si=
mplify porting existing project to Windows. With these features, you would =
not need to use __delcspec() to make library usable. This could help save a=
 lot of time before project adopts
 to usage of __delcspec().</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; c=
olor: rgb(0, 0, 0);">
<br>
</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; c=
olor: rgb(0, 0, 0);">
One issue with this feature on MSVC is that it may (and usually&nbsp;will) =
result in exporting undesired symbols. This particularly applies to project=
s which already use __declspec() to control which symbols to export from th=
e DLL.</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; c=
olor: rgb(0, 0, 0);">
<br>
</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; c=
olor: rgb(0, 0, 0);">
Note that on mingw, unless explicitly used, --export-all-symbols will not b=
e active if there are any symbols with __declspec(dllexport) in object file=
s or a .def file is used. This prevents the issue with undesired symbols be=
ing exported on mingw.</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; c=
olor: rgb(0, 0, 0);">
<br>
</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; c=
olor: rgb(0, 0, 0);">
I think it would be useful if libtool allowed to explicitly disable this fe=
ature, while current behavior would remain default for backward compatibili=
ty.</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; c=
olor: rgb(0, 0, 0);">
<br>
</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; c=
olor: rgb(0, 0, 0);">
- Kirill Makurin</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; c=
olor: rgb(0, 0, 0);">
<br>
</div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; c=
olor: rgb(0, 0, 0);">
[1] <a href=3D"https://sourceware.org/binutils/docs/ld/WIN32.html" id=3D"OW=
Af57804ef-5ef4-b94d-177a-a5b517f9a162" class=3D"OWAAutoLink elementToProof"=
 style=3D"margin: 0px; text-align: left;">
https://sourceware.org/binutils/docs/ld/WIN32.html</a></div>
<div class=3D"elementToProof" style=3D"font-family: Aptos, Aptos_EmbeddedFo=
nt, Aptos_MSFontService, Calibri, Helvetica, sans-serif; font-size: 12pt; c=
olor: rgb(0, 0, 0);">
<br>
</div>
<div id=3D"appendonsend"></div>
<hr style=3D"display:inline-block;width:98%" tabindex=3D"-1">
<div id=3D"divRplyFwdMsg" dir=3D"ltr"><font face=3D"Calibri, sans-serif" st=
yle=3D"font-size:11pt" color=3D"#000000"><b>From:</b> Bruno Haible &lt;brun=
[email protected]&gt;<br>
<b>Sent:</b> Thursday, June 5, 2025 1:45 AM<br>
<b>To:</b> [email protected] &lt;[email protected]&gt;<br>
<b>Cc:</b> Kirill Makurin &lt;[email protected]&gt;<br>
<b>Subject:</b> Re: exported symbols of shared libraries on MSVC</font>
<div>&nbsp;</div>
</div>
<div class=3D"BodyFragment"><font size=3D"2"><span style=3D"font-size:11pt;=
">
<div class=3D"PlainText">Hi Kirill,<br>
<br>
&gt; If you look at commands executed by libtool when it creates a DLL,<br>
&gt; you may see that it runs $NM on all object files which go into DLL.<br=
>
&gt; Then it uses some awk script to generate list of all `extern` symbols<=
br>
&gt; defined in those object files. Libtool then appends each symbol with<b=
r>
&gt; `-link -export:` so link.exe will export all of them.<br>
&gt; ...<br>
&gt; I don't like how libtool handles this. This may result in unwanted<br>
&gt; symbols to be exported.<br>
&gt; <br>
&gt; I wish we had some option to pass to LT_INIT() to disable this behavio=
r,<br>
&gt; but keep old behavior as default.<br>
<br>
I'm not the libtool maintainer, but I think the major reason for the<br>
behaviour of &quot;libtool --mode=3Dlink&quot; on MSVC is to be compatible =
with<br>
the behaviour on other platforms, in particular ELF-based ones.<br>
On these platforms, when you create a shared library (&quot;gcc -shared ...=
&quot;),<br>
it exports all global symbols.<br>
<br>
Which set of symbols would you want to be exported by default?<br>
<br>
Authors of shared libraries typically use one of various techniques [1]<br>
to decide which symbols to export. There is no single technique for all<br>
possible situations.<br>
<br>
Bruno<br>
<br>
[1] <a href=3D"https://www.gnu.org/software/gnulib/manual/html_node/Exporte=
d-Symbols-of-Shared-Libraries.html">
https://www.gnu.org/software/gnulib/manual/html_node/Exported-Symbols-of-Sh=
ared-Libraries.html</a><br>
<br>
<br>
<br>
</div>
</span></font></div>
</body>
</html>

--_000_DM4PR84MB13733569847EFD8728C2B487B16CADM4PR84MB1373NAMP_--