public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Multiple libstdc++ builds
@ 2024-04-03 11:34 John F
  2024-04-03 13:05 ` Jonathan Wakely
  0 siblings, 1 reply; 3+ messages in thread
From: John F @ 2024-04-03 11:34 UTC (permalink / raw)
  To: gcc-help

[-- Attachment #1: Type: text/plain, Size: 1446 bytes --]

Hello,

I’m building GCC from a release branch (13.2.0). For the majority of things I’m trying to compile, I want to produce static + lto’d binaries, linking the c++ lib in statically via the typical -static-libstdc++. So I initially configured gcc with —disable-shared and everything seemed to work just fine.

There are a few things though that I need to build dynamically. In the past, I configured with —with-pic, but I wanted to avoid paying the PIC tax for my true static links. So I rebuilt gcc without —disable-shared. And again, everything works fine and now I can produce shared c++ libraries where I need.

But I noticed that now the libstdc++ components objects are again getting built with -fPIC -DPIC as far as I can tell. Not surprising but disappointing.

Which brings me to the question: is there a good way to produce the libstdc++.a and .so from separate compilations s.t. the objects in the archive don’t have -fPIC?  Or, even better, produce both a libstdc++.a and a libstdc++_pic.a (assuming I can then link the latter via  -nostdlib++ libstdc++_pic.a)?  I tried to wrap my head around the build machinery, but couldn’t really make any progress.

Relatedly, can libstdc++.a practically be built with (fat) LTO support for non-cross builds? Bug 59893 discusses some issues with Canadian crosses but nothing for native and the discussion is largely from a decade ago.

Appreciate your time!




^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Multiple libstdc++ builds
  2024-04-03 11:34 Multiple libstdc++ builds John F
@ 2024-04-03 13:05 ` Jonathan Wakely
  2024-04-08 21:32   ` John F
  0 siblings, 1 reply; 3+ messages in thread
From: Jonathan Wakely @ 2024-04-03 13:05 UTC (permalink / raw)
  To: John F; +Cc: gcc-help

[-- Attachment #1: Type: text/plain, Size: 2483 bytes --]

On Wed, 3 Apr 2024, 12:36 John F via Gcc-help, <gcc-help@gcc.gnu.org> wrote:

> Hello,
>
> I’m building GCC from a release branch (13.2.0). For the majority of
> things I’m trying to compile, I want to produce static + lto’d binaries,
> linking the c++ lib in statically via the typical -static-libstdc++. So I
> initially configured gcc with —disable-shared and everything seemed to work
> just fine.
>
> There are a few things though that I need to build dynamically. In the
> past, I configured with —with-pic, but I wanted to avoid paying the PIC tax
> for my true static links. So I rebuilt gcc without —disable-shared. And
> again, everything works fine and now I can produce shared c++ libraries
> where I need.
>
> But I noticed that now the libstdc++ components objects are again getting
> built with -fPIC -DPIC as far as I can tell. Not surprising but
> disappointing.
>
> Which brings me to the question: is there a good way to produce the
> libstdc++.a and .so from separate compilations s.t. the objects in the
> archive don’t have -fPIC?




It's doable but I don't remember the incantation off the top of my head.
Some users want to link libstdc++.a into their own .so and doing that needs
the .a to be built with PIC. The default build supports that and most users
who are just using the .a directly via static linking will never notice any
overhead from PIC.


Or, even better, produce both a libstdc++.a and a libstdc++_pic.a (assuming
> I can then link the latter via  -nostdlib++ libstdc++_pic.a)?  I tried to
> wrap my head around the build machinery, but couldn’t really make any
> progress.
>

Not easily, no.

TBH I'd just build GCC twice and copy the .a from one build into the
installed tree from the other build (renaming it to _pic.a if desired). You
could then use a spec file to select the right one based on other options
such as -shared or -fPIC being used.


> Relatedly, can libstdc++.a practically be built with (fat) LTO support for
> non-cross builds? Bug 59893 discusses some issues with Canadian crosses but
> nothing for native and the discussion is largely from a decade ago.
>


No, using LTO for libstdc++ is not possible. We rely on the compiler not
being able to see past the boundary between translation units. It might be
possible to disable LTO just for the relevant files, but somebody would
have to do the work to determine which ones are the relevant ones.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Multiple libstdc++ builds
  2024-04-03 13:05 ` Jonathan Wakely
@ 2024-04-08 21:32   ` John F
  0 siblings, 0 replies; 3+ messages in thread
From: John F @ 2024-04-08 21:32 UTC (permalink / raw)
  To: Jonathan Wakely; +Cc: gcc-help

On Wed, Apr 3, 2024, at 8:05 AM, Jonathan Wakely wrote:
> TBH I'd just build GCC twice and copy the .a from one build into the installed tree from the other build (renaming it to _pic.a if desired). You could then use a spec file to select the right one based on other options such as -shared or -fPIC being used.
Thanks for the advice. Very helpful.

I was getting some spooky crashes in iostream code (segfault putting a uint16_t to cerr for example) that ended up being due to a different issue (a 3rd-party library pulling in the system libstdc++.so and that clashing with my static non-PIC build). Not sure if that's maybe supposed to work, but luckily I was able to recompile that library as well and sub in my build of libstdc++.

Along the way to debugging that though, I diffed across the two gcc build tree and noticed some differences in bits/c++config.h

diff -r include/c++/13.2.0/x86_64-pc-linux-gnu/bits/c++config.h include_pic/c++/13.2.0/x86_64-pc-linux-gnu/bits/c++config.h
973c973
< /* #undef _GLIBCXX_HAVE_EXCEPTION_PTR_SINCE_GCC46 */
---
> #define _GLIBCXX_HAVE_EXCEPTION_PTR_SINCE_GCC46 1
1296c1296
< /* #undef _GLIBCXX_HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT */
---
> #define _GLIBCXX_HAVE_SYMVER_SYMBOL_RENAMING_RUNTIME_SUPPORT 1
1762c1762
< /* #undef _GLIBCXX_SYMVER */
---
> #define _GLIBCXX_SYMVER 1
1768c1768
< /* #undef _GLIBCXX_SYMVER_GNU */
---
> #define _GLIBCXX_SYMVER_GNU 1


I think most of them end up being no-ops as far as the include headers, but there is a difference in whether _GLIBCXX_SYMVER_GNU is defined. And that one *is* used in the iostream header.

  // For construction of filebuffers for cout, cin, cerr, clog et. al.
  // When the init_priority attribute is usable, we do this initialization
  // in the compiled library instead (src/c++98/globals_io.cc).
#if !(_GLIBCXX_USE_INIT_PRIORITY_ATTRIBUTE \
      && __has_attribute(__init_priority__))
  static ios_base::Init __ioinit;
#elif defined(_GLIBCXX_SYMVER_GNU)
  __extension__ __asm (".globl _ZSt21ios_base_library_initv");
#endif


So the libstdc++ headers are ultimately slightly sensitive to whether the library was built for shared or not. And it is an iostream initialization difference, so I may ultimately have been seeing a manifestation of a similar issue.  Anyways, the point for anybody else who stumbles across this is that in addition to installing the pic build of the archive, it seemed like I *also* needed to install a separate copy of the headers to use with my pic builds (via --nostdinc++).

> No, using LTO for libstdc++ is not possible. We rely on the compiler not being able to see past the boundary between translation units. It might be possible to disable LTO just for the relevant files, but somebody would have to do the work to determine which ones are the relevant ones.
I'd be happy to help, though I can't say I understand what types of issues require avoiding cross-unit visibility.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-04-08 21:33 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-03 11:34 Multiple libstdc++ builds John F
2024-04-03 13:05 ` Jonathan Wakely
2024-04-08 21:32   ` John F

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).