Skip to content

Commit 2a06c68

Browse files
authored
Merging Unstable into master (#36)
* Added handlers for retrieving dependencies * Fixed some issues on build sequence caching * Fixed issue where `MODELSIM` env was not taken into account when checking for existing libraries
2 parents 3821093 + f28bf04 commit 2a06c68

18 files changed

+373
-128
lines changed

hdlcc/builders/base_builder.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,14 @@ def getState(self):
132132
del state['_lock']
133133
return state
134134

135+
@staticmethod
136+
def isAvailable(): # pragma: no cover
137+
"""
138+
Method that should be overriden by child classes and return True
139+
if the given builder is available on the current environment
140+
"""
141+
raise NotImplementedError
142+
135143
def checkEnvironment(self):
136144
"""
137145
Sanity environment check for child classes. Any exception raised
@@ -159,6 +167,7 @@ def _makeRecords(self, message):
159167

160168
def _getRebuilds(self, source, line):
161169
"""
170+
Gets info on what should be rebuilt to satisfy the builder
162171
"""
163172
try:
164173
parse_results = self._searchForRebuilds(line)
@@ -267,7 +276,7 @@ def _buildAndParse(self, source, flags=None):
267276
# content, so we dump the buffer content to a temporary file
268277
# and tell the compiler to compile it instead
269278
if source.hasBufferContent():
270-
build_path = source.dumpBufferContentToFile()
279+
build_path = source.getDumpPath()
271280
self._logger.debug("Source has buffered content, using %s",
272281
build_path)
273282
else:

hdlcc/builders/fallback.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ def _shouldIgnoreLine(self, line): # pragma: no cover
4040
def _checkEnvironment(self):
4141
return
4242

43+
@staticmethod
44+
def isAvailable():
45+
return True
46+
4347
def _buildSource(self, path, library, flags=None): # pragma: no cover
4448
return [], []
4549

hdlcc/builders/ghdl.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ def _checkEnvironment(self):
9696
"Version number is '%s'", \
9797
stdout[:-1], self._version)
9898

99+
@staticmethod
100+
def isAvailable():
101+
return not os.system('ghdl --version')
102+
99103
def getBuiltinLibraries(self):
100104
return self._builtin_libraries
101105

hdlcc/builders/msim.py

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import os
2020
import os.path as p
2121
import re
22+
from shutil import copyfile
2223
from .base_builder import BaseBuilder
2324
from hdlcc.utils import getFileType
2425

@@ -130,6 +131,11 @@ def _checkEnvironment(self):
130131
"Version number is '%s'", \
131132
stdout, self._version)
132133

134+
@staticmethod
135+
def isAvailable():
136+
return ((not os.system('vcom -version')) and
137+
(not os.system('vlog -version')))
138+
133139
def _parseBuiltinLibraries(self):
134140
"Discovers libraries that exist regardless before we do anything"
135141
if not self._iniFileExists():
@@ -169,6 +175,9 @@ def _buildSource(self, path, library, flags=None):
169175
filetype, path)
170176

171177
def _getExtraFlags(self, lang):
178+
"""
179+
Gets extra flags configured for the specific language
180+
"""
172181
libs = []
173182
for library in self._added_libraries + self._external_libraries[lang]:
174183
libs = ['-L', library]
@@ -218,6 +227,9 @@ def _createLibrary(self, library):
218227
raise
219228

220229
def _iniFileExists(self):
230+
"""
231+
Checks if the modelsim.ini file exists at the expected location
232+
"""
221233
_modelsim_ini = p.join(self._target_folder, 'modelsim.ini')
222234

223235
return p.exists(_modelsim_ini)
@@ -226,7 +238,6 @@ def _createIniFile(self):
226238
"""
227239
Adds a library to a non-existent ModelSim init file
228240
"""
229-
230241
_modelsim_ini = p.join(self._target_folder, 'modelsim.ini')
231242

232243
if not p.exists(self._target_folder): # pragma: no cover
@@ -235,24 +246,32 @@ def _createIniFile(self):
235246
self._logger.info("modelsim.ini not found at '%s', creating",
236247
p.abspath(_modelsim_ini))
237248

238-
cwd = p.abspath(os.curdir)
239-
self._logger.debug("Current dir is %s, changing to %s",
240-
cwd, self._target_folder)
241-
os.chdir(self._target_folder)
242-
if cwd == os.curdir: # pragma: no cover
243-
self._logger.fatal("cwd: %s, curdir: %s, error!", cwd, os.curdir)
244-
assert 0
245-
246-
247-
self._subprocessRunner(['vmap', '-c'])
248-
249-
self._logger.debug("After vmap at '%s'", p.abspath(os.curdir))
250-
for _dir in os.listdir(p.abspath(os.curdir)):
251-
self._logger.debug("- '%s'", _dir)
252-
253-
self._logger.debug("Current dir is %s, changing to %s",
254-
p.abspath(os.curdir), cwd)
255-
os.chdir(cwd)
249+
modelsim_env = os.environ.get('MODELSIM')
250+
if modelsim_env is not None: # pragma: no cover
251+
self._logger.info("MODELSIM environment variable set to %s, using "
252+
"this path as default modelsim.ini",
253+
modelsim_env)
254+
# Copy the modelsim.ini as indicated by the MODELSIM environment
255+
# variable
256+
copyfile(modelsim_env, _modelsim_ini)
257+
else:
258+
cwd = p.abspath(os.curdir)
259+
self._logger.debug("Current dir is %s, changing to %s",
260+
cwd, self._target_folder)
261+
os.chdir(self._target_folder)
262+
if cwd == os.curdir: # pragma: no cover
263+
self._logger.fatal("cwd: %s, curdir: %s, error!", cwd, os.curdir)
264+
assert 0
265+
266+
self._subprocessRunner(['vmap', '-c'])
267+
268+
self._logger.debug("After vmap at '%s'", p.abspath(os.curdir))
269+
for _dir in os.listdir(p.abspath(os.curdir)):
270+
self._logger.debug("- '%s'", _dir)
271+
272+
self._logger.debug("Current dir is %s, changing to %s",
273+
p.abspath(os.curdir), cwd)
274+
os.chdir(cwd)
256275

257276
def deleteLibrary(self, library):
258277
"Deletes a library from ModelSim init file"

hdlcc/builders/xvhdl.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ def _checkEnvironment(self):
9797
"Version number is '%s'", \
9898
stdout[:-1], self._version)
9999

100+
@staticmethod
101+
def isAvailable():
102+
return not os.system('xvhdl --nolog --version')
103+
100104
def getBuiltinLibraries(self):
101105
# FIXME: Built-in libraries should not be statically defined
102106
# like this. Review this at some point

hdlcc/config_parser.py

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
"Configuration file parser"
1818

1919
import os.path as p
20-
import shutil
2120
import re
2221
import logging
2322
from threading import Lock
@@ -137,15 +136,15 @@ def _addVunitIfFound(self):
137136
if not foundVunit() or self._parms['builder'] == 'fallback':
138137
return
139138

140-
import vunit
139+
import vunit # pylint: disable=import-error
140+
logging.getLogger('vunit').setLevel(logging.WARNING)
141141

142142
self._logger.info("VUnit installation found")
143-
# logging.getLogger('vunit').setLevel(logging.ERROR)
144143

145144
builder_class = getBuilderByName(self.getBuilder())
146145

147146
if 'systemverilog' in builder_class.file_types:
148-
from vunit.verilog import VUnit
147+
from vunit.verilog import VUnit # pylint: disable=import-error
149148
self._logger.debug("Builder supports Verilog, "
150149
"using vunit.verilog.VUnit")
151150
builder_class.addExternalLibrary('verilog', 'vunit_lib')
@@ -154,7 +153,7 @@ def _addVunitIfFound(self):
154153
'include'))
155154
self._importVunitFiles(VUnit)
156155

157-
from vunit import VUnit
156+
from vunit import VUnit # pylint: disable=import-error
158157
self._importVunitFiles(VUnit)
159158

160159
def _importVunitFiles(self, vunit_module):
@@ -307,8 +306,8 @@ def _doParseConfigFile(self):
307306
# to speed up parsing (important especially for libraries with
308307
# many files. The multiprocessing.Pool class used to hang, so
309308
# watch out if this behaves well enough to be used
309+
self._logger.info("Adding %d sources", len(source_build_list))
310310
for source in getSourceFileObjects(source_build_list):
311-
self._logger.debug("Adding source %s", source)
312311
self._sources[source.filename] = source
313312

314313
self._cleanUpSourcesList(source_path_list)
@@ -339,23 +338,17 @@ def _discoverBuilder(self):
339338
If no builder was specified, try to find one that works using
340339
a dummy target dir
341340
"""
342-
target_dir = '.dummy'
343341
builder_class = None
344342
self._logger.debug("Searching for builder among %s",
345343
AVAILABLE_BUILDERS)
346344
for builder_class in AVAILABLE_BUILDERS:
347345
if builder_class.builder_name == 'fallback':
348346
continue
349-
try:
350-
builder_class(target_dir)
347+
if builder_class.isAvailable():
351348
break
352-
except hdlcc.exceptions.SanityCheckError:
353-
self._logger.debug("Builder '%s' failed",
354-
builder_class.builder_name)
349+
else:
350+
self._logger.debug("'%s' failed", builder_class.builder_name)
355351
continue
356-
finally:
357-
if p.exists(target_dir): # pragma: no cover
358-
shutil.rmtree(target_dir)
359352

360353
if builder_class is not None:
361354
self._logger.info("Builder '%s' has worked",
@@ -471,7 +464,6 @@ def _handleParsedSource(self, library, path, flags):
471464

472465
# If the source should be built, return the build info for it
473466
if self._shouldAddSource(path, library, flags_set):
474-
self._logger.debug("Adding source: lib '%s', '%s'", library, path)
475467
return {'filename' : path, 'library' : library, 'flags' : flags_set}
476468

477469
def _shouldAddSource(self, source_path, library, flags):

hdlcc/handlers.py

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ def _getServerByProjectFile(project_file):
5959
project file. If the object doesn't exists yet it gets created and
6060
then returned
6161
"""
62+
if isinstance(project_file, str) and project_file.lower() == 'none':
63+
project_file = None
6264
try:
6365
return _hdlcc_objects[project_file]
6466
except KeyError:
@@ -165,15 +167,8 @@ def getMessagesByPath():
165167
_logger.debug("Getting messages for '%s', '%s', %s", project_file, path,
166168
"no content" if content is None else "with content")
167169

168-
169170
server = _getServerByProjectFile(project_file)
170-
response = {}
171-
if content is None:
172-
response['messages'] = server.getMessagesByPath(path)
173-
else:
174-
response['messages'] = server.getMessagesWithText(path, content)
175-
176-
return response
171+
return {'messages': server.getMessagesByPath(path)}
177172

178173
@app.post('/get_ui_messages')
179174
@_exceptionWrapper
@@ -223,6 +218,44 @@ def shutdownServer():
223218
_logger.info("Shutting down server")
224219
utils.terminateProcess(os.getpid())
225220

221+
@app.post('/get_dependencies')
222+
@_exceptionWrapper
223+
def getDependencies():
224+
"""
225+
Returns the direct dependencies of a given source path
226+
"""
227+
project_file = bottle.request.forms.get('project_file')
228+
path = bottle.request.forms.get('path')
229+
230+
_logger.debug("Getting dependencies for '%s', '%s'", project_file, path)
231+
232+
server = _getServerByProjectFile(project_file)
233+
source, _ = server.getSourceByPath(path)
234+
content = []
235+
for dependency in source.getDependencies():
236+
content.append("%s.%s" % (dependency['library'], dependency['unit']))
237+
238+
_logger.debug("Found %d dependencies", len(content))
239+
240+
return {'dependencies' : content}
241+
242+
@app.post('/get_build_sequence')
243+
@_exceptionWrapper
244+
def getBuildSequence():
245+
"""
246+
Returns the build sequence of a given source path
247+
"""
248+
project_file = bottle.request.forms.get('project_file')
249+
path = bottle.request.forms.get('path')
250+
251+
_logger.debug("Getting build sequence for '%s', '%s'", project_file, path)
252+
253+
server = _getServerByProjectFile(project_file)
254+
source, _ = server.getSourceByPath(path)
255+
256+
return {'sequence' : [x.filename for x in
257+
server.updateBuildSequenceCache(source)]}
258+
226259
# We'll store a dict to store differents hdlcc objects
227260
_hdlcc_objects = {} # pylint: disable=invalid-name
228261
setupSignalHandlers()

0 commit comments

Comments
 (0)