This commit is contained in:
parent
4d54f903be
commit
2848f3dee4
18 changed files with 1200 additions and 240 deletions
31
Cargo.lock
generated
31
Cargo.lock
generated
|
@ -319,6 +319,7 @@ dependencies = [
|
|||
"jobslot",
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
"ordered-float",
|
||||
"petgraph",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -524,6 +525,17 @@ version = "1.19.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
|
||||
[[package]]
|
||||
name = "ordered-float"
|
||||
version = "5.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f4779c6901a562440c3786d08192c6fbda7c1c2060edd10006b05ee35d10f2d"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"rand",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "petgraph"
|
||||
version = "0.8.1"
|
||||
|
@ -576,6 +588,25 @@ version = "0.7.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"rand_core",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.31"
|
||||
|
|
|
@ -30,6 +30,7 @@ indexmap = { version = "2.5.0", features = ["serde"] }
|
|||
jobslot = "0.2.23"
|
||||
num-bigint = "0.4.6"
|
||||
num-traits = "0.2.16"
|
||||
ordered-float = { version = "5.1.0", features = ["serde"] }
|
||||
petgraph = "0.8.1"
|
||||
prettyplease = "0.2.20"
|
||||
proc-macro2 = "1.0.83"
|
||||
|
|
|
@ -26,6 +26,7 @@ hashbrown.workspace = true
|
|||
jobslot.workspace = true
|
||||
num-bigint.workspace = true
|
||||
num-traits.workspace = true
|
||||
ordered-float.workspace = true
|
||||
petgraph.workspace = true
|
||||
serde_json.workspace = true
|
||||
serde.workspace = true
|
||||
|
|
|
@ -6,6 +6,7 @@ use crate::{
|
|||
bundle::{Bundle, BundleType},
|
||||
intern::{Intern, InternSlice, Interned},
|
||||
module::Module,
|
||||
platform::{DynPlatform, Platform},
|
||||
util::{job_server::AcquiredJob, os_str_strip_prefix},
|
||||
vendor,
|
||||
};
|
||||
|
@ -318,6 +319,7 @@ impl<K: JobKind> JobKindAndArgs<K> {
|
|||
self,
|
||||
dependencies: <K::Dependencies as JobDependencies>::KindsAndArgs,
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<JobAndDependencies<K>> {
|
||||
K::args_to_jobs(
|
||||
JobArgsAndDependencies {
|
||||
|
@ -325,6 +327,7 @@ impl<K: JobKind> JobKindAndArgs<K> {
|
|||
dependencies,
|
||||
},
|
||||
params,
|
||||
global_params,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -446,8 +449,12 @@ where
|
|||
}
|
||||
|
||||
impl<K: JobKind> JobArgsAndDependencies<K> {
|
||||
pub fn args_to_jobs(self, params: &JobParams) -> eyre::Result<JobAndDependencies<K>> {
|
||||
K::args_to_jobs(self, params)
|
||||
pub fn args_to_jobs(
|
||||
self,
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<JobAndDependencies<K>> {
|
||||
K::args_to_jobs(self, params, global_params)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -455,6 +462,7 @@ impl<K: JobKind<Dependencies = JobKindAndDependencies<D>>, D: JobKind> JobArgsAn
|
|||
pub fn args_to_jobs_simple<F>(
|
||||
self,
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
f: F,
|
||||
) -> eyre::Result<JobAndDependencies<K>>
|
||||
where
|
||||
|
@ -464,7 +472,7 @@ impl<K: JobKind<Dependencies = JobKindAndDependencies<D>>, D: JobKind> JobArgsAn
|
|||
args: JobKindAndArgs { kind, args },
|
||||
dependencies,
|
||||
} = self;
|
||||
let mut dependencies = dependencies.args_to_jobs(params)?;
|
||||
let mut dependencies = dependencies.args_to_jobs(params, global_params)?;
|
||||
let job = f(kind, args, &mut dependencies)?;
|
||||
Ok(JobAndDependencies {
|
||||
job: JobAndKind { kind, job },
|
||||
|
@ -479,6 +487,7 @@ impl<C: external::ExternalCommand<Dependencies = JobKindAndDependencies<D>>, D:
|
|||
pub fn args_to_jobs_external_simple<F>(
|
||||
self,
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
f: F,
|
||||
) -> eyre::Result<(
|
||||
C::AdditionalJobData,
|
||||
|
@ -494,7 +503,7 @@ impl<C: external::ExternalCommand<Dependencies = JobKindAndDependencies<D>>, D:
|
|||
args: JobKindAndArgs { kind: _, args },
|
||||
dependencies,
|
||||
} = self;
|
||||
let mut dependencies = dependencies.args_to_jobs(params)?;
|
||||
let mut dependencies = dependencies.args_to_jobs(params, global_params)?;
|
||||
let additional_job_data = f(args, &mut dependencies)?;
|
||||
Ok((additional_job_data, dependencies))
|
||||
}
|
||||
|
@ -624,7 +633,6 @@ impl_job_dependencies! {
|
|||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct JobParams {
|
||||
main_module: Module<Bundle>,
|
||||
application_name: Interned<str>,
|
||||
}
|
||||
|
||||
impl AsRef<Self> for JobParams {
|
||||
|
@ -634,24 +642,65 @@ impl AsRef<Self> for JobParams {
|
|||
}
|
||||
|
||||
impl JobParams {
|
||||
pub fn new_canonical(main_module: Module<Bundle>, application_name: Interned<str>) -> Self {
|
||||
Self {
|
||||
main_module,
|
||||
application_name,
|
||||
}
|
||||
pub fn new_canonical(main_module: Module<Bundle>) -> Self {
|
||||
Self { main_module }
|
||||
}
|
||||
pub fn new<B: BundleType>(
|
||||
main_module: impl AsRef<Module<B>>,
|
||||
application_name: impl AsRef<str>,
|
||||
) -> Self {
|
||||
Self::new_canonical(
|
||||
main_module.as_ref().canonical(),
|
||||
application_name.as_ref().intern(),
|
||||
)
|
||||
pub fn new<B: BundleType>(main_module: impl AsRef<Module<B>>) -> Self {
|
||||
Self::new_canonical(main_module.as_ref().canonical())
|
||||
}
|
||||
pub fn main_module(&self) -> &Module<Bundle> {
|
||||
&self.main_module
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct GlobalParams {
|
||||
top_level_cmd: Option<clap::Command>,
|
||||
application_name: Interned<str>,
|
||||
}
|
||||
|
||||
impl AsRef<Self> for GlobalParams {
|
||||
fn as_ref(&self) -> &Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl GlobalParams {
|
||||
pub fn new(top_level_cmd: Option<clap::Command>, application_name: impl AsRef<str>) -> Self {
|
||||
Self {
|
||||
top_level_cmd,
|
||||
application_name: application_name.as_ref().intern(),
|
||||
}
|
||||
}
|
||||
pub fn top_level_cmd(&self) -> Option<&clap::Command> {
|
||||
self.top_level_cmd.as_ref()
|
||||
}
|
||||
pub fn into_top_level_cmd(self) -> Option<clap::Command> {
|
||||
self.top_level_cmd
|
||||
}
|
||||
pub fn extract_clap_error(&self, e: eyre::Report) -> eyre::Result<clap::Error> {
|
||||
let e = e.downcast::<clap::Error>()?;
|
||||
Ok(match &self.top_level_cmd {
|
||||
Some(cmd) => e.with_cmd(cmd),
|
||||
None => e,
|
||||
})
|
||||
}
|
||||
pub fn exit_if_clap_error(&self, e: eyre::Report) -> eyre::Report {
|
||||
match self.extract_clap_error(e) {
|
||||
Ok(e) => e.exit(),
|
||||
Err(e) => e,
|
||||
}
|
||||
}
|
||||
pub fn clap_error(
|
||||
&self,
|
||||
kind: clap::error::ErrorKind,
|
||||
message: impl fmt::Display,
|
||||
) -> clap::Error {
|
||||
match self.top_level_cmd.clone() {
|
||||
Some(top_level_cmd) => top_level_cmd.clone().error(kind, message),
|
||||
None => clap::Error::raw(kind, message),
|
||||
}
|
||||
}
|
||||
pub fn application_name(&self) -> Interned<str> {
|
||||
self.application_name
|
||||
}
|
||||
|
@ -710,6 +759,7 @@ pub trait JobKind: 'static + Send + Sync + Hash + Eq + fmt::Debug + Sized + Copy
|
|||
fn args_to_jobs(
|
||||
args: JobArgsAndDependencies<Self>,
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<JobAndDependencies<Self>>;
|
||||
fn inputs(self, job: &Self::Job) -> Interned<[JobItemName]>;
|
||||
fn outputs(self, job: &Self::Job) -> Interned<[JobItemName]>;
|
||||
|
@ -720,6 +770,7 @@ pub trait JobKind: 'static + Send + Sync + Hash + Eq + fmt::Debug + Sized + Copy
|
|||
job: &Self::Job,
|
||||
inputs: &[JobItem],
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
acquired_job: &mut AcquiredJob,
|
||||
) -> eyre::Result<Vec<JobItem>>;
|
||||
fn subcommand_hidden(self) -> bool {
|
||||
|
@ -1064,6 +1115,7 @@ trait DynJobArgsTrait: 'static + Send + Sync + fmt::Debug {
|
|||
self: Arc<Self>,
|
||||
dependencies_args: Vec<DynJobArgs>,
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<(DynJob, Vec<DynJob>)>;
|
||||
}
|
||||
|
||||
|
@ -1117,12 +1169,13 @@ impl<K: JobKind> DynJobArgsTrait for DynJobArgsInner<K> {
|
|||
self: Arc<Self>,
|
||||
dependencies_args: Vec<DynJobArgs>,
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<(DynJob, Vec<DynJob>)> {
|
||||
let JobAndDependencies { job, dependencies } = JobArgsAndDependencies {
|
||||
args: Arc::unwrap_or_clone(self).0,
|
||||
dependencies: K::Dependencies::from_dyn_args(dependencies_args),
|
||||
}
|
||||
.args_to_jobs(params)?;
|
||||
.args_to_jobs(params, global_params)?;
|
||||
Ok((job.into(), K::Dependencies::into_dyn_jobs(dependencies)))
|
||||
}
|
||||
}
|
||||
|
@ -1179,8 +1232,9 @@ impl DynJobArgs {
|
|||
self,
|
||||
dependencies_args: Vec<DynJobArgs>,
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<(DynJob, Vec<DynJob>)> {
|
||||
DynJobArgsTrait::args_to_jobs(self.0, dependencies_args, params)
|
||||
DynJobArgsTrait::args_to_jobs(self.0, dependencies_args, params, global_params)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1261,6 +1315,7 @@ trait DynJobTrait: 'static + Send + Sync + fmt::Debug {
|
|||
&self,
|
||||
inputs: &[JobItem],
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
acquired_job: &mut AcquiredJob,
|
||||
) -> eyre::Result<Vec<JobItem>>;
|
||||
}
|
||||
|
@ -1317,9 +1372,11 @@ impl<T: JobKind> DynJobTrait for DynJobInner<T> {
|
|||
&self,
|
||||
inputs: &[JobItem],
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
acquired_job: &mut AcquiredJob,
|
||||
) -> eyre::Result<Vec<JobItem>> {
|
||||
self.kind.run(&self.job, inputs, params, acquired_job)
|
||||
self.kind
|
||||
.run(&self.job, inputs, params, global_params, acquired_job)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1429,9 +1486,10 @@ impl DynJob {
|
|||
&self,
|
||||
inputs: &[JobItem],
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
acquired_job: &mut AcquiredJob,
|
||||
) -> eyre::Result<Vec<JobItem>> {
|
||||
DynJobTrait::run(&*self.0, inputs, params, acquired_job)
|
||||
DynJobTrait::run(&*self.0, inputs, params, global_params, acquired_job)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1481,56 +1539,159 @@ impl<'de> Deserialize<'de> for DynJob {
|
|||
}
|
||||
|
||||
pub trait RunBuild<Extra: ToArgs = NoArgs>: Sized {
|
||||
fn main<F>(make_params: F)
|
||||
fn main_without_platform<F>(application_name: impl AsRef<str>, make_params: F)
|
||||
where
|
||||
Self: clap::Parser + Clone,
|
||||
F: FnOnce(Self, Extra) -> eyre::Result<JobParams>,
|
||||
{
|
||||
match Self::try_main(make_params) {
|
||||
let application_name = application_name.as_ref();
|
||||
match Self::try_main_without_platform(application_name, make_params) {
|
||||
Ok(()) => {}
|
||||
Err(e) => {
|
||||
let e = GlobalParams::new(Some(Self::command()), application_name)
|
||||
.exit_if_clap_error(e);
|
||||
eprintln!("{e:#}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
fn try_main<F>(make_params: F) -> eyre::Result<()>
|
||||
fn try_main_without_platform<F>(
|
||||
application_name: impl AsRef<str>,
|
||||
make_params: F,
|
||||
) -> eyre::Result<()>
|
||||
where
|
||||
Self: clap::Parser + Clone,
|
||||
F: FnOnce(Self, Extra) -> eyre::Result<JobParams>,
|
||||
{
|
||||
let args = Self::parse();
|
||||
let global_params = GlobalParams::new(Some(Self::command()), application_name);
|
||||
args.clone()
|
||||
.run(|extra| make_params(args, extra), Self::command())
|
||||
.run_without_platform(|extra| make_params(args, extra), &global_params)
|
||||
.map_err(|e| global_params.exit_if_clap_error(e))
|
||||
}
|
||||
fn run<F>(self, make_params: F, cmd: clap::Command) -> eyre::Result<()>
|
||||
fn run_without_platform<F>(
|
||||
self,
|
||||
make_params: F,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<()>
|
||||
where
|
||||
F: FnOnce(Extra) -> eyre::Result<JobParams>;
|
||||
fn main<F>(application_name: impl AsRef<str>, make_params: F)
|
||||
where
|
||||
Self: clap::Parser + Clone + GetPlatform,
|
||||
F: FnOnce(Self, DynPlatform, Extra) -> eyre::Result<JobParams>,
|
||||
{
|
||||
let application_name = application_name.as_ref();
|
||||
match Self::try_main(application_name, make_params) {
|
||||
Ok(()) => {}
|
||||
Err(e) => {
|
||||
let e = GlobalParams::new(Some(Self::command()), application_name)
|
||||
.exit_if_clap_error(e);
|
||||
eprintln!("{e:#}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
fn try_main<F>(application_name: impl AsRef<str>, make_params: F) -> eyre::Result<()>
|
||||
where
|
||||
Self: clap::Parser + Clone + GetPlatform,
|
||||
F: FnOnce(Self, DynPlatform, Extra) -> eyre::Result<JobParams>,
|
||||
{
|
||||
let args = Self::parse();
|
||||
let global_params = GlobalParams::new(Some(Self::command()), application_name);
|
||||
let Some(platform) = args.get_platform() else {
|
||||
return args.handle_missing_platform(&global_params);
|
||||
};
|
||||
args.clone()
|
||||
.run(
|
||||
|platform, extra| make_params(args, platform, extra),
|
||||
platform,
|
||||
&global_params,
|
||||
)
|
||||
.map_err(|e| global_params.exit_if_clap_error(e))
|
||||
}
|
||||
fn handle_missing_platform(self, global_params: &GlobalParams) -> eyre::Result<()> {
|
||||
global_params
|
||||
.clap_error(
|
||||
clap::error::ErrorKind::MissingRequiredArgument,
|
||||
"--platform is required",
|
||||
)
|
||||
.exit();
|
||||
}
|
||||
fn run<F>(
|
||||
self,
|
||||
make_params: F,
|
||||
platform: DynPlatform,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<()>
|
||||
where
|
||||
F: FnOnce(DynPlatform, Extra) -> eyre::Result<JobParams>,
|
||||
{
|
||||
self.run_without_platform(|extra| make_params(platform, extra), global_params)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: JobKind> RunBuild for JobArgsAndDependencies<K> {
|
||||
fn run<F>(self, make_params: F, cmd: clap::Command) -> eyre::Result<()>
|
||||
fn run_without_platform<F>(
|
||||
self,
|
||||
make_params: F,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<()>
|
||||
where
|
||||
F: FnOnce(NoArgs) -> eyre::Result<JobParams>,
|
||||
{
|
||||
let params = make_params(NoArgs)?;
|
||||
self.args_to_jobs(¶ms)?.run(|_| Ok(params), cmd)
|
||||
self.args_to_jobs(¶ms, global_params)?
|
||||
.run_without_platform(|_| Ok(params), global_params)
|
||||
}
|
||||
fn run<F>(
|
||||
self,
|
||||
make_params: F,
|
||||
platform: DynPlatform,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<()>
|
||||
where
|
||||
F: FnOnce(DynPlatform, NoArgs) -> eyre::Result<JobParams>,
|
||||
{
|
||||
let params = make_params(platform.clone(), NoArgs)?;
|
||||
self.args_to_jobs(¶ms, global_params)?
|
||||
.run(|_, _| Ok(params), platform, global_params)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: JobKind> RunBuild for JobAndDependencies<K> {
|
||||
fn run<F>(self, make_params: F, cmd: clap::Command) -> eyre::Result<()>
|
||||
fn run_without_platform<F>(
|
||||
self,
|
||||
make_params: F,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<()>
|
||||
where
|
||||
F: FnOnce(NoArgs) -> eyre::Result<JobParams>,
|
||||
{
|
||||
let _ = cmd;
|
||||
let params = make_params(NoArgs)?;
|
||||
let Self { job, dependencies } = self;
|
||||
let mut jobs = vec![DynJob::from(job)];
|
||||
K::Dependencies::into_dyn_jobs_extend(dependencies, &mut jobs);
|
||||
let mut job_graph = JobGraph::new();
|
||||
job_graph.add_jobs(jobs); // add all at once to avoid recomputing graph properties multiple times
|
||||
job_graph.run(¶ms)
|
||||
job_graph.run(¶ms, global_params)
|
||||
}
|
||||
fn run<F>(
|
||||
self,
|
||||
make_params: F,
|
||||
platform: DynPlatform,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<()>
|
||||
where
|
||||
F: FnOnce(DynPlatform, NoArgs) -> eyre::Result<JobParams>,
|
||||
{
|
||||
let params = make_params(platform, NoArgs)?;
|
||||
let Self { job, dependencies } = self;
|
||||
let mut jobs = vec![DynJob::from(job)];
|
||||
K::Dependencies::into_dyn_jobs_extend(dependencies, &mut jobs);
|
||||
let mut job_graph = JobGraph::new();
|
||||
job_graph.add_jobs(jobs); // add all at once to avoid recomputing graph properties multiple times
|
||||
job_graph.run(¶ms, global_params)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1629,15 +1790,18 @@ impl<Extra: ToArgs> clap::FromArgMatches for RunSingleJob<Extra> {
|
|||
}
|
||||
|
||||
impl<Extra: ToArgs> RunBuild<Extra> for RunSingleJob<Extra> {
|
||||
fn run<F>(self, make_params: F, cmd: clap::Command) -> eyre::Result<()>
|
||||
fn run_without_platform<F>(
|
||||
self,
|
||||
make_params: F,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<()>
|
||||
where
|
||||
F: FnOnce(Extra) -> eyre::Result<JobParams>,
|
||||
{
|
||||
let _ = cmd;
|
||||
let params = make_params(self.extra)?;
|
||||
let mut job_graph = JobGraph::new();
|
||||
job_graph.add_jobs([self.job]);
|
||||
job_graph.run(¶ms)
|
||||
job_graph.run(¶ms, global_params)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1674,11 +1838,18 @@ impl Completions {
|
|||
}
|
||||
|
||||
impl RunBuild for Completions {
|
||||
fn run<F>(self, _make_params: F, mut cmd: clap::Command) -> eyre::Result<()>
|
||||
fn run_without_platform<F>(
|
||||
self,
|
||||
_make_params: F,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<()>
|
||||
where
|
||||
F: FnOnce(NoArgs) -> eyre::Result<JobParams>,
|
||||
{
|
||||
let Self::Completions { shell } = self;
|
||||
let Some(cmd) = global_params.top_level_cmd() else {
|
||||
eyre::bail!("completions command requires GlobalParams::top_level_cmd() to be Some");
|
||||
};
|
||||
let bin_name = cmd.get_bin_name().map(str::intern).unwrap_or_else(|| {
|
||||
program_name_for_internal_jobs()
|
||||
.to_interned_str()
|
||||
|
@ -1686,12 +1857,15 @@ impl RunBuild for Completions {
|
|||
});
|
||||
clap_complete::aot::generate(
|
||||
shell,
|
||||
&mut cmd,
|
||||
&mut cmd.clone(),
|
||||
&*bin_name,
|
||||
&mut std::io::BufWriter::new(std::io::stdout().lock()),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
fn handle_missing_platform(self, global_params: &GlobalParams) -> eyre::Result<()> {
|
||||
self.run_without_platform(|_| unreachable!(), global_params)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(
|
||||
|
@ -1730,16 +1904,52 @@ pub enum BuildCli<Extra: ToArgs = NoArgs> {
|
|||
}
|
||||
|
||||
impl<Extra: ToArgs> RunBuild<Extra> for BuildCli<Extra> {
|
||||
fn run<F>(self, make_params: F, cmd: clap::Command) -> eyre::Result<()>
|
||||
fn run_without_platform<F>(
|
||||
self,
|
||||
make_params: F,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<()>
|
||||
where
|
||||
F: FnOnce(Extra) -> eyre::Result<JobParams>,
|
||||
{
|
||||
match self {
|
||||
BuildCli::Job(v) => v.run(make_params, cmd),
|
||||
BuildCli::RunSingleJob(v) => v.run(make_params, cmd),
|
||||
BuildCli::Completions(v) => v.run(|NoArgs {}| unreachable!(), cmd),
|
||||
BuildCli::Job(v) => v.run_without_platform(make_params, global_params),
|
||||
BuildCli::RunSingleJob(v) => v.run_without_platform(make_params, global_params),
|
||||
BuildCli::Completions(v) => {
|
||||
v.run_without_platform(|NoArgs {}| unreachable!(), global_params)
|
||||
}
|
||||
#[cfg(unix)]
|
||||
BuildCli::CreateUnixShellScript(v) => v.run(make_params, cmd),
|
||||
BuildCli::CreateUnixShellScript(v) => {
|
||||
v.run_without_platform(make_params, global_params)
|
||||
}
|
||||
}
|
||||
}
|
||||
fn handle_missing_platform(self, global_params: &GlobalParams) -> eyre::Result<()> {
|
||||
match self {
|
||||
BuildCli::Job(v) => v.handle_missing_platform(global_params),
|
||||
BuildCli::RunSingleJob(v) => v.handle_missing_platform(global_params),
|
||||
BuildCli::Completions(v) => v.handle_missing_platform(global_params),
|
||||
#[cfg(unix)]
|
||||
BuildCli::CreateUnixShellScript(v) => v.handle_missing_platform(global_params),
|
||||
}
|
||||
}
|
||||
fn run<F>(
|
||||
self,
|
||||
make_params: F,
|
||||
platform: DynPlatform,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<()>
|
||||
where
|
||||
F: FnOnce(DynPlatform, Extra) -> eyre::Result<JobParams>,
|
||||
{
|
||||
match self {
|
||||
BuildCli::Job(v) => v.run(make_params, platform, global_params),
|
||||
BuildCli::RunSingleJob(v) => v.run(make_params, platform, global_params),
|
||||
BuildCli::Completions(v) => {
|
||||
v.run(|_, NoArgs {}| unreachable!(), platform, global_params)
|
||||
}
|
||||
#[cfg(unix)]
|
||||
BuildCli::CreateUnixShellScript(v) => v.run(make_params, platform, global_params),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1759,7 +1969,11 @@ enum CreateUnixShellScriptInner<Extra: ToArgs> {
|
|||
pub struct CreateUnixShellScript<Extra: ToArgs = NoArgs>(CreateUnixShellScriptInner<Extra>);
|
||||
|
||||
impl<Extra: ToArgs> RunBuild<Extra> for CreateUnixShellScript<Extra> {
|
||||
fn run<F>(self, make_params: F, cmd: clap::Command) -> eyre::Result<()>
|
||||
fn run_without_platform<F>(
|
||||
self,
|
||||
make_params: F,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<()>
|
||||
where
|
||||
F: FnOnce(Extra) -> eyre::Result<JobParams>,
|
||||
{
|
||||
|
@ -1774,16 +1988,17 @@ impl<Extra: ToArgs> RunBuild<Extra> for CreateUnixShellScript<Extra> {
|
|||
} = self.0;
|
||||
let extra_args = extra.to_interned_args_vec();
|
||||
let params = make_params(extra)?;
|
||||
let (job, dependencies) = args.args_to_jobs(dependencies_args, ¶ms)?;
|
||||
let bin_name = global_params
|
||||
.top_level_cmd()
|
||||
.and_then(clap::Command::get_bin_name)
|
||||
.map(|v| OsStr::new(v).intern());
|
||||
let (job, dependencies) = args.args_to_jobs(dependencies_args, ¶ms, global_params)?;
|
||||
let mut job_graph = JobGraph::new();
|
||||
job_graph.add_jobs([job].into_iter().chain(dependencies));
|
||||
std::io::stdout().write_all(
|
||||
job_graph
|
||||
.to_unix_shell_script_with_internal_program_prefix(
|
||||
&[cmd
|
||||
.get_bin_name()
|
||||
.map(|v| OsStr::new(v).intern())
|
||||
.unwrap_or_else(|| program_name_for_internal_jobs())],
|
||||
&[bin_name.unwrap_or_else(|| program_name_for_internal_jobs())],
|
||||
&extra_args,
|
||||
)
|
||||
.as_bytes(),
|
||||
|
@ -1956,21 +2171,24 @@ impl<Extra: ToArgs> clap::FromArgMatches for AnyJobSubcommand<Extra> {
|
|||
}
|
||||
|
||||
impl<Extra: ToArgs> RunBuild<Extra> for AnyJobSubcommand<Extra> {
|
||||
fn run<F>(self, make_params: F, cmd: clap::Command) -> eyre::Result<()>
|
||||
fn run_without_platform<F>(
|
||||
self,
|
||||
make_params: F,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<()>
|
||||
where
|
||||
F: FnOnce(Extra) -> eyre::Result<JobParams>,
|
||||
{
|
||||
let _ = cmd;
|
||||
let Self {
|
||||
args,
|
||||
dependencies_args,
|
||||
extra,
|
||||
} = self;
|
||||
let params = make_params(extra)?;
|
||||
let (job, dependencies) = args.args_to_jobs(dependencies_args, ¶ms)?;
|
||||
let (job, dependencies) = args.args_to_jobs(dependencies_args, ¶ms, global_params)?;
|
||||
let mut job_graph = JobGraph::new();
|
||||
job_graph.add_jobs([job].into_iter().chain(dependencies)); // add all at once to avoid recomputing graph properties multiple times
|
||||
job_graph.run(¶ms)
|
||||
job_graph.run(¶ms, global_params)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2045,6 +2263,7 @@ impl JobKind for CreateOutputDirJobKind {
|
|||
fn args_to_jobs(
|
||||
args: JobArgsAndDependencies<Self>,
|
||||
_params: &JobParams,
|
||||
_global_params: &GlobalParams,
|
||||
) -> eyre::Result<JobAndDependencies<Self>> {
|
||||
let JobArgsAndDependencies {
|
||||
args:
|
||||
|
@ -2120,6 +2339,7 @@ impl JobKind for CreateOutputDirJobKind {
|
|||
job: &Self::Job,
|
||||
inputs: &[JobItem],
|
||||
_params: &JobParams,
|
||||
_global_params: &GlobalParams,
|
||||
_acquired_job: &mut AcquiredJob,
|
||||
) -> eyre::Result<Vec<JobItem>> {
|
||||
let [] = inputs else {
|
||||
|
@ -2162,11 +2382,14 @@ pub struct BaseJobArgs {
|
|||
/// run commands even if their results are already cached
|
||||
#[arg(long, env = Self::RUN_EVEN_IF_CACHED_ENV_NAME)]
|
||||
pub run_even_if_cached: bool,
|
||||
/// platform
|
||||
#[arg(long)]
|
||||
pub platform: Option<DynPlatform>,
|
||||
}
|
||||
|
||||
impl BaseJobArgs {
|
||||
pub const RUN_EVEN_IF_CACHED_ENV_NAME: &'static str = "FAYALITE_RUN_EVEN_IF_CACHED";
|
||||
pub fn from_output_dir_and_env(output: PathBuf) -> Self {
|
||||
pub fn from_output_dir_and_env(output: PathBuf, platform: Option<DynPlatform>) -> Self {
|
||||
Self {
|
||||
create_output_dir_args: CreateOutputDirArgs {
|
||||
output: Some(output),
|
||||
|
@ -2174,6 +2397,7 @@ impl BaseJobArgs {
|
|||
},
|
||||
file_stem: None,
|
||||
run_even_if_cached: std::env::var_os(Self::RUN_EVEN_IF_CACHED_ENV_NAME).is_some(),
|
||||
platform,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2184,6 +2408,7 @@ impl ToArgs for BaseJobArgs {
|
|||
create_output_dir_args,
|
||||
file_stem,
|
||||
run_even_if_cached,
|
||||
platform,
|
||||
} = self;
|
||||
create_output_dir_args.to_args(args);
|
||||
if let Some(file_stem) = file_stem {
|
||||
|
@ -2192,6 +2417,9 @@ impl ToArgs for BaseJobArgs {
|
|||
if *run_even_if_cached {
|
||||
args.write_arg("--run-even-if-cached");
|
||||
}
|
||||
if let Some(platform) = platform {
|
||||
args.write_long_option_eq("platform", platform.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2202,6 +2430,7 @@ pub struct BaseJob {
|
|||
create_output_dir: CreateOutputDir,
|
||||
file_stem: Interned<OsStr>,
|
||||
run_even_if_cached: bool,
|
||||
platform: Option<DynPlatform>,
|
||||
}
|
||||
|
||||
impl BaseJob {
|
||||
|
@ -2219,6 +2448,9 @@ impl BaseJob {
|
|||
pub fn run_even_if_cached(&self) -> bool {
|
||||
self.run_even_if_cached
|
||||
}
|
||||
pub fn platform(&self) -> Option<&DynPlatform> {
|
||||
self.platform.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
|
||||
|
@ -2236,17 +2468,22 @@ impl JobKind for BaseJobKind {
|
|||
fn args_to_jobs(
|
||||
args: JobArgsAndDependencies<Self>,
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<JobAndDependencies<Self>> {
|
||||
let BaseJobArgs {
|
||||
create_output_dir_args,
|
||||
file_stem,
|
||||
run_even_if_cached,
|
||||
platform,
|
||||
} = args.args.args;
|
||||
let create_output_dir_args = JobKindAndArgs {
|
||||
kind: CreateOutputDirJobKind,
|
||||
args: create_output_dir_args,
|
||||
};
|
||||
let create_output_dir = create_output_dir_args.args_to_jobs((), params)?.job.job;
|
||||
let create_output_dir = create_output_dir_args
|
||||
.args_to_jobs((), params, global_params)?
|
||||
.job
|
||||
.job;
|
||||
let file_stem = file_stem
|
||||
.map(Intern::intern_deref)
|
||||
.unwrap_or(params.main_module().name().into());
|
||||
|
@ -2257,6 +2494,7 @@ impl JobKind for BaseJobKind {
|
|||
create_output_dir,
|
||||
file_stem,
|
||||
run_even_if_cached,
|
||||
platform,
|
||||
},
|
||||
},
|
||||
dependencies: (),
|
||||
|
@ -2284,9 +2522,16 @@ impl JobKind for BaseJobKind {
|
|||
job: &Self::Job,
|
||||
inputs: &[JobItem],
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
acquired_job: &mut AcquiredJob,
|
||||
) -> eyre::Result<Vec<JobItem>> {
|
||||
CreateOutputDirJobKind.run(&job.create_output_dir, inputs, params, acquired_job)
|
||||
CreateOutputDirJobKind.run(
|
||||
&job.create_output_dir,
|
||||
inputs,
|
||||
params,
|
||||
global_params,
|
||||
acquired_job,
|
||||
)
|
||||
}
|
||||
|
||||
fn subcommand_hidden(self) -> bool {
|
||||
|
@ -2382,3 +2627,105 @@ impl<K: JobKind> GetJob<K::Job, GetJobPositionJob> for JobAndDependencies<K> {
|
|||
&this.job.job
|
||||
}
|
||||
}
|
||||
|
||||
impl<J, Position, K: JobKind<Dependencies: JobDependencies<KindsAndArgs: GetJob<J, Position>>>>
|
||||
GetJob<J, GetJobPositionDependencies<Position>> for JobArgsAndDependencies<K>
|
||||
{
|
||||
fn get_job(this: &Self) -> &J {
|
||||
GetJob::get_job(&this.dependencies)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: JobKind> GetJob<K::Args, GetJobPositionJob> for JobArgsAndDependencies<K> {
|
||||
fn get_job(this: &Self) -> &K::Args {
|
||||
&this.args.args
|
||||
}
|
||||
}
|
||||
|
||||
impl<J, Position, K: JobKind<Dependencies: GetJob<J, Position>>>
|
||||
GetJob<J, GetJobPositionDependencies<Position>> for JobKindAndDependencies<K>
|
||||
{
|
||||
fn get_job(this: &Self) -> &J {
|
||||
GetJob::get_job(&this.dependencies)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: JobKind> GetJob<K, GetJobPositionJob> for JobKindAndDependencies<K> {
|
||||
fn get_job(this: &Self) -> &K {
|
||||
&this.kind
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GetPlatform {
|
||||
fn get_platform(&self) -> Option<DynPlatform>;
|
||||
}
|
||||
|
||||
impl<T: ?Sized + GetPlatform> GetPlatform for &'_ T {
|
||||
fn get_platform(&self) -> Option<DynPlatform> {
|
||||
T::get_platform(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized + GetPlatform> GetPlatform for &'_ mut T {
|
||||
fn get_platform(&self) -> Option<DynPlatform> {
|
||||
T::get_platform(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized + GetPlatform> GetPlatform for Box<T> {
|
||||
fn get_platform(&self) -> Option<DynPlatform> {
|
||||
T::get_platform(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl GetPlatform for BaseJobArgs {
|
||||
fn get_platform(&self) -> Option<DynPlatform> {
|
||||
self.platform.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl GetPlatform for BaseJob {
|
||||
fn get_platform(&self) -> Option<DynPlatform> {
|
||||
self.platform.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl GetPlatform for JobAndDependencies<BaseJobKind> {
|
||||
fn get_platform(&self) -> Option<DynPlatform> {
|
||||
self.job.get_platform()
|
||||
}
|
||||
}
|
||||
|
||||
impl GetPlatform for JobArgsAndDependencies<BaseJobKind> {
|
||||
fn get_platform(&self) -> Option<DynPlatform> {
|
||||
self.args.get_platform()
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: JobKind<Job: GetPlatform>> GetPlatform for JobAndKind<K> {
|
||||
fn get_platform(&self) -> Option<DynPlatform> {
|
||||
self.job.get_platform()
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: JobKind<Args: GetPlatform>> GetPlatform for JobKindAndArgs<K> {
|
||||
fn get_platform(&self) -> Option<DynPlatform> {
|
||||
self.args.get_platform()
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: JobKind<Dependencies: JobDependencies<JobsAndKinds: GetPlatform>>> GetPlatform
|
||||
for JobAndDependencies<K>
|
||||
{
|
||||
fn get_platform(&self) -> Option<DynPlatform> {
|
||||
self.dependencies.get_platform()
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: JobKind<Dependencies: JobDependencies<KindsAndArgs: GetPlatform>>> GetPlatform
|
||||
for JobArgsAndDependencies<K>
|
||||
{
|
||||
fn get_platform(&self) -> Option<DynPlatform> {
|
||||
self.dependencies.get_platform()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
use crate::{
|
||||
build::{
|
||||
ArgsWriter, BaseJob, CommandParams, GetJob, JobAndDependencies, JobAndKind,
|
||||
ArgsWriter, BaseJob, CommandParams, GetJob, GlobalParams, JobAndDependencies, JobAndKind,
|
||||
JobArgsAndDependencies, JobDependencies, JobItem, JobItemName, JobKind, JobKindAndArgs,
|
||||
JobParams, ToArgs, WriteArgs,
|
||||
},
|
||||
|
@ -996,6 +996,7 @@ pub trait ExternalCommand: 'static + Send + Sync + Hash + Eq + fmt::Debug + Size
|
|||
fn args_to_jobs(
|
||||
args: JobArgsAndDependencies<ExternalCommandJobKind<Self>>,
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<(
|
||||
Self::AdditionalJobData,
|
||||
<Self::Dependencies as JobDependencies>::JobsAndKinds,
|
||||
|
@ -1028,6 +1029,7 @@ impl<T: ExternalCommand> JobKind for ExternalCommandJobKind<T> {
|
|||
fn args_to_jobs(
|
||||
args: JobArgsAndDependencies<Self>,
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<JobAndDependencies<Self>> {
|
||||
let JobKindAndArgs {
|
||||
kind,
|
||||
|
@ -1042,7 +1044,7 @@ impl<T: ExternalCommand> JobKind for ExternalCommandJobKind<T> {
|
|||
additional_args: _,
|
||||
},
|
||||
} = args.args;
|
||||
let (additional_job_data, dependencies) = T::args_to_jobs(args, params)?;
|
||||
let (additional_job_data, dependencies) = T::args_to_jobs(args, params, global_params)?;
|
||||
let base_job = GetJob::<BaseJob, _>::get_job(&dependencies);
|
||||
let job = ExternalCommandJob {
|
||||
additional_job_data,
|
||||
|
@ -1078,7 +1080,8 @@ impl<T: ExternalCommand> JobKind for ExternalCommandJobKind<T> {
|
|||
self,
|
||||
job: &Self::Job,
|
||||
inputs: &[JobItem],
|
||||
params: &JobParams,
|
||||
_params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
acquired_job: &mut AcquiredJob,
|
||||
) -> eyre::Result<Vec<JobItem>> {
|
||||
assert!(
|
||||
|
@ -1093,7 +1096,7 @@ impl<T: ExternalCommand> JobKind for ExternalCommandJobKind<T> {
|
|||
} = job.command_params();
|
||||
ExternalJobCaching::new(
|
||||
&job.output_dir,
|
||||
¶ms.application_name(),
|
||||
&global_params.application_name(),
|
||||
&T::job_kind_name(),
|
||||
job.run_even_if_cached,
|
||||
)?
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
use crate::{
|
||||
build::{
|
||||
BaseJob, BaseJobKind, CommandParams, DynJobKind, JobAndDependencies,
|
||||
BaseJob, BaseJobKind, CommandParams, DynJobKind, GlobalParams, JobAndDependencies,
|
||||
JobArgsAndDependencies, JobItem, JobItemName, JobKind, JobKindAndDependencies, JobParams,
|
||||
ToArgs, WriteArgs,
|
||||
},
|
||||
|
@ -64,9 +64,11 @@ impl JobKind for FirrtlJobKind {
|
|||
fn args_to_jobs(
|
||||
args: JobArgsAndDependencies<Self>,
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<JobAndDependencies<Self>> {
|
||||
args.args_to_jobs_simple(
|
||||
params,
|
||||
global_params,
|
||||
|_kind, FirrtlArgs { export_options }, dependencies| {
|
||||
Ok(Firrtl {
|
||||
base: dependencies.get_job::<BaseJob, _>().clone(),
|
||||
|
@ -103,6 +105,7 @@ impl JobKind for FirrtlJobKind {
|
|||
job: &Self::Job,
|
||||
inputs: &[JobItem],
|
||||
params: &JobParams,
|
||||
_global_params: &GlobalParams,
|
||||
_acquired_job: &mut AcquiredJob,
|
||||
) -> eyre::Result<Vec<JobItem>> {
|
||||
let [JobItem::Path { path: input_path }] = *inputs else {
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
use crate::{
|
||||
build::{
|
||||
BaseJob, CommandParams, DynJobKind, GetJobPositionDependencies, JobAndDependencies,
|
||||
JobArgsAndDependencies, JobDependencies, JobItem, JobItemName, JobKind,
|
||||
BaseJob, CommandParams, DynJobKind, GetJobPositionDependencies, GlobalParams,
|
||||
JobAndDependencies, JobArgsAndDependencies, JobDependencies, JobItem, JobItemName, JobKind,
|
||||
JobKindAndDependencies, JobParams, ToArgs, WriteArgs,
|
||||
external::{
|
||||
ExternalCommand, ExternalCommandJob, ExternalCommandJobKind, ExternalProgramTrait,
|
||||
|
@ -201,6 +201,7 @@ impl JobKind for WriteSbyFileJobKind {
|
|||
fn args_to_jobs(
|
||||
mut args: JobArgsAndDependencies<Self>,
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<JobAndDependencies<Self>> {
|
||||
args.dependencies
|
||||
.dependencies
|
||||
|
@ -209,7 +210,7 @@ impl JobKind for WriteSbyFileJobKind {
|
|||
.additional_args
|
||||
.verilog_dialect
|
||||
.get_or_insert(VerilogDialect::Yosys);
|
||||
args.args_to_jobs_simple(params, |_kind, args, dependencies| {
|
||||
args.args_to_jobs_simple(params, global_params, |_kind, args, dependencies| {
|
||||
let FormalArgs {
|
||||
sby_extra_args,
|
||||
formal_mode,
|
||||
|
@ -255,6 +256,7 @@ impl JobKind for WriteSbyFileJobKind {
|
|||
job: &Self::Job,
|
||||
inputs: &[JobItem],
|
||||
params: &JobParams,
|
||||
_global_params: &GlobalParams,
|
||||
_acquired_job: &mut AcquiredJob,
|
||||
) -> eyre::Result<Vec<JobItem>> {
|
||||
assert!(inputs.iter().map(JobItem::name).eq(self.inputs(job)));
|
||||
|
@ -351,11 +353,12 @@ impl ExternalCommand for Formal {
|
|||
fn args_to_jobs(
|
||||
args: JobArgsAndDependencies<ExternalCommandJobKind<Self>>,
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<(
|
||||
Self::AdditionalJobData,
|
||||
<Self::Dependencies as JobDependencies>::JobsAndKinds,
|
||||
)> {
|
||||
args.args_to_jobs_external_simple(params, |args, dependencies| {
|
||||
args.args_to_jobs_external_simple(params, global_params, |args, dependencies| {
|
||||
let FormalAdditionalArgs {} = args.additional_args;
|
||||
let write_sby_file = dependencies.get_job::<WriteSbyFileJob, _>().clone();
|
||||
Ok(Formal {
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
// See Notices.txt for copyright information
|
||||
|
||||
use crate::{
|
||||
build::{DynJob, JobItem, JobItemName, JobParams, program_name_for_internal_jobs},
|
||||
build::{
|
||||
DynJob, GlobalParams, JobItem, JobItemName, JobParams, program_name_for_internal_jobs,
|
||||
},
|
||||
intern::Interned,
|
||||
util::{HashMap, HashSet, job_server::AcquiredJob},
|
||||
};
|
||||
|
@ -639,7 +641,7 @@ impl JobGraph {
|
|||
}
|
||||
retval
|
||||
}
|
||||
pub fn run(&self, params: &JobParams) -> eyre::Result<()> {
|
||||
pub fn run(&self, params: &JobParams, global_params: &GlobalParams) -> eyre::Result<()> {
|
||||
// use scope to auto-join threads on errors
|
||||
thread::scope(|scope| {
|
||||
struct WaitingJobState {
|
||||
|
@ -725,13 +727,18 @@ impl JobGraph {
|
|||
job: DynJob,
|
||||
inputs: Vec<JobItem>,
|
||||
params: &'a JobParams,
|
||||
global_params: &'a GlobalParams,
|
||||
acquired_job: AcquiredJob,
|
||||
finished_jobs_sender: mpsc::Sender<<JobGraphInner as GraphBase>::NodeId>,
|
||||
}
|
||||
impl RunningJobInThread<'_> {
|
||||
fn run(mut self) -> eyre::Result<Vec<JobItem>> {
|
||||
self.job
|
||||
.run(&self.inputs, self.params, &mut self.acquired_job)
|
||||
self.job.run(
|
||||
&self.inputs,
|
||||
self.params,
|
||||
self.global_params,
|
||||
&mut self.acquired_job,
|
||||
)
|
||||
}
|
||||
}
|
||||
impl Drop for RunningJobInThread<'_> {
|
||||
|
@ -749,6 +756,7 @@ impl JobGraph {
|
|||
})
|
||||
}))?,
|
||||
params,
|
||||
global_params,
|
||||
acquired_job: AcquiredJob::acquire()?,
|
||||
finished_jobs_sender: finished_jobs_sender.clone(),
|
||||
};
|
||||
|
|
|
@ -4,10 +4,9 @@
|
|||
use crate::{
|
||||
build::{DynJobKind, JobKind, built_in_job_kinds},
|
||||
intern::Interned,
|
||||
util::InternedStrCompareAsStr,
|
||||
};
|
||||
use std::{
|
||||
borrow::Borrow,
|
||||
cmp::Ordering,
|
||||
collections::BTreeMap,
|
||||
fmt,
|
||||
sync::{Arc, OnceLock, RwLock, RwLockWriteGuard},
|
||||
|
@ -23,33 +22,6 @@ impl DynJobKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
struct InternedStrCompareAsStr(Interned<str>);
|
||||
|
||||
impl fmt::Debug for InternedStrCompareAsStr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for InternedStrCompareAsStr {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
str::cmp(&self.0, &other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for InternedStrCompareAsStr {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl Borrow<str> for InternedStrCompareAsStr {
|
||||
fn borrow(&self) -> &str {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct JobKindRegistry {
|
||||
job_kinds: BTreeMap<InternedStrCompareAsStr, DynJobKind>,
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
use crate::{
|
||||
build::{
|
||||
BaseJob, CommandParams, DynJobKind, GetJobPositionDependencies, GetJobPositionJob,
|
||||
JobAndDependencies, JobArgsAndDependencies, JobDependencies, JobItem, JobItemName, JobKind,
|
||||
JobKindAndDependencies, JobParams, ToArgs, WriteArgs,
|
||||
GlobalParams, JobAndDependencies, JobArgsAndDependencies, JobDependencies, JobItem,
|
||||
JobItemName, JobKind, JobKindAndDependencies, JobParams, ToArgs, WriteArgs,
|
||||
external::{
|
||||
ExternalCommand, ExternalCommandJob, ExternalCommandJobKind, ExternalProgramTrait,
|
||||
},
|
||||
|
@ -152,11 +152,12 @@ impl ExternalCommand for UnadjustedVerilog {
|
|||
fn args_to_jobs(
|
||||
args: JobArgsAndDependencies<ExternalCommandJobKind<Self>>,
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<(
|
||||
Self::AdditionalJobData,
|
||||
<Self::Dependencies as JobDependencies>::JobsAndKinds,
|
||||
)> {
|
||||
args.args_to_jobs_external_simple(params, |args, dependencies| {
|
||||
args.args_to_jobs_external_simple(params, global_params, |args, dependencies| {
|
||||
let UnadjustedVerilogArgs {
|
||||
firtool_extra_args,
|
||||
verilog_dialect,
|
||||
|
@ -316,8 +317,9 @@ impl JobKind for VerilogJobKind {
|
|||
fn args_to_jobs(
|
||||
args: JobArgsAndDependencies<Self>,
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<JobAndDependencies<Self>> {
|
||||
args.args_to_jobs_simple(params, |_kind, args, dependencies| {
|
||||
args.args_to_jobs_simple(params, global_params, |_kind, args, dependencies| {
|
||||
let VerilogJobArgs {} = args;
|
||||
let base_job = dependencies.get_job::<BaseJob, _>();
|
||||
Ok(VerilogJob {
|
||||
|
@ -364,6 +366,7 @@ impl JobKind for VerilogJobKind {
|
|||
job: &Self::Job,
|
||||
inputs: &[JobItem],
|
||||
_params: &JobParams,
|
||||
_global_params: &GlobalParams,
|
||||
_acquired_job: &mut AcquiredJob,
|
||||
) -> eyre::Result<Vec<JobItem>> {
|
||||
assert!(inputs.iter().map(JobItem::name).eq(self.inputs(job)));
|
||||
|
|
|
@ -8,10 +8,12 @@ use crate::{
|
|||
module::{Module, ModuleBuilder, ModuleIO, connect_with_loc, instance_with_loc, wire_with_loc},
|
||||
source_location::SourceLocation,
|
||||
ty::{CanonicalType, Type},
|
||||
util::HashMap,
|
||||
util::{HashMap, InternedStrCompareAsStr},
|
||||
};
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error};
|
||||
use std::{
|
||||
any::{Any, TypeId},
|
||||
borrow::Cow,
|
||||
cmp::Ordering,
|
||||
collections::{BTreeMap, BTreeSet},
|
||||
convert::Infallible,
|
||||
|
@ -19,13 +21,16 @@ use std::{
|
|||
hash::{Hash, Hasher},
|
||||
marker::PhantomData,
|
||||
mem,
|
||||
sync::{Arc, Mutex, MutexGuard, OnceLock},
|
||||
sync::{Arc, Mutex, MutexGuard, OnceLock, RwLock, RwLockWriteGuard},
|
||||
};
|
||||
|
||||
pub mod peripherals;
|
||||
|
||||
trait DynPlatformTrait: 'static + Send + Sync + fmt::Debug {
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
fn eq_dyn(&self, other: &dyn DynPlatformTrait) -> bool;
|
||||
fn hash_dyn(&self, state: &mut dyn Hasher);
|
||||
fn name_dyn(&self) -> Interned<str>;
|
||||
fn new_peripherals_dyn<'builder>(
|
||||
&self,
|
||||
builder_factory: PeripheralsBuilderFactory<'builder>,
|
||||
|
@ -51,6 +56,10 @@ impl<T: Platform> DynPlatformTrait for T {
|
|||
self.hash(&mut state);
|
||||
}
|
||||
|
||||
fn name_dyn(&self) -> Interned<str> {
|
||||
self.name()
|
||||
}
|
||||
|
||||
fn new_peripherals_dyn<'builder>(
|
||||
&self,
|
||||
builder_factory: PeripheralsBuilderFactory<'builder>,
|
||||
|
@ -155,6 +164,9 @@ impl Peripherals for DynPeripherals {
|
|||
|
||||
impl Platform for DynPlatform {
|
||||
type Peripherals = DynPeripherals;
|
||||
fn name(&self) -> Interned<str> {
|
||||
DynPlatformTrait::name_dyn(&*self.0)
|
||||
}
|
||||
fn new_peripherals<'a>(
|
||||
&self,
|
||||
builder_factory: PeripheralsBuilderFactory<'a>,
|
||||
|
@ -1033,6 +1045,7 @@ impl<'a> fmt::Debug for PlatformIOBuilder<'a> {
|
|||
|
||||
pub trait Platform: Clone + 'static + Send + Sync + fmt::Debug + Hash + Eq {
|
||||
type Peripherals: Peripherals;
|
||||
fn name(&self) -> Interned<str>;
|
||||
fn new_peripherals<'builder>(
|
||||
&self,
|
||||
builder_factory: PeripheralsBuilderFactory<'builder>,
|
||||
|
@ -1144,3 +1157,393 @@ pub trait Platform: Clone + 'static + Send + Sync + fmt::Debug + Hash + Eq {
|
|||
.unwrap_or_else(|e: Infallible| match e {})
|
||||
}
|
||||
}
|
||||
|
||||
impl DynPlatform {
|
||||
pub fn registry() -> PlatformRegistrySnapshot {
|
||||
PlatformRegistrySnapshot(PlatformRegistry::get())
|
||||
}
|
||||
#[track_caller]
|
||||
pub fn register(self) {
|
||||
PlatformRegistry::register(PlatformRegistry::lock(), self);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct PlatformRegistry {
|
||||
platforms: BTreeMap<InternedStrCompareAsStr, DynPlatform>,
|
||||
}
|
||||
|
||||
enum PlatformRegisterError {
|
||||
SameName {
|
||||
name: InternedStrCompareAsStr,
|
||||
old_platform: DynPlatform,
|
||||
new_platform: DynPlatform,
|
||||
},
|
||||
}
|
||||
|
||||
impl fmt::Display for PlatformRegisterError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::SameName {
|
||||
name,
|
||||
old_platform,
|
||||
new_platform,
|
||||
} => write!(
|
||||
f,
|
||||
"two different `Platform` can't share the same name:\n\
|
||||
{name:?}\n\
|
||||
old platform:\n\
|
||||
{old_platform:?}\n\
|
||||
new platform:\n\
|
||||
{new_platform:?}",
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait PlatformRegistryRegisterLock {
|
||||
type Locked;
|
||||
fn lock(self) -> Self::Locked;
|
||||
fn make_mut(locked: &mut Self::Locked) -> &mut PlatformRegistry;
|
||||
}
|
||||
|
||||
impl PlatformRegistryRegisterLock for &'static RwLock<Arc<PlatformRegistry>> {
|
||||
type Locked = RwLockWriteGuard<'static, Arc<PlatformRegistry>>;
|
||||
fn lock(self) -> Self::Locked {
|
||||
self.write().expect("shouldn't be poisoned")
|
||||
}
|
||||
fn make_mut(locked: &mut Self::Locked) -> &mut PlatformRegistry {
|
||||
Arc::make_mut(locked)
|
||||
}
|
||||
}
|
||||
|
||||
impl PlatformRegistryRegisterLock for &'_ mut PlatformRegistry {
|
||||
type Locked = Self;
|
||||
|
||||
fn lock(self) -> Self::Locked {
|
||||
self
|
||||
}
|
||||
|
||||
fn make_mut(locked: &mut Self::Locked) -> &mut PlatformRegistry {
|
||||
locked
|
||||
}
|
||||
}
|
||||
|
||||
impl PlatformRegistry {
|
||||
fn lock() -> &'static RwLock<Arc<Self>> {
|
||||
static REGISTRY: OnceLock<RwLock<Arc<PlatformRegistry>>> = OnceLock::new();
|
||||
REGISTRY.get_or_init(Default::default)
|
||||
}
|
||||
fn try_register<L: PlatformRegistryRegisterLock>(
|
||||
lock: L,
|
||||
platform: DynPlatform,
|
||||
) -> Result<(), PlatformRegisterError> {
|
||||
use std::collections::btree_map::Entry;
|
||||
let name = InternedStrCompareAsStr(platform.name());
|
||||
// run user code only outside of lock
|
||||
let mut locked = lock.lock();
|
||||
let this = L::make_mut(&mut locked);
|
||||
let result = match this.platforms.entry(name) {
|
||||
Entry::Occupied(entry) => Err(PlatformRegisterError::SameName {
|
||||
name,
|
||||
old_platform: entry.get().clone(),
|
||||
new_platform: platform,
|
||||
}),
|
||||
Entry::Vacant(entry) => {
|
||||
entry.insert(platform);
|
||||
Ok(())
|
||||
}
|
||||
};
|
||||
drop(locked);
|
||||
// outside of lock now, so we can test if it's the same DynPlatform
|
||||
match result {
|
||||
Err(PlatformRegisterError::SameName {
|
||||
name: _,
|
||||
old_platform,
|
||||
new_platform,
|
||||
}) if old_platform == new_platform => Ok(()),
|
||||
result => result,
|
||||
}
|
||||
}
|
||||
#[track_caller]
|
||||
fn register<L: PlatformRegistryRegisterLock>(lock: L, platform: DynPlatform) {
|
||||
match Self::try_register(lock, platform) {
|
||||
Err(e) => panic!("{e}"),
|
||||
Ok(()) => {}
|
||||
}
|
||||
}
|
||||
fn get() -> Arc<Self> {
|
||||
Self::lock().read().expect("shouldn't be poisoned").clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for PlatformRegistry {
|
||||
fn default() -> Self {
|
||||
let mut retval = Self {
|
||||
platforms: BTreeMap::new(),
|
||||
};
|
||||
for platform in built_in_platforms() {
|
||||
Self::register(&mut retval, platform);
|
||||
}
|
||||
retval
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PlatformRegistrySnapshot(Arc<PlatformRegistry>);
|
||||
|
||||
impl PlatformRegistrySnapshot {
|
||||
pub fn get() -> Self {
|
||||
PlatformRegistrySnapshot(PlatformRegistry::get())
|
||||
}
|
||||
pub fn get_by_name<'a>(&'a self, name: &str) -> Option<&'a DynPlatform> {
|
||||
self.0.platforms.get(name)
|
||||
}
|
||||
pub fn iter_with_names(&self) -> PlatformRegistryIterWithNames<'_> {
|
||||
PlatformRegistryIterWithNames(self.0.platforms.iter())
|
||||
}
|
||||
pub fn iter(&self) -> PlatformRegistryIter<'_> {
|
||||
PlatformRegistryIter(self.0.platforms.values())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for &'a PlatformRegistrySnapshot {
|
||||
type Item = &'a DynPlatform;
|
||||
type IntoIter = PlatformRegistryIter<'a>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for &'a mut PlatformRegistrySnapshot {
|
||||
type Item = &'a DynPlatform;
|
||||
type IntoIter = PlatformRegistryIter<'a>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.iter()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PlatformRegistryIter<'a>(
|
||||
std::collections::btree_map::Values<'a, InternedStrCompareAsStr, DynPlatform>,
|
||||
);
|
||||
|
||||
impl<'a> Iterator for PlatformRegistryIter<'a> {
|
||||
type Item = &'a DynPlatform;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.0.next()
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.0.size_hint()
|
||||
}
|
||||
|
||||
fn count(self) -> usize
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.0.count()
|
||||
}
|
||||
|
||||
fn last(self) -> Option<Self::Item> {
|
||||
self.0.last()
|
||||
}
|
||||
|
||||
fn nth(&mut self, n: usize) -> Option<Self::Item> {
|
||||
self.0.nth(n)
|
||||
}
|
||||
|
||||
fn fold<B, F>(self, init: B, f: F) -> B
|
||||
where
|
||||
F: FnMut(B, Self::Item) -> B,
|
||||
{
|
||||
self.0.fold(init, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> std::iter::FusedIterator for PlatformRegistryIter<'a> {}
|
||||
|
||||
impl<'a> ExactSizeIterator for PlatformRegistryIter<'a> {}
|
||||
|
||||
impl<'a> DoubleEndedIterator for PlatformRegistryIter<'a> {
|
||||
fn next_back(&mut self) -> Option<Self::Item> {
|
||||
self.0.next_back()
|
||||
}
|
||||
|
||||
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
|
||||
self.0.nth_back(n)
|
||||
}
|
||||
|
||||
fn rfold<B, F>(self, init: B, f: F) -> B
|
||||
where
|
||||
F: FnMut(B, Self::Item) -> B,
|
||||
{
|
||||
self.0.rfold(init, f)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PlatformRegistryIterWithNames<'a>(
|
||||
std::collections::btree_map::Iter<'a, InternedStrCompareAsStr, DynPlatform>,
|
||||
);
|
||||
|
||||
impl<'a> Iterator for PlatformRegistryIterWithNames<'a> {
|
||||
type Item = (Interned<str>, &'a DynPlatform);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.0.next().map(|(name, platform)| (name.0, platform))
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.0.size_hint()
|
||||
}
|
||||
|
||||
fn count(self) -> usize
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.0.count()
|
||||
}
|
||||
|
||||
fn last(self) -> Option<Self::Item> {
|
||||
self.0.last().map(|(name, platform)| (name.0, platform))
|
||||
}
|
||||
|
||||
fn nth(&mut self, n: usize) -> Option<Self::Item> {
|
||||
self.0.nth(n).map(|(name, platform)| (name.0, platform))
|
||||
}
|
||||
|
||||
fn fold<B, F>(self, init: B, f: F) -> B
|
||||
where
|
||||
F: FnMut(B, Self::Item) -> B,
|
||||
{
|
||||
self.0
|
||||
.map(|(name, platform)| (name.0, platform))
|
||||
.fold(init, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> std::iter::FusedIterator for PlatformRegistryIterWithNames<'a> {}
|
||||
|
||||
impl<'a> ExactSizeIterator for PlatformRegistryIterWithNames<'a> {}
|
||||
|
||||
impl<'a> DoubleEndedIterator for PlatformRegistryIterWithNames<'a> {
|
||||
fn next_back(&mut self) -> Option<Self::Item> {
|
||||
self.0
|
||||
.next_back()
|
||||
.map(|(name, platform)| (name.0, platform))
|
||||
}
|
||||
|
||||
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
|
||||
self.0
|
||||
.nth_back(n)
|
||||
.map(|(name, platform)| (name.0, platform))
|
||||
}
|
||||
|
||||
fn rfold<B, F>(self, init: B, f: F) -> B
|
||||
where
|
||||
F: FnMut(B, Self::Item) -> B,
|
||||
{
|
||||
self.0
|
||||
.map(|(name, platform)| (name.0, platform))
|
||||
.rfold(init, f)
|
||||
}
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
pub fn register_platform<K: Platform>(kind: K) {
|
||||
DynPlatform::new(kind).register();
|
||||
}
|
||||
|
||||
impl Serialize for DynPlatform {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
self.name().serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for DynPlatform {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let name = Cow::<str>::deserialize(deserializer)?;
|
||||
match Self::registry().get_by_name(&name) {
|
||||
Some(retval) => Ok(retval.clone()),
|
||||
None => Err(D::Error::custom(format_args!(
|
||||
"unknown platform: name not found in registry: {name:?}"
|
||||
))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default)]
|
||||
pub struct DynPlatformValueParser;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
struct DynPlatformValueEnum {
|
||||
name: Interned<str>,
|
||||
platform: DynPlatform,
|
||||
}
|
||||
|
||||
impl clap::ValueEnum for DynPlatformValueEnum {
|
||||
fn value_variants<'a>() -> &'a [Self] {
|
||||
Interned::into_inner(
|
||||
PlatformRegistrySnapshot::get()
|
||||
.iter_with_names()
|
||||
.map(|(name, platform)| Self {
|
||||
name,
|
||||
platform: platform.clone(),
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
||||
fn to_possible_value(&self) -> Option<clap::builder::PossibleValue> {
|
||||
Some(clap::builder::PossibleValue::new(Interned::into_inner(
|
||||
self.name,
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
impl clap::builder::TypedValueParser for DynPlatformValueParser {
|
||||
type Value = DynPlatform;
|
||||
|
||||
fn parse_ref(
|
||||
&self,
|
||||
cmd: &clap::Command,
|
||||
arg: Option<&clap::Arg>,
|
||||
value: &std::ffi::OsStr,
|
||||
) -> clap::error::Result<Self::Value> {
|
||||
clap::builder::EnumValueParser::<DynPlatformValueEnum>::new()
|
||||
.parse_ref(cmd, arg, value)
|
||||
.map(|v| v.platform)
|
||||
}
|
||||
|
||||
fn possible_values(
|
||||
&self,
|
||||
) -> Option<Box<dyn Iterator<Item = clap::builder::PossibleValue> + '_>> {
|
||||
static ENUM_VALUE_PARSER: OnceLock<clap::builder::EnumValueParser<DynPlatformValueEnum>> =
|
||||
OnceLock::new();
|
||||
ENUM_VALUE_PARSER
|
||||
.get_or_init(clap::builder::EnumValueParser::<DynPlatformValueEnum>::new)
|
||||
.possible_values()
|
||||
}
|
||||
}
|
||||
|
||||
impl clap::builder::ValueParserFactory for DynPlatform {
|
||||
type Parser = DynPlatformValueParser;
|
||||
|
||||
fn value_parser() -> Self::Parser {
|
||||
DynPlatformValueParser::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn built_in_platforms() -> impl IntoIterator<Item = DynPlatform> {
|
||||
crate::vendor::built_in_platforms()
|
||||
}
|
||||
|
|
20
crates/fayalite/src/platform/peripherals.rs
Normal file
20
crates/fayalite/src/platform/peripherals.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
// See Notices.txt for copyright information
|
||||
|
||||
use crate::prelude::*;
|
||||
use ordered_float::NotNan;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)]
|
||||
#[non_exhaustive]
|
||||
pub struct ClockInputProperties {
|
||||
pub frequency: NotNan<f64>,
|
||||
}
|
||||
|
||||
type PhantomConstClockInputProperties = PhantomConst<ClockInputProperties>;
|
||||
|
||||
#[hdl(no_static)]
|
||||
pub struct ClockInput {
|
||||
pub clk: Clock,
|
||||
pub properties: PhantomConstClockInputProperties,
|
||||
}
|
|
@ -33,7 +33,6 @@ pub use const_cmp::{
|
|||
#[doc(inline)]
|
||||
pub use scoped_ref::ScopedRef;
|
||||
|
||||
pub(crate) use misc::chain;
|
||||
#[doc(inline)]
|
||||
pub use misc::{
|
||||
BitSliceWriteWithBase, DebugAsDisplay, DebugAsRawString, MakeMutSlice, RcWriter,
|
||||
|
@ -42,6 +41,7 @@ pub use misc::{
|
|||
os_str_strip_suffix, serialize_to_json_ascii, serialize_to_json_ascii_pretty,
|
||||
serialize_to_json_ascii_pretty_with_indent, slice_range, try_slice_range,
|
||||
};
|
||||
pub(crate) use misc::{InternedStrCompareAsStr, chain};
|
||||
|
||||
pub mod job_server;
|
||||
pub mod prefix_sum;
|
||||
|
|
|
@ -585,3 +585,30 @@ pub fn os_str_strip_suffix<'a>(os_str: &'a OsStr, suffix: impl AsRef<str>) -> Op
|
|||
unsafe { OsStr::from_encoded_bytes_unchecked(bytes) }
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
pub(crate) struct InternedStrCompareAsStr(pub(crate) Interned<str>);
|
||||
|
||||
impl fmt::Debug for InternedStrCompareAsStr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for InternedStrCompareAsStr {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
str::cmp(&self.0, &other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for InternedStrCompareAsStr {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::borrow::Borrow<str> for InternedStrCompareAsStr {
|
||||
fn borrow(&self) -> &str {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,3 +6,7 @@ pub mod xilinx;
|
|||
pub(crate) fn built_in_job_kinds() -> impl IntoIterator<Item = crate::build::DynJobKind> {
|
||||
xilinx::built_in_job_kinds()
|
||||
}
|
||||
|
||||
pub(crate) fn built_in_platforms() -> impl IntoIterator<Item = crate::platform::DynPlatform> {
|
||||
xilinx::built_in_platforms()
|
||||
}
|
||||
|
|
165
crates/fayalite/src/vendor/xilinx.rs
vendored
165
crates/fayalite/src/vendor/xilinx.rs
vendored
|
@ -1,8 +1,16 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
// See Notices.txt for copyright information
|
||||
|
||||
use crate::{annotations::make_annotation_enum, intern::Interned};
|
||||
use crate::{
|
||||
annotations::make_annotation_enum,
|
||||
build::{GlobalParams, ToArgs, WriteArgs},
|
||||
intern::Interned,
|
||||
};
|
||||
use clap::ValueEnum;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
|
||||
pub mod arty_a7;
|
||||
pub mod yosys_nextpnr_prjxray;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
|
@ -23,6 +31,157 @@ make_annotation_enum! {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn built_in_job_kinds() -> impl IntoIterator<Item = crate::build::DynJobKind> {
|
||||
yosys_nextpnr_prjxray::built_in_job_kinds()
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)]
|
||||
pub struct XilinxArgs {
|
||||
#[arg(long)]
|
||||
pub device: Option<Device>,
|
||||
}
|
||||
|
||||
impl XilinxArgs {
|
||||
pub fn require_device(&self, global_params: &GlobalParams) -> clap::error::Result<Device> {
|
||||
self.device.ok_or_else(|| {
|
||||
global_params.clap_error(
|
||||
clap::error::ErrorKind::MissingRequiredArgument,
|
||||
"missing --device option",
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ToArgs for XilinxArgs {
|
||||
fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) {
|
||||
if let Some(device) = self.device {
|
||||
args.write_long_option_eq("device", device.as_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! make_device_enum {
|
||||
($vis:vis enum $Device:ident {
|
||||
$(
|
||||
#[
|
||||
name = $name:literal,
|
||||
xray_part = $xray_part:literal,
|
||||
xray_device = $xray_device:literal,
|
||||
xray_family = $xray_family:literal,
|
||||
]
|
||||
$variant:ident,
|
||||
)*
|
||||
}) => {
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, ValueEnum)]
|
||||
$vis enum $Device {
|
||||
$(
|
||||
#[value(name = $name, alias = $xray_part)]
|
||||
$variant,
|
||||
)*
|
||||
}
|
||||
|
||||
impl $Device {
|
||||
$vis fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
$(Self::$variant => $name,)*
|
||||
}
|
||||
}
|
||||
$vis fn xray_part(self) -> &'static str {
|
||||
match self {
|
||||
$(Self::$variant => $xray_part,)*
|
||||
}
|
||||
}
|
||||
$vis fn xray_device(self) -> &'static str {
|
||||
match self {
|
||||
$(Self::$variant => $xray_device,)*
|
||||
}
|
||||
}
|
||||
$vis fn xray_family(self) -> &'static str {
|
||||
match self {
|
||||
$(Self::$variant => $xray_family,)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct DeviceVisitor;
|
||||
|
||||
impl<'de> serde::de::Visitor<'de> for DeviceVisitor {
|
||||
type Value = $Device;
|
||||
|
||||
fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str("a Xilinx device string")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
match $Device::from_str(v, false) {
|
||||
Ok(v) => Ok(v),
|
||||
Err(_) => Err(E::invalid_value(serde::de::Unexpected::Str(v), &self)),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
match str::from_utf8(v).ok().and_then(|v| $Device::from_str(v, false).ok()) {
|
||||
Some(v) => Ok(v),
|
||||
None => Err(E::invalid_value(serde::de::Unexpected::Bytes(v), &self)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for $Device {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_string(DeviceVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for $Device {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
self.as_str().serialize(serializer)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
make_device_enum! {
|
||||
pub enum Device {
|
||||
#[
|
||||
name = "xc7a35ticsg324-1L",
|
||||
xray_part = "xc7a35tcsg324-1",
|
||||
xray_device = "xc7a35t",
|
||||
xray_family = "artix7",
|
||||
]
|
||||
Xc7a35ticsg324_1l,
|
||||
#[
|
||||
name = "xc7a100ticsg324-1L",
|
||||
xray_part = "xc7a100tcsg324-1",
|
||||
xray_device = "xc7a100t",
|
||||
xray_family = "artix7",
|
||||
]
|
||||
Xc7a100ticsg324_1l,
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Device {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str(self.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn built_in_job_kinds() -> impl IntoIterator<Item = crate::build::DynJobKind> {
|
||||
arty_a7::built_in_job_kinds()
|
||||
.into_iter()
|
||||
.chain(yosys_nextpnr_prjxray::built_in_job_kinds())
|
||||
}
|
||||
|
||||
pub(crate) fn built_in_platforms() -> impl IntoIterator<Item = crate::platform::DynPlatform> {
|
||||
arty_a7::built_in_platforms()
|
||||
.into_iter()
|
||||
.chain(yosys_nextpnr_prjxray::built_in_platforms())
|
||||
}
|
||||
|
|
81
crates/fayalite/src/vendor/xilinx/arty_a7.rs
vendored
Normal file
81
crates/fayalite/src/vendor/xilinx/arty_a7.rs
vendored
Normal file
|
@ -0,0 +1,81 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
// See Notices.txt for copyright information
|
||||
|
||||
use crate::{
|
||||
intern::{Intern, Interned},
|
||||
platform::{DynPlatform, PeripheralsBuilderFactory, PeripheralsBuilderFinished, Platform},
|
||||
prelude::{ModuleBuilder, SourceLocation},
|
||||
vendor::xilinx::Device,
|
||||
};
|
||||
|
||||
macro_rules! arty_a7_platform {
|
||||
(
|
||||
$vis:vis enum $ArtyA7Platform:ident {
|
||||
$(#[name = $name:literal, device = $device:ident]
|
||||
$Variant:ident,)*
|
||||
}
|
||||
) => {
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
#[non_exhaustive]
|
||||
$vis enum $ArtyA7Platform {
|
||||
$($Variant,)*
|
||||
}
|
||||
|
||||
impl $ArtyA7Platform {
|
||||
$vis const VARIANTS: &'static [Self] = &[$(Self::$Variant,)*];
|
||||
$vis fn device(self) -> Device {
|
||||
match self {
|
||||
$(Self::$Variant => Device::$device,)*
|
||||
}
|
||||
}
|
||||
$vis const fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
$(Self::$Variant => $name,)*
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
arty_a7_platform! {
|
||||
pub enum ArtyA7Platform {
|
||||
#[name = "arty-a7-35t", device = Xc7a35ticsg324_1l]
|
||||
ArtyA7_35T,
|
||||
#[name = "arty-a7-100t", device = Xc7a100ticsg324_1l]
|
||||
ArtyA7_100T,
|
||||
}
|
||||
}
|
||||
|
||||
impl Platform for ArtyA7Platform {
|
||||
type Peripherals = ();
|
||||
|
||||
fn name(&self) -> Interned<str> {
|
||||
self.as_str().intern()
|
||||
}
|
||||
|
||||
fn new_peripherals<'builder>(
|
||||
&self,
|
||||
builder_factory: PeripheralsBuilderFactory<'builder>,
|
||||
) -> (Self::Peripherals, PeripheralsBuilderFinished<'builder>) {
|
||||
let builder = builder_factory.builder();
|
||||
(todo!(), builder.finish())
|
||||
}
|
||||
|
||||
fn source_location(&self) -> SourceLocation {
|
||||
SourceLocation::builtin()
|
||||
}
|
||||
|
||||
fn add_peripherals_in_wrapper_module(&self, m: &ModuleBuilder, peripherals: Self::Peripherals) {
|
||||
let () = peripherals;
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn built_in_job_kinds() -> impl IntoIterator<Item = crate::build::DynJobKind> {
|
||||
[]
|
||||
}
|
||||
|
||||
pub(crate) fn built_in_platforms() -> impl IntoIterator<Item = DynPlatform> {
|
||||
ArtyA7Platform::VARIANTS
|
||||
.iter()
|
||||
.map(|&v| DynPlatform::new(v))
|
||||
}
|
|
@ -4,8 +4,8 @@
|
|||
use crate::{
|
||||
annotations::Annotation,
|
||||
build::{
|
||||
BaseJob, CommandParams, DynJobKind, GetJobPositionDependencies, JobAndDependencies,
|
||||
JobArgsAndDependencies, JobDependencies, JobItem, JobItemName, JobKind,
|
||||
BaseJob, CommandParams, DynJobKind, GetJobPositionDependencies, GlobalParams,
|
||||
JobAndDependencies, JobArgsAndDependencies, JobDependencies, JobItem, JobItemName, JobKind,
|
||||
JobKindAndDependencies, ToArgs, WriteArgs,
|
||||
external::{
|
||||
ExternalCommand, ExternalCommandJob, ExternalCommandJobKind, ExternalProgramTrait,
|
||||
|
@ -18,9 +18,10 @@ use crate::{
|
|||
module::{Module, NameId},
|
||||
prelude::JobParams,
|
||||
util::job_server::AcquiredJob,
|
||||
vendor::xilinx::{XdcIOStandardAnnotation, XdcLocationAnnotation, XilinxAnnotation},
|
||||
vendor::xilinx::{
|
||||
Device, XdcIOStandardAnnotation, XdcLocationAnnotation, XilinxAnnotation, XilinxArgs,
|
||||
},
|
||||
};
|
||||
use clap::ValueEnum;
|
||||
use eyre::Context;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
|
@ -105,6 +106,7 @@ impl JobKind for YosysNextpnrXrayWriteYsFileJobKind {
|
|||
fn args_to_jobs(
|
||||
mut args: JobArgsAndDependencies<Self>,
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<JobAndDependencies<Self>> {
|
||||
args.dependencies
|
||||
.dependencies
|
||||
|
@ -113,7 +115,7 @@ impl JobKind for YosysNextpnrXrayWriteYsFileJobKind {
|
|||
.additional_args
|
||||
.verilog_dialect
|
||||
.get_or_insert(VerilogDialect::Yosys);
|
||||
args.args_to_jobs_simple(params, |_kind, args, dependencies| {
|
||||
args.args_to_jobs_simple(params, global_params, |_kind, args, dependencies| {
|
||||
let YosysNextpnrXrayWriteYsFileArgs {} = args;
|
||||
let base_job = dependencies.get_job::<BaseJob, _>();
|
||||
let verilog_job = dependencies.get_job::<VerilogJob, _>();
|
||||
|
@ -153,6 +155,7 @@ impl JobKind for YosysNextpnrXrayWriteYsFileJobKind {
|
|||
job: &Self::Job,
|
||||
inputs: &[JobItem],
|
||||
params: &JobParams,
|
||||
_global_params: &GlobalParams,
|
||||
_acquired_job: &mut AcquiredJob,
|
||||
) -> eyre::Result<Vec<JobItem>> {
|
||||
assert!(inputs.iter().map(JobItem::name).eq(self.inputs(job)));
|
||||
|
@ -260,11 +263,12 @@ impl ExternalCommand for YosysNextpnrXraySynth {
|
|||
fn args_to_jobs(
|
||||
args: JobArgsAndDependencies<ExternalCommandJobKind<Self>>,
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<(
|
||||
Self::AdditionalJobData,
|
||||
<Self::Dependencies as JobDependencies>::JobsAndKinds,
|
||||
)> {
|
||||
args.args_to_jobs_external_simple(params, |args, dependencies| {
|
||||
args.args_to_jobs_external_simple(params, global_params, |args, dependencies| {
|
||||
let YosysNextpnrXraySynthArgs {} = args.additional_args;
|
||||
Ok(Self {
|
||||
write_ys_file: dependencies.job.job.clone(),
|
||||
|
@ -429,6 +433,7 @@ impl JobKind for YosysNextpnrXrayWriteXdcFileJobKind {
|
|||
fn args_to_jobs(
|
||||
args: JobArgsAndDependencies<Self>,
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<JobAndDependencies<Self>> {
|
||||
let firrtl_export_options = args
|
||||
.dependencies
|
||||
|
@ -439,7 +444,7 @@ impl JobKind for YosysNextpnrXrayWriteXdcFileJobKind {
|
|||
.args
|
||||
.args
|
||||
.export_options;
|
||||
args.args_to_jobs_simple(params, |_kind, args, dependencies| {
|
||||
args.args_to_jobs_simple(params, global_params, |_kind, args, dependencies| {
|
||||
let YosysNextpnrXrayWriteXdcFileArgs {} = args;
|
||||
let base_job = dependencies.get_job::<BaseJob, _>();
|
||||
Ok(YosysNextpnrXrayWriteXdcFile {
|
||||
|
@ -474,6 +479,7 @@ impl JobKind for YosysNextpnrXrayWriteXdcFileJobKind {
|
|||
job: &Self::Job,
|
||||
inputs: &[JobItem],
|
||||
params: &JobParams,
|
||||
_global_params: &GlobalParams,
|
||||
_acquired_job: &mut AcquiredJob,
|
||||
) -> eyre::Result<Vec<JobItem>> {
|
||||
assert!(inputs.iter().map(JobItem::name).eq(self.inputs(job)));
|
||||
|
@ -508,130 +514,12 @@ impl ExternalProgramTrait for NextpnrXilinx {
|
|||
}
|
||||
}
|
||||
|
||||
macro_rules! make_device_enum {
|
||||
($vis:vis enum $Device:ident {
|
||||
$(
|
||||
#[
|
||||
name = $name:literal,
|
||||
xray_part = $xray_part:literal,
|
||||
xray_device = $xray_device:literal,
|
||||
xray_family = $xray_family:literal,
|
||||
]
|
||||
$variant:ident,
|
||||
)*
|
||||
}) => {
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, ValueEnum)]
|
||||
$vis enum $Device {
|
||||
$(
|
||||
#[value(name = $name, alias = $xray_part)]
|
||||
$variant,
|
||||
)*
|
||||
}
|
||||
|
||||
impl $Device {
|
||||
$vis fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
$(Self::$variant => $name,)*
|
||||
}
|
||||
}
|
||||
$vis fn xray_part(self) -> &'static str {
|
||||
match self {
|
||||
$(Self::$variant => $xray_part,)*
|
||||
}
|
||||
}
|
||||
$vis fn xray_device(self) -> &'static str {
|
||||
match self {
|
||||
$(Self::$variant => $xray_device,)*
|
||||
}
|
||||
}
|
||||
$vis fn xray_family(self) -> &'static str {
|
||||
match self {
|
||||
$(Self::$variant => $xray_family,)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct DeviceVisitor;
|
||||
|
||||
impl<'de> serde::de::Visitor<'de> for DeviceVisitor {
|
||||
type Value = $Device;
|
||||
|
||||
fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str("a Xilinx device string")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
match $Device::from_str(v, false) {
|
||||
Ok(v) => Ok(v),
|
||||
Err(_) => Err(E::invalid_value(serde::de::Unexpected::Str(v), &self)),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
match str::from_utf8(v).ok().and_then(|v| $Device::from_str(v, false).ok()) {
|
||||
Some(v) => Ok(v),
|
||||
None => Err(E::invalid_value(serde::de::Unexpected::Bytes(v), &self)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for $Device {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_string(DeviceVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for $Device {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
self.as_str().serialize(serializer)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
make_device_enum! {
|
||||
pub enum Device {
|
||||
#[
|
||||
name = "xc7a35ticsg324-1L",
|
||||
xray_part = "xc7a35tcsg324-1",
|
||||
xray_device = "xc7a35t",
|
||||
xray_family = "artix7",
|
||||
]
|
||||
Xc7a35ticsg324_1l,
|
||||
#[
|
||||
name = "xc7a100ticsg324-1L",
|
||||
xray_part = "xc7a100tcsg324-1",
|
||||
xray_device = "xc7a100t",
|
||||
xray_family = "artix7",
|
||||
]
|
||||
Xc7a100ticsg324_1l,
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Device {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str(self.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Debug, clap::Args)]
|
||||
pub struct YosysNextpnrXrayRunNextpnrArgs {
|
||||
#[command(flatten)]
|
||||
pub common: XilinxArgs,
|
||||
#[arg(long, env = "CHIPDB_DIR", value_hint = clap::ValueHint::DirPath)]
|
||||
pub nextpnr_xilinx_chipdb_dir: PathBuf,
|
||||
#[arg(long)]
|
||||
pub device: Device,
|
||||
#[arg(long, default_value_t = 0)]
|
||||
pub nextpnr_xilinx_seed: i32,
|
||||
}
|
||||
|
@ -639,12 +527,12 @@ pub struct YosysNextpnrXrayRunNextpnrArgs {
|
|||
impl ToArgs for YosysNextpnrXrayRunNextpnrArgs {
|
||||
fn to_args(&self, args: &mut (impl WriteArgs + ?Sized)) {
|
||||
let Self {
|
||||
common,
|
||||
nextpnr_xilinx_chipdb_dir,
|
||||
device,
|
||||
nextpnr_xilinx_seed,
|
||||
} = self;
|
||||
common.to_args(args);
|
||||
args.write_long_option_eq("nextpnr-xilinx-chipdb-dir", nextpnr_xilinx_chipdb_dir);
|
||||
args.write_long_option_eq("device", device.as_str());
|
||||
args.write_display_arg(format_args!("--nextpnr-xilinx-seed={nextpnr_xilinx_seed}"));
|
||||
}
|
||||
}
|
||||
|
@ -690,14 +578,15 @@ impl ExternalCommand for YosysNextpnrXrayRunNextpnr {
|
|||
fn args_to_jobs(
|
||||
args: JobArgsAndDependencies<ExternalCommandJobKind<Self>>,
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<(
|
||||
Self::AdditionalJobData,
|
||||
<Self::Dependencies as JobDependencies>::JobsAndKinds,
|
||||
)> {
|
||||
args.args_to_jobs_external_simple(params, |args, dependencies| {
|
||||
args.args_to_jobs_external_simple(params, global_params, |args, dependencies| {
|
||||
let YosysNextpnrXrayRunNextpnrArgs {
|
||||
common,
|
||||
nextpnr_xilinx_chipdb_dir,
|
||||
device,
|
||||
nextpnr_xilinx_seed,
|
||||
} = args.additional_args;
|
||||
let base_job = dependencies.get_job::<BaseJob, _>();
|
||||
|
@ -707,7 +596,7 @@ impl ExternalCommand for YosysNextpnrXrayRunNextpnr {
|
|||
let fasm_file = base_job.file_with_ext("fasm");
|
||||
Ok(Self {
|
||||
nextpnr_xilinx_chipdb_dir: nextpnr_xilinx_chipdb_dir.intern_deref(),
|
||||
device,
|
||||
device: common.require_device(global_params)?,
|
||||
nextpnr_xilinx_seed,
|
||||
xdc_file: write_xdc_file.xdc_file,
|
||||
xdc_file_name: write_xdc_file
|
||||
|
@ -842,11 +731,12 @@ impl ExternalCommand for YosysNextpnrXray {
|
|||
fn args_to_jobs(
|
||||
args: JobArgsAndDependencies<ExternalCommandJobKind<Self>>,
|
||||
params: &JobParams,
|
||||
global_params: &GlobalParams,
|
||||
) -> eyre::Result<(
|
||||
Self::AdditionalJobData,
|
||||
<Self::Dependencies as JobDependencies>::JobsAndKinds,
|
||||
)> {
|
||||
args.args_to_jobs_external_simple(params, |args, dependencies| {
|
||||
args.args_to_jobs_external_simple(params, global_params, |args, dependencies| {
|
||||
let YosysNextpnrXrayArgs { prjxray_db_dir } = args.additional_args;
|
||||
let base_job = dependencies.get_job::<BaseJob, _>();
|
||||
let frames_file = base_job.file_with_ext("frames");
|
||||
|
@ -918,3 +808,7 @@ pub(crate) fn built_in_job_kinds() -> impl IntoIterator<Item = DynJobKind> {
|
|||
DynJobKind::new(ExternalCommandJobKind::<YosysNextpnrXray>::new()),
|
||||
]
|
||||
}
|
||||
|
||||
pub(crate) fn built_in_platforms() -> impl IntoIterator<Item = crate::platform::DynPlatform> {
|
||||
[]
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue