Search code examples
pythonbazel

Bazel: create py_binary from python file in py_library


New to the Bazel build system.

I want to create a py_binary from a file in a py_library which is created from an http_archive.

Currently I have:

WORKSPACE:

new_http_archive(
    name = "cpplint_archive",
    url = "https://pypi.python.org/packages/source/c/cpplint/cpplint-1.2.2.tar.gz",
    sha256 = "b2979ff630299293f23c52096e408f2b359e2e26cb5cdf24aed4ce53e4293468",
    build_file = "cpplint.BUILD",
    strip_prefix = "cpplint-1.2.2"
)

cpplint.BUILD:

py_library(
    name = "cpplint",
    srcs = glob(["*.py"]),
    visibility = ['//visibility:public']
)

src/BUILD:

py_binary(
    name = "lint",
    main = ":cpplint/cpplint.py",
    srcs = [":cpplint/cpplint.py"],
    deps = [
        "@cpplint_archive//:cpplint"
    ]
)

The path in srcs an main is wrong, giving "no such package 'cpplint/cpplint.py'" when I run bazel run src/lint. I can't figure out how to refer to a file included in the library.


Solution

  • You can put the py_binary rule directly into cpplint.BUILD:

    py_binary(
        name = "cpplint",
        srcs = ["cpplint.py"],
    )
    

    and then build it like this:

    $ bazel build @cpplint_archive//:cpplint
    INFO: Found 1 target...
    Target @cpplint_archive//:cpplint up-to-date:
      bazel-bin/external/cpplint_archive/cpplint
    INFO: Elapsed time: 2.327s, Critical Path: 0.01s
    

    If you really do want the py_binary rule to be in the main repository, you can do:

    cpplint.BUILD:

    exports_files(["cpplint.py"])
    

    BUILD:

    py_binary(
        name = "cpplint",
        srcs = ["@cpplint_archive//:cpplint.py"],
    )
    

    But it's typically not as nice to pull in files from other packages.