diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0608aba..f66a350 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -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 diff --git a/Makefile b/Makefile index a9df912..50ef78c 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/rust_icu_ecma402/Cargo.toml b/rust_icu_ecma402/Cargo.toml index 64f8344..74d1a60 100644 --- a/rust_icu_ecma402/Cargo.toml +++ b/rust_icu_ecma402/Cargo.toml @@ -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" } diff --git a/rust_icu_ecma402/build.rs b/rust_icu_ecma402/build.rs new file mode 100644 index 0000000..17295bd --- /dev/null +++ b/rust_icu_ecma402/build.rs @@ -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() {} diff --git a/rust_icu_ulistformatter/Cargo.toml b/rust_icu_ulistformatter/Cargo.toml index 214e84f..81f841e 100644 --- a/rust_icu_ulistformatter/Cargo.toml +++ b/rust_icu_ulistformatter/Cargo.toml @@ -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" } diff --git a/rust_icu_ulistformatter/build.rs b/rust_icu_ulistformatter/build.rs new file mode 100644 index 0000000..17295bd --- /dev/null +++ b/rust_icu_ulistformatter/build.rs @@ -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() {} diff --git a/rust_icu_unumberformatter/Cargo.toml b/rust_icu_unumberformatter/Cargo.toml index 1ec150c..0f2e0b5 100644 --- a/rust_icu_unumberformatter/Cargo.toml +++ b/rust_icu_unumberformatter/Cargo.toml @@ -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" } diff --git a/rust_icu_unumberformatter/build.rs b/rust_icu_unumberformatter/build.rs new file mode 100644 index 0000000..17295bd --- /dev/null +++ b/rust_icu_unumberformatter/build.rs @@ -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() {}