#
# Copyright 2008 Develer S.r.l. (http://www.develer.com/)
#
-# $Id$
#
# Author: Lorenzo Berni <duplo@develer.com>
#
getCommentList, sub,
# Project creation functions
- projectFileGenerator, versionFileGenerator, makefileGenerator,
- userMkGenerator, mkGenerator, loadPlugin, mergeSources,
+ projectFileGenerator, versionFileGenerator, loadPlugin,
+ mergeSources,
# Custom exceptions
ParseError, SupportedException
)
+import bertos_utils
+
+from compatibility import updateProject
class BProject(object):
"""
def loadBertosProject(self, project_file, info_dict):
project_dir = os.path.dirname(project_file)
project_data = pickle.loads(open(project_file, "r").read())
+ updateProject(project_data)
# If PROJECT_NAME is not defined it use the directory name as PROJECT_NAME
# NOTE: this can throw an Exception if the user has changed the directory containing the project
self.infos["PROJECT_NAME"] = project_data.get("PROJECT_NAME", os.path.basename(project_dir))
self.infos["PROJECT_PATH"] = os.path.dirname(project_file)
- project_src_path = project_data.get("PROJECT_SRC_PATH", None)
- project_src_path = os.path.join(project_dir, project_data.get("PROJECT_SRC_PATH", None))
+ project_src_path = os.path.join(project_dir, project_data.get("PROJECT_SRC_PATH", project_data["PROJECT_NAME"]))
if project_src_path:
self.infos["PROJECT_SRC_PATH"] = project_src_path
-
+
else:
# In projects created with older versions of the Wizard this metadata doesn't exist
self.infos["PROJECT_SRC_PATH"] = os.path.join(self.infos["PROJECT_PATH"], self.infos["PROJECT_NAME"])
+ self.infos["PROJECT_HW_PATH"] = os.path.join(self.infos["PROJECT_PATH"], project_data.get("PROJECT_HW_PATH", self.infos["PROJECT_PATH"]))
+
+ linked_sources_path = project_data["BERTOS_PATH"]
+ sources_abspath = os.path.abspath(os.path.join(project_dir, linked_sources_path))
+ project_data["BERTOS_PATH"] = sources_abspath
- wizard_version = project_data.get("WIZARD_VERSION", 0)
- if wizard_version < 1:
- # Ignore the BERTOS_PATH inside the project file for older project
- project_data["BERTOS_PATH"] = project_dir
- else:
- linked_sources_path = project_data["BERTOS_PATH"]
- sources_abspath = os.path.abspath(os.path.join(project_dir, linked_sources_path))
- project_data["BERTOS_PATH"] = sources_abspath
-
self._loadBertosSourceStuff(project_data["BERTOS_PATH"], info_dict.get("BERTOS_PATH", None))
-
+
self.infos["PRESET"] = project_data.get("PRESET", False)
# For those projects that don't have a VERSION file create a dummy one.
- if not isBertosDir(project_dir):
+ if not isBertosDir(project_dir) and not self.is_preset:
version_file = open(os.path.join(const.DATA_DIR, "vtemplates/VERSION"), "r").read()
open(os.path.join(project_dir, "VERSION"), "w").write(version_file.replace("$version", "").strip())
project_data = pickle.loads(open(project_file, "r").read())
self.loadSourceTree()
self._loadCpuStuff(project_data["CPU_NAME"], project_data["SELECTED_FREQ"])
- self._loadToolchainStuff(project_data["TOOLCHAIN"])
+
# NOTE: this is a HACK!!!
# TODO: find a better way to reuse loadModuleData
preset_project_name = project_data.get("PROJECT_NAME", os.path.basename(preset))
preset_prj_src_path = os.path.join(preset, project_data.get("PROJECT_SRC_PATH", os.path.join(preset, preset_project_name)))
+ preset_prj_hw_path = os.path.join(preset, project_data.get("PROJECT_HW_PATH", preset))
old_project_name = self.infos["PROJECT_NAME"]
old_project_path = self.infos["PROJECT_PATH"]
old_project_src_path = self.infos["PROJECT_SRC_PATH"]
+ old_project_hw_path = self.infos["PROJECT_HW_PATH"]
self.infos["PROJECT_NAME"] = preset_project_name
self.infos["PROJECT_PATH"] = preset
self.infos["PROJECT_SRC_PATH"] = preset_prj_src_path
+ self.infos["PROJECT_HW_PATH"] = preset_prj_hw_path
self.loadModuleData(True)
self.setEnabledModules(project_data["ENABLED_MODULES"])
self.infos["PROJECT_NAME"] = old_project_name
self.infos["PROJECT_PATH"] = old_project_path
self.infos["PROJECT_SRC_PATH"] = old_project_src_path
+ self.infos["PROJECT_HW_PATH"] = old_project_hw_path
+ # End of the ugly HACK!
self.infos["PRESET_NAME"] = preset_project_name
self.infos["PRESET_PATH"] = preset
self.infos["PRESET_SRC_PATH"] = preset_prj_src_path
+ self.infos["PRESET_HW_PATH"] = preset_prj_hw_path
def loadProjectPresets(self):
"""
"""
# NOTE: this method does nothing (for now).
preset_path = os.path.join(self.infos["BERTOS_PATH"], const.PREDEFINED_BOARDS_DIR)
- preset_tree = {}
+ preset_tree = {"children": []}
if os.path.exists(preset_path):
preset_tree = self._loadProjectPresetTree(preset_path)
self.infos["PRESET_TREE"] = preset_tree
_tree["info"] = self._loadPresetInfo(os.path.join(path, const.PREDEFINED_BOARD_SPEC_FILE))
_tree["info"]["filename"] = os.path.basename(path)
_tree["info"]["path"] = path
- _tree["children"] = []
+ _tree["children"] = {}
entries = set(os.listdir(path))
for entry in entries:
_path = os.path.join(path, entry)
if os.path.isdir(_path):
sub_entries = set(os.listdir(_path))
if const.PREDEFINED_BOARD_SPEC_FILE in sub_entries:
- _tree["children"].append(self._loadProjectPresetTree(_path))
+ _tree["children"][_path] = self._loadProjectPresetTree(_path)
# Add into the info dict the dir type (dir/project)
if _tree["children"]:
_tree["info"]["type"] = "dir"
def _loadPresetInfo(self, preset_spec_file):
D = {}
- execfile(preset_spec_file, {}, D)
+ try:
+ execfile(preset_spec_file, {}, D)
+ except IOError, e:
+ pass
return D
def loadModuleData(self, edit=False):
try:
to_be_parsed, module_dict = loadModuleDefinition(comment_list[0])
except ParseError, err:
- raise DefineException.ModuleDefineException(path, err.line_number, err.line)
+ raise DefineException.ModuleDefineException(os.path.join(path, filename), err.line_number, err.line)
for module, information in module_dict.items():
if "depends" not in information:
information["depends"] = ()
information["depends"] += (filename.split(".")[0],)
information["category"] = os.path.basename(path)
+
+ # Hack to remove 'bertos/' from the configuration file path.
+ #
+ # The new module information format substitute paths like 'bertos/cfg/config_file.h'
+ # with the relative path into the bertos directory ('cfg/config_file.h')
+ information["configuration"] = information["configuration"].replace("bertos/", "")
+ information["hw"] = [hw.replace("bertos/", "") for hw in information["hw"]]
+
if "configuration" in information and len(information["configuration"]):
configuration = module_dict[module]["configuration"]
try:
- configuration_info[configuration] = loadConfigurationInfos(self.infos["BERTOS_PATH"] + "/" + configuration)
+ cfg_file_path = os.path.join(self.bertos_srcdir, configuration)
+ configuration_info[configuration] = loadConfigurationInfos(cfg_file_path)
except ParseError, err:
- raise DefineException.ConfigurationDefineException(self.infos["BERTOS_PATH"] + "/" + configuration, err.line_number, err.line)
+ raise DefineException.ConfigurationDefineException(cfg_file_path, err.line_number, err.line)
if edit:
try:
path = self.infos["PROJECT_SRC_PATH"]
- user_configuration = loadConfigurationInfos(configuration.replace("bertos", path))
- configuration_info[configuration] = updateConfigurationValues(configuration_info[configuration], user_configuration)
+ cfg_file_path = os.path.join(path, configuration)
+ configuration_info[configuration] = updateConfigurationValues(configuration_info[configuration], loadConfigurationInfos(cfg_file_path))
except ParseError, err:
- raise DefineException.ConfigurationDefineException(configuration.replace("bertos", path))
+ raise DefineException.ConfigurationDefineException(cfg_file_path, err.line_number, err.line)
+ except IOError, err:
+ # The wizard can't find the file, use the default configuration
+ pass
module_info_dict.update(module_dict)
configuration_info_dict.update(configuration_info)
if to_be_parsed:
list_dict = loadDefineLists(comment_list[1:])
list_info_dict.update(list_dict)
except ParseError, err:
- raise DefineException.EnumDefineException(path, err.line_number, err.line)
+ raise DefineException.EnumDefineException(os.path.join(path, filename), err.line_number, err.line)
for tag in self.infos["CPU_INFOS"]["CPU_TAGS"]:
for filename, path in self.findDefinitions("*_" + tag + ".h"):
comment_list = getCommentList(open(path + "/" + filename, "r").read())
self._newBertosProjectFromPreset()
def _newBertosProject(self):
- for directory in (self.maindir, self.srcdir, self.prjdir, self.cfgdir):
+ for directory in (self.maindir, self.srcdir, self.prjdir, self.cfgdir, self.hwdir):
self._createDirectory(directory)
# Write the project file
self._writeProjectFile(os.path.join(self.maindir, "project.bertos"))
# VERSION file
self._writeVersionFile(os.path.join(self.maindir, "VERSION"))
# Destination makefile
- self._writeMakefile(os.path.join(self.maindir, "Makefile"))
+ self._writeMakefile()
# Copy the sources
- self._copySources(self.sources_dir, self.srcdir)
+ self._copySources(self.bertos_maindir, self.srcdir)
# Set properly the autoenabled parameters
self._setupAutoenabledParameters()
# Copy all the configuration files
- self._writeCfgFiles(self.sources_dir, self.cfgdir)
+ self._writeCfgFiles(self.bertos_srcdir, self.cfgdir)
# Destination wizard mk file
- self._writeWizardMkFile(os.path.join(self.prjdir, os.path.basename(self.prjdir) + "_wiz.mk"))
+ self._writeWizardMkFile()
def _newCustomBertosProject(self):
# Create/write/copy the common things
# Copy the clean hw files
self._createDirectory(self.hwdir)
# Copy all the hw files
- self._writeHwFiles(self.sources_dir, self.hwdir)
+ self._writeHwFiles(self.bertos_srcdir, self.hwdir)
# Destination user mk file
- self._writeUserMkFile(os.path.join(self.prjdir, os.path.basename(self.prjdir) + ".mk"))
+ self._writeUserMkFile()
# Destination main.c file
self._writeMainFile(self.prjdir + "/main.c")
# Create project files for selected plugins
# Create/write/copy the common things
self._newBertosProject()
- # Copy all the files and dirs except cfg/hw/*_wiz.mk
+ # Copy all the files and dirs except cfg/hw/*.mk
self._writeCustomSrcFiles()
- if self.infos["EMPTY_MAIN"]:
- # Create and empty main.c file only if the user check the box
- self._writeMainFile(self.prjdir + "/main.c")
+ # Copy the hw files
+ self._writeAllPresetHwFiles(self.src_hwdir, self.hwdir)
+
+ # Copyt the new *_user.mk file
+ self._writeUserMkFileFromPreset()
# Create project files for selected plugins
self._createProjectFiles()
def _editBertosProject(self):
# Write the project file
self._writeProjectFile(os.path.join(self.maindir, "project.bertos"))
- # VERSION file
- self._writeVersionFile(os.path.join(self.maindir, "VERSION"))
- # Destination makefile
- self._writeMakefile(os.path.join(self.maindir, "Makefile"))
- # Merge sources
- self._mergeSources(self.sources_dir, self.srcdir, self.old_srcdir)
- # Copy all the hw files
- self._writeHwFiles(self.sources_dir, self.hwdir)
+ if not self.is_preset:
+ # Generate this files only if the project isn't a preset
+ # VERSION file
+ self._writeVersionFile(os.path.join(self.maindir, "VERSION"))
+ # Destination makefile
+ self._writeMakefile()
+ # Merge sources
+ self._mergeSources(self.bertos_maindir, self.srcdir, self.old_srcdir)
+ # Copy all the hw files
+ self._writeHwFiles(self.bertos_srcdir, self.hwdir)
+
+ # Destination wizard mk file (it seems that this file need to be
+ # rewritten also if the project is a preset)...
+ self._writeWizardMkFile()
+
# Set properly the autoenabled parameters
self._setupAutoenabledParameters()
# Copy all the configuration files
- self._writeCfgFiles(self.sources_dir, self.cfgdir)
- # Destination wizard mk file
- self._writeWizardMkFile(os.path.join(self.prjdir, os.path.basename(self.prjdir) + "_wiz.mk"))
- # Create project files for selected plugins
- self._createProjectFiles()
+ self._writeCfgFiles(self.bertos_srcdir, self.cfgdir)
+ if not self.is_preset:
+ # Create project files for selected plugins only if the project isn't a preset
+ self._createProjectFiles()
def _createProjectFiles(self):
# Files for selected plugins
self.infos["RELEVANT_FILES"] = relevants_files
def _writeVersionFile(self, filename):
- version_file = open(os.path.join(const.DATA_DIR, "vtemplates/VERSION"), "r").read()
- open(filename, "w").write(versionFileGenerator(self, version_file))
+ if not self.edit or self.old_srcdir:
+ version_file = open(os.path.join(const.DATA_DIR, "vtemplates/VERSION"), "r").read()
+ open(filename, "w").write(versionFileGenerator(self, version_file))
def _writeProjectFile(self, filename):
f = open(filename, "w")
f.write(projectFileGenerator(self))
f.close()
- def _writeMakefile(self, filename):
- makefile = open(os.path.join(const.DATA_DIR, "mktemplates/Makefile"), "r").read()
- makefile = makefileGenerator(self, makefile)
- open(filename, "w").write(makefile)
+ def _writeMakefile(self):
+ bertos_utils.makefileGenerator(self)
- def _writeUserMkFile(self, filename):
- makefile = open(os.path.join(const.DATA_DIR, "mktemplates/template.mk"), "r").read()
- # Deadly performances loss was here :(
- makefile = userMkGenerator(self, makefile)
- open(filename, "w").write(makefile)
+ def _writeUserMkFile(self):
+ bertos_utils.userMkGenerator(self)
- def _writeWizardMkFile(self, filename):
- makefile = open(os.path.join(const.DATA_DIR, "mktemplates/template_wiz.mk"), "r").read()
- makefile = mkGenerator(self, makefile)
- open(filename, "w").write(makefile)
+ def _writeUserMkFileFromPreset(self):
+ bertos_utils.userMkGeneratorFromPreset(self)
+
+ def _writeWizardMkFile(self):
+ bertos_utils.mkGenerator(self)
def _writeMainFile(self, filename):
main = open(os.path.join(const.DATA_DIR, "srctemplates/main.c"), "r").read()
def _writeHwFiles(self, source_dir, destination_dir):
for module, information in self.infos["MODULES"].items():
for hwfile in information["hw"]:
+ if hwfile == "":
+ continue
string = open(source_dir + "/" + hwfile, "r").read()
hwfile_path = destination_dir + "/" + os.path.basename(hwfile)
if not self.edit or not os.path.exists(hwfile_path):
# editing mode it copies only the files that don't exist yet
open(os.path.join(destination_dir,os.path.basename(hwfile)), "w").write(string)
+ def _writeAllPresetHwFiles(self, source_dir, destination_dir):
+ """
+ Copy all but directories contained into the preset hw directory.
+ It's needed because some presets need custom hw files not defined with
+ Wizard directives into modules...
+ """
+ source_dir = os.path.join(source_dir, "hw")
+ for f in os.listdir(source_dir):
+ abspath = os.path.join(source_dir, f)
+ if not os.path.isdir(abspath):
+ # Exlude directories from the copy!
+ hw_file = open(os.path.join(source_dir, f), 'r').read()
+ open(os.path.join(destination_dir, f), 'w').write(hw_file)
+
def _writeCfgFiles(self, source_dir, destination_dir):
for configuration, information in self.infos["CONFIGURATIONS"].items():
string = open(source_dir + "/" + configuration, "r").read()
# Files to be ignored (all project files, cfg dir, wizard mk file, all global ignored dirs)
project_related_stuff = (
"cfg",
- self.infos["PROJECT_NAME"] + "_wiz.mk",
+ "hw",
+ self.infos["PRESET_NAME"] + ".mk",
+ self.infos["PRESET_NAME"] + "_user.mk",
"project.bertos",
- self.infos["PROJECT_NAME"] + ".project",
- self.infos["PROJECT_NAME"] + ".workspace",
+ self.infos["PRESET_NAME"] + ".project",
+ self.infos["PRESET_NAME"] + ".workspace",
) + const.IGNORE_LIST
for element in os.listdir(origin):
if element not in project_related_stuff:
configuration[parameter]["value"] = "1" if information["enabled"] else "0"
self.infos["CONFIGURATIONS"] = configurations
+ # Project related properties
@property
def maindir(self):
return self.infos.get("PROJECT_PATH", None)
def old_srcdir(self):
return self.infos.get("OLD_BERTOS_PATH", None)
+ # BeRTOS sources related properties
@property
- def sources_dir(self):
+ def bertos_maindir(self):
return self.infos.get("BERTOS_PATH", None)
+ @property
+ def bertos_srcdir(self):
+ if self.bertos_maindir:
+ return os.path.join(self.bertos_maindir, "bertos")
+ else:
+ return None
+
+ @property
+ def src_hwdir(self):
+ if self.from_preset:
+ return os.path.join(self.infos["PRESET_PATH"], self.infos["PRESET_HW_PATH"])
+ else:
+ return self.bertos_maindir
+
@property
def from_preset(self):
return self.infos.get("PROJECT_FROM_PRESET", False)
+ @property
+ def is_preset(self):
+ return self.infos.get("PRESET", False)
+
def _createDirectory(self, directory):
if not directory:
return