Can I instruct bazel to emit a ".elf" suffix to executables? - bazel

cc_binary (on osx / linux) creates executables with no suffix. This makes sense, since the standard on those platforms is to not use extensions.
When using Bazel as a cross-compiler through a custom CROSSTOOL, though, I'd like Bazel to emit an elf file with an explicit .elf suffix.
Is this possible, either through CROSSTOOL or a custom "rename" rule?

You can name your cc_binary 'foo.elf' and bazel will just build it. Or you can use genrule to do the renaming afterwards.
Now if you need to build the same cc_binary with multiple toolchains, each time producing a different extension, that's a little bit more tricky. But genrule will work there too.

Related

Should I use a dedicated bazel BUILD file for tests?

Is there any bazel convention for defining all of a project's test targets in some subfolder tests with its own BUILD file. Is that layout preferred to one main BUILD file that combines everything in one place: bins, libs, and tests?
An all in one build file could get lengthy, but it has the benefit of using in-package sibling target references, ie the ":siblingTarget" references.
Short answer: Yes.
Why would you like to couple your test with the implementation? You should always try to reduce dependencies between different parts of your code. That makes it easier to understand. See also here.
Imaging you find some BUILD file that contains implementation and test rules (e.g. cc_library, cc_binary, cc_test). Imagine some developer needed for some test some library - and only for testing proposes (e. g. cc_library(name="some_lib"). How would you know if this library is only needed for testing? If it is in a BUILD file contained in test folder then it would be clear from the folder structure that there is a high probability that this lib is only needed for testing proposes.

Can BUILD files have arbitrary file extensions?

I am aware that bazel accepts both BUILD and BUILD.bazel as valid filenames.
The android tools seem to also have a BUILD.tools file.
In general, does bazel have any restrictions for a BUILD file's extension? For example, could i have BUILD.generated to delineate generate BUILD files from non-generated BUILD files?
The .tools extension is part of building Bazel itself. From the perspective of Bazel, it's just any ordinary file. It gets picked up here: https://github.com/bazelbuild/bazel/blob/bbc8ed16aee07c3ba9321d58aa4c0ffc55fa2ba9/tools/android/BUILD#L197
then eventually gets processed here: https://github.com/bazelbuild/bazel/blob/c816b89a2224c3c318f1228755ef41c53975f45c/src/create_embedded_tools.py#L74
For the use case you mention, one way to go about it is to generate a .bzl file with a meaningful name that contains a macro that you can call from a BUILD or BUILD.bazel file. That way you can separate the generated rules from manually maintained rules. This is similar to how generate_workspace works: https://docs.bazel.build/versions/master/generate-workspace.html

During 'bazel build', when is `target.runfiles` directory properly set up?

For a cc_binary (or py_binary, sh_binary), when does bazel create its runfiles directory and have all symlinks correctly set up?
Is it created right after the cc_binary is built, and before any rule that takes this cc_binary as input, OR
Is it created after the whole build process of all targets is finished?
I'm trying to write a custom rule to pack the contents in the runfiles directory of a cc_binary into a tarball. This custom rule takes the cc_binary and all targets in its runfiles as input. If the runfiles directory is properly set up right after the cc_binary is built, then I just need to directly pack this directory. If not, I probably need to set up a tmp runfiles directory by myself in my custom rule.
Also, is this behavior guaranteed to keep in the future releases?
Thanks a lot!
Bazel does not guarantee any ordering; all it guarantees is that by the end of the build, both the binary and the runfiles tree should be there.
If you want an action to be executed after both of these have been built, you need to depend on both the binary and its runfiles manifest. This doesn't guarantee, though, that the runfiles tree will be in the sandbox the packing action rules on.
I think it's possibly to craft something from ctx.actions.run(input_manifests=) and ctx.resolve_command that does that, although it's very arcane at the moment.

Recommended strategy to accumulate data in bazel aspects output files

I'm writing a post-build tool that needs the location of a list of target's jar files.
For these locations I have an aspect that runs on a list of targets (separately for each target using --aspects) and fetch the jar file path for each of them.
I've managed to get each jar file path in a custom output file (e.g. jar.txt) in each target's output folder.
But this will mean I would need to go over each jar.txt file separately to get the location.
Is there a way to accumulate the jar files paths in a single file?
Something like:
Try and write to the same output folder with append command in the aspect. I'm not sure if a shared output folder is possible.
Create a synthetic target which depends on all the relevant targets, then run an aspect on this target and accumulate the jars and only write them at the root after the recursion is back.
Are 1. or 2. valid options?
What is the recommended strategy to accumulate data in bazel aspects output files?
Bazel doesn't provide facitlities in Skylark for accumulating information between targets that are not related to each other in the target graph (e.g. ones that are mentioned on the command line next to each other).
One possibility would be to write a Skylark rule that depends on all the targets you usually mention on the command line and built that one; that rule will be able to collate the classpaths from each Java target to a single file.
Another possibility is to tell Bazel to write build events (that includes all the outputs of all targets the specified build pattern expands to) to a file using the --experimental_build_event_{json,text,binary}_file. (The "experimental" will be removed soon.). The files contain instances of this message:
https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto
Natan,
If I understand correctly, you want to transitively propagate the information from each aspect node out into a single result. To do this, build the transitive set in your aspect rule implementation and pass it via the "provider" mechanism [^1]. I wrote up some examples on bazel aspects, perhaps you'll find it useful[^2].
https://github.com/pcj/bazel_aspects/blob/master/aspects.bzl#L94-L104
https://github.com/pcj/bazel_aspects

Prefix Static Library iOS

I'm building an iOS static library (as per https://github.com/jverkoey/iOS-Framework). I depend on SBJson and AFNetworking. I would like to include these libraries to avoid version issues and for installation simplicity; to do so, I need to prefix these libraries to avoid naming conflicts.
How can I prefix other static libraries in a simple way?
Ideally, it would be part of my build process. Less ideally, but acceptable, are tips on how to refactor and rename in a sane manner.
The only safe solution (other than not doing this at all) is to build any dependencies with a prefix on all symbols.
The easiest method of prefixing is the classic "find-and-replace". This is error-prone, so it's a good idea to hit the .a with nm -a and scour the results for any non-prefixed symbols.
A second, much safer method is to use a two-pass compilation process.
The first pass builds the dependent project and runs nm to dump all symbols into a header file.
The second pass builds the dependent project again, but this time with the generated prefix header file imported in the precompiled header. This prefix header must be used anywhere you reference symbols from the dependency in your framework in order to properly refer to the renamed symbols.
For reference, we use this with Nimbus to generate the Nimbus prefix headers:
https://github.com/jverkoey/nimbus/blob/master/scripts/generate_namespace_header
This allows you to distribute a .framework with a prefixed version of Nimbus embedded.
You can now link the resulting .a into your framework and safely avoid any linker conflicts when a third party developer inevitably links their own version of the dependency into their project.

Resources