facebook / buck2

Build system, successor to Buck
https://buck2.build/
Apache License 2.0
3.33k stars 194 forks source link

Does not prebuilt_cxx_library.static_lib support $(location //:target)? #592

Open yaoddao opened 2 months ago

yaoddao commented 2 months ago

When using prebuilt_cxx_libary, it is OK if the member static_lib is set to a relative path. However, when I use $(location //:target) buck2 reports the following error I asked if prebuilt_cxx_libary.static_lib supports $(location //:target), just like prebuilt_cxx_libary.exported_linker_flags supports it. Thanks!

prebuilt_cxx_libary(
   exported_linker_flags = [
      "-L$(location //:ext-link)/local/lib",
   ],
   static_lib = '$(location //:ext-link)/opt/b28/s-5.8.003/linux_x86_64_rhel7/lib/liblef.a',
 )
Caused by:
    0: Error looking up configured node root//app/gps:seascape_main (prelude//platforms:default#524f8da68ea2a374)
    1: Error looking up configured node root//:pre_ext_headers (prelude//platforms:default#524f8da68ea2a374)
    2: looking up unconfigured target node `root//:pre_ext_headers`
    3: Error loading targets in package `root//` for target `root//:pre_ext_headers`
    4: Error evaluating build file: `root//:BUCK`
    5: Traceback (most recent call last):
         * BUCK:16, in <module>
             prebuilt_cxx_library(
         * prelude/native.bzl:234, in _prebuilt_cxx_library_macro_stub
             __rules__["prebuilt_cxx_library"](
       error: Error coercing attribute `static_lib` of `root//:pre_ext_headers`
          --> prelude/native.bzl:234:5
           |
       234 |       __rules__["prebuilt_cxx_library"](
           |  _____^
       235 | |         exported_preprocessor_flags = _concat(
       236 | |             exported_preprocessor_flags,
       237 | |             _versioned_param_to_select(versioned_exported_preprocessor_flags),
       238 | |         ),
       239 | |         exported_lang_preprocessor_flags = _concat(
       240 | |             exported_lang_preprocessor_flags,
       241 | |             _versioned_param_to_select(versioned_exported_lang_preprocessor_flags),
       242 | |         ),
       243 | |         exported_platform_preprocessor_flags = _concat(
       244 | |             exported_platform_preprocessor_flags,
       245 | |             _versioned_param_to_select(versioned_exported_platform_preprocessor_flags),
       246 | |         ),
       247 | |         exported_lang_platform_preprocessor_flags = _concat(
       248 | |             exported_lang_platform_preprocessor_flags,
       249 | |             _versioned_param_to_select(versioned_exported_lang_platform_preprocessor_flags),
       250 | |         ),
       251 | |         static_lib = _at_most_one(static_lib, _versioned_param_to_select(versioned_static_lib)),
       252 | |         static_pic_lib = _at_most_one(static_pic_lib, _versioned_param_to_select(versioned_static_pic_lib)),
       253 | |         shared_lib = _at_most_one(shared_lib, _versioned_param_to_select(versioned_shared_lib)),
       254 | |         header_dirs = _at_most_one(header_dirs, _versioned_param_to_select(versioned_header_dirs)),
       255 | |         **kwargs
       256 | |     )
           | |_____^
           |

    6: Error coercing attribute `static_lib` of type `attrs.option(attrs.source(), default=None)`
    7: Error coercing "(//:ext-link)/opt/b28/s-5.8.003/linux_x86_64_rhel7/lib/liblef.a"
    8: Couldn't coerce `(//:ext-link)/opt/b28/s-5.8.003/linux_x86_64_rhel7/lib/liblef.a` as a source.
         Error when treated as a target: Invalid absolute target pattern `(//:ext-link)/opt/b28/s-5.8.003/linux_x86_64_rhel7/lib/liblef.a` is not allowed: Invalid target name `ext-link)/opt/b28/s-5.8.003/linux_x86_64_rhel7/lib/liblef.a`. Target names are non-empty strings and can only contain alpha numeric characters, and symbols `,`, `.`, `=`, `-`, `/`, `~`, `@`, `!`, `+`, `$`, and `_`. No other characters are allowed.: Invalid target name `ext-link)/opt/b28/s-5.8.003/linux_x86_64_rhel7/lib/liblef.a`. Target names are non-empty strings and can only contain alpha numeric characters, and symbols `,`, `.`, `=`, `-`, `/`, `~`, `@`, `!`, `+`, `$`, and `_`. No other characters are allowed.
         Error when treated as a path: expected a normalized path but got an un-normalized path instead: `(//:ext-link)/opt/b28/s-5.8.003/linux_x86_64_rhel7/lib/liblef.a`
zjturner commented 1 month ago

You probably need to make a rule that can export a subpath, then you can use tge static_lib=“:foo” syntax

cjhopman commented 1 month ago

Yep, you need it to be the default output of a target or subtarget. What kind of rule is //:ext-link? If it's a genrule, that already has support for adding subtargets for paths in its output. If it's an http_file/archive, i'm not sure it has that support but it seems like it'd be a nice thing to add. That'd be something like:

http_archive(
  name = "ext-link",
  named_outs = { "liblef.a": "/opt/b28/s-5.8.003/linux_x86_64_rhel7/lib/liblef.a"}
  ...
)

prebuilt_cxx_libary(
   static_lib = '//:ext-link[liblef.a]',
   ...
 )
zjturner commented 1 month ago

As a temporary workaround though (until http_archive supports it natively), you can also just write a rule that takes a target (such as an http_archive) as a dep, and re-export it.

def _inner_path_impl(ctx):
    original_default_output = ctx.attrs.target[DefaultInfo].default_outputs[0]

    return [
        DefaultInfo(default_outputs = [original_default_output.project(ctx.attrs.subpath)])
    ]

inner_path = rule(
    impl = _inner_path_impl,
    attrs = {
        "target": attrs.dep(providers = [DefaultInfo]),
        "subpath": attrs.string()
    }
)

Then you use it like this:

http_archive(
  name = "_ext-link",
  named_outs = { "liblef.a": "/opt/b28/s-5.8.003/linux_x86_64_rhel7/lib/liblef.a"}
  ...
)

inner_path(
    name = "ext-link",
    target = ":_ext-link",
    subpath = "opt/b28/s-5.8.003/linux_x86_64_rhel7/lib/liblef.a"
)

prebuilt_cxx_libary(
   static_lib = '//:ext-link',
   ...
 )