mirror of https://github.com/ARMmbed/mbed-os.git
Compute source folders exclusions.
parent
e717c781b0
commit
9e84338178
|
|
@ -1,5 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
<?fileVersion 4.0.0?>
|
||||
<!-- Generated by the GNU ARM Eclipse exporter from an mBed project. -->
|
||||
<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.{{debug_config_uid}}">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.{{debug_config_uid}}" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
|
|
@ -156,7 +158,7 @@
|
|||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry excluding="mbed-os" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||
<entry excluding="{{excluded_folders}}" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||
</sourceEntries>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
|
|
@ -313,7 +315,7 @@
|
|||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry excluding="mbed-os" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||
<entry excluding="{{excluded_folders}}" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||
</sourceEntries>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated by the GNU ARM Eclipse exporter from an mBed project. -->
|
||||
<projectDescription>
|
||||
<name>{{name}}</name>
|
||||
<comment>This file was automagically generated by mbed.org. For more information, see http://mbed.org/handbook/Exporting-To-GNU-ARM-Eclipse</comment>
|
||||
|
|
|
|||
|
|
@ -13,22 +13,38 @@ distributed under the License is distributed on an "AS IS" BASIS,
|
|||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Title: GNU ARM Eclipse (http://gnuarmeclipse.github.io) exporter.
|
||||
|
||||
Description: Creates a managed build project that can be imported by
|
||||
the GNU ARM Eclipse plug-ins.
|
||||
|
||||
Author: Liviu Ionescu <ilg@livius.net>
|
||||
"""
|
||||
from tools.export.exporters import Exporter
|
||||
from os.path import splitext, basename, relpath
|
||||
from os.path import splitext, basename, relpath, dirname
|
||||
from random import randint
|
||||
import os
|
||||
import copy
|
||||
|
||||
from tools.targets import TARGET_MAP
|
||||
from tools.utils import NotSupportedException
|
||||
|
||||
|
||||
class UID:
|
||||
"""
|
||||
Helper class, used to generate unique ids required by .cproject symbols.
|
||||
"""
|
||||
@property
|
||||
def id(self):
|
||||
return "%0.9u" % randint(0, 999999999)
|
||||
|
||||
# Global UID generator instance.
|
||||
# Passed to the template engine, and referred as {{u.id}}.
|
||||
# Each invocation generates a new number.
|
||||
u = UID()
|
||||
|
||||
|
||||
class GNUARMEclipse(Exporter):
|
||||
NAME = 'GNU ARM Eclipse'
|
||||
TOOLCHAIN = 'GCC_ARM'
|
||||
|
|
@ -39,6 +55,9 @@ class GNUARMEclipse(Exporter):
|
|||
|
||||
@staticmethod
|
||||
def filter_dot(s):
|
||||
"""
|
||||
Remove the './' prefix, if present.
|
||||
"""
|
||||
if s == None:
|
||||
return None
|
||||
if s[:2] == './':
|
||||
|
|
@ -54,6 +73,9 @@ class GNUARMEclipse(Exporter):
|
|||
ld_flags - linker flags
|
||||
asm_flags - assembler flags
|
||||
common_flags - common options
|
||||
|
||||
The difference from the parent function is that it does not
|
||||
add macro definitions, since they are passed separately.
|
||||
"""
|
||||
config_header = self.toolchain.get_config_header()
|
||||
flags = {key + "_flags": copy.deepcopy(value) for key, value
|
||||
|
|
@ -66,9 +88,129 @@ class GNUARMEclipse(Exporter):
|
|||
config_header)
|
||||
return flags
|
||||
|
||||
def dump_tree(self, node, depth=0):
|
||||
for k in node.keys():
|
||||
n = node[k]
|
||||
pn = n['parent']['name'] if 'parent' in n.keys() else ''
|
||||
print ' ' * depth, n['name'], n['is_used'], pn
|
||||
if len(n['children'].keys()) != 0:
|
||||
self.dump_tree(n['children'], depth + 1)
|
||||
|
||||
def dump_paths(self, node, depth=0):
|
||||
for k in node.keys():
|
||||
n = node[k]
|
||||
x = []
|
||||
ni = n
|
||||
while True:
|
||||
x.insert(0, ni['name'])
|
||||
if 'parent' not in ni:
|
||||
break
|
||||
ni = ni['parent']
|
||||
path = '/'.join(x)
|
||||
print path, n['is_used']
|
||||
self.dump_paths(n['children'], depth + 1)
|
||||
|
||||
def recurse_excludings(self, node):
|
||||
"""
|
||||
Recurse the tree and collect all unused folders; descend
|
||||
the hierarchy only for used nodes.
|
||||
"""
|
||||
for k in node.keys():
|
||||
n = node[k]
|
||||
if n['is_used'] == False:
|
||||
x = []
|
||||
ni = n
|
||||
while True:
|
||||
x.insert(0, ni['name'])
|
||||
if 'parent' not in ni:
|
||||
break
|
||||
ni = ni['parent']
|
||||
path = '/'.join(x)
|
||||
# print path
|
||||
self.excluded_folders.append(path)
|
||||
else:
|
||||
self.recurse_excludings(n['children'])
|
||||
|
||||
def add_source_folder_to_tree(self, path, is_used=False):
|
||||
"""
|
||||
Decompose a path in an array of folder names and create the tree.
|
||||
On the second pass the nodes should be already there; mark them
|
||||
as used.
|
||||
"""
|
||||
# print path, is_used
|
||||
a = path.split(os.sep)
|
||||
n = self.source_tree
|
||||
p = None
|
||||
for s in a:
|
||||
if s[0] == '.':
|
||||
continue
|
||||
if s not in n.keys():
|
||||
nn = {}
|
||||
nn['name'] = s
|
||||
nn['children'] = {}
|
||||
if p != None:
|
||||
nn['parent'] = p
|
||||
n[s] = nn
|
||||
n[s]['is_used'] = is_used
|
||||
p = n[s]
|
||||
n = n[s]['children']
|
||||
|
||||
def compute_exclusions(self):
|
||||
"""
|
||||
With the project root as the only source folder known to CDT,
|
||||
based on the list of source files, compute the folders to not
|
||||
be included in the build.
|
||||
|
||||
The steps are:
|
||||
- get the list of source folders, as dirname(source_file)
|
||||
- compute the top folders (subfolders of the project folders)
|
||||
- iterate all subfolders and add them to a tree, with all
|
||||
nodes markes as 'not used'
|
||||
- iterate the source folders and mark them as 'used' in the
|
||||
tree, including all intermediate nodes
|
||||
- recurse the tree and collect all unused folders; descend
|
||||
the hierarchy only for used nodes
|
||||
"""
|
||||
source_folders = [self.filter_dot(s) for s in set(dirname(
|
||||
src) for src in self.resources.c_sources + self.resources.cpp_sources + self.resources.s_sources)]
|
||||
source_folders.remove('.')
|
||||
# print 'source folders'
|
||||
# print source_folders
|
||||
|
||||
top_folders = [f for f in set(s.split(os.sep)[0]
|
||||
for s in source_folders)]
|
||||
# print 'top folders'
|
||||
# print top_folders
|
||||
|
||||
self.source_tree = {}
|
||||
for top_folder in top_folders:
|
||||
for root, dirs, files in os.walk(top_folder):
|
||||
if len(dirs) == 0:
|
||||
self.add_source_folder_to_tree(root)
|
||||
|
||||
for folder in source_folders:
|
||||
self.add_source_folder_to_tree(folder, True)
|
||||
|
||||
# print
|
||||
# print self.source_tree
|
||||
# self.dump_paths(self.source_tree)
|
||||
|
||||
# print 'excludings'
|
||||
self.excluded_folders = []
|
||||
self.recurse_excludings(self.source_tree)
|
||||
|
||||
def generate(self):
|
||||
"""
|
||||
Override the parent method with code generation.
|
||||
"""
|
||||
if not self.resources.linker_script:
|
||||
raise NotSupportedException("No linker script found.")
|
||||
|
||||
# TODO: Check if this is needed.
|
||||
# self.resources.win_to_unix()
|
||||
|
||||
libraries = []
|
||||
print self.resources.libraries
|
||||
for lib in self.resources.libraries:
|
||||
l, _ = splitext(basename(lib))
|
||||
libraries.append(l[3:])
|
||||
|
|
@ -88,7 +230,7 @@ class GNUARMEclipse(Exporter):
|
|||
core = self.toolchain.target.core
|
||||
|
||||
try:
|
||||
# cortex-m0, cortex-m0-small-multiply, cortex-m0plus,
|
||||
# cortex-m0, cortex-m0-small-multiply, cortex-m0plus,
|
||||
# cortex-m0plus-small-multiply, cortex-m1, cortex-m1-small-multiply,
|
||||
# cortex-m3, cortex-m4, cortex-m7.
|
||||
target_mcpu = MCPUS[core]['mcpu']
|
||||
|
|
@ -101,16 +243,21 @@ class GNUARMEclipse(Exporter):
|
|||
|
||||
if target_fpu_unit != None:
|
||||
target_fpu_abi = 'hard'
|
||||
|
||||
|
||||
except AttributeError:
|
||||
# TODO filter out projects with toolchain core not supported,
|
||||
# instead of raising an exception.
|
||||
raise NotSupportedException('Target core {0} not supported.'.format(core))
|
||||
raise NotSupportedException(
|
||||
'Target core {0} not supported.'.format(core))
|
||||
|
||||
# TODO: clarify how to use objects; enabling this adds another
|
||||
# object 'main.o'.
|
||||
objects = [] # self.resources.objects
|
||||
print self.resources.objects
|
||||
# TODO: get the list from existing .cproject
|
||||
build_folders = ['Debug', 'Release']
|
||||
|
||||
objects = [self.filter_dot(s) for s in self.resources.objects]
|
||||
for bf in build_folders:
|
||||
objects = [o for o in objects if not o.startswith(bf + '/')]
|
||||
print 'objects'
|
||||
print objects
|
||||
|
||||
f = self.flags
|
||||
print 'common_flags'
|
||||
|
|
@ -124,10 +271,16 @@ class GNUARMEclipse(Exporter):
|
|||
print 'ld_flags'
|
||||
print f['ld_flags']
|
||||
|
||||
source_folders = [self.filter_dot(s) for s in set(dirname(
|
||||
src) for src in self.resources.c_sources + self.resources.cpp_sources + self.resources.s_sources)]
|
||||
source_folders.remove('.')
|
||||
|
||||
self.compute_exclusions()
|
||||
|
||||
asm_defines = self.toolchain.get_symbols(True)
|
||||
c_defines = self.toolchain.get_symbols()
|
||||
cpp_defines = self.toolchain.get_symbols()
|
||||
|
||||
|
||||
include_paths = [self.filter_dot(s) for s in self.resources.inc_dirs]
|
||||
|
||||
library_paths = [self.filter_dot(s) for s in self.resources.lib_dirs]
|
||||
|
|
@ -136,6 +289,7 @@ class GNUARMEclipse(Exporter):
|
|||
|
||||
ctx = {
|
||||
'name': self.project_name,
|
||||
'excluded_folders': '|'.join(self.excluded_folders),
|
||||
'include_paths': include_paths,
|
||||
'library_paths': library_paths,
|
||||
'object_files': objects,
|
||||
|
|
@ -166,7 +320,26 @@ class GNUARMEclipse(Exporter):
|
|||
'u': u,
|
||||
}
|
||||
|
||||
# ctx.update(f)
|
||||
|
||||
self.gen_file('gnuarmeclipse/.project.tmpl', ctx, '.project')
|
||||
self.gen_file('gnuarmeclipse/.cproject.tmpl', ctx, '.cproject')
|
||||
|
||||
@staticmethod
|
||||
def build(project_name, log_name="build_log.txt", cleanup=True):
|
||||
"""
|
||||
Build GNU ARM Eclipse project.
|
||||
"""
|
||||
|
||||
ret_code = 0
|
||||
|
||||
# TODO: add code to run the build in a headless configuration.
|
||||
|
||||
# Cleanup the exported and built files
|
||||
if cleanup:
|
||||
os.remove('.project')
|
||||
os.remove('.cproject')
|
||||
|
||||
if ret_code !=0:
|
||||
# Seems like something went wrong.
|
||||
return -1
|
||||
else:
|
||||
return 0
|
||||
|
|
|
|||
Loading…
Reference in New Issue