Search code examples
bazel

Bazel function: git_repository vs new_git_repository?


What are the differences between functions git_repository and new_git_repository?

Can new_git_repository do everything git_repository does? If so, why do we have two separate functions?

(Was reading https://docs.bazel.build/versions/main/repo/git.html)


Solution

  • Usually, you use git_repository if the underlying repository is already bazelized otherwise new_git_repository.

    new_git_repository provides the attributes build_file and build_file_content whereas git_repository does not have those attributes.

    For example Google Test is already using Bazel as a build system (i.e. it provides WORKSPACE file in its root directory). To fetch it you can simply do:

    # GoogleTest- Google Testing and Mocking Framework
    git_repository(
        name = "googletest",
        commit = "703bd9caab50b139428cea1aaff9974ebee5742e",  # googletest v1.10.0
        remote = "https://github.com/google/googletest",
        shallow_since = "1570114335 -0400",
    )
    

    You can then easily use Google Test as an dependency in some BUILD file:

    cc_test(
        name = "tests",
        timeout = "short",
        srcs = ["test.cpp"],
        deps = [
            "@googletest//:gtest_main", # Use GoogleTest as a dependency
        ],
    )
    

    new_git_repository is usually used if the underlying dependency is not bazelized. new_git_repository gives you the possibility to provide a BUILD file that is so to say injected in the repository under consideration. Besides this also a trivial WORKSPACE file is generated for the dependency. This way you can provide a BUILD file form outside to a git repo to make it working with the Bazel build system.

    Example https://github.com/fmtlib/fmt is not bazelized. You can wirte a fmt.BUILD file with the following content:

    cc_library(
        name = "fmt",
        srcs = [
            "include/fmt/args.h",
            "include/fmt/chrono.h",
            "include/fmt/color.h",
            "include/fmt/compile.h",
            "include/fmt/core.h",
            "include/fmt/format.h",
            "include/fmt/format-inl.h",
            "include/fmt/locale.h",
            "include/fmt/os.h",
            "include/fmt/ostream.h",
            "include/fmt/printf.h",
            "include/fmt/ranges.h",
            "include/fmt/xchar.h",
            #"src/fmt.cc", # No C++ module support
            "src/format.cc",
            "src/os.cc",
        ],
        hdrs = [
            "include/fmt/core.h",
            "include/fmt/format.h",
        ],
        includes = [
            "include",
            "src",
        ],
        strip_include_prefix = "include",
        visibility = ["//visibility:public"],
    )
    

    Now you can use new_git_repository to provide (inject) the above build file, e.g.:

    new_git_repository(
        name = "fmt",
        build_file = "//third_party:fmt.BUILD",
        ...
    )
    

    BTW: Also the workspace rule local_repository comes in two flavors: local_repository and new_local_repository. Again the new variant accepts also an external BUILD file. Older version of Bazel (< 0.29.0) had also new_http_archive - neverthless with an current version of Bazel (4.2.1) there is only http_archive that accepts also the attributes build_file and build_file_content.