Skip to content
Closed
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
41 changes: 41 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,47 @@ term health of the repository.
* Please keep PRs limited to a single topic of change. This makes the PR easier to
review, and easier to roll back, if that becomes necessary.

## ICU version feature detection

Several crates in this workspace contain code that is conditionally compiled
based on the ICU library version, using attributes such as
`#[cfg(feature = "icu_version_64_plus")]`.

**There are two mechanisms by which these features are activated, and both
must be kept in sync:**

### 1. Automatic detection via `build.rs` (used when `icu_config` is active)

Crates that have a `build.rs` call `rust_icu_release::run()`, which queries
`pkg-config` for the installed ICU version and emits
`cargo:rustc-cfg=feature="icu_version_XX_plus"` instructions. This activates
the version features automatically when using the default feature set
(`use-bindgen`, `icu_config`, `renaming`), so `cargo test` works without
any explicit `--features` flags.

**Every crate that contains `#[cfg(feature = "icu_version_XX_plus")]`-gated
code MUST have a `build.rs`** that follows this pattern. Without it, the
version-gated code is silently excluded from compilation and testing when
the crate is built with default features, even if a modern ICU version is
installed.

Crates that currently have a `build.rs` for this purpose:
`rust_icu_sys`, `rust_icu_udat`, `rust_icu_uloc`, `rust_icu_ulistformatter`,
`rust_icu_unumberformatter`, `rust_icu_ecma402`.

### 2. Explicit Cargo features (used when `icu_config` is inactive)

When `icu_config` is disabled (e.g. when using pre-generated static bindgen
files with `icu_version_in_env`), the version features must be passed
explicitly via `--features=icu_version_64_plus,...`. The `build.rs` no-ops in
this case. The CI `test-with-features` matrix job covers this path.

### Adding a new crate with version-gated code

If you add `#[cfg(feature = "icu_version_XX_plus")]` to a new crate, you must
also add a `build.rs` (copy from any existing crate such as `rust_icu_uloc`)
and add the corresponding `[build-dependencies]` to the crate's `Cargo.toml`.

## Community Guidelines

This project follows [Google's Open Source Community
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,11 @@ macos-test:
&& PATH="$$ICU_PREFIX/bin:$$PATH" \
PKG_CONFIG_PATH="$$ICU_PREFIX/lib/pkgconfig:$$PKG_CONFIG_PATH" \
RUSTFLAGS="-L $$ICU_PREFIX/lib" \
cargo test --no-default-features --features=use-bindgen,icu_config,renaming,icu_version_64_plus,icu_version_67_plus,icu_version_68_plus \
cargo test \
&& PATH="$$ICU_PREFIX/bin:$$PATH" \
PKG_CONFIG_PATH="$$ICU_PREFIX/lib/pkgconfig:$$PKG_CONFIG_PATH" \
RUSTFLAGS="-L $$ICU_PREFIX/lib" \
cargo test --no-default-features --features=use-bindgen,icu_config,renaming,icu_version_64_plus,icu_version_67_plus,icu_version_68_plus,static
cargo test --features=static
.PHONY: macos-test

# Refreshes the static bindgen output (contents of ./rust_icu_sys/bindgen) based
Expand Down
4 changes: 4 additions & 0 deletions rust_icu_ecma402/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ icu_version_69_max = [
"rust_icu_ustring/icu_version_69_max",
]

[build-dependencies]
anyhow = "1.0"
rust_icu_release = { path = "../rust_icu_release", version = "5.6.0" }

[badges]
maintenance = { status = "actively-developed" }
is-it-maintained-issue-resolution = { repository = "google/rust_icu" }
Expand Down
31 changes: 31 additions & 0 deletions rust_icu_ecma402/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2025 Google LLC
//
// 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.

//! See LICENSE for licensing information.
//!
//! This build.rs script provides Cargo _features_ indicating the target ICU4C library version,
//! enabling some conditionally compiled Rust code in this crate that depends on the particular
//! ICU4C version.
//!
//! Please refer to README.md for instructions on how to build the library for your use.

#[cfg(feature = "icu_config")]
fn main() -> anyhow::Result<()> {
use rust_icu_release::run;
run()
}

/// No-op if icu_config is disabled.
#[cfg(not(feature = "icu_config"))]
fn main() {}
4 changes: 4 additions & 0 deletions rust_icu_ulistformatter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ icu_version_69_max = [
"rust_icu_ustring/icu_version_69_max",
]

[build-dependencies]
anyhow = "1.0"
rust_icu_release = { path = "../rust_icu_release", version = "5.6.0" }

[badges]
maintenance = { status = "actively-developed" }
is-it-maintained-issue-resolution = { repository = "google/rust_icu" }
Expand Down
31 changes: 31 additions & 0 deletions rust_icu_ulistformatter/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2025 Google LLC
//
// 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.

//! See LICENSE for licensing information.
//!
//! This build.rs script provides Cargo _features_ indicating the target ICU4C library version,
//! enabling some conditionally compiled Rust code in this crate that depends on the particular
//! ICU4C version.
//!
//! Please refer to README.md for instructions on how to build the library for your use.

#[cfg(feature = "icu_config")]
fn main() -> anyhow::Result<()> {
use rust_icu_release::run;
run()
}

/// No-op if icu_config is disabled.
#[cfg(not(feature = "icu_config"))]
fn main() {}
4 changes: 4 additions & 0 deletions rust_icu_unumberformatter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ icu_version_69_max = [
"rust_icu_ustring/icu_version_69_max",
]

[build-dependencies]
anyhow = "1.0"
rust_icu_release = { path = "../rust_icu_release", version = "5.6.0" }

[badges]
maintenance = { status = "actively-developed" }
is-it-maintained-issue-resolution = { repository = "google/rust_icu" }
Expand Down
31 changes: 31 additions & 0 deletions rust_icu_unumberformatter/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2025 Google LLC
//
// 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.

//! See LICENSE for licensing information.
//!
//! This build.rs script provides Cargo _features_ indicating the target ICU4C library version,
//! enabling some conditionally compiled Rust code in this crate that depends on the particular
//! ICU4C version.
//!
//! Please refer to README.md for instructions on how to build the library for your use.

#[cfg(feature = "icu_config")]
fn main() -> anyhow::Result<()> {
use rust_icu_release::run;
run()
}

/// No-op if icu_config is disabled.
#[cfg(not(feature = "icu_config"))]
fn main() {}
Loading