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

feat: conditional compilation support #97

Merged
merged 4 commits into from
Nov 22, 2024
Merged
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
14 changes: 0 additions & 14 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,16 +1,2 @@
#
# https://stackoverflow.com/questions/28124221/error-linking-with-cc-failed-exit-code-1
#
[target.aarch64-apple-darwin]
rustflags = [
"-C", "link-arg=-undefined",
"-C", "link-arg=dynamic_lookup",
]
[target.x86_64-apple-darwin]
rustflags = [
"-C", "link-arg=-undefined",
"-C", "link-arg=dynamic_lookup",
]

[env]
CACHE_DIR = { value = ".cache", relative = true }
19 changes: 11 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

53 changes: 53 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/// Example buildscript for an nginx module.
///
/// Due to the limitations of cargo[1], this buildscript _requires_ adding `nginx-sys` to the
/// direct dependencies of your crate.
///
/// [1]: https://github.com/rust-lang/cargo/issues/3544
fn main() {
// Generate `ngx_os` and `ngx_feature` cfg values

// Specify acceptable values for `ngx_feature`
println!("cargo::rerun-if-env-changed=DEP_NGINX_FEATURES_CHECK");
println!(
"cargo::rustc-check-cfg=cfg(ngx_feature, values({}))",
std::env::var("DEP_NGINX_FEATURES_CHECK").unwrap_or("any()".to_string())
);
// Read feature flags detected by nginx-sys and pass to the compiler.
println!("cargo::rerun-if-env-changed=DEP_NGINX_FEATURES");
if let Ok(features) = std::env::var("DEP_NGINX_FEATURES") {
for feature in features.split(',').map(str::trim) {
println!("cargo::rustc-cfg=ngx_feature=\"{}\"", feature);
}
}

// Specify acceptable values for `ngx_os`
println!("cargo::rerun-if-env-changed=DEP_NGINX_OS_CHECK");
println!(
"cargo::rustc-check-cfg=cfg(ngx_os, values({}))",
std::env::var("DEP_NGINX_OS_CHECK").unwrap_or("any()".to_string())
);
// Read operating system detected by nginx-sys and pass to the compiler.
println!("cargo::rerun-if-env-changed=DEP_NGINX_OS");
if let Ok(os) = std::env::var("DEP_NGINX_OS") {
println!("cargo::rustc-cfg=ngx_os=\"{}\"", os);
}

// Generate cfg values for version checks
// println!("cargo::rustc-check-cfg=cfg(nginx1_27_0)");
// println!("cargo::rerun-if-env-changed=DEP_NGINX_VERSION_NUMBER");
// if let Ok(version) = std::env::var("DEP_NGINX_VERSION_NUMBER") {
// let version: u64 = version.parse().unwrap();
//
// if version >= 1_027_000 {
// println!("cargo::rustc-cfg=nginx1_27_0");
// }
// }

// Generate required compiler flags
if cfg!(target_os = "macos") {
// https://stackoverflow.com/questions/28124221/error-linking-with-cc-failed-exit-code-1
println!("cargo::rustc-link-arg=-undefined");
println!("cargo::rustc-link-arg=dynamic_lookup");
}
}
9 changes: 6 additions & 3 deletions examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@ homepage.workspace = true
repository.workspace = true
rust-version.workspace = true

[dev-dependencies]
build = "../build.rs"

[dependencies]
nginx-sys = { path = "../nginx-sys/", default-features = false }
ngx = { path = "../", default-features = false }

[dev-dependencies]
aws-sign-v4 = "0.3.0"
chrono = "0.4.23"
http = "1.1.0"
Expand Down Expand Up @@ -42,8 +47,6 @@ name = "async"
path = "async.rs"
crate-type = ["cdylib"]

[dependencies]

[features]
default = ["export-modules", "ngx/vendored"]
# Generate `ngx_modules` table with module exports
Expand Down
5 changes: 5 additions & 0 deletions nginx-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ categories = ["external-ffi-bindings"]
description = "FFI bindings to NGINX"
keywords = ["nginx", "ffi", "sys"]
build = "build/main.rs"
# This field is required to export DEP_NGINX_ vars
# See https://github.com/rust-lang/cargo/issues/3544
links = "nginx"
edition.workspace = true
license.workspace = true
homepage.workspace = true
Expand All @@ -15,8 +18,10 @@ rust-version.workspace = true

[build-dependencies]
bindgen = "0.70.1"
cc = "1.2.0"
duct = { version = "0.13.7", optional = true }
flate2 = { version = "1.0.28", optional = true }
regex = "1.11.1"
tar = { version = "0.4.40", optional = true }
ureq = { version = "2.9.6", features = ["tls"], optional = true }
which = { version = "6.0.0", optional = true }
Expand Down
129 changes: 129 additions & 0 deletions nginx-sys/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# nginx-sys

The `nginx-sys` crate provides low-level bindings for the nginx C API, allowing
Rust applications to interact with nginx servers and modules.

## Usage

Add `nginx-sys` as a dependency in your `Cargo.toml`:

```toml
[dependencies]
nginx-sys = "0.5.0"
```

## Features

- `vendored`: Enables the build scripts to download and build a copy of nginx
source and link against it.
This feature is enabled by default.

## Output variables

Following metadata variables are passed to the build scripts of any **direct**
dependents of the package.

Check the [using another sys crate] and the [links manifest key] sections of the
Cargo Book for more details about passing metadata between packages.

### `DEP_NGINX_FEATURES`

nginx has various configuration options that may affect the availability of
functions, constants and structure fields. This is not something that can be
detected at runtime, as an attempt to use a symbol unavailable in the bindings
would result in compilation error.

`DEP_NGINX_FEATURES_CHECK` contains the full list of feature flags supported
by `nginx-sys`, i.e. everything that can be used for feature checks.
The most common use for this variable is to specify [`cargo::rustc-check-cfg`].

`DEP_NGINX_FEATURES` contains the list of features enabled in the version of
nginx being built against.

An example of a build script with these variables:
```rust
// Specify acceptable values for `ngx_feature`.
println!("cargo::rerun-if-env-changed=DEP_NGINX_FEATURES_CHECK");
println!(
"cargo::rustc-check-cfg=cfg(ngx_feature, values({}))",
std::env::var("DEP_NGINX_FEATURES_CHECK").unwrap_or("any()".to_string())
);
// Read feature flags detected by nginx-sys and pass to the compiler.
println!("cargo::rerun-if-env-changed=DEP_NGINX_FEATURES");
if let Ok(features) = std::env::var("DEP_NGINX_FEATURES") {
for feature in features.split(',').map(str::trim) {
println!("cargo::rustc-cfg=ngx_feature=\"{}\"", feature);
}
}
```

And an usage example:
```rust
#[cfg(ngx_feature = "debug")]
println!("this nginx binary was built with debug logging enabled");
```

### `DEP_NGINX_OS`

Version, as detected by the nginx configuration script.

`DEP_NGINX_OS_CHECK` contains the full list of supported values, and
`DEP_NGINX_OS` the currently detected one.

Usage examples:
```rust
// Specify acceptable values for `ngx_os`
println!("cargo::rerun-if-env-changed=DEP_NGINX_OS_CHECK");
println!(
"cargo::rustc-check-cfg=cfg(ngx_os, values({}))",
std::env::var("DEP_NGINX_OS_CHECK").unwrap_or("any()".to_string())
);
// Read operating system detected by nginx-sys and pass to the compiler.
println!("cargo::rerun-if-env-changed=DEP_NGINX_OS");
if let Ok(os) = std::env::var("DEP_NGINX_OS") {
println!("cargo::rustc-cfg=ngx_os=\"{}\"", os);
}
```

```rust
#[cfg(ngx_os = "freebsd")]
println!("this nginx binary was built on FreeBSD");
```

### Version and build information

- `DEP_NGINX_VERSION_NUMBER`:
a numeric representation with 3 digits for each component: `1026002`
- `DEP_NGINX_VERSION`:
human-readable string in a product/version format: `nginx/1.26.2`
- `DEP_NGINX_BUILD`:
version string with the optional build name (`--build=`) included:
`nginx/1.25.5 (nginx-plus-r32)`

Usage example:
```rust
println!("cargo::rustc-check-cfg=cfg(nginx1_27_0)");
println!("cargo::rerun-if-env-changed=DEP_NGINX_VERSION_NUMBER");
if let Ok(version) = std::env::var("DEP_NGINX_VERSION_NUMBER") {
let version: u64 = version.parse().unwrap();

if version >= 1_027_000 {
println!("cargo::rustc-cfg=nginx1_27_0");
}
}
```

## Examples

### Get nginx Version

This example demonstrates how to retrieve the version of the nginx server.

```rust,no_run
use nginx_sys::nginx_version;

println!("nginx version: {}", nginx_version);
```
[using another sys crate]: https://doc.rust-lang.org/nightly/cargo/reference/build-script-examples.html#using-another-sys-crate
[links manifest key]: https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#the-links-manifest-key
[`cargo::rustc-check-cfg`]: https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#rustc-check-cfg
Loading
Loading