I know that in general when linker runs in C++, the order of linked arguments in the command matters (as mentioned here).
In what order does Bazel link files? Does it just go top to bottom of the build file and is there a way to customize it?
I know that in general when linker runs in C++, the order of linked arguments in the command matters (as mentioned here).
In what order does Bazel link files? Does it just go top to bottom of the build file and is there a way to customize it?
Bazel uses 'topological' ordering for linking. From the docs;
"topological" (formerly "link"): A topological ordering from the root down to the leaves. There is no left-to-right guarantee.
The leaves in this scenario are all your library dependencies as represented as a tree. The linking order is not related to the order the targets are listed in the BUILD file.
You can confirm this by inspecting the source code. The docstring from the source code gives a better explanation than the depset docs.
* <p>LINK_ORDER: a variation of left-to-right preorder that enforces topological sorting. In
* Starlark it is called "topological"; its older deprecated name is "link".
*
* <p>For example, for the nested set {A, C, {B, D}}, the iteration order is "A C B D"
* (parent-first).
*
* <p>This type of set would typically be used for artifacts where elements of nested sets go after
* the direct members of a set, for example when providing a list of libraries to the C++ compiler.
*
* <p>The custom ordering has the property that elements of nested sets always come before elements
* of descendant nested sets. Left-to-right order is preserved if possible, both for items and for
* references to nested sets.
*
* <p>The left-to-right pre-order-like ordering is implemented by running a right-to-left postorder
* traversal and then reversing the result.
There is a way to customise it. Though it is not trivial and involves writing your own starlark plugin.
For example if you where to modify the my_c_archive.bzl example adding a different ordering parameter to each call to the depset constructor you could in theory change the order of linking. e.g. this
libraries = depset(direct = [
cc_common.create_library_to_link(
actions = ctx.actions,
feature_configuration = feature_configuration,
cc_toolchain = cc_toolchain,
static_library = output_file,
),
]),
Would become this;
libraries = depset(direct = [
cc_common.create_library_to_link(
actions = ctx.actions,
feature_configuration = feature_configuration,
cc_toolchain = cc_toolchain,
static_library = output_file,
),
],
# NEW
order = "preorder"
),