Add command line option for custom cache directory
This commit is contained in:
@@ -63,7 +63,7 @@ The translation is dependent on the environment chosen.
|
|||||||
The default is a dummy environment that produces placeholder values.
|
The default is a dummy environment that produces placeholder values.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
wasm2obj [--target TARGET] [-cdg] [--enable-simd] <file> -o <output>
|
wasm2obj [--target TARGET] [-dg] [--cache | --cache-dir=<cache_dir>] [--enable-simd] <file> -o <output>
|
||||||
wasm2obj --help | --version
|
wasm2obj --help | --version
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
@@ -71,7 +71,9 @@ Options:
|
|||||||
-h, --help print this help message
|
-h, --help print this help message
|
||||||
--target <TARGET> build for the target triple; default is the host machine
|
--target <TARGET> build for the target triple; default is the host machine
|
||||||
-g generate debug information
|
-g generate debug information
|
||||||
-c, --cache enable caching system
|
-c, --cache enable caching system, use default cache directory
|
||||||
|
--cache-dir=<cache_dir>
|
||||||
|
enable caching system, use specified cache directory
|
||||||
--enable-simd enable proposed SIMD instructions
|
--enable-simd enable proposed SIMD instructions
|
||||||
--version print the Cranelift version
|
--version print the Cranelift version
|
||||||
-d, --debug enable debug output on stderr/stdout
|
-d, --debug enable debug output on stderr/stdout
|
||||||
@@ -85,6 +87,7 @@ struct Args {
|
|||||||
flag_g: bool,
|
flag_g: bool,
|
||||||
flag_debug: bool,
|
flag_debug: bool,
|
||||||
flag_cache: bool,
|
flag_cache: bool,
|
||||||
|
flag_cache_dir: Option<String>,
|
||||||
flag_enable_simd: bool,
|
flag_enable_simd: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,7 +114,10 @@ fn main() {
|
|||||||
wasmtime::init_file_per_thread_logger("wasm2obj.dbg.");
|
wasmtime::init_file_per_thread_logger("wasm2obj.dbg.");
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_conf::init(args.flag_cache);
|
cache_conf::init(
|
||||||
|
args.flag_cache || args.flag_cache_dir.is_some(),
|
||||||
|
args.flag_cache_dir.as_ref(),
|
||||||
|
);
|
||||||
|
|
||||||
let path = Path::new(&args.arg_file);
|
let path = Path::new(&args.arg_file);
|
||||||
match handle_module(
|
match handle_module(
|
||||||
|
|||||||
@@ -61,14 +61,16 @@ including calling the start function if one is present. Additional functions
|
|||||||
given with --invoke are then called.
|
given with --invoke are then called.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
wasmtime [-ocdg] [--enable-simd] [--wasi-c] [--preload=<wasm>...] [--env=<env>...] [--dir=<dir>...] [--mapdir=<mapping>...] <file> [<arg>...]
|
wasmtime [-odg] [--enable-simd] [--wasi-c] [--cache | --cache-dir=<cache_dir>] [--preload=<wasm>...] [--env=<env>...] [--dir=<dir>...] [--mapdir=<mapping>...] <file> [<arg>...]
|
||||||
wasmtime [-ocdg] [--enable-simd] [--wasi-c] [--preload=<wasm>...] [--env=<env>...] [--dir=<dir>...] [--mapdir=<mapping>...] --invoke=<fn> <file> [<arg>...]
|
wasmtime [-odg] [--enable-simd] [--wasi-c] [--cache | --cache-dir=<cache_dir>] [--preload=<wasm>...] [--env=<env>...] [--dir=<dir>...] [--mapdir=<mapping>...] --invoke=<fn> <file> [<arg>...]
|
||||||
wasmtime --help | --version
|
wasmtime --help | --version
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
--invoke=<fn> name of function to run
|
--invoke=<fn> name of function to run
|
||||||
-o, --optimize runs optimization passes on the translated functions
|
-o, --optimize runs optimization passes on the translated functions
|
||||||
-c, --cache enable caching system
|
-c, --cache enable caching system, use default cache directory
|
||||||
|
--cache-dir=<cache_dir>
|
||||||
|
enable caching system, use specified cache directory
|
||||||
-g generate debug information
|
-g generate debug information
|
||||||
-d, --debug enable debug output on stderr/stdout
|
-d, --debug enable debug output on stderr/stdout
|
||||||
--enable-simd enable proposed SIMD instructions
|
--enable-simd enable proposed SIMD instructions
|
||||||
@@ -88,6 +90,7 @@ struct Args {
|
|||||||
arg_arg: Vec<String>,
|
arg_arg: Vec<String>,
|
||||||
flag_optimize: bool,
|
flag_optimize: bool,
|
||||||
flag_cache: bool,
|
flag_cache: bool,
|
||||||
|
flag_cache_dir: Option<String>,
|
||||||
flag_debug: bool,
|
flag_debug: bool,
|
||||||
flag_g: bool,
|
flag_g: bool,
|
||||||
flag_enable_simd: bool,
|
flag_enable_simd: bool,
|
||||||
@@ -211,7 +214,10 @@ fn rmain() -> Result<(), Error> {
|
|||||||
wasmtime::init_file_per_thread_logger("wasmtime.dbg.");
|
wasmtime::init_file_per_thread_logger("wasmtime.dbg.");
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_conf::init(args.flag_cache);
|
cache_conf::init(
|
||||||
|
args.flag_cache || args.flag_cache_dir.is_some(),
|
||||||
|
args.flag_cache_dir.as_ref(),
|
||||||
|
);
|
||||||
|
|
||||||
let isa_builder = cranelift_native::builder()
|
let isa_builder = cranelift_native::builder()
|
||||||
.map_err(|s| format_err!("host machine is not a supported target: {}", s))?;
|
.map_err(|s| format_err!("host machine is not a supported target: {}", s))?;
|
||||||
|
|||||||
@@ -41,14 +41,16 @@ const USAGE: &str = "
|
|||||||
Wast test runner.
|
Wast test runner.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
run_wast [-cdo] [--enable-simd] <file>...
|
run_wast [-do] [--enable-simd] [--cache | --cache-dir=<cache_dir>] <file>...
|
||||||
run_wast --help | --version
|
run_wast --help | --version
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
-h, --help print this help message
|
-h, --help print this help message
|
||||||
--version print the Cranelift version
|
--version print the Cranelift version
|
||||||
-o, --optimize runs optimization passes on the translated functions
|
-o, --optimize runs optimization passes on the translated functions
|
||||||
-c, --cache enable caching system
|
-c, --cache enable caching system, use default cache directory
|
||||||
|
--cache-dir=<cache_dir>
|
||||||
|
enable caching system, use specified cache directory
|
||||||
-d, --debug enable debug output on stderr/stdout
|
-d, --debug enable debug output on stderr/stdout
|
||||||
--enable-simd enable proposed SIMD instructions
|
--enable-simd enable proposed SIMD instructions
|
||||||
";
|
";
|
||||||
@@ -60,6 +62,7 @@ struct Args {
|
|||||||
flag_function: Option<String>,
|
flag_function: Option<String>,
|
||||||
flag_optimize: bool,
|
flag_optimize: bool,
|
||||||
flag_cache: bool,
|
flag_cache: bool,
|
||||||
|
flag_cache_dir: Option<String>,
|
||||||
flag_enable_simd: bool,
|
flag_enable_simd: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +82,10 @@ fn main() {
|
|||||||
wasmtime::init_file_per_thread_logger("cranelift.dbg.");
|
wasmtime::init_file_per_thread_logger("cranelift.dbg.");
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_conf::init(args.flag_cache);
|
cache_conf::init(
|
||||||
|
args.flag_cache || args.flag_cache_dir.is_some(),
|
||||||
|
args.flag_cache_dir.as_ref(),
|
||||||
|
);
|
||||||
|
|
||||||
let isa_builder = cranelift_native::builder().unwrap_or_else(|_| {
|
let isa_builder = cranelift_native::builder().unwrap_or_else(|_| {
|
||||||
panic!("host machine is not a supported target");
|
panic!("host machine is not a supported target");
|
||||||
|
|||||||
@@ -6,13 +6,11 @@ use core::hash::Hasher;
|
|||||||
use cranelift_codegen::{ir, isa};
|
use cranelift_codegen::{ir, isa};
|
||||||
use cranelift_entity::PrimaryMap;
|
use cranelift_entity::PrimaryMap;
|
||||||
use cranelift_wasm::DefinedFuncIndex;
|
use cranelift_wasm::DefinedFuncIndex;
|
||||||
use directories::ProjectDirs;
|
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use log::{debug, warn};
|
use log::{debug, warn};
|
||||||
use serde::de::{self, Deserialize, Deserializer, MapAccess, SeqAccess, Visitor};
|
use serde::de::{self, Deserialize, Deserializer, MapAccess, SeqAccess, Visitor};
|
||||||
use serde::ser::{self, Serialize, SerializeSeq, SerializeStruct, Serializer};
|
use serde::ser::{self, Serialize, SerializeSeq, SerializeStruct, Serializer};
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
use std::ffi::OsString;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io;
|
use std::io;
|
||||||
@@ -21,52 +19,116 @@ use std::string::{String, ToString};
|
|||||||
|
|
||||||
/// Module for configuring the cache system.
|
/// Module for configuring the cache system.
|
||||||
pub mod conf {
|
pub mod conf {
|
||||||
|
use directories::ProjectDirs;
|
||||||
|
use log::{debug, warn};
|
||||||
use spin::Once;
|
use spin::Once;
|
||||||
|
use std::fs;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
|
struct Config {
|
||||||
|
pub cache_enabled: bool,
|
||||||
|
pub cache_dir: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
// Private static, so only internal function can access it.
|
// Private static, so only internal function can access it.
|
||||||
static CACHE_ENABLED: Once<bool> = Once::new();
|
static CONFIG: Once<Config> = Once::new();
|
||||||
|
static INIT_CALLED: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
/// Returns true if and only if the cache is enabled.
|
/// Returns true if and only if the cache is enabled.
|
||||||
pub fn cache_enabled() -> bool {
|
pub fn cache_enabled() -> bool {
|
||||||
// Not everyone knows about the cache system, i.e. the tests,
|
// Not everyone knows about the cache system, i.e. the tests,
|
||||||
// so the default is false.
|
// so the default is cache disabled.
|
||||||
*CACHE_ENABLED.call_once(|| false)
|
CONFIG
|
||||||
|
.call_once(|| Config::new_cache_disabled())
|
||||||
|
.cache_enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns path to the cache directory.
|
||||||
|
///
|
||||||
|
/// Panics if the cache is disabled.
|
||||||
|
pub fn cache_directory() -> &'static PathBuf {
|
||||||
|
&CONFIG
|
||||||
|
.r#try()
|
||||||
|
.expect("Cache system must be initialized")
|
||||||
|
.cache_dir
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initializes the cache system. Should be called exactly once,
|
/// Initializes the cache system. Should be called exactly once,
|
||||||
/// and before using the cache system. Otherwise it can panic.
|
/// and before using the cache system. Otherwise it can panic.
|
||||||
pub fn init(enabled: bool) {
|
pub fn init<P: AsRef<Path>>(enabled: bool, dir: Option<P>) {
|
||||||
// init() should be called exactly once
|
INIT_CALLED
|
||||||
assert!(CACHE_ENABLED.r#try().is_none());
|
.compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
|
||||||
let val = *CACHE_ENABLED.call_once(|| enabled);
|
.expect("Cache system init must be called at most once");
|
||||||
// But multiple threads can pass the first assertion, so let's guarantee consistency:
|
assert!(
|
||||||
assert!(val == enabled);
|
CONFIG.r#try().is_none(),
|
||||||
|
"Cache system init must be called before using the system."
|
||||||
|
);
|
||||||
|
let conf = CONFIG.call_once(|| Config::new(enabled, dir));
|
||||||
|
debug!(
|
||||||
|
"Cache init(): enabled={}, cache-dir={:?}",
|
||||||
|
conf.cache_enabled, conf.cache_dir
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Config {
|
||||||
|
pub fn new_cache_disabled() -> Self {
|
||||||
|
Self {
|
||||||
|
cache_enabled: false,
|
||||||
|
cache_dir: PathBuf::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new<P: AsRef<Path>>(enabled: bool, dir: Option<P>) -> Self {
|
||||||
|
if enabled {
|
||||||
|
match dir {
|
||||||
|
Some(dir) => Self::new_step2(dir.as_ref()),
|
||||||
|
None => match ProjectDirs::from("", "CraneStation", "wasmtime") {
|
||||||
|
Some(proj_dirs) => Self::new_step2(proj_dirs.cache_dir()),
|
||||||
|
None => {
|
||||||
|
warn!("Cache directory not specified and failed to find the default. Disabling cache.");
|
||||||
|
Self::new_cache_disabled()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Self::new_cache_disabled()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_step2(dir: &Path) -> Self {
|
||||||
|
// On Windows, if we want long paths, we need '\\?\' prefix, but it doesn't work
|
||||||
|
// with relative paths. One way to get absolute path (the only one?) is to use
|
||||||
|
// fs::canonicalize, but it requires that given path exists. The extra advantage
|
||||||
|
// of this method is fact that the method prepends '\\?\' on Windows.
|
||||||
|
match fs::create_dir_all(dir) {
|
||||||
|
Ok(()) => match fs::canonicalize(dir) {
|
||||||
|
Ok(p) => Self {
|
||||||
|
cache_enabled: true,
|
||||||
|
cache_dir: p,
|
||||||
|
},
|
||||||
|
Err(err) => {
|
||||||
|
warn!(
|
||||||
|
"Failed to canonicalize the cache directory. Disabling cache. \
|
||||||
|
Message: {}",
|
||||||
|
err
|
||||||
|
);
|
||||||
|
Self::new_cache_disabled()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(err) => {
|
||||||
|
warn!(
|
||||||
|
"Failed to create the cache directory. Disabling cache. Message: {}",
|
||||||
|
err
|
||||||
|
);
|
||||||
|
Self::new_cache_disabled()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref CACHE_DIR: Option<PathBuf> =
|
|
||||||
match ProjectDirs::from("", "CraneStation", "wasmtime") {
|
|
||||||
Some(proj_dirs) => {
|
|
||||||
let cache_dir = proj_dirs.cache_dir();
|
|
||||||
// Temporary workaround for: https://github.com/rust-lang/rust/issues/32689
|
|
||||||
if cfg!(windows) {
|
|
||||||
let mut long_path = OsString::new();
|
|
||||||
if !cache_dir.starts_with("\\\\?\\") {
|
|
||||||
long_path.push("\\\\?\\");
|
|
||||||
}
|
|
||||||
long_path.push(cache_dir.as_os_str());
|
|
||||||
Some(PathBuf::from(long_path))
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Some(cache_dir.to_path_buf())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
warn!("Failed to find proper cache directory location.");
|
|
||||||
None
|
|
||||||
}
|
|
||||||
};
|
|
||||||
static ref SELF_MTIME: String = {
|
static ref SELF_MTIME: String = {
|
||||||
match std::env::current_exe() {
|
match std::env::current_exe() {
|
||||||
Ok(path) => match fs::metadata(&path) {
|
Ok(path) => match fs::metadata(&path) {
|
||||||
@@ -125,28 +187,32 @@ impl ModuleCacheEntry {
|
|||||||
generate_debug_info: bool,
|
generate_debug_info: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mod_cache_path = if conf::cache_enabled() {
|
let mod_cache_path = if conf::cache_enabled() {
|
||||||
CACHE_DIR.clone().map(|p| {
|
let hash = Sha256Hasher::digest(module, function_body_inputs);
|
||||||
let hash = Sha256Hasher::digest(module, function_body_inputs);
|
let compiler_dir = if cfg!(debug_assertions) {
|
||||||
let compiler_dir = if cfg!(debug_assertions) {
|
format!(
|
||||||
format!(
|
"{comp_name}-{comp_ver}-{comp_mtime}",
|
||||||
"{comp_name}-{comp_ver}-{comp_mtime}",
|
comp_name = compiler_name,
|
||||||
comp_name = compiler_name,
|
comp_ver = env!("GIT_REV"),
|
||||||
comp_ver = env!("GIT_REV"),
|
comp_mtime = *SELF_MTIME,
|
||||||
comp_mtime = *SELF_MTIME,
|
)
|
||||||
)
|
} else {
|
||||||
} else {
|
format!(
|
||||||
format!(
|
"{comp_name}-{comp_ver}",
|
||||||
"{comp_name}-{comp_ver}",
|
comp_name = compiler_name,
|
||||||
comp_name = compiler_name,
|
comp_ver = env!("GIT_REV"),
|
||||||
comp_ver = env!("GIT_REV"),
|
)
|
||||||
)
|
};
|
||||||
};
|
let mod_filename = format!(
|
||||||
p.join(isa.name()).join(compiler_dir).join(format!(
|
"mod-{mod_hash}{mod_dbg}",
|
||||||
"mod-{mod_hash}{mod_dbg}",
|
mod_hash = base64::encode_config(&hash, base64::URL_SAFE_NO_PAD), // standard encoding uses '/' which can't be used for filename
|
||||||
mod_hash = base64::encode_config(&hash, base64::URL_SAFE_NO_PAD), // standard encoding uses '/' which can't be used for filename
|
mod_dbg = if generate_debug_info { ".d" } else { "" },
|
||||||
mod_dbg = if generate_debug_info { ".d" } else { "" },
|
);
|
||||||
))
|
Some(
|
||||||
})
|
conf::cache_directory()
|
||||||
|
.join(isa.name())
|
||||||
|
.join(compiler_dir)
|
||||||
|
.join(mod_filename),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user