Skip to content
Open
Show file tree
Hide file tree
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
8 changes: 8 additions & 0 deletions .bazelignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Directories populated by the CMake build (FetchContent checkouts and the
# third_party/absl symlink) contain their own BUILD files and must not be
# treated as packages of this workspace.
third_party/abseil-cpp
third_party/absl
third_party/benchmark
build
python
10 changes: 10 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# SentencePiece requires C++17.
build --enable_platform_specific_config

build:linux --cxxopt=-std=c++17 --host_cxxopt=-std=c++17
build:macos --cxxopt=-std=c++17 --host_cxxopt=-std=c++17
build:freebsd --cxxopt=-std=c++17 --host_cxxopt=-std=c++17
build:windows --cxxopt=/std:c++17 --host_cxxopt=/std:c++17
build:windows --cxxopt=/utf-8 --host_cxxopt=/utf-8

test --test_output=errors
1 change: 1 addition & 0 deletions .bazelversion
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
9.1.1
77 changes: 77 additions & 0 deletions .github/workflows/bazel.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: CI for Bazel build

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:

permissions:
contents: read

jobs:
build-and-test:
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest, ubuntu-24.04-arm, macos-latest, windows-latest ]

runs-on: ${{ matrix.os }}
timeout-minutes: 60

env:
# Stop the MSYS bash on Windows from rewriting Bazel labels like
# //src:spm_test as filesystem paths.
MSYS_NO_PATHCONV: "1"
MSYS2_ARG_CONV_EXCL: "*"

steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

- name: Mount Bazel caches
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: |
~/.cache/bazel-disk
~/.cache/bazel-repo
key: bazel-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('MODULE.bazel', '.bazelrc', '.bazelversion') }}
restore-keys: |
bazel-${{ runner.os }}-${{ runner.arch }}-

- name: Configure Bazel
shell: bash
run: |
home="$HOME"
if [[ "$RUNNER_OS" == "Windows" ]]; then
home="$(cygpath -m "$HOME")"
# Keep output paths short to stay within MAX_PATH limits.
echo "startup --output_user_root=C:/bzl" >> "$HOME/.bazelrc"
# Materialize the runfiles tree so tests can read their data
# dependencies from the working directory, as on Linux/macOS.
echo "build --enable_runfiles" >> "$HOME/.bazelrc"
if [[ -z "${BAZEL_SH:-}" ]]; then
echo 'BAZEL_SH=C:\Program Files\Git\bin\bash.exe' >> "$GITHUB_ENV"
fi
fi
echo "build --disk_cache=$home/.cache/bazel-disk" >> "$HOME/.bazelrc"
echo "build --repository_cache=$home/.cache/bazel-repo" >> "$HOME/.bazelrc"

- name: Build
shell: bash
run: bazel build --verbose_failures //...

- name: Test
shell: bash
run: bazel test //src:spm_test

- name: Smoke test
shell: bash
run: |
workdir="$PWD"
if [[ "$RUNNER_OS" == "Windows" ]]; then
workdir="$(cygpath -m "$PWD")"
fi
bazel run //src:spm_train -- \
--input="$workdir/data/botchan.txt" --model_prefix="$workdir/m" --vocab_size=1000
echo "Hello world." | bazel-bin/src/spm_encode --model="$workdir/m.model"
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,7 @@ python/test/sp_*.pickle
third_party/absl

test_tmp

# Bazel
/bazel-*
MODULE.bazel.lock
31 changes: 31 additions & 0 deletions BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2018 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.!

package(default_visibility = ["//visibility:public"])

exports_files([
"VERSION.txt",
"config.h.in",
"LICENSE",
])

alias(
name = "sentencepiece",
actual = "//src:sentencepiece",
)

alias(
name = "sentencepiece_train",
actual = "//src:sentencepiece_train",
)
13 changes: 1 addition & 12 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -193,21 +193,10 @@ if (SPM_ABSL_PROVIDER STREQUAL "module")
GIT_PROGRESS TRUE
GIT_TAG 20260526.0)
add_subdirectory(third_party/abseil-cpp)
if (NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/third_party/absl)
file(CREATE_LINK
${CMAKE_CURRENT_SOURCE_DIR}/third_party/abseil-cpp/absl
${CMAKE_CURRENT_SOURCE_DIR}/third_party/absl
SYMBOLIC)
endif()
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third_party/abseil-cpp)
elseif (SPM_ABSL_PROVIDER STREQUAL "package")
find_package(absl REQUIRED)
get_target_property(ABSL_INCLUDE_DIRS absl::base INTERFACE_INCLUDE_DIRECTORIES)
if (NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/third_party/absl)
file(CREATE_LINK
${ABSL_INCLUDE_DIRS}/absl
${CMAKE_CURRENT_SOURCE_DIR}/third_party/absl
SYMBOLIC)
endif()
include_directories(${ABSL_INCLUDE_DIRS})
endif()

Expand Down
37 changes: 37 additions & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Copyright 2018 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.!

module(
name = "sentencepiece",
version = "0.2.2",
)

# Keep in sync with the abseil-cpp GIT_TAG in CMakeLists.txt.
bazel_dep(name = "abseil-cpp", version = "20260526.0")

# Upstream darts-clone v0.32h plus the compatibility helpers (copy_array,
# validate, ...) that the vendored third_party/darts_clone copy carries.
bazel_dep(name = "darts-clone", version = "0.32h.bcr.1")

# Upstream esaxx at the commit the vendored third_party/esaxx copy is based
# on. The .bcr.1 revision exports esa.hxx and carries the index_type(0)
# template-deduction fix that the int64_t instantiation of esaxx() needs.
bazel_dep(name = "esaxx", version = "20250106.1.bcr.1")
bazel_dep(name = "platforms", version = "1.1.0")

# The .pb.cc/.pb.h files are regenerated from src/*.proto at build time, so
# the Bazel build follows the SPM_PROTOBUF_PROVIDER=package CMake
# configuration instead of the vendored third_party/protobuf-lite runtime.
bazel_dep(name = "protobuf", version = "35.1")
bazel_dep(name = "rules_cc", version = "0.2.18")
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ To run these benchmarks yourself, see the [reproduction instructions and scripts
For detailed guides, API references, and advanced usage, please refer to the following resources:

* [Command Line Interface (CLI) & Build Guide](doc/cli.md)
* [Building with Bazel](doc/bazel.md)
* [C++ API Reference](doc/cpp.md)
* [Python API Reference](python/README.md) & [Python Module Directory](python/)
* [Python Tokenizer Comparison Cheat Sheet](python/tokenizer_comparison_cheat_sheet.md)
Expand Down
11 changes: 0 additions & 11 deletions cmake/modify_headers.cmake

This file was deleted.

4 changes: 2 additions & 2 deletions contrib/nlcodec/bpe_model_trainer_nlcodec.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

#include "contrib/nlcodec/bpe_model_trainer_nlcodec.h"

#include "third_party/absl/container/flat_hash_set.h"
#include "third_party/absl/flags/flag.h"
#include "absl/container/flat_hash_set.h"
#include "absl/flags/flag.h"
#include "util.h"

// Flag defined here so it's available to all binaries (spm_train, tests, etc.)
Expand Down
4 changes: 2 additions & 2 deletions contrib/nlcodec/bpe_model_trainer_nlcodec_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
#include "sentencepiece_processor.h"
#include "sentencepiece_trainer.h"
#include "testharness.h"
#include "third_party/absl/flags/flag.h"
#include "third_party/absl/strings/str_cat.h"
#include "absl/flags/flag.h"
#include "absl/strings/str_cat.h"
#include "util.h"

ABSL_DECLARE_FLAG(bool, nlcodec_bpe);
Expand Down
23 changes: 23 additions & 0 deletions data/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright 2018 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.!

package(default_visibility = ["//visibility:public"])

filegroup(
name = "testdata",
srcs = glob(
["**"],
exclude = ["BUILD.bazel"],
),
)
85 changes: 85 additions & 0 deletions doc/bazel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Building SentencePiece with Bazel

In addition to the [CMake build](cli.md), SentencePiece can be built with
[Bazel](https://bazel.build). All third-party dependencies are resolved
through the [Bazel Central Registry](https://registry.bazel.build):

- [abseil-cpp](https://github.com/abseil/abseil-cpp), at the same version as
the `GIT_TAG` pinned in `CMakeLists.txt`;
- [protobuf](https://github.com/protocolbuffers/protobuf): the protobuf code
is regenerated from `src/*.proto` at build time, matching the
`SPM_PROTOBUF_PROVIDER=package` CMake configuration (CMake defaults to the
vendored protobuf-lite runtime instead);
- [darts-clone](https://github.com/s-yata/darts-clone), as the
`0.32h.bcr.1` module that carries the compatibility helpers of the
vendored copy;
- [esaxx](https://github.com/hillbig/esaxx), as the `20250106.1.bcr.1`
module, which exports `esa.hxx` and carries the template-deduction fix
the vendored copy has for the `int64_t` instantiation used by
`--train_extremely_large_corpus`.

The vendored sources under `third_party/` and the pre-generated protobuf
code in `src/builtin_pb` are only used by CMake.

## Prerequisites

- Bazel 7.2.1 or later (bzlmod is used; installing via
[Bazelisk](https://github.com/bazelbuild/bazelisk) is recommended)
- A C++17 compiler

## Building

Build the libraries and all command line tools:

```bash
bazel build //...
```

The main targets are:

| Target | Description |
| --- | --- |
| `//src:sentencepiece` (alias `//:sentencepiece`) | Runtime library (encode/decode) |
| `//src:sentencepiece_train` (alias `//:sentencepiece_train`) | Trainer library |
| `//src:spm_train` | Model trainer CLI |
| `//src:spm_encode` | Encoder CLI |
| `//src:spm_decode` | Decoder CLI |
| `//src:spm_normalize` | Text normalizer CLI |
| `//src:spm_export_vocab` | Vocabulary exporter CLI |

Run a tool directly:

```bash
bazel run //src:spm_train -- \
--input=$(pwd)/data/botchan.txt --model_prefix=$(pwd)/m --vocab_size=8000
echo "Hello world." | bazel-bin/src/spm_encode --model=m.model
```

## Running the unit tests

The unit tests are a single test binary, like the `spm_test` target that
CMake builds with `-DSPM_BUILD_TEST=ON`:

```bash
bazel test //src:spm_test
```

## Notes

- The optional CMake features `SPM_ENABLE_NFKC_COMPILE` (ICU),
`SPM_ENABLE_TCMALLOC`, `SPM_ENABLE_BENCHMARK`, and `SPM_NLCODEC_BPE` have no
Bazel equivalent yet.
- The SentencePiece sources include third-party headers with the standard
paths the upstream projects export (`absl/...`, `darts.h`, `esa.hxx`), so
Bazel resolves them directly against the Bazel Central Registry modules.
CMake resolves the same includes against the abseil-cpp checkout and the
vendored copies under `third_party/`. No third-party code is vendored into
the Bazel build.
- To use SentencePiece as a dependency in another Bazel module:

```starlark
bazel_dep(name = "sentencepiece", version = "0.2.2")
```

and depend on `@sentencepiece//:sentencepiece` (and
`@sentencepiece//:sentencepiece_train` for training support).
Loading
Loading