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: modify cache & NGINX dir #72

Merged
merged 8 commits into from
Apr 3, 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
3 changes: 3 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ rustflags = [
"-C", "link-arg=-undefined",
"-C", "link-arg=dynamic_lookup",
]

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

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

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ nginx-sys = { path = "nginx-sys", version = "0.5.0"}

[badges]
maintenance = { status = "experimental" }

[dev-dependencies]
target-triple = "0.1.2"
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ In short, this SDK allows writing NGINX modules using the Rust language.

NGINX modules can be built against a particular version of NGINX. The following environment variables can be used to specify a particular version of NGINX or an NGINX dependency:

* `ZLIB_VERSION` (default 1.3.1) -
* `PCRE2_VERSION` (default 10.42 for NGINX 1.22.0 and later, or 8.45 for earlier)
* `OPENSSL_VERSION` (default 3.2.1 for NGINX 1.22.0 and later, or 1.1.1w for earlier)
* `ZLIB_VERSION` (default 1.3.1) - zlib version
* `PCRE2_VERSION` (default 10.42 for NGINX 1.22.0 and later, or 8.45 for earlier) - PCRE1 or PCRE2 version
* `OPENSSL_VERSION` (default 3.2.1 for NGINX 1.22.0 and later, or 1.1.1w for earlier) - OpenSSL version
* `NGX_VERSION` (default 1.24.0) - NGINX OSS version
* `NGX_DEBUG` (default to false)- if set to true, then will compile NGINX `--with-debug` option

Expand All @@ -38,9 +38,15 @@ cargo build --package=examples --examples --features=linux --release
After compilation, the modules can be found in the path `target/release/examples/` ( with the `.so` file extension for
Linux or `.dylib` for MacOS).

Additionally, the folder `.cache/nginx/{NGX_VERSION}/{OS}/` will contain the compiled version of NGINX used to build
Additionally, the folder `.cache/nginx/{NGX_VERSION}/{TARGET}` (`{TARGET}` means rustc's target triple string) will contain the compiled version of NGINX used to build
the SDK. You can start NGINX directly from this directory if you want to test the module.

The following environment variables can be used to change locations of cache directory and NGINX directory:

* `CACHE_DIR` (default `[nginx-sys's root directory]/.cache`) - the directory containing cache files, means PGP keys, tarballs, PGP signatures, and unpacked source codes. It also contains compiled NGINX in default configuration.
* `NGINX_INSTALL_ROOT_DIR` (default `{CACHE_DIR}/nginx`) - the directory containing the series of compiled NGINX in its subdirectories
* `NGINX_INSTALL_DIR` (default `{NGINX_INSTALL_BASE_DIR}/{NGX_VERSION}/{TARGET}`) - the directory containing the NGINX compiled in the build

### Mac OS dependencies

In order to use the optional GNU make build process on MacOS, you will need to install additional tools. This can be
Expand Down
51 changes: 28 additions & 23 deletions nginx-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ const NGX_LINUX_ADDITIONAL_OPTS: [&str; 3] = [
"--with-cc-opt=-g -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC",
"--with-ld-opt=-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie",
];
const ENV_VARS_TRIGGERING_RECOMPILE: [&str; 9] = [
const ENV_VARS_TRIGGERING_RECOMPILE: [&str; 12] = [
"DEBUG",
"OUT_DIR",
"ZLIB_VERSION",
Expand All @@ -109,6 +109,9 @@ const ENV_VARS_TRIGGERING_RECOMPILE: [&str; 9] = [
"CARGO_CFG_TARGET_OS",
"CARGO_MANIFEST_DIR",
"CARGO_TARGET_TMPDIR",
"CACHE_DIR",
"NGX_INSTALL_ROOT_DIR",
"NGX_INSTALL_DIR",
];

/// Function invoked when `cargo build` is executed.
Expand All @@ -129,7 +132,7 @@ fn main() -> Result<(), Box<dyn StdError>> {
}
println!("Verified GPG permissions");
// Configure and Compile NGINX
let (_nginx_install_dir, nginx_src_dir) = compile_nginx()?;
let (_nginx_install_dir, nginx_src_dir) = compile_nginx(&cache_dir)?;
// Hint cargo to rebuild if any of the these environment variables values change
// because they will trigger a recompilation of NGINX with different parameters
for var in ENV_VARS_TRIGGERING_RECOMPILE {
Expand Down Expand Up @@ -269,20 +272,17 @@ fn gpg_path() -> Option<PathBuf> {
}

/// Returns the base path to extract tarball contents into
fn source_output_dir(cache_dir: &Path) -> PathBuf {
env::var("CARGO_TARGET_TMPDIR").map(PathBuf::from).unwrap_or_else(|_| {
cache_dir
.join("src")
.join(format!("{}-{}", env::consts::OS, env::consts::ARCH))
})
fn source_output_dir(cache_dir: &Path, target: &str) -> PathBuf {
env::var("CARGO_TARGET_TMPDIR")
.map(PathBuf::from)
.unwrap_or_else(|_| cache_dir.join("src").join(target))
}

#[allow(clippy::ptr_arg)]
/// Returns the path to install NGINX to
fn nginx_install_dir(base_dir: &PathBuf) -> PathBuf {
fn nginx_install_dir(base_dir: &Path, target: &str) -> PathBuf {
let nginx_version = env::var("NGX_VERSION").unwrap_or_else(|_| NGX_DEFAULT_VERSION.to_string());
let platform = format!("{}-{}", env::consts::OS, env::consts::ARCH);
base_dir.join("nginx").join(nginx_version).join(platform)
base_dir.join(nginx_version).join(target)
}

/// Ensure the correct permissions are applied to the local gnupg directory
Expand Down Expand Up @@ -378,12 +378,12 @@ fn make_cache_dir() -> Result<PathBuf, Box<dyn StdError>> {
let base_dir = env::var("CARGO_MANIFEST_DIR")
.map(PathBuf::from)
.unwrap_or_else(|_| env::current_dir().expect("Failed to get current directory"));
// Choose the parent directory of the manifest directory (nginx-sys) as the cache directory
// Fail if we do not have a parent directory
let cache_dir = base_dir
.parent()
.expect("Failed to find parent directory of manifest directory")
.join(".cache");
// Choose `.cache` relative to the manifest directory (nginx-sys) as the default cache directory
// Environment variable `CACHE_DIR` overrides this
// Recommendation: set env "CACHE_DIR = { value = ".cache", relative = true }" in `.cargo/config.toml` in your project
let cache_dir = env::var("CACHE_DIR")
.map(PathBuf::from)
.unwrap_or(base_dir.join(".cache"));
if !cache_dir.exists() {
fs::create_dir_all(&cache_dir)?;
}
Expand Down Expand Up @@ -530,10 +530,10 @@ fn extract_archive(
}

/// Extract all of the tarballs into subdirectories within the source base directory.
fn extract_all_archives(cache_dir: &Path) -> Result<Vec<(String, PathBuf)>, Box<dyn StdError>> {
fn extract_all_archives(cache_dir: &Path, target: &str) -> Result<Vec<(String, PathBuf)>, Box<dyn StdError>> {
let archives = all_archives();
let mut sources = Vec::new();
let extract_output_base_dir = source_output_dir(cache_dir);
let extract_output_base_dir = source_output_dir(cache_dir, target);
if !extract_output_base_dir.exists() {
fs::create_dir_all(&extract_output_base_dir)?;
}
Expand All @@ -548,17 +548,22 @@ fn extract_all_archives(cache_dir: &Path) -> Result<Vec<(String, PathBuf)>, Box<

/// Invoke external processes to run autoconf `configure` to generate a makefile for NGINX and
/// then run `make install`.
fn compile_nginx() -> Result<(PathBuf, PathBuf), Box<dyn StdError>> {
fn compile_nginx(cache_dir: &Path) -> Result<(PathBuf, PathBuf), Box<dyn StdError>> {
fn find_dependency_path<'a>(sources: &'a [(String, PathBuf)], name: &str) -> Result<&'a PathBuf, String> {
sources
.iter()
.find(|(n, _)| n == name)
.map(|(_, p)| p)
.ok_or(format!("Unable to find dependency [{name}] path"))
}
let cache_dir = make_cache_dir()?;
let nginx_install_dir = nginx_install_dir(&cache_dir);
let sources = extract_all_archives(&cache_dir)?;
let target = env::var("TARGET")?;
let nginx_install_base_dir = env::var("NGX_INSTALL_ROOT_DIR")
.map(PathBuf::from)
.unwrap_or(cache_dir.join("nginx"));
let nginx_install_dir = env::var("NGX_INSTALL_DIR")
.map(PathBuf::from)
.unwrap_or(nginx_install_dir(&nginx_install_base_dir, &target));
let sources = extract_all_archives(cache_dir, &target)?;
let zlib_src_dir = find_dependency_path(&sources, "zlib")?;
let openssl_src_dir = find_dependency_path(&sources, "openssl")?;
let pcre2_src_dir = find_dependency_path(&sources, "pcre2").or(find_dependency_path(&sources, "pcre"))?;
Expand Down
3 changes: 3 additions & 0 deletions tests/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
println!("cargo:rustc-env=TARGET={}", std::env::var("TARGET").unwrap());
}
4 changes: 2 additions & 2 deletions tests/log_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ impl Default for Nginx {
/// create nginx with default
fn default() -> Nginx {
let path = env::current_dir().unwrap();
let version = env::var("NGX_VERSION").unwrap_or_else(|_| NGX_DEFAULT_VERSION.to_string());
let platform = format!("{}-{}", env::consts::OS, env::consts::ARCH);
let version = env::var("NGX_VERSION").unwrap_or(NGX_DEFAULT_VERSION.into());
let platform = target_triple::TARGET;
let ngx_path = format!(".cache/nginx/{}/{}", version, platform);
let install_path = format!("{}/{}", path.display(), ngx_path);
Nginx { install_path }
Expand Down
Loading