Referring to the current workspace in .bzl file

970 views
Skip to first unread message

pylal...@google.com

unread,
Jun 13, 2018, 5:09:52 PM6/13/18
to bazel-discuss
Hi there,

I'm defining some custom rules and macros in a .bzl file in a workspace that others are supposed to import as an archive into their own projects.

In one of the macros, I need to add a dependency on a target which is hosted in the same workspace. If I refer to it as `//foo/bar`, I get an error as Bazel is looking for that target in the main workspace, which is not my workspace.
I'm currently referring to it as `my_workspace@//foo/bar`, which works but is flimsy as it only works if my workspace is being imported under that very name.

IS there any way to make that reference relative to the workspace in which it is defined?

Thanks,
=py=

ittai zeidman

unread,
Jun 13, 2018, 11:25:11 PM6/13/18
to bazel-discuss
As far as I know there isn’t.
Note that if someone declares your project with a different name they will get a warning about the mismatch and there was discussion to forbid it but I’m not actually sure where that stands.

pylal...@google.com

unread,
Jun 13, 2018, 11:31:59 PM6/13/18
to bazel-discuss
On Wednesday, June 13, 2018 at 8:25:11 PM UTC-7, ittai zeidman wrote:
> As far as I know there isn’t.
> Note that if someone declares your project with a different name they will get a warning about the mismatch and there was discussion to forbid it but I’m not actually sure where that stands.

Where should the name be declared in the imported workspace?

ittai zeidman

unread,
Jun 13, 2018, 11:55:43 PM6/13/18
to pylal...@google.com, bazel-discuss
Not sure I follow.
In the imported workspace you declare its name (FOO) in the WORKSPACE file.
In the imported workspace’s bzl you use “FOO”.
In the importing workspace you define an external repository named “FOO”.

Is that clearer?
--
You received this message because you are subscribed to a topic in the Google Groups "bazel-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/bazel-discuss/qNuyIu-akq8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to bazel-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/727e965b-41fb-4e70-b5cc-b5fc1ca2a9cb%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

pylal...@google.com

unread,
Jun 14, 2018, 12:10:35 AM6/14/18
to bazel-discuss
On Wednesday, June 13, 2018 at 8:55:43 PM UTC-7, ittai zeidman wrote:
> Not sure I follow.
> In the imported workspace you declare its name (FOO) in the WORKSPACE file.

Right now my WORKSPACE file is empty. How do I add a name in there? Nothing stands out in https://docs.bazel.build/versions/master/be/workspace.html.

ittai zeidman

unread,
Jun 14, 2018, 1:04:30 AM6/14/18
to pylal...@google.com, bazel-discuss
Add this:
workspace(name = "FOO") #all caps is probably not a good choice for a workspace name
--
You received this message because you are subscribed to a topic in the Google Groups "bazel-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/bazel-discuss/qNuyIu-akq8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to bazel-discus...@googlegroups.com.

pylal...@google.com

unread,
Jun 14, 2018, 2:40:30 AM6/14/18
to bazel-discuss
I added that line to my workspace but I'm not seeing any warning even though I'm trying to import the workspace under a different name. The build breaks the moment I use the custom rule that tries to add a dependency using the declared name.

ittai zeidman

unread,
Jun 14, 2018, 2:47:48 AM6/14/18
to pylal...@google.com, bazel-discuss
Is there something you can share? I’m a bit in the dark.
Btw, where are you importing the workspace that you just named? How are you importing it?

pylal...@google.com

unread,
Jun 14, 2018, 12:28:30 PM6/14/18
to bazel-discuss
https://fuchsia-review.googlesource.com/c/scripts/+/165123

The test workspace tries to refer to the SDK workspace (imported via "local_repository") with a different name than the SDK workspace declares for itself.

ittai zeidman

unread,
Jun 15, 2018, 7:08:04 AM6/15/18
to pylal...@google.com, bazel-discuss
Where is the WORKSPACE file that depends on this WORKSPACE file? In it the name that is given is different than "fuchsia_sdk"? 
Because I just now encountered the warning so it definitely happens 

pylal...@google.com

unread,
Jun 15, 2018, 11:02:31 AM6/15/18
to bazel-discuss
It's generated by generate-tests.py. This script creates a WORKSPACE file with:

local_repository(
name = "fuchsia_other_name",
. . .
)

whereas the original repository is declared as:

workspace(name = "fuchsia_sdk")

Interestingly, under $ROOT/bazel-my_test_workspace/external/fuchsia_other_name I don't see any WORKSPACE file. I see one for e.g. local_cc_config. Maybe this is a byproduct of using a local_repository and not an http_archive?

ittai zeidman

unread,
Jun 16, 2018, 10:22:25 PM6/16/18
to pylal...@google.com, bazel-discuss
Short on time so I’d advise you manually craft two very small repositories and check it out there.
Maybe the local repository indeed has a different behavior.

Dmitry Lomov

unread,
Jun 18, 2018, 8:30:45 AM6/18/18
to ittai zeidman, pylal...@google.com, bazel-discuss
Sorry for late reply, and our docs are not awesome.

This line
      "@fuchsia_sdk//pkg/fidl_cpp",
needs to read
      Label("@fuchsia_sdk//pkg/fidl_cpp",relative_to_caller_repository = True)

(https://docs.bazel.build/versions/master/skylark/lib/Label.html#Label, we need to improve the docs and undeprecate this arg).


Here is how it works. Let's ignore .bzl files and macros for a second. Let's just talk about BUILD files.
Imagine you have a project that has 2 external repostiories, a and b.

a: fooA/BUILD
b: fooB/BUILD

main:
  src/BUILD

All targets within that project have unique, canonical labels pointing at them:
  @a//fooA:bar
  @b//fooB:baz
  @//src:quux
In Skylark terms, once you have a Label object in you hands, that object uniquely identifies a target.
However in BUILD files, we do not usually create Label objects - we use strings and those strings convert to Labels under the hood.

Now in BUILD files from different repos we convert strings to labels _relative to which repo the BUILD file is in_. Therefore in a BUILD files within repo a you can refer to //fooA:bar, within repo b you can refer to //fooB:baz and in the main repo you can refer to //src:quux.

If you have, in some BUILD file within repo A, smth like
   cc_library(name = ....
                    deps = ["//fooA:bar"]
   )

then this is what happens here:
   1. deps is an attr.label_list attribute of cc_library, therefore
   2. a conversion from string to Label needs to happen, and
   3. this conversion happens in a BUILD file within repo A, therefore
   4. in this case "//fooA:bar" becomes "@a//fooA:bar"
You can think of it as a call to Label("//fooA:bar") silently inserted whenever the conversion happens.

Now let's add macros to this mix. Imagine that repo a has:

fooA/macro.bzl:
...
def my_macro(name , other_dep)    
  cc_library(name = name,
                    deps = ["//fooA:bar", other_dep]
   )

and in main repo in src/BUILD we have

src/BUILD
  load("@a//fooA:macro.bzl", "my_macro")
  my_macro(name = "xyz", other_dep = "//src:other_library")

What happens here? The way this works in Bazel is that we convert a string to a label _in the topmost file on the execution stack_.
In this case, the call stack is:
   @//src:...                     <<toplevel>>
   @a//fooA:macro.bzl:  my_macro
so "//fooA:bar" is converted to Label in _the context of main repository_. which is probably not what author intended. 

Why did we do it that way? You can probably guess from this example: see the `other_dep` argument to a macro. It is is also a string and it comes from the calling, toplevel, context.  It would be very surprising and error-prone if we interpreted that label in repo a context.

But of course sometimes macro writers need to refer to labels relative to their repository
The way to do that is to use relative_to_caller_repository parameter of Label constructor:

def my_macro(name , other_dep)    
  cc_library(name = name,
                    deps = [Label("//fooA:bar", relative_to_caller_repository=True), other_dep]
   )


Another important thing to keep in mind is that while .bzl file is loading and its top-level declarations are executed, that file itself is the top of execution stack.
For example, consider:

fooA/macro.bzl:

my_rule = rule(_implementation, 
                   attrs = { 
                        "_tool" : attr.label(default = "//fooA:bar")  # relative to repo a
                    } 
my_bar_label = Label("//fooA:bar") # relative to repo A
def my_macro(name , other_dep)    
  cc_library(name = name,
                    deps = [
                          "//fooA:bar",  # relative to whoever calls my_macro
                          other_dep]
   )


Conversions within assignments "my_rule = ..." and "my_bar_label = ..." occur _while macro.bzl is being loaded_. At that point macro.bzl is its own topmost file on the execution stack, so string->label conversions happen relative to the repo it belongs to.

In contrast, the conversion within the body of my_macro does not occur until my_macro is called, therefore that conversion happens relative to whichever repo the topmost file at the time of that call belongs.

HTH, 
please let me know if this is unclear, and I'll try to make this part of our docs as well
Dmitry

On Sun, Jun 17, 2018 at 4:22 AM, ittai zeidman <itt...@gmail.com> wrote:
Short on time so I’d advise you manually craft two very small repositories and check it out there.
Maybe the local repository indeed has a different behavior.

--
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discuss+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/CAOfK4wUjFW%3DZ2LqhCknT%3DukUAs0RtnyqZJX%2BPeHygDvofhiN7A%40mail.gmail.com.

For more options, visit https://groups.google.com/d/optout.



--
Google Germany GmbH
Erika-Mann-Straße 33, 80636 München, Germany

pylal...@google.com

unread,
Jun 18, 2018, 8:40:48 AM6/18/18
to bazel-discuss
Thanks for the exhaustive answer! Very enlightening. I have two questions, see inline.


On Monday, June 18, 2018 at 5:30:45 AM UTC-7, Dmitry Lomov wrote:
> Sorry for late reply, and our docs are not awesome.
> TL;DR: here (https://fuchsia-review.googlesource.com/c/scripts/+/165123/1/sdk/bazel/base/build_defs/fidl_cc.bzl#b133)
>
>
> This line
>       "@fuchsia_sdk//pkg/fidl_cpp",
>
> needs to read
>
>      Label("@fuchsia_sdk//pkg/fidl_cpp",relative_to_caller_repository = True)

Can it just be Label("//pkg/fidl_cpp",relative_to_caller_repository = True) without the @fuchsia_sdk, since it's relative to the caller?


>
> (https://docs.bazel.build/versions/master/skylark/lib/Label.html#Label, we need to improve the docs and undeprecate this arg).
>

relative_to_caller_repository is marked as deprecated there. Still fine to use it?
> To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discus...@googlegroups.com.

Dmitry Lomov

unread,
Jun 18, 2018, 8:45:49 AM6/18/18
to pylal...@google.com, bazel-discuss
On Mon, Jun 18, 2018 at 2:40 PM, pylaligand via bazel-discuss <bazel-...@googlegroups.com> wrote:
Thanks for the exhaustive answer! Very enlightening. I have two questions, see inline.


On Monday, June 18, 2018 at 5:30:45 AM UTC-7, Dmitry Lomov wrote:
> Sorry for late reply, and our docs are not awesome.
> TL;DR: here (https://fuchsia-review.googlesource.com/c/scripts/+/165123/1/sdk/bazel/base/build_defs/fidl_cc.bzl#b133)
>
>
> This line
>       "@fuchsia_sdk//pkg/fidl_cpp",
>
> needs to read
>
>      Label("@fuchsia_sdk//pkg/fidl_cpp",relative_to_caller_repository = True)

Can it just be Label("//pkg/fidl_cpp",relative_to_caller_repository = True) without the @fuchsia_sdk, since it's relative to the caller?

Yes! Sorry, my mistake. 


>
> (https://docs.bazel.build/versions/master/skylark/lib/Label.html#Label, we need to improve the docs and undeprecate this arg).
>

relative_to_caller_repository is marked as deprecated there. Still fine to use it?

Yes (as I said, we need to undeprecate it, working on PR as we speak)

To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discuss+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/136a2f20-fb93-4939-a98f-43bf660a1953%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

pylal...@google.com

unread,
Jun 18, 2018, 9:00:45 AM6/18/18
to bazel-discuss
On Monday, June 18, 2018 at 5:45:49 AM UTC-7, Dmitry Lomov wrote:
> On Mon, Jun 18, 2018 at 2:40 PM, pylaligand via bazel-discuss <bazel-...@googlegroups.com> wrote:
> Thanks for the exhaustive answer! Very enlightening. I have two questions, see inline.
>
>
>
>
>
> On Monday, June 18, 2018 at 5:30:45 AM UTC-7, Dmitry Lomov wrote:
>
> > Sorry for late reply, and our docs are not awesome.
>
> > TL;DR: here (https://fuchsia-review.googlesource.com/c/scripts/+/165123/1/sdk/bazel/base/build_defs/fidl_cc.bzl#b133)
>
> >
>
> >
>
> > This line
>
> >       "@fuchsia_sdk//pkg/fidl_cpp",
>
> >
>
> > needs to read
>
> >
>
> >      Label("@fuchsia_sdk//pkg/fidl_cpp",relative_to_caller_repository = True)
>
>
>
> Can it just be Label("//pkg/fidl_cpp",relative_to_caller_repository = True) without the @fuchsia_sdk, since it's relative to the caller?
>
>
>
> Yes! Sorry, my mistake. 

I just gave this a try and still got an error:
BUILD:7:1: no such package 'pkg/fidl_cpp': BUILD file not found on package path and referenced by '//fidl-cc:cc'
It looks like //pkg/fidl_cpp is still being searched for in the main repo.

I also noticed in the Label doc:
"When relative_to_caller_repository is True and the calling thread is a rule's implementation function, then a repo-relative label //foo:bar is resolved relative to the rule's repository."
It mentions the calling thread of a rule's implementation function, which I supposed is different from the macro thread.

I tried setting the attribute to False... and it worked. It looks like using an explicit Label is all I needed.

Dmitry Lomov

unread,
Jun 18, 2018, 9:16:25 AM6/18/18
to pylal...@google.com, bazel-discuss
On Mon, Jun 18, 2018 at 3:00 PM, pylaligand via bazel-discuss <bazel-...@googlegroups.com> wrote:
On Monday, June 18, 2018 at 5:45:49 AM UTC-7, Dmitry Lomov wrote:
> On Mon, Jun 18, 2018 at 2:40 PM, pylaligand via bazel-discuss <bazel-...@googlegroups.com> wrote:
> Thanks for the exhaustive answer! Very enlightening. I have two questions, see inline.
>
>
>
>
>
> On Monday, June 18, 2018 at 5:30:45 AM UTC-7, Dmitry Lomov wrote:
>
> > Sorry for late reply, and our docs are not awesome.
>
> > TL;DR: here (https://fuchsia-review.googlesource.com/c/scripts/+/165123/1/sdk/bazel/base/build_defs/fidl_cc.bzl#b133)
>
> >
>
> >
>
> > This line
>
> >       "@fuchsia_sdk//pkg/fidl_cpp",
>
> >
>
> > needs to read
>
> >
>
> >      Label("@fuchsia_sdk//pkg/fidl_cpp",relative_to_caller_repository = True)
>
>
>
> Can it just be Label("//pkg/fidl_cpp",relative_to_caller_repository = True) without the @fuchsia_sdk, since it's relative to the caller?
>
>
>
> Yes! Sorry, my mistake. 

I just gave this a try and still got an error:
BUILD:7:1: no such package 'pkg/fidl_cpp': BUILD file not found on package path and referenced by '//fidl-cc:cc'
It looks like //pkg/fidl_cpp is still being searched for in the main repo.

I also noticed in the Label doc:
"When relative_to_caller_repository is True and the calling thread is a rule's implementation function, then a repo-relative label //foo:bar is resolved relative to the rule's repository."
It mentions the calling thread of a rule's implementation function, which I supposed is different from the macro thread.

I tried setting the attribute to False... and it worked. It looks like using an explicit Label is all I needed.

You are right. Apologies! Indeed, the default Label construct converts relative to the file where the call occurred (which I realized while writing the PR to undeprecate :)).
We need a clear guidance on this.

To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discuss+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/306e4014-37b5-4228-ac90-e1f6972c3c7c%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages