@@ -301,45 +301,58 @@ def prepare(workdir):
301301# --------------------------------------------------------------------------
302302# One patch to gmp.h beyond configure's substitutions.
303303#
304- # gmp.h picks how to spell "inline" through a vendor cascade. The GCC branch
305- # gives `extern __inline__ __attribute__ ((__gnu_inline__))` -- GNU89 inline
306- # semantics: the body in the header is for inlining only and is NEVER emitted
307- # as a standalone symbol, because the out-of-line copy comes from the one TU
308- # that compiles with -D__GMP_FORCE_<fn> (mpz/get_ui.c, mpn/generic/sub.c, ...).
309- # The whole library depends on that division.
304+ # gmp.h picks how to spell "inline" through a vendor cascade. About a dozen
305+ # small functions (mpz_get_ui, mpn_add, mpn_cmp, ...) are then defined in the
306+ # header under __GMP_EXTERN_INLINE, AND out of line by the one TU that
307+ # compiles with -D__GMP_FORCE_<fn> (mpz/get_ui.c, mpn/generic/add.c, ...).
308+ # That only works if the header's copy never becomes a standalone symbol.
309+ # The GCC branch guarantees it with
310+ # `extern __inline__ __attribute__ ((__gnu_inline__))`.
310311#
311- # The `_MSC_VER` branch further down is the only one in the cascade WITHOUT a
312- # `! defined (__GMP_EXTERN_INLINE)` guard (the SunPro and SCO branches have
313- # one), so on a compiler that is BOTH -- clang targeting the MSVC ABI, which
314- # is what this index uses on Windows -- it silently overwrites the GCC answer
315- # with plain `__inline`. Under MS inline semantics that emits an external
316- # definition in every TU that includes gmp.h, and the link dies on ten
317- # duplicate symbols against the forced copies:
312+ # The `_MSC_VER` branch answers plain `__inline`, whose MS semantics DO emit
313+ # an external definition in every TU that includes the header -- and it is the
314+ # only branch in the cascade without a `! defined (__GMP_EXTERN_INLINE)` guard
315+ # (SunPro and SCO both have one).
316+ #
317+ # This index compiles Windows with clang targeting the MSVC ABI, and that
318+ # compiler defines _MSC_VER but NOT __GNUC__ (measured: guarding the branch on
319+ # `! defined (__GNUC__)` changed nothing), so it lands on the MSVC answer and
320+ # the link dies on ten duplicate symbols:
318321#
319322# lld-link: error: duplicate symbol: __gmpz_get_ui
320- # >>> defined at gmp.h:1793 obj/.../mpz/pprime_p.o
323+ # >>> defined at gmp.h:1800 obj/.../mpz/pprime_p.o
321324# >>> defined at obj/.../mpz/get_ui.o
322325#
323- # Upstream never hit this because it has no MSVC-ABI build at all. Adding the
324- # same guard the neighbouring branches already carry is the minimal fix, and
325- # it is a no-op everywhere else: non-Windows targets never define _MSC_VER,
326- # and real MSVC never defines __GNUC__.
326+ # Fix: `static __inline`, which is what GMP itself answers for the other two
327+ # compilers whose "extern inline" leaks a global (DEC C and SCO OpenUNIX).
328+ # Non-forced TUs get a file-local copy that still inlines; the forced TU is
329+ # unaffected because gmp.h suppresses __GMP_EXTERN_INLINE there by hand
330+ # (`#if ! defined (__GMP_FORCE_<fn>)`), so the external definition still comes
331+ # from exactly one object. The added guard keeps a future GNU-compatible
332+ # compiler that also sets _MSC_VER on the gnu_inline answer.
333+ #
334+ # Upstream never hit any of this: it has no MSVC-ABI build at all.
327335GMP_H_PATCHES = [(
328336 """/* Microsoft's C compiler accepts __inline */
329337#ifdef _MSC_VER
330338#define __GMP_EXTERN_INLINE __inline
331339#endif
332340""" ,
333341 """/* Microsoft's C compiler accepts __inline */
334- /* mcpp-index (compat.gmp): `&& ! defined (__GNUC__)`, which upstream's
335- neighbouring vendor branches already carry in spirit. clang targeting the
336- MSVC ABI defines BOTH __GNUC__ and _MSC_VER; without the guard this line
337- replaces the GCC branch's gnu_inline spelling with MS inline semantics, the
338- header starts emitting an external definition of every __GMP_EXTERN_INLINE
339- function in every TU that includes it, and the link fails with ten
340- duplicate symbols against the -D__GMP_FORCE_<fn> copies. */
341- #if defined (_MSC_VER) && ! defined (__GNUC__)
342- #define __GMP_EXTERN_INLINE __inline
342+ /* mcpp-index (compat.gmp): `static __inline`, not `__inline`, and guarded.
343+ Plain `__inline` has MS inline semantics -- the header's copy of every
344+ __GMP_EXTERN_INLINE function becomes an external definition in EVERY TU
345+ that includes gmp.h, which collides with the out-of-line copy the
346+ -D__GMP_FORCE_<fn> TU emits (ten `lld-link: duplicate symbol` errors on
347+ clang targeting the MSVC ABI, which defines _MSC_VER but not __GNUC__).
348+ `static __inline` is the answer GMP already gives for the other compilers
349+ whose "extern inline" leaks a global (DEC C, SCO OpenUNIX): the header's
350+ copy stays file-local and still inlines, while the forced TU -- where
351+ gmp.h suppresses this macro by hand -- remains the single external
352+ definition. The guard mirrors the SunPro/SCO branches, so a GNU-compatible
353+ compiler that also sets _MSC_VER keeps the gnu_inline answer above. */
354+ #if defined (_MSC_VER) && ! defined (__GMP_EXTERN_INLINE)
355+ #define __GMP_EXTERN_INLINE static __inline
343356#endif
344357""" )]
345358
0 commit comments