Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

-static-libstdc++ -static-libgcc does not work with MOSTLY STATIC linking #2840

Closed
htuch opened this issue Apr 18, 2017 · 8 comments
Closed
Assignees
Labels

Comments

@htuch
Copy link

htuch commented Apr 18, 2017

When the -static-libstdc++ -static-libgcc flags are supplied as linkopts to cc_binary and linkstatic = 1, the resulting binary is still dynamically linked against libgcc/libc++, witness:

(cd /usr/local/google/home/htuch/.cache/bazel/_bazel_htuch/89676793239ac96d94294e6c7a44597f/execroot/envoy && \
  exec env - \
  /google/src/files/151979262/depot/google3/third_party/crosstool/v18/stable/wrappers/x86_64-grtev4-linux-gnu/bin/gcc -o bazel-out/local-fastbuild/bin/source/exe/envoy-static -pthread '-Wl,--build-id=md5' '-Wl,--hash-style=gnu' -static-libstdc++ -static-libgcc '-fuse-ld=gold' -Wl,-no-as-needed -Wl,-z,relro,-z,now -B/g
oogle/src/files/151979262/depot/google3/third_party/crosstool/v18/stable/wrappers/x86_64-grtev4-linux-gnu/bin -B/usr/bin '-Wl,--build-id=md5' '-Wl,--hash-style=gnu' -pass-exit-codes -Wl,-S -Wl,@bazel-out/local-fastbuild/bin/source/exe/envoy-static-2.params)
Target //source/exe:envoy-static up-to-date:
  bazel-bin/source/exe/envoy-static
INFO: Elapsed time: 168.321s, Critical Path: 50.97s
<static-link> htuch@htuch00:~/src/envoy ⊧ ldd bazel-bin/source/exe/envoy-static
        linux-vdso.so.1 =>  (0x00007ffc0c3c7000)
        librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f60e820f000)
        libstdc++.so.6 => /google/src/files/151979262/depot/google3/third_party/crosstool/v18/stable/toolchain/x86_64-grtev4-linux-gnu/lib64/libstdc++.so.6 (0x00007f60e80f0000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f60e7dea000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f60e7bcc000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f60e7804000)
        /usr/grte/v4/lib64/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x000055f7c0973000)
        libgcc_s.so.1 => /google/src/files/151979262/depot/google3/third_party/crosstool/v18/stable/toolchain/x86_64-grtev4-linux-gnu/lib64/libgcc_s.so.1 (0x00007f60e75ed000)

From the compiler man page, it looks like these flags are only supposed to work under the g++ driver. Even manually rerunning the command under g++ doesn't fix this. I had to modify bazel-out/local-fastbuild/bin/source/exe/envoy-static-2.params to remove the -lstdc++.

The Envoy (https://github.com/lyft/envoy/) Bazel build needs this mostly static link, where the Envoy libraries, external deps and standard C/C++ libs are statically linked, but the rest of the system libs are dynamically linked.

Looks like this requires some additional Bazel implementation work to properly support (at least as far as CROSSTOOLS goes, maybe another kind of pseudo-static link type). Are there any suggested workarounds in the meanwhile?

CC: @mattklein123 envoyproxy/envoy#415

htuch added a commit to htuch/envoy that referenced this issue Apr 18, 2017
…c static linking.

We import cc_configure.bzl from https://github.com/bazelbuild/bazel at d6fec93 in this patch.
This allows us to workaround bazelbuild/bazel#2840 (see the header comment for further details).
mattklein123 pushed a commit to envoyproxy/envoy that referenced this issue Apr 19, 2017
…c static linking. (#782)

We import cc_configure.bzl from https://github.com/bazelbuild/bazel at d6fec93 in this patch.
This allows us to workaround bazelbuild/bazel#2840 (see the header comment for further details).
@aehlig
Copy link
Contributor

aehlig commented Apr 19, 2017

over to our C++ expert, to triage further

@htuch
Copy link
Author

htuch commented Apr 19, 2017

FTR, our workaround was to fork cc_configure.bzl into our repo and make the modifications indicated in envoyproxy/envoy#782.

@jmillikin-stripe
Copy link
Contributor

jmillikin-stripe commented Jul 14, 2017

Here's a smaller reproduction than building all of Envoy:

#!/bin/bash
set -e

touch WORKSPACE
cat >hello.cc <<EOF
#include <iostream>

int main() {
  std::cout << "hello world!\n";
  return 0;
}
EOF
cat >BUILD <<EOF
cc_binary(
  name="hello",
  srcs=["hello.cc"],
  linkstatic=1,
  linkopts=[
    "-static-libstdc++",
    "-static-libgcc",
  ],
)
EOF

bazel build :hello
cp bazel-bin/hello hello-bazel

gcc -c hello.cc -o hello-gcc.o
gcc -o hello-gcc hello-gcc.o -static-libstdc++ -static-libgcc -lstdc++
g++ -o hello-g++ hello-gcc.o -static-libstdc++ -static-libgcc

ldd hello-{bazel,g++,gcc}
$ ./test.sh
.
INFO: Found 1 target...
Target //:hello up-to-date:
  bazel-bin/hello
INFO: Elapsed time: 4.187s, Critical Path: 0.02s
hello-bazel:
	linux-vdso.so.1 =>  (0x00007ffe0bfda000)
	libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f3fb5cb4000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f3fb59ab000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3fb55e0000)
	/lib64/ld-linux-x86-64.so.2 (0x00005652fdb8e000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f3fb53ca000)
hello-g++:
	linux-vdso.so.1 =>  (0x00007fff9dadc000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f480aea6000)
	/lib64/ld-linux-x86-64.so.2 (0x000055c2a4dcf000)
hello-gcc:
	linux-vdso.so.1 =>  (0x00007ffe4f8f1000)
	libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fe7ae568000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe7ae19e000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fe7ade94000)
	/lib64/ld-linux-x86-64.so.2 (0x0000559b6e494000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fe7adc7e000)

We can see that gcc -lstdc++ has different linker behavior than g++, and the presence of libstdc++.so.6 in the final ELF also drags in libm and libgcc_s via transitive dependencies.

Explicitly referencing libstdc++.a allows gcc to work as expected:

$ gcc -o hello-gcc-2 hello-gcc.o -static-libgcc -l:libstdc++.a
$ ldd hello-gcc-2
	linux-vdso.so.1 =>  (0x00007ffdc5fdf000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb4b0789000)
	/lib64/ld-linux-x86-64.so.2 (0x00005581b559b000)

jmillikin-stripe added a commit to jmillikin-stripe/bazel that referenced this issue Nov 6, 2017
This allows libstdc++ to be statically linked, which is normally only
possible when invoking GCC as `g++` with the `-static-libstdc++` flag.

Fixes bazelbuild#2840

See envoyproxy/envoy#415 for additional
background and context.
jmillikin-stripe added a commit to jmillikin-stripe/bazel that referenced this issue Nov 12, 2017
This allows libstdc++ to be statically linked, which is normally only
possible when invoking GCC as `g++` with the `-static-libstdc++` flag.

Fixes bazelbuild#2840

See envoyproxy/envoy#415 for additional
background and context.
jmillikin-stripe added a commit to jmillikin-stripe/bazel that referenced this issue Dec 4, 2017
This allows libstdc++ to be statically linked, which is normally only
possible when invoking GCC as `g++` with the `-static-libstdc++` flag.

Fixes bazelbuild#2840

See envoyproxy/envoy#415 for additional
background and context.
jmillikin-stripe added a commit to jmillikin-stripe/bazel that referenced this issue Dec 4, 2017
This allows libstdc++ to be statically linked, which is normally only
possible when invoking GCC as `g++` with the `-static-libstdc++` flag.

Fixes bazelbuild#2840

See envoyproxy/envoy#415 for additional
background and context.
bazel-io pushed a commit that referenced this issue Jan 19, 2018
*** Reason for rollback ***

Breaks C++ on gcc 4.8.4 (specifically, TensorFlow: #4474)

Fixes #4474

*** Original change description ***

When linking mostly-static Linux binaries, link libstdc++.a explicitly.

This allows libstdc++ to be statically linked, which is normally only
possible when invoking GCC as `g++` with the `-static-libstdc++` flag.

Fixes #2840

See envoyproxy/envoy#415 for additional
background and context.

cc @htuch (for Envoy) and @calpeyser @hlopko (who I talked to earlier about this)...

***

RELNOTES: None.
PiperOrigin-RevId: 182519445
iirina pushed a commit that referenced this issue Jan 19, 2018
*** Reason for rollback ***

Breaks C++ on gcc 4.8.4 (specifically, TensorFlow: #4474)

Fixes #4474

*** Original change description ***

When linking mostly-static Linux binaries, link libstdc++.a explicitly.

This allows libstdc++ to be statically linked, which is normally only
possible when invoking GCC as `g++` with the `-static-libstdc++` flag.

Fixes #2840

See envoyproxy/envoy#415 for additional
background and context.

cc @htuch (for Envoy) and @calpeyser @hlopko (who I talked to earlier about this)...

***

RELNOTES: None.
PiperOrigin-RevId: 182519445
iirina pushed a commit that referenced this issue Jan 23, 2018
*** Reason for rollback ***

Breaks C++ on gcc 4.8.4 (specifically, TensorFlow: #4474)

Fixes #4474

*** Original change description ***

When linking mostly-static Linux binaries, link libstdc++.a explicitly.

This allows libstdc++ to be statically linked, which is normally only
possible when invoking GCC as `g++` with the `-static-libstdc++` flag.

Fixes #2840

See envoyproxy/envoy#415 for additional
background and context.

cc @htuch (for Envoy) and @calpeyser @hlopko (who I talked to earlier about this)...

***

RELNOTES: None.
PiperOrigin-RevId: 182519445
iirina pushed a commit that referenced this issue Jan 24, 2018
*** Reason for rollback ***

Breaks C++ on gcc 4.8.4 (specifically, TensorFlow: #4474)

Fixes #4474

*** Original change description ***

When linking mostly-static Linux binaries, link libstdc++.a explicitly.

This allows libstdc++ to be statically linked, which is normally only
possible when invoking GCC as `g++` with the `-static-libstdc++` flag.

Fixes #2840

See envoyproxy/envoy#415 for additional
background and context.

cc @htuch (for Envoy) and @calpeyser @hlopko (who I talked to earlier about this)...

***

RELNOTES: None.
PiperOrigin-RevId: 182519445
iirina pushed a commit that referenced this issue Jan 26, 2018
*** Reason for rollback ***

Breaks C++ on gcc 4.8.4 (specifically, TensorFlow: #4474)

Fixes #4474

*** Original change description ***

When linking mostly-static Linux binaries, link libstdc++.a explicitly.

This allows libstdc++ to be statically linked, which is normally only
possible when invoking GCC as `g++` with the `-static-libstdc++` flag.

Fixes #2840

See envoyproxy/envoy#415 for additional
background and context.

cc @htuch (for Envoy) and @calpeyser @hlopko (who I talked to earlier about this)...

***

RELNOTES: None.
PiperOrigin-RevId: 182519445
iirina pushed a commit that referenced this issue Jan 26, 2018
*** Reason for rollback ***

Breaks C++ on gcc 4.8.4 (specifically, TensorFlow: #4474)

Fixes #4474

*** Original change description ***

When linking mostly-static Linux binaries, link libstdc++.a explicitly.

This allows libstdc++ to be statically linked, which is normally only
possible when invoking GCC as `g++` with the `-static-libstdc++` flag.

Fixes #2840

See envoyproxy/envoy#415 for additional
background and context.

cc @htuch (for Envoy) and @calpeyser @hlopko (who I talked to earlier about this)...

***

RELNOTES: None.
PiperOrigin-RevId: 182519445
iirina pushed a commit that referenced this issue Jan 30, 2018
*** Reason for rollback ***

Breaks C++ on gcc 4.8.4 (specifically, TensorFlow: #4474)

Fixes #4474

*** Original change description ***

When linking mostly-static Linux binaries, link libstdc++.a explicitly.

This allows libstdc++ to be statically linked, which is normally only
possible when invoking GCC as `g++` with the `-static-libstdc++` flag.

Fixes #2840

See envoyproxy/envoy#415 for additional
background and context.

cc @htuch (for Envoy) and @calpeyser @hlopko (who I talked to earlier about this)...

***

RELNOTES: None.
PiperOrigin-RevId: 182519445
iirina pushed a commit that referenced this issue Jan 30, 2018
*** Reason for rollback ***

Breaks C++ on gcc 4.8.4 (specifically, TensorFlow: #4474)

Fixes #4474

*** Original change description ***

When linking mostly-static Linux binaries, link libstdc++.a explicitly.

This allows libstdc++ to be statically linked, which is normally only
possible when invoking GCC as `g++` with the `-static-libstdc++` flag.

Fixes #2840

See envoyproxy/envoy#415 for additional
background and context.

cc @htuch (for Envoy) and @calpeyser @hlopko (who I talked to earlier about this)...

***

RELNOTES: None.
PiperOrigin-RevId: 182519445
iirina pushed a commit that referenced this issue Feb 12, 2018
*** Reason for rollback ***

Breaks C++ on gcc 4.8.4 (specifically, TensorFlow: #4474)

Fixes #4474

*** Original change description ***

When linking mostly-static Linux binaries, link libstdc++.a explicitly.

This allows libstdc++ to be statically linked, which is normally only
possible when invoking GCC as `g++` with the `-static-libstdc++` flag.

Fixes #2840

See envoyproxy/envoy#415 for additional
background and context.

cc @htuch (for Envoy) and @calpeyser @hlopko (who I talked to earlier about this)...

***

RELNOTES: None.
PiperOrigin-RevId: 182519445
@jmillikin-stripe
Copy link
Contributor

Can we re-open this, since the fix got rolled back?

@lberki lberki reopened this Feb 21, 2018
werkt pushed a commit to werkt/bazel that referenced this issue Mar 2, 2018
*** Reason for rollback ***

Breaks C++ on gcc 4.8.4 (specifically, TensorFlow: bazelbuild#4474)

Fixes bazelbuild#4474

*** Original change description ***

When linking mostly-static Linux binaries, link libstdc++.a explicitly.

This allows libstdc++ to be statically linked, which is normally only
possible when invoking GCC as `g++` with the `-static-libstdc++` flag.

Fixes bazelbuild#2840

See envoyproxy/envoy#415 for additional
background and context.

cc @htuch (for Envoy) and @calpeyser @hlopko (who I talked to earlier about this)...

***

RELNOTES: None.
PiperOrigin-RevId: 182519445
@kamalmarhubi
Copy link
Contributor

What was the reason for the rollback, and is it something we can resolve soon?

@hlopko
Copy link
Member

hlopko commented Apr 11, 2018

#4474 was the main culprit. I don't think I will have time in Q2 to fix this.

@mzeren-vmw
Copy link
Contributor

mzeren-vmw commented Oct 13, 2018

I opened PR #6360 with a fix. However, not surprisingly, it breaks several CI tests. If anyone has time to help triage / fix the failures that would be greatly appreciated.

@hlopko
Copy link
Member

hlopko commented Dec 14, 2018

The PR is merged, I'm closing this issue. Thank you Mark!

@hlopko hlopko closed this as completed Dec 14, 2018
bazel-io pushed a commit that referenced this issue Jun 19, 2019
Using this variable is will be possible to specify system libraries that
should be added after default linker flags, after libraries to link, and
after user link flags (i.e. after --linkopt and `linkopts` rule attribute).

Flag separator is `:`, similarly to `BAZEL_LINKOPTS`. Escaping is done by
`%`.

Default value is empty string.

With this it's possible to force Bazel to statically link `libstdc++` by
using:

```
BAZEL_LINKOPTS=-static-libstdc++ BAZEL_LINKLIBS=-l%:libstdc++.a bazel build //foo
```

Fixes #2840.
Relevant for #8652.

RELNOTES: Bazel's C++ autoconfiguration now understands `BAZEL_LINKLIBS` environment variable to specify system libraries that should be appended to the link command line.

Closes #8660.

PiperOrigin-RevId: 253946433
siberex pushed a commit to siberex/bazel that referenced this issue Jul 4, 2019
Using this variable is will be possible to specify system libraries that
should be added after default linker flags, after libraries to link, and
after user link flags (i.e. after --linkopt and `linkopts` rule attribute).

Flag separator is `:`, similarly to `BAZEL_LINKOPTS`. Escaping is done by
`%`.

Default value is empty string.

With this it's possible to force Bazel to statically link `libstdc++` by
using:

```
BAZEL_LINKOPTS=-static-libstdc++ BAZEL_LINKLIBS=-l%:libstdc++.a bazel build //foo
```

Fixes bazelbuild#2840.
Relevant for bazelbuild#8652.

RELNOTES: Bazel's C++ autoconfiguration now understands `BAZEL_LINKLIBS` environment variable to specify system libraries that should be appended to the link command line.

Closes bazelbuild#8660.

PiperOrigin-RevId: 253946433
irengrig pushed a commit to irengrig/bazel that referenced this issue Jul 15, 2019
Using this variable is will be possible to specify system libraries that
should be added after default linker flags, after libraries to link, and
after user link flags (i.e. after --linkopt and `linkopts` rule attribute).

Flag separator is `:`, similarly to `BAZEL_LINKOPTS`. Escaping is done by
`%`.

Default value is empty string.

With this it's possible to force Bazel to statically link `libstdc++` by
using:

```
BAZEL_LINKOPTS=-static-libstdc++ BAZEL_LINKLIBS=-l%:libstdc++.a bazel build //foo
```

Fixes bazelbuild#2840.
Relevant for bazelbuild#8652.

RELNOTES: Bazel's C++ autoconfiguration now understands `BAZEL_LINKLIBS` environment variable to specify system libraries that should be appended to the link command line.

Closes bazelbuild#8660.

PiperOrigin-RevId: 253946433
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants