The Meson Build System
http://mesonbuild.com/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
4.0 KiB
120 lines
4.0 KiB
# SPDX-License-Identifier: Apache-2.0 |
|
# Copyright 2017 The Meson development team |
|
|
|
from __future__ import annotations |
|
import itertools |
|
import typing as T |
|
|
|
from . import ExtensionModule, ModuleReturnValue, ModuleInfo |
|
from .. import build |
|
from .. import mesonlib |
|
from ..interpreter.type_checking import CT_INPUT_KW |
|
from ..interpreterbase.decorators import KwargInfo, typed_kwargs, typed_pos_args |
|
|
|
if T.TYPE_CHECKING: |
|
from typing_extensions import TypedDict |
|
|
|
from . import ModuleState |
|
from ..interpreter import Interpreter |
|
from ..programs import ExternalProgram |
|
|
|
class ProjectKwargs(TypedDict): |
|
|
|
sources: T.List[T.Union[mesonlib.FileOrString, build.GeneratedTypes]] |
|
constraint_file: T.Union[mesonlib.FileOrString, build.GeneratedTypes] |
|
|
|
class IceStormModule(ExtensionModule): |
|
|
|
INFO = ModuleInfo('FPGA/Icestorm', '0.45.0', unstable=True) |
|
|
|
def __init__(self, interpreter: Interpreter) -> None: |
|
super().__init__(interpreter) |
|
self.tools: T.Dict[str, T.Union[ExternalProgram, build.Executable]] = {} |
|
self.methods.update({ |
|
'project': self.project, |
|
}) |
|
|
|
def detect_tools(self, state: ModuleState) -> None: |
|
self.tools['yosys'] = state.find_program('yosys') |
|
self.tools['arachne'] = state.find_program('arachne-pnr') |
|
self.tools['icepack'] = state.find_program('icepack') |
|
self.tools['iceprog'] = state.find_program('iceprog') |
|
self.tools['icetime'] = state.find_program('icetime') |
|
|
|
@typed_pos_args('icestorm.project', str, |
|
varargs=(str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, |
|
build.GeneratedList)) |
|
@typed_kwargs( |
|
'icestorm.project', |
|
CT_INPUT_KW.evolve(name='sources'), |
|
KwargInfo( |
|
'constraint_file', |
|
(str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList), |
|
required=True, |
|
) |
|
) |
|
def project(self, state: ModuleState, |
|
args: T.Tuple[str, T.List[T.Union[mesonlib.FileOrString, build.GeneratedTypes]]], |
|
kwargs: ProjectKwargs) -> ModuleReturnValue: |
|
if not self.tools: |
|
self.detect_tools(state) |
|
proj_name, arg_sources = args |
|
all_sources = self.interpreter.source_strings_to_files( |
|
list(itertools.chain(arg_sources, kwargs['sources']))) |
|
|
|
blif_target = build.CustomTarget( |
|
f'{proj_name}_blif', |
|
state.subdir, |
|
state.subproject, |
|
state.environment, |
|
[self.tools['yosys'], '-q', '-p', 'synth_ice40 -blif @OUTPUT@', '@INPUT@'], |
|
all_sources, |
|
[f'{proj_name}.blif'], |
|
) |
|
|
|
asc_target = build.CustomTarget( |
|
f'{proj_name}_asc', |
|
state.subdir, |
|
state.subproject, |
|
state.environment, |
|
[self.tools['arachne'], '-q', '-d', '1k', '-p', '@INPUT@', '-o', '@OUTPUT@'], |
|
[kwargs['constraint_file'], blif_target], |
|
[f'{proj_name}.asc'], |
|
) |
|
|
|
bin_target = build.CustomTarget( |
|
f'{proj_name}_bin', |
|
state.subdir, |
|
state.subproject, |
|
state.environment, |
|
[self.tools['icepack'], '@INPUT@', '@OUTPUT@'], |
|
[asc_target], |
|
[f'{proj_name}.bin'], |
|
build_by_default=True, |
|
) |
|
|
|
upload_target = build.RunTarget( |
|
f'{proj_name}-upload', |
|
[self.tools['iceprog'], bin_target], |
|
[], |
|
state.subdir, |
|
state.subproject, |
|
state.environment, |
|
) |
|
|
|
time_target = build.RunTarget( |
|
f'{proj_name}-time', |
|
[self.tools['icetime'], bin_target], |
|
[], |
|
state.subdir, |
|
state.subproject, |
|
state.environment, |
|
) |
|
|
|
return ModuleReturnValue( |
|
None, |
|
[blif_target, asc_target, bin_target, upload_target, time_target]) |
|
|
|
|
|
def initialize(interp: Interpreter) -> IceStormModule: |
|
return IceStormModule(interp)
|
|
|