This issue was coming from "NM=llvm-nm.exe". I was setting some of variables to 
use llvm tools, since they are installed alongside clang-cl.exe. I *did not* 
expect this to cause any issues, since most packages were building successfully.

It was happening when libtool was running $NM on all object files. With 
llvm-nm.exe it was marking sprintf for export, while with dumpbin.exe it was 
not. Btw, this is the feature we mentioned on libtool mailing list.

I think it is safe to assume that other unwanted symbols were exported as well.

Interesting thing is that both llvm-nm.exe and dumpbin.exe *do* list sprintf 
function as a defined symbol (unless I misunderstand their output). Should this 
be considered a libtool bug?

With "dumpbin -symbols":

```
019 00000000 SECT8  notype ()    External     | sprintf
```

With "llvm-nm -A":

```
./srclib/libicrt_a-strerror.obj: 00000000 T sprintf
```

After changing to NM="dumpbin.exe -nologo -symbols" (which I use with cl.exe), 
both libtextstyle and libunistring build successfully.

- Kirill Makurin
________________________________
From: bug-gnulib-bounces+maiddaisuki=outlook....@gnu.org 
<bug-gnulib-bounces+maiddaisuki=outlook....@gnu.org> on behalf of Kirill 
Makurin <maiddais...@outlook.com>
Sent: Monday, June 16, 2025 9:26 AM
To: Bruno Haible <br...@clisp.org>
Cc: bug-gnulib@gnu.org <bug-gnulib@gnu.org>
Subject: Re: clang-cl: undeclared library function 'sprintf'

Thanks for the info. Now I see that affected files are compiled twice and only 
the second compilation fails.

I will try to find out what causes iconv-2.dll to export sprintf. It should at 
least give us some answers.

- Kirill Makurin
________________________________
From: Bruno Haible <br...@clisp.org>
Sent: Monday, June 16, 2025 8:56 AM
To: Kirill Makurin <maiddais...@outlook.com>
Cc: bug-gnulib@gnu.org <bug-gnulib@gnu.org>
Subject: Re: clang-cl: undeclared library function 'sprintf'

Kirill Makurin wrote:
> I tried further investigate this issue and I have discovered that 
> libtextstyle/lib/config.h contains following lines:
>
> ```
> #define sprintf libtextstyle_sprintf
> #define sscanf libtextstyle_sscanf
> ```
>
> Since config.h is included before any system header file, later when system's 
> stdio.h is included, I assume this macro is defined and instead of 
> declaring/defining inline sprintf it ends up declaring/defining 
> libtextstyle_sprintf.

What you are seeing here is similar to what you saw with iconv-2.dll:
These config.h lines get generated by libtextstyle/lib/Makefile.am:
In a first pass all object files are compiled without these #defines,
then the exported symbols of these files (look at the file 'exported.sh')
are collected and remapped to symbols with a 'libtextstyle_' prefix.
So, it means that during this first pass, at least one object file
had 'sprintf' as an exported symbol, and likewise for 'sscanf'.

libiconv does not have this same compilation-in-two-passes technique;
this is why there the symbol 'sprintf' is exported without a prefix.

Still, the origin seems to be the same: the MSVC headers must contain
some inlinable definition of sprintf and sscanf, and your 'clang-cl'
must be stuffing these into the object files as exported symbols.
Which, as you noted, is a no-go for shared libraries.

Bruno



Reply via email to