diff --git a/.cargo/config.toml b/.cargo/config.toml index 42bcf6d..f002391 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -11,3 +11,6 @@ rustflags = [ "-C", "link-arg=-undefined", "-C", "link-arg=dynamic_lookup", ] + +[env] +CACHE_DIR = { value = ".cache", relative = true } diff --git a/Cargo.lock b/Cargo.lock index 51078b9..8285061 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -568,6 +568,7 @@ name = "ngx" version = "0.5.0" dependencies = [ "nginx-sys", + "target-triple", ] [[package]] @@ -949,6 +950,12 @@ dependencies = [ "xattr", ] +[[package]] +name = "target-triple" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea67965c3f2666e59325eec14b6f0e296d27044051e65fc2a7d77ed3a3eff82d" + [[package]] name = "termcolor" version = "1.2.0" diff --git a/Cargo.toml b/Cargo.toml index b14b786..f013af7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,3 +23,6 @@ nginx-sys = { path = "nginx-sys", version = "0.5.0"} [badges] maintenance = { status = "experimental" } + +[dev-dependencies] +target-triple = "0.1.2" diff --git a/README.md b/README.md index c84872a..d74aebd 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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 diff --git a/nginx-sys/build.rs b/nginx-sys/build.rs index 77542df..12847c2 100644 --- a/nginx-sys/build.rs +++ b/nginx-sys/build.rs @@ -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", @@ -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. @@ -129,7 +132,7 @@ fn main() -> Result<(), Box> { } 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 { @@ -269,20 +272,17 @@ fn gpg_path() -> Option { } /// 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 @@ -378,12 +378,12 @@ fn make_cache_dir() -> Result> { 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)?; } @@ -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, Box> { +fn extract_all_archives(cache_dir: &Path, target: &str) -> Result, Box> { 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)?; } @@ -548,7 +548,7 @@ fn extract_all_archives(cache_dir: &Path) -> Result, 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> { +fn compile_nginx(cache_dir: &Path) -> Result<(PathBuf, PathBuf), Box> { fn find_dependency_path<'a>(sources: &'a [(String, PathBuf)], name: &str) -> Result<&'a PathBuf, String> { sources .iter() @@ -556,9 +556,14 @@ fn compile_nginx() -> Result<(PathBuf, PathBuf), Box> { .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"))?; diff --git a/tests/build.rs b/tests/build.rs new file mode 100644 index 0000000..db200c9 --- /dev/null +++ b/tests/build.rs @@ -0,0 +1,3 @@ +fn main() { + println!("cargo:rustc-env=TARGET={}", std::env::var("TARGET").unwrap()); +} diff --git a/tests/log_test.rs b/tests/log_test.rs index 27f93b2..1ad05bc 100644 --- a/tests/log_test.rs +++ b/tests/log_test.rs @@ -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 }