How to access toolchain info in bazel aspect - bazel

I'm looking for a way to access toolchain information in an custom aspect. Ideally would be to access the cc_toolchain rule in the aspect, but somehow the aspects are not run for this kind of rule. Any ideas how to get information about the used toolchain? Include paths, compiler flags, etc. ?

Based on github.com/bazelbuild/intellij/blob/master/aspect/… attr_aspects should contain '_cc_toolchain'

Related

Bazel Clang cross platform

I'm trying to get bazel to use clang as the compiler on both Windows and Linux. (Debian 10 if that matters)
On Windows I managed to get it working by adding a windows-clang platform and registering the toolchain as described here.
Is there a similarly easy way to get switch to using clang on Linux?
I've dug around a but and as far as I can tell, you have two (or three options):
You can configure your won cc_toolchain. This may be arguably the "correct" solution.
You can try to tweak cc_configure() from #bazel_tools//tools/cpp:cc_configure.bzl and use it in your WORKSPACE. But that is both challenging and not necessarily pretty.
Neither of the two ways are likely to qualify as "easy". For that, the quickest would appear to be:
Automagic toolchain resolution considers environmental variable CC (only, not CXX) and if set its value is used for toolchain configuration. Hence, for instance this would do:
CC=/usr/bin/clang bazel build //:some_tgt
I hope I haven't missed anything, but I have not spotted a way to choose compiler through platforms (without having your own toolchain definition in place) as of today.

What is the difference between cc_toolchain_suite and register_toolchains?

In the context of C++ toolchain, I am trying to understand the difference of the concept between cc_toolchain_suite and register_toolchains, to me it seems they achieve the same purpose: select a toolchain based on command line parameters.
See https://docs.bazel.build/versions/master/toolchains.html for register_toolchains
See https://docs.bazel.build/versions/master/cc-toolchain-config-reference.html for cc_toolchain_suite
Can someone please help understand the subtlety behind these 2 concepts?
TL;DR The cc_toolchain_suite is part of the legacy toolchain configuration system. It still exists in Bazel because the migration to the new API is not complete. The register_toolchains is part of the newer, unified toolchain API. When possible use register_toolchains instead of cc_toolchain_suite/--*crosstool_top
Originally the concept of a 'toolchain' was not standardised in Bazel, so a Java toolchain would be implemented very differently than a cc toolchain.
Before the unified starlark toolchain API, cc toolchains were specified in proto-text formatted 'CROSSTOOL' files.
With the introduction of the platforms API and the unified toolchains API, the concepts in the CROSSTOOL files were converted almost 1:1 to the new unified platforms/toolchains starlark API. This was mostly to ensure that there was compatibility between the old/new API's.
One of the concepts in the older 'CROSSTOOL' configuration system was a 'toolchain suite', that allowed you to define a group of toolchains targeting different CPU's (This was before the platforms API was introduced).
As far as I understand the only reason that cc_toolchain_suite is still a part of Bazel's starlark API is that some of the apple/android toolchains have not yet been completely migrated across.
Here are a few examples of where I've opted to using the newer register_toolchains approach. Note that these toolchains do not use cc_toolchain_suite anymore.

Restricting a Bazel target to specific platforms

I have a target which can only be built for Linux (in this case, because it depends on syscalls only available on Linux and there is no desire to try and make this cross-platform). How can I express this in my BUILD files?
I can see from the Platforms documentation that there exists a Linux platform definition as #bazel_tools//platforms:linux, but it is not clear to me how to make use of this to restrict a target. Trying to specify this in compatible_with results in an error like this:
(13:27:09) ERROR: /foo/BUILD:4:1: in compatible_with attribute of go_library rule //foo:go_default_library: constraint_value rule '#bazel_tools//platforms:linux' is misplaced here (expected environment). Since this rule was created by the macro 'go_library_macro', the error might have been caused by the macro implementation in /foo/BUILD:4:1
So I have a few related questions:
The error seems to indicate I've supplied the wrong type of rule to compatible_with. What is an environment and how do I provide one? (I've struggled to find documentation on this)
I gather that the migration to Platforms might not yet be complete and rules_go might not have been updated. If it's not possible with Platforms, is there an "old way" to do this instead?
Ideally, I would like this not to result in build errors when running commands like bazel test //:all on a different (non-Linux) platform – ie. I'd prefer it just exclude these, or something. Is this possible?
Thanks for your help 😊
Turns out that this is an open issue. Once this is fixed, I think it should be possible: https://github.com/bazelbuild/bazel/issues/3780

How to combine bazel aspects and cc_library

I want to build a rule that is very similar to cc_proto_library. The key features are that it would apply an aspect to all the transitive proto_library dependencies and generate .cc and .h files for all of the dependencies. In addition it would generate actions that would compile these into object files.
While I understand how I can do the file generation, I don't see how to easily do the object generation. The native module is not available for rule (or aspect) implementations, and I cannot use a macro on top of the aspect as I need the object files to be generated in the same package as the proto_library so that it is generated only once.
cc_proto_library can do this I believe because it is not written in Skylark and thus has access to more primitives. Is there anyway to do this with just Skylark?
This is unfortunately currently not possible. There is no Skylark API to the C++ rules/actions (what we call C++ sandwich). We have plans to implement this in Q1 2018. There are many tracking issues, this one looks the most relevant: https://github.com/bazelbuild/bazel/issues/2163.

Can Bazel aspects access the current target's java_common.provider

As part of our efforts to create a bazel-maven transition interop tool (that creates maven sized jars from more granular sized bazel jars),
we want the aspect that runs on bazel build to access the target's java_common.provider in order to fetch the jars and ijars from it.
Is that possible?
The short answer is yes, that's possible.
You can use the java_common module in an aspect implementation the same way you would use it in a rule implementation.
From the documentation on java_common.provider:
java_common.provider.compile_jars and java_common.provider.transitive_compile_time_jars refer to the ijars used at compilation time
java_common.provider.transitive_runtime_jars refer to the full jars used at runtime.
The full jars at compilation time are not yet available, but someone is working on exposing this feature. (Issue #3528 on GitHub.)
Make sure you also read the blog post on this topic: https://blog.bazel.build/2017/03/07/java-sandwich.html

Resources