You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This change adds two main features:
1. You can configure compile commands for certain targets or groups of
targets to go into separate files
For embedded systems development in particular, `clangd` doesn't work
well with `compile_commands.json` generated for multiple targets. For
example, if you have a build target that runs on your host machine in
one configuration and another that runs on device in another
configuration, `compile_commands.json` will contain multiple conflicting
compile commands for the same source files. `clangd` will just use the
first one it finds, which may not be the one you want to use for code
intelligence. It's convenient to have separate compile commands files
for each target, and switch the file `clangd` uses depending on how you
want to navigate your code.
By providing the `target_collections` argument, you can associate
targets with named collections. Separate compile commands files will be
generated for each of the specified collections, and will be placed in
subdirectories with the specified names. This is most useful when you
associate multiple targets with a collection, for example, to configure
code intelligence to use the compile commands for all of the targets
that build for one architecture or device.
This means that you can now specify a target more than once, generating
compile commands for builds of the same target but with different flags
(e.g. `--platform`). Before, you implicitly could only specify each
target once since the targets were dict keys.
2. You can specify a different output path
If you are generating multiple compile commands files, its preferable
not to output them into the workspace root. So you can specify a
separate output path, relative to the workspace root.
This patch doesn't change any existing behavior; if you don't add either
of the new arguments to your invocation of `refresh_compile_commands`,
everything will work exactly as it did before.
Copy file name to clipboardexpand all lines: refresh_compile_commands.bzl
+136-11
Original file line number
Diff line number
Diff line change
@@ -36,6 +36,30 @@ refresh_compile_commands(
36
36
# ^ excluding headers will speed up compile_commands.json generation *considerably* because we won't need to preprocess your code to figure out which headers you use.
37
37
# However, if you use clangd and are looking for speed, we strongly recommend you follow the instructions below instead, since clangd is going to regularly infer the wrong commands for headers and give you lots of annoyingly unnecessary red squigglies.
38
38
39
+
# Need to create separate files for specific targets? Give those targets a name and their compile commands file will be written into a subdirectory with that name.
40
+
# target_groups = {
41
+
# "host": "//:host_build",
42
+
# "target": "//:target_build",
43
+
# }
44
+
45
+
# You can define target groups, sort of like "meta-targets" that contain combination of compile commands from the specified targets.
46
+
# This is useful for multi-architecture projects, where you might be building the same files in multiple different ways depending on what architecture or device the code will run on.
47
+
# It only makes sense to get code intelligence for a consistent build, so you can produce consistent compile commands with target groups.
48
+
# Targets only need to be specified in either `targets` or `target_groups`; there's no need to add them to both.
# Need to write compile commands to some directory other than the workspace root? Provide a path relative to the workspace root. This is useful if you use target groups.
61
+
# out_dir = ".compile_commands"
62
+
39
63
# Need things to run faster? [Either for compile_commands.json generation or clangd indexing.]
40
64
# First: You might be able to refresh compile_commands.json slightly less often, making the current runtime okay.
41
65
# If you're adding files, clangd should make pretty decent guesses at completions, using commands from nearby files. And if you're deleting files, there's not a problem. So you may not need to rerun refresh.py on every change to BUILD files. Instead, maybe refresh becomes something you run every so often when you can spare the time, making the current runtime okay.
**kwargs): # For the other common attributes. Tags, compatible_with, etc. https://docs.bazel.build/versions/main/be/common-definitions.html#common-attributes.
94
+
95
+
# Given `targets` that may be absent, or be a single string target:
96
+
# targets = "//:some_target"
97
+
#
98
+
# ... or be a list of string targets:
99
+
# targets = [
100
+
# "//:some_target",
101
+
# "//:another_target"
102
+
# ]
103
+
#
104
+
# ... or be a dict of string targets and build flags:
105
+
# targets = {
106
+
# "//:some_target": "--flag ...",
107
+
# "//:another_target": "--arg ..."
108
+
# }
109
+
#
110
+
# And given `target_groups` that may be absent, or have a group name associated with a string target or list of string targets:
111
+
# target_groups = {
112
+
# "host": "//:host_target",
113
+
# "device": [
114
+
# "//:device_target",
115
+
# ...
116
+
# ]
117
+
# }
118
+
#
119
+
# ... or have group names associated with lists of string targets with build flags:
# ... we want to produce a `string_dict_list` that we can pass into the Python script template to assemble the `target_flag_pairs`.
134
+
# A simple dict with target name keys isn't adequate, because we can specify a target more than once with different build flags (see the last example above).
135
+
# So we assemble a dict where the keys are unique to each target+flag combination, and the values are a list of strings in this format: [<target>, <flags>]
136
+
#
137
+
# That takes care of the `target_flag_pairs`, which determines which targets to generate compile commands for.
138
+
#
139
+
# Associating compile commands with target groups is easier; we pass `target_groups`, but with the target names and flags concatenated in the same way
140
+
# as described above. This lets us associate each target+flag combination we generate compile commands for with its membership(s) in target groups.
141
+
142
+
target_group_targets_list= []
143
+
serialized_target_groups= {}
144
+
145
+
iftarget_groups:
146
+
# Convert the targets specified in `target_groups` into the format we'll use with `targets`, so we can combine them into one list of targets to generate compile commands for.
147
+
fortargets_for_groupintarget_groups.values():
148
+
# You can specify a bare string target if the group only has one target.
149
+
iftype(targets_for_group) !="list":
150
+
targets_for_group= [targets_for_group]
151
+
152
+
fortargetintargets_for_group:
153
+
# The target can either be a plain string target name, or a tuple of a target name and build flags, similar to the format of `targets`.
# Targets may appear in multiple groups. We don't want duplicates in the final list, but Starlark doesn't have Python's set class. So we de-duplicate manually.
163
+
iftarget_datanotintarget_group_targets_list:
164
+
target_group_targets_list.append(target_data)
165
+
166
+
# Assemble the association between target groups and their targets.
# Convert the various, acceptable target shorthands into the dictionary format
69
182
# In Python, `type(x) == y` is an antipattern, but [Starlark doesn't support inheritance](https://bazel.build/rules/language), so `isinstance` doesn't exist, and this is the correct way to switch on type.
70
-
ifnottargets: # Default to all targets in main workspace
71
-
targets= {"@//...": ""}
183
+
ifnottargetsandnottarget_groups: # Default to all targets in main workspace
184
+
targets= {"@//...": ["@//...", ""]}
185
+
elifnottargets: # In this case, targets were defined only in `target_groups`
" {windows_default_include_paths}": "\n".join([" %r,"%pathforpathinfind_cpp_toolchain(ctx).built_in_include_directories]), # find_cpp_toolchain is from https://docs.bazel.build/versions/main/integrating-with-rules-cc.html
0 commit comments