Skip to content

Commit 2b2893d

Browse files
committed
Adds manual dependency support
1 parent 5cb57cd commit 2b2893d

4 files changed

Lines changed: 116 additions & 3 deletions

File tree

vunit/project.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ def __init__(self,
4242
self._verilog_parser = verilog_parser
4343
self._libraries = {}
4444
self._source_files_in_order = []
45+
self._manual_dependencies = []
4546
self._depend_on_components = depend_on_components
4647
self._depend_on_package_body = depend_on_package_body
4748

@@ -97,6 +98,12 @@ def add_source_file(self, file_name, library_name, file_type='vhdl', include_dir
9798
self._source_files_in_order.append(source_file)
9899
return source_file
99100

101+
def add_manual_dependency(self, source_file, depends_on):
102+
"""
103+
Add manual dependency where 'source_file' depends_on 'depends_on'
104+
"""
105+
self._manual_dependencies.append((source_file, depends_on))
106+
100107
@staticmethod
101108
def _find_primary_secondary_design_unit_dependencies(source_file):
102109
"""
@@ -257,6 +264,9 @@ def add_dependencies(dependency_function, files):
257264
if self._depend_on_components:
258265
add_dependencies(self._find_component_design_unit_dependencies, vhdl_files)
259266

267+
for source_file, depends_on in self._manual_dependencies:
268+
add_dependency(depends_on, source_file)
269+
260270
return dependency_graph
261271

262272
def get_files_in_compile_order(self, incremental=True):

vunit/test/unit/test_project.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,29 @@ def create_project():
759759
module = create_project()
760760
self.assert_should_recompile([module])
761761

762+
def test_manual_dependencies(self):
763+
self.project.add_library("lib", "lib_path")
764+
ent1 = self.add_source_file("lib", "ent1.vhd", """\
765+
entity ent1 is
766+
end ent1;
767+
768+
architecture arch of ent1 is
769+
begin
770+
end architecture;
771+
""")
772+
773+
ent2 = self.add_source_file("lib", "ent2.vhd", """\
774+
entity ent2 is
775+
end ent2;
776+
777+
architecture arch of ent2 is
778+
begin
779+
end architecture;
780+
""")
781+
782+
self.project.add_manual_dependency(ent2, depends_on=ent1)
783+
self.assert_compiles(ent1, before=ent2)
784+
762785
def test_file_type_of(self):
763786
self.assertEqual(file_type_of("file.vhd"), "vhdl")
764787
self.assertEqual(file_type_of("file.vhdl"), "vhdl")

vunit/test/unit/test_ui.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,63 @@ def test_get_source_files_errors(self):
206206
self.assertRaisesRegexp(ValueError, ".*Found no file named.*%s.* in library 'lib1'" % non_existant_name,
207207
ui.get_source_file, non_existant_name, "lib1")
208208

209+
@mock.patch("vunit.project.Project.add_manual_dependency", autospec=True)
210+
def test_add_single_file_manual_dependencies(self, add_manual_dependency):
211+
# pylint: disable=protected-access
212+
ui = self._create_ui()
213+
lib = ui.library("lib")
214+
file_name1 = self.create_entity_file(1)
215+
file_name2 = self.create_entity_file(2)
216+
file1 = lib.add_source_file(file_name1)
217+
file2 = lib.add_source_file(file_name2)
218+
219+
add_manual_dependency.assert_has_calls([])
220+
file1.depends_on(file2)
221+
add_manual_dependency.assert_has_calls([
222+
mock.call(ui._project,
223+
file1._source_file,
224+
depends_on=file2._source_file)])
225+
226+
@mock.patch("vunit.project.Project.add_manual_dependency", autospec=True)
227+
def test_add_multiple_file_manual_dependencies(self, add_manual_dependency):
228+
# pylint: disable=protected-access
229+
ui = self._create_ui()
230+
lib = ui.library("lib")
231+
self.create_file("foo1.vhd")
232+
self.create_file("foo2.vhd")
233+
self.create_file("foo3.vhd")
234+
self.create_file("bar.vhd")
235+
foo_files = lib.add_source_files("foo*.vhd")
236+
bar_file = lib.add_source_file("bar.vhd")
237+
238+
add_manual_dependency.assert_has_calls([])
239+
bar_file.depends_on(foo_files)
240+
add_manual_dependency.assert_has_calls([
241+
mock.call(ui._project,
242+
bar_file._source_file,
243+
depends_on=foo_file._source_file)
244+
for foo_file in foo_files])
245+
246+
@mock.patch("vunit.project.Project.add_manual_dependency", autospec=True)
247+
def test_add_fileset_manual_dependencies(self, add_manual_dependency):
248+
# pylint: disable=protected-access
249+
ui = self._create_ui()
250+
lib = ui.library("lib")
251+
self.create_file("foo1.vhd")
252+
self.create_file("foo2.vhd")
253+
self.create_file("foo3.vhd")
254+
self.create_file("bar.vhd")
255+
foo_files = lib.add_source_files("foo*.vhd")
256+
bar_file = lib.add_source_file("bar.vhd")
257+
258+
add_manual_dependency.assert_has_calls([])
259+
foo_files.depends_on(bar_file)
260+
add_manual_dependency.assert_has_calls([
261+
mock.call(ui._project,
262+
foo_file._source_file,
263+
depends_on=bar_file._source_file)
264+
for foo_file in foo_files])
265+
209266
def _test_pre_config_helper(self, retval, test_not_entity=False):
210267
"""
211268
Helper method to test pre_config where the pre config can return different values

vunit/ui.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ def get_source_files(self, pattern="*", library_name=None, allow_empty=False):
280280
fnmatch(relpath(source_file.name), pattern)):
281281
continue
282282

283-
results.append(FileFacade(source_file))
283+
results.append(FileFacade(source_file, self._project))
284284

285285
if (not allow_empty) and len(results) == 0:
286286
raise ValueError(("Pattern %r did not match any file. "
@@ -317,7 +317,8 @@ def add_source_file(self, file_name, library_name, preprocessors=None, include_d
317317
return FileFacade(self._project.add_source_file(file_name,
318318
library_name,
319319
file_type=file_type,
320-
include_dirs=include_dirs))
320+
include_dirs=include_dirs),
321+
self._project)
321322

322323
def _preprocess(self, library_name, file_name, preprocessors):
323324
"""
@@ -816,20 +817,42 @@ def set_compile_option(self, name, value):
816817
for source_file in self:
817818
source_file.set_compile_option(name, value)
818819

820+
def depends_on(self, source_file):
821+
"""
822+
Add manual dependency of these files on another
823+
"""
824+
for my_source_file in self:
825+
my_source_file.depends_on(source_file)
826+
819827

820828
class FileFacade(object):
821829
"""
822830
A single file
823831
"""
824-
def __init__(self, source_file):
832+
def __init__(self, source_file, project):
825833
self._source_file = source_file
834+
self._project = project
826835

827836
def set_compile_option(self, name, value):
828837
"""
829838
Set compile option
830839
"""
831840
self._source_file.set_compile_option(name, value)
832841

842+
def depends_on(self, source_file):
843+
"""
844+
Add manual dependency of this file on another
845+
"""
846+
if isinstance(source_file, FileFacade):
847+
private_source_file = source_file._source_file # pylint: disable=protected-access
848+
self._project.add_manual_dependency(self._source_file,
849+
depends_on=private_source_file)
850+
elif hasattr(source_file, "__iter__"):
851+
for element in source_file:
852+
self.depends_on(element)
853+
else:
854+
raise ValueError(source_file)
855+
833856

834857
def select_vhdl_standard():
835858
"""

0 commit comments

Comments
 (0)