Search code examples
bazelpatchbazel-rules

With Bazels `http_archive` - is there a way to add outside files to repository after downloading


With Bazel I'm building an external library using http_archive together with some patches which bring additional files.

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
    http_archive(
        name="some-lib",
        build_file="@my-project//some-lib:BUILD.some-lib",
        url="https://example/download/some-lib.tar.gz",
        sha256="x"
        patches=[
            "//@abc/bcd.txt",
        ],
    )

I am trying to add additional file through patches "//@abc/bcd.txt" which will be later used in build file but I am not able to find it. how can I access this patch file and where can I find the patch files so that I can use it in the BUILD file I provide? Thanks.

considering if I use patch_cmds = ["echo 'hello world' > efg.txt"], then I can find this efg file after extracting the package

some-lib
├── BUILD
├── BUILD.some-lib
├── efg.txt
├── ...original files/directory

how can I find the location of patches?


Solution

  • patches (at least without also manipulating patch_tool and patch_args) would not add files it finds, but will apply them as patches. I.e. if you wanted to create a efg.txt file in the root of your unpacked archive, the add_efg_txt.patch could look like this:

    --- /dev/null
    +++ efg.txt
    @@ -0,0 +1 @@
    +hello world
    

    As to where to store the patch files themselves? Theoretically anywhere, but likely in the same (bzl) package where you invoke http_archive. You then use their bazel label in the list of patches attribute of http_archive.

    Once the file has been patched into existence, you can refer to it inside the BUILD file in the root of the package (in your example): @my-project//some-lib:BUILD.some-lib and if exported from there and visible also from your workspace via @some-lib//:efg.txt.


    To respond to your comment. No, you cannot access the source file or its content with patch_cmds, check out the docs [emphasis added]:

    Sequence of Bash commands to be applied on Linux/Macos after patches are applied.

    In other words, this is for action(s) you can perform to wrap up the patching session.

    As stated before, by far the most straightforward way to patch file into existence is to provide it as a diff. You can create one by comparing your file to "nothing" (/dev/null):

    $ diff -u /dev/null efg.txt > add_efg_txt.patch
    

    You could in theory write your own dump_to_efg_txt.sh:

    #!/bin/bash
    cat > efg.txt
    

    And pass that into patch_tool which is fed the file(s) from patches via stdin. But this approach would be problematic in multiple ways and really would not make much sense unless confusion was the ultimate goal.