-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
incompatible_remove_legacy_whole_archive: Remove --legacy_whole_archive while setting default to false #7362
Comments
CC @trybka |
This flag disables legacy whole archive behavior, as well as makes the --legacy_whole_archive option a noop. See details in #7362. It also introduces a possibility to enable legacy behavior per target by `--features=legacy_whole_archive` option, or `features = [ "legacy_whole_archive" ]` attribute. RELNOTES: None. PiperOrigin-RevId: 233691404
*** Reason for rollback *** Breaks a target in the canary's nightly, thus preventing us from releasing tomorrow: [] b/124656723 *** Original change description *** Introduce --incompatible_remove_legacy_whole_archive This flag disables legacy whole archive behavior, as well as makes the --legacy_whole_archive option a noop. See details in #7362. It also introduces a possibility to enable legacy behavior per target by `--features=legacy_whole_archive` option, or `features = [ "legacy_whole_archive" ]` attribute. RELNOTES: None. PiperOrigin-RevId: 234481950
@hlopko I added the breaking-change-0.26 label since no one seems to have spoken up about increasing the window. TBH, I'm not sure what the significance of the label is if you don't actually flip the flag, but letting you know jic :) |
@dkelmer Thank you! Because the flag is only available in 0.25, people actually didn't have a chance to try it out yet. I'm not in hurry to flip this flag, so I added migration-0.26 and breaking-change-0.27. |
Sounds good :) |
I think this breaks Android. On Android, to build an Example commands I'm seeing:
Adding |
Did you try adding |
Adding |
This flag was not flipped in 0.27, targeting 1.0? |
Yes, this didn't make it into 0.27, we're postponing the flip until 1.0. Could you create the labels so I can update our flags? |
I know I'm very late to the game here, but what's the suggested mitigation? I had been using |
Hey @johnmarkwayve, What you could do is to introduce a cc_library wrapper that you use throughout your project. In the wrapper you'll set alwayslink attribute to a select (https://docs.bazel.build/versions/master/configurable-attributes.html). The default condition will be 0, the condition with a build_setting or --define will be 1. Whenever you'll be building the .so for distribution, you will pass that build_setting or --define. This will roughly emulate the behavior of |
Oh I was just told that alwayslink attribute is not selectable. That complicates things. then your cc_library wrapper will have to create 2 cc_libraries, one with alwayslink set, one with it unset, and an alias rule with the select in its 'actual' attribute. Select will choose one of cc_libraries. |
@hlopko thanks for the advice. It's a lot uglier than I'd like but it should work. I realise my use case isn't super common, but it doesn't seem unreasonable either ("this |
@johnmarkwayve yeah, this is actually just a deficiency of how
However In actuality, One could imagine having an In lieu of such a thing, The alternatives are less palatable (IMO), but: |
I have the exact problem as @johnmarkwayve. I have hundreds of small targets Because the It seems like at minimum an attribute like the cc_library(
name = "all.a",
alwayslink = True,
alwayslink_deps = [":small1", ":small2", ":small3"],
) ... at which point I could convert The work-around of using a macro to declare two For now my workaround is to implement a But in general I'd like if cc_library and/or cc_binary had the capability to deliver shared objects out of the box, instead of having to roll my own starlark for it. |
…ge: bazelbuild/bazel#7362 Imported from GitHub PR tensorflow#32040 Update tensorflow for upcoming incompatible change: bazelbuild/bazel#7362 This PR updates `cc_library`s to use `alwayslink=1` when needed. Currently, library archives and library object groups are wrapped in `--whole_archive`, `--no_whole_archive`, thus the whole library is always linked. This will change with Bazel 1.0, and libraries that export otherwise unused symbols must be tagged as `alwayslink=1`. Copybara import of the project: - 001117f Add alwayslink = 1 to cc_libraries to ensure that their s... by scentini <[email protected]> - 846b892 Fix a typo by scentini <[email protected]> - ceb6ae5 Merge 846b892 into 3c2be... by scentini <[email protected]> PiperOrigin-RevId: 267108524 (cherry picked from commit c3619ce)
bazelbuild/bazel#7362 Barring last minute regressions, this is the last commit of this type. This PR updates `cc_library`s to use `alwayslink=1` when needed. Currently, library archives and library object groups are wrapped in `--whole_archive`, `--no_whole_archive`, thus the whole library is always linked. This changes with Bazel 1.0, and libraries that export otherwise unused symbols must be tagged as `alwayslink=1`. PiperOrigin-RevId: 277303614 Change-Id: I5b2aefbb9d402bfd1c21f4d2ad95592ba3a392d5 (cherry picked from commit 9760bc2)
bazelbuild/bazel#7362 This PR updates `cc_library`s to use `alwayslink=1` when needed. Currently, library archives and library object groups are wrapped in `--whole_archive`, `--no_whole_archive`, thus the whole library is always linked. This changes with Bazel 1.0, and libraries that export otherwise unused symbols must be tagged as `alwayslink=1`. This PR fixes tensorflow#32835 (once again, as it was fixed by tensorflow#33415 but the codebase regressed in the meantime.) It also fixes most of the TF tests. PiperOrigin-RevId: 276772147 Change-Id: I05db02e84200a484df52f4f02b601dc486636912 (cherry picked from commit 52167ad)
To add a question for discussion: What exactly is "
I would argue that having I agree with the original point of this issue, that |
One random idea that I didn't pursue is that maybe we can produce a linker script (version script) that will export all symbols present? I haven't written a linker script but it sounds like it might be possible? Passing the linker script to the cc_binary producing shared library is simple. |
…default of --incompatible_remove_legacy_whole_archive in cl/277339372 This should fix the latest issue reported in #33415. Also fixes an internally reported missing symbol. Related to bazelbuild/bazel#7362 PiperOrigin-RevId: 279792794 Change-Id: I6f5d26ee37b9c886662df5e2daf9273c15cae865
…rty/protobuf:protobuf to include alwayslink = 1. This is needed because tensorflow_framework.so currently defines the symbols provided by //third_party/protobuf:protobuf. Incompatible change bazelbuild/bazel#7362 is going to be flipped in Bazel 1.0. and is going to disable --legacy_whole_archive that was enabled by default and that caused every transitive cc_library linked into a transitive shared library to be linked in a whole-archive block. Putting alwayslink = 1 recreates the behavior from before the flag flip. The principled solution is to talk to the protobuf team and ask them to maintain a cc_library with alwayslink = 1 target that projects such as TF can depend on. This PR is a fast-fix for Bazel 1.0. And maybe we'll discover that those symbols shouldn't be defined by the protobuf_tensorflow.so at all and instead //third_party/protobuf:protobuf should be a dependency of executables using those symbols. PiperOrigin-RevId: 266779761 (cherry picked from commit 2d2d6cf)
…-incompatible_remove_legacy_whole_archive (bazelbuild/bazel#7362) is flipped Currently, library archives and library object groups are wrapped in `--whole_archive`, `--no_whole_archive`, thus the whole library is always linked. This will change with Bazel 1.0, and libraries that export otherwise unused symbols must be tagged as `alwayslink=1`. PiperOrigin-RevId: 267115768 (cherry picked from commit afb7639)
…ymbols Imported from GitHub PR #34044 This should fix tensorflow/addons#663, caused by changing logic in Bazel on which symbols we export (see bazelbuild/bazel#7362). Copybara import of the project: PiperOrigin-RevId: 280275294 Change-Id: I1a21010f47367f66ab33ba51aefe5226f8191b30
…default of --incompatible_remove_legacy_whole_archive in cl/277339372 This should fix the latest issue reported in tensorflow#33415. Also fixes an internally reported missing symbol. Related to bazelbuild/bazel#7362 PiperOrigin-RevId: 279792794 Change-Id: I6f5d26ee37b9c886662df5e2daf9273c15cae865
Update: in RobotLocomotion/drake#12262, I've written a |
…for TensorFlow. Context: swiftlang/swift#28438 (comment) Related Bazel change: bazelbuild/bazel#7362 (`--incompatible_remove_legacy_whole_archive`) Previously, libraries were wrapped in `--whole_archive` and `--no_whole_archive` so that entire libraries were linked. With Bazel 1.0, libraries that export unused symbols must be explicitly tagged with `alwayslink = 1`. PiperOrigin-RevId: 282157053 Change-Id: Ica85797aeeb99e15402cdd06e61bbbf58011f141
When upgrading to the latest bazel, I kept seeing errors like this: File "/dev/shm/bazel-sandbox.62240ff599163761312fdbd652f7452abc23edc253dee6214f406f29dde5568b/linux-sandbox/2481/execroot/org_frc971/bazel-out/host/bin/y2019/control_loops/python/intake.runfiles/slycot_repo/slycot/_wrapper.py", line 1, in <module> from slycot._fortranwrapper import * ImportError: dynamic module does not define init function (init_fortranwrapper) And sure enough: $ objdump -TC bazel-bin/external/slycot_repo/slycot/_fortranwrapper.so bazel-bin/external/slycot_repo/slycot/_fortranwrapper.so: file format elf64-x86-64 DYNAMIC SYMBOL TABLE: 0000000000000000 w D *UND* 0000000000000000 __gmon_start__ 0000000000000000 w DF *UND* 0000000000000000 GLIBC_2.2.5 __cxa_finalize 0000000000000000 w D *UND* 0000000000000000 _ITM_deregisterTMCloneTable 0000000000000000 w D *UND* 0000000000000000 _ITM_registerTMCloneTable 0000000000002009 g D .fini_array 0000000000000000 Base _end 0000000000002008 g D .fini_array 0000000000000000 Base _edata 0000000000002008 g D .fini_array 0000000000000000 Base __bss_start With version 1.0, bazel changed the default linker flags. See bazelbuild/bazel#7362 for some more information. This patch forces the symbols defined in the `cc_library` to make it into the .so file. Change-Id: Id71f57001ae84ee37d5951eb54261c0774320ff4
Fixes #7362 RELNOTES: --incompatible_remove_legacy_whole_archive has been flipped. See bazelbuild/bazel#7362 for more information PiperOrigin-RevId: 267126102
*** Reason for rollback *** Breaks a target in the canary's nightly, thus preventing us from releasing tomorrow: [] b/124656723 *** Original change description *** Introduce --incompatible_remove_legacy_whole_archive This flag disables legacy whole archive behavior, as well as makes the --legacy_whole_archive option a noop. See details in bazelbuild/bazel#7362. It also introduces a possibility to enable legacy behavior per target by `--features=legacy_whole_archive` option, or `features = [ "legacy_whole_archive" ]` attribute. RELNOTES: None. PiperOrigin-RevId: 234481950
This flag disables legacy whole archive behavior, as well as makes the --legacy_whole_archive option a noop. See details in bazelbuild/bazel#7362. It also introduces a possibility to enable legacy behavior per target by `--features=legacy_whole_archive` option, or `features = [ "legacy_whole_archive" ]` attribute. RELNOTES: None. PiperOrigin-RevId: 233691404
Flag:
--incompatible_remove_legacy_whole_archive
Available since: 0.25
Will be flipped: 0.26, unless we hear from Bazel users it's not enough. Bazel 1.0 is the latest flipping possibility, but we will gladly postpone the flip until then, if Bazel users need more time. Please speak up.
Motivation
The docs of this flag say:
What this means is that all library archives (and library object groups, as defined by --start-lib/--end-lib) are added to the link command wrapped in -whole-archive, -no-whole-archive, which instructs the linker to always include the entire library. Even with dead code elimination, this can be pernicious if the library defines some global initializer, as that will cause all of the code dependencies of those initializers to be kept.
History
--(legacy_)whole-archive
was introduced on 2004-04-19, with the commit description saying:Problem
"Legacy" whole-archive behavior is a poor default, but it is difficult to change.
--[no]legacy_whole_archive
is a whole build option. It is impossible to "tag" individual shared, statically linked, dynamic libraries which can be built without "whole-archive" semantics.Care must be taken to flip the default--libraries which export symbols must be tagged as
alwayslink=1
unless some other mechanism exists in the dylib to preserve the symbols which are being exported.It is a difficult thing to test: unexported symbols are only noticed at runtime, which means that 100% test coverage would have to exist for a depot-wide mass cleanup.
Migration
--legacy_whole_archive
will be superseded by--incompatible_remove_legacy_whole_archive
.--incompatible_remove_legacy_whole_archive
, when true, removes both the old flag, and the behavior enabled by features (explained below).Bazel now has a mechanism to configure individual
cc_binary
targets which can be built without--legacy_whole_archive
. This mechanism still honors the--incompatible_remove_legacy_whole_archive
. This mechanism is based on feature named "legacy_whole_archive". When added to thefeatures
attribute ofcc_binary
, Bazel will keep the legacy whole archive behavior, but only for thecc_binary
, not for the whole build.This is the migration plan we will follow at Google:
features = "-legacy_whole_archive"
(note, minus here) to targets that are safe to build without the legacy behavior.features = [ "-legacy_whole_archive" ]
.legacy_whole_archive
from global .bazelrc.-legacy_whole_archive
features from targets.The text was updated successfully, but these errors were encountered: