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_link_cpp_runtimes doesn't link the libstdc++ statically #14342

Open
tomgr opened this issue Nov 29, 2021 · 9 comments
Open

static_link_cpp_runtimes doesn't link the libstdc++ statically #14342

tomgr opened this issue Nov 29, 2021 · 9 comments
Labels
P3 We're not considering working on this, but happy to review a PR. (No assignee) team-Rules-CPP Issues for C++ rules type: bug

Comments

@tomgr
Copy link

tomgr commented Nov 29, 2021

Description of the problem / feature request:

The static_link_cpp_runtimes feature doesn't link libstdc++ statically despite appearing to be intended to as per https://docs.bazel.build/versions/main/cc-toolchain-config-reference.html#well-known-features.

Bugs: what's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

Create the following files:

BUILD:

cc_binary(
  name = "test",
  srcs = ["main.cc"],
  features = ["static_link_cpp_runtimes"],
)

main.cc:

#include <iostream>

int main(int argc, char** argv) { 
  std::cout << "Hello" << std::endl;
}

WORKSPACE:

Running bazel build //:test && ldd bazel-bin/test gives:

        linux-vdso.so.1 (0x00007fffccffa000)
        libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f3b2a2c9000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f3b2a1e5000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3b29fbd000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f3b2a4ea000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f3b29fa3000)

What operating system are you running Bazel on?

Ubuntu 22.04, but observed on several other Linuxes

What's the output of bazel info release?

release 6.0.0-pre.20211110.1. Using last_green with bazelisk also shows the same error (when I ran this last_green was cd4bc7c).

Have you found anything relevant by searching the web?

#8672 has a similar problem with fully_static_link, but this also statically links glibc, which we don't want. The solution there also depends on setting BAZEL_LINKLIBS but we'd like to be able to control which targets link libstdc++ statically individually. static_link_cpp_runtimes is also compiler-independent (if supported by the toolchain), unlike BAZEL_LINKLIBS.

@keith
Copy link
Member

keith commented Nov 29, 2021

I just looked briefly but it looks to me like this just isn't supported in bazel, maybe it is in blaze

/* supportsEmbeddedRuntimes= */ false,

@tomgr
Copy link
Author

tomgr commented Dec 1, 2021

Thanks. I think it's only the auto-configuration that's not enabled as it seems you can define the static_link_cpp_runtimes feature yourself. If I copy the auto-generated local_config_cc and patch cc_toolchain_config.bzl to add:

    static_link_cpp_runtimes_feature = feature(
        name = "static_link_cpp_runtimes",
        enabled = False,
        flag_sets = [
            flag_set(
                actions = [
                    ACTION_NAMES.cpp_link_executable,
                    ACTION_NAMES.cpp_link_dynamic_library,
                    ACTION_NAMES.lto_index_for_executable,
                    ACTION_NAMES.lto_index_for_dynamic_library,
                ],
                flag_groups = [flag_group(flags = ["-static-libstdc++"])],
            ),
        ],
    )

(and also add this to the list of features that are exported), then I can get static linking to work by setting features = ["static_link_cpp_runtimes"]. To ensure that normal cc_binary targets remain dynamically linked I also had to modify the user_link_flags feature to add another flag set:

            flag_set(
                actions = all_link_actions + lto_index_actions,
                flag_groups = [flag_group(flags = ["-lstdc++"])],
                with_features = [
                    with_feature_set(
                        not_features = ["static_link_cpp_runtimes"],
                    ),
                ],
            ),

and then I modified the default value of BAZEL_LINKLIBS to remove "-lstdc++".

I wonder if it's worth patching bazel's unix_cc_configure.bzl to:

  • Accept a user-definable list of flags that would be used to dynamically link the C++ runtime (maybe BAZEL_CXXSTDLIB_DYNAMIC). This would default to -lstdc++ and -lstdc++ would be removed from BAZEL_LINKLIBS.
  • Accept a user-definable list of flags that would be used to statically link the C++ runtime (maybe BAZEL_CXXSTDLIB_STATIC). This would default to -static-libstdc++.

This would make it much easier to statically or dynamically link the c++ standard library than it is now, and would enable users to enable it either per binary, or globally. I'd be happy to work on a patch if this sounds like a useful direction.

@fmeum
Copy link
Collaborator

fmeum commented Dec 1, 2021

I would find this very useful. Making the auto-configured toolchains work well with all advertised Bazel features is also especially helpful for those new to Bazel.

@sventiffe sventiffe added team-Rules-CPP Issues for C++ rules untriaged labels Dec 8, 2021
@oquenchil oquenchil added P3 We're not considering working on this, but happy to review a PR. (No assignee) type: bug and removed untriaged labels Feb 14, 2022
@github-actions
Copy link

Thank you for contributing to the Bazel repository! This issue has been marked as stale since it has not had any activity in the last 1+ years. It will be closed in the next 14 days unless any other activity occurs or one of the following labels is added: "not stale", "awaiting-bazeler". Please reach out to the triage team (@bazelbuild/triage) if you think this issue is still relevant or you are interested in getting the issue resolved.

@github-actions github-actions bot added the stale Issues or PRs that are stale (no activity for 30 days) label Jun 13, 2023
@fhanau
Copy link

fhanau commented Jun 22, 2023

This is an ongoing issue and should not be marked as stale.

The workaround of setting BAZEL_LINKLIBS works for me on Linux (e.g. BAZEL_LINKLIBS='-l%:libc++.a -lm -static-libgcc' when using libc++) and by using --action_env it can also be used through the command line or bazelrc. Still, it would be much nicer to have the feature flag supported so this can be set on the target level.

@github-actions github-actions bot removed the stale Issues or PRs that are stale (no activity for 30 days) label Jun 22, 2023
CheckmkCI pushed a commit to Checkmk/checkmk that referenced this issue Jul 19, 2024
See https://bazel.build/docs/cc-toolchain-config-reference#wellknown-features
for a description of the feature.

See bazelbuild/bazel#14342 (comment) for
the patch.

We prefer patching to forking to benefit from upstream improvements to
the toolchain config.

CMK-18270

Change-Id: I199b4b22ed9c5aa32f6065400044dc57ad5fabcb
@Synss
Copy link

Synss commented Aug 1, 2024

I've added the feature to unix_cc_toolchain_config.bzl based on @tomgr's comment. Maybe that's useful to others as well.

That's basically all there is to it.

Change is Checkmk/checkmk@3ee513a

@fmeum
Copy link
Collaborator

fmeum commented Aug 1, 2024

@Synss Would you be willing to send a PR to Bazel with this change? It looks good to me and I can also help find a reviewer.

@Synss
Copy link

Synss commented Aug 1, 2024

Of course! I’ll be happy if the patch gets upstreamed and I don’t have to maintain it! 😉 I’ll look into sending a PR tomorrow.

Synss added a commit to Synss/bazel that referenced this issue Aug 3, 2024
This patch adds the `static_link_cpp_runtimes` feature to
`unix_cc_toolchain_config`.  The feature is documented as
a well-known feature[1] but not implemented.

The patch implements the solution proposed on GitHub.[2]

For the feature to work as expected, users have to remove
the linker flag `"-lstdc++"` from `link_libs` (or `link_flags`)
from the call to `unix_cc_toolchain_config`.

[1] https://bazel.build/docs/cc-toolchain-config-reference#wellknown-features
[2] bazelbuild#14342
Synss added a commit to Synss/bazel that referenced this issue Aug 3, 2024
This patch implements the `static_link_cpp_runtimes` feature
in `unix_cc_toolchain_config`.  The feature is documented as
a well-known feature[1] and was added to the toolchain[2] but
not implemented.

The patch follows the solution proposed on GitHub.[3]

For the feature to work as expected, users have to remove
the linker flag `"-lstdc++"` from `link_libs` (or `link_flags`)
from the call to `unix_cc_toolchain_config`.

[1] https://bazel.build/docs/cc-toolchain-config-reference#wellknown-features
[2] bazelbuild#17391
[3] bazelbuild#14342
Synss added a commit to Synss/bazel that referenced this issue Aug 3, 2024
This patch implements the `static_link_cpp_runtimes` feature
in `unix_cc_toolchain_config`.  The feature is documented as
a well-known feature[1] and was added to the toolchain[2] but
not implemented.

The patch adapts a solution proposed on GitHub.[3]

[1] https://bazel.build/docs/cc-toolchain-config-reference#wellknown-features
[2] bazelbuild#17391
[3] bazelbuild#14342
@apivovarov
Copy link

Related Discussion:

How to build cpp executable with static libsdtc++.a? -lstdc++ is hardcoded in bazel!!!
#23324

Solution:

export BAZEL_LINKLIBS="-l%:libstdc++.a:-lm"

After that all executables generated by bazel build will have libstdc++ linked statically.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P3 We're not considering working on this, but happy to review a PR. (No assignee) team-Rules-CPP Issues for C++ rules type: bug
Projects
None yet
Development

No branches or pull requests

8 participants