Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Describe a better approach of how to use {fmt} as a depency in a Bazel build #2516

Merged
merged 1 commit into from
Oct 2, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 45 additions & 57 deletions support/bazel/README.md
Original file line number Diff line number Diff line change
@@ -1,85 +1,73 @@
# Bazel support

Bazel is an open-source build tool.
More information about Bazel can be found [here](https://bazel.build/).
To get [Bazel](https://bazel.build/) working with {fmt} you can copy the files `BUILD.bazel`, `WORKSPACE.bazel`, `.bazelrc`, and `.bazelversion` from this folder (`support/bazel`) to the root folder of this project. This way {fmt} gets bazelized and can be used with Bazel (e.g. doing a `bazel build //...` on {fmt}).

## Using the fmt repository with Bazel
## Using {fmt} as a dependency

Even though the {fmt} repository does not contain a `WORKSPACE` file in its root directory,
there is an easy approach to use the {fmt} repository with Bazel out of the box.
This is demonstrated in the following example.
The following minimal example shows how to use {fmt} as a dependency within a Bazel project.

Add to your `WORKSPACE` file:
The following file structure is assumed:

```python
load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository")

# Fetch all files from fmt including the BUILD file `support/bazel/BUILD.bazel`
new_git_repository(
name = "fmt_workaround",
branch = "master",
remote = "https://github.com/fmtlib/fmt/",
build_file_content = "# Empty build file on purpose"
)

# Now the BUILD file `support/bazel/BUILD.bazel` can be used:
new_git_repository(
name = "fmt",
branch = "master",
remote = "https://github.com/fmtlib/fmt/",
build_file = "@fmt_workaround//:support/bazel/BUILD.bazel"
)
```

Create a `BUILD.bazel` file and add a dependency to {fmt}:

```python
cc_binary( # Build a binary
name = "Demo", # Name of the binary
srcs = ["main.cpp"], # List of files - we only have main.cpp
deps = ["@fmt//:fmt"], # Depend on fmt
)
example
├── BUILD.bazel
├── main.cpp
└── WORKSPACE.bazel
```

Make use of {fmt} in `main.cpp`:
*main.cpp*:

```C++
```c++
#include "fmt/core.h"

int main() {
fmt::print("The answer is {}.\n", 42);
fmt::print("The answer is {}\n", 42);
}
```

The expected output of this example is `The answer is 42`.

## Bazelize fmt

First downloading a build file and then making use of it can be considered as a bit unclean, nevertheless, it works.

A cleaner Bazel solution would be to move the `WORKSPACE` and `BUILD` files to the root folder of the {fmt} Git repository.

In favor of keeping the {fmt} project directory clean, those files were not added to the project root directory.

If you do not like this, you can fork this repository and move the files `BUILD.bazel`, `WORKSPACE.bazel`, `.bazelrc`, and `.bazelversion` from this folder (`support/bazel`) to the root folder of this project.

This way {fmt} gets bazelized and can be used in your Bazel builds.

**Example**

Create a `WORKSPACE.bazel` file with the following content:
*WORKSPACE.bazel*:

```python
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")

# Fetch bazelized fmt
git_repository(
name = "fmt",
branch = "bazel-support", # A copy of master where BUILD.bazel, WORKSPACE.bazel, .bazelrc and .bazelversion are moved to root
remote = "https://github.com/<user_or_organisation>/fmt", # replace <user_or_organisation> by a valid account
branch = "master",
remote = "https://github.com/fmtlib/fmt",
patch_cmds = [
"mv support/bazel/.bazelrc .bazelrc",
"mv support/bazel/.bazelversion .bazelversion",
"mv support/bazel/BUILD.bazel BUILD.bazel",
"mv support/bazel/WORKSPACE.bazel WORKSPACE.bazel",
],
Vertexwahn marked this conversation as resolved.
Show resolved Hide resolved
# Windows-related patch commands are only needed in the case MSYS2 is not installed.
# More details about the installation process of MSYS2 on Windows systems can be found here:
# https://docs.bazel.build/versions/main/install-windows.html#installing-compilers-and-language-runtimes
# Even if MSYS2 is installed the Windows related patch commands can still be used.
patch_cmds_win = [
"Move-Item -Path support/bazel/.bazelrc -Destination .bazelrc",
"Move-Item -Path support/bazel/.bazelversion -Destination .bazelversion",
"Move-Item -Path support/bazel/BUILD.bazel -Destination BUILD.bazel",
"Move-Item -Path support/bazel/WORKSPACE.bazel -Destination WORKSPACE.bazel",
],
)
```

Create a `BUILD.bazel` file and add a dependency to {fmt} (same as above).
In the *WORKSPACE* file, the {fmt} GitHub repository is fetched. Using the attribute `patch_cmds` the files `BUILD.bazel`, `WORKSPACE.bazel`, `.bazelrc`, and `.bazelversion` are moved to the root of the {fmt} repository. This way the {fmt} repository is recognized as a bazelized workspace.

*BUILD.bazel*:

```python
cc_binary(
name = "Demo",
srcs = ["main.cpp"],
deps = ["@fmt"],
)
```

The *BUILD* file defines a binary named `Demo` that has a dependency to {fmt}.

To execute the binary you can run `bazel run //:Demo`.

Make use of {fmt} in `main.cpp` (same as above).