Merge pull request #5532 from cmens23/master

Exporter for Netbeans GCC_ARM
pull/5898/head
Cruz Monrreal 2018-01-22 10:31:24 -06:00 committed by GitHub
commit c2784c8962
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 740 additions and 0 deletions

View File

@ -33,6 +33,7 @@ from tools.export import embitz, coide, kds, simplicity, atmelstudio, mcuxpresso
from tools.export import sw4stm32, e2studio, zip, cmsis, uvision, cdt, vscode
from tools.export import gnuarmeclipse
from tools.export import qtcreator
from tools.export import nb
from tools.targets import TARGET_NAMES
EXPORTERS = {
@ -57,6 +58,7 @@ EXPORTERS = {
'eclipse_iar' : cdt.EclipseIAR,
'eclipse_armc5' : cdt.EclipseArmc5,
'gnuarmeclipse': gnuarmeclipse.GNUARMEclipse,
'netbeans': nb.GNUARMNetbeans,
'mcuxpresso': mcuxpresso.MCUXpresso,
'qtcreator': qtcreator.QtCreator,
'vscode_gcc_arm' : vscode.VSCodeGcc,

View File

@ -0,0 +1,139 @@
#
# There exist several targets which are by default empty and which can be
# used for execution of your targets. These targets are usually executed
# before and after some main targets. They are:
#
# .build-pre: called before 'build' target
# .build-post: called after 'build' target
# .clean-pre: called before 'clean' target
# .clean-post: called after 'clean' target
# .clobber-pre: called before 'clobber' target
# .clobber-post: called after 'clobber' target
# .all-pre: called before 'all' target
# .all-post: called after 'all' target
# .help-pre: called before 'help' target
# .help-post: called after 'help' target
#
# Targets beginning with '.' are not intended to be called on their own.
#
# Main targets can be executed directly, and they are:
#
# build build a specific configuration
# clean remove built files from a configuration
# clobber remove all built files
# all build all configurations
# help print help mesage
#
# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and
# .help-impl are implemented in nbproject/makefile-impl.mk.
#
# Available make variables:
#
# CND_BASEDIR base directory for relative paths
# CND_DISTDIR default top distribution directory (build artifacts)
# CND_BUILDDIR default top build directory (object files, ...)
# CONF name of current configuration
# CND_PLATFORM_${CONF} platform name (current configuration)
# CND_ARTIFACT_DIR_${CONF} directory of build artifact (current configuration)
# CND_ARTIFACT_NAME_${CONF} name of build artifact (current configuration)
# CND_ARTIFACT_PATH_${CONF} path to build artifact (current configuration)
# CND_PACKAGE_DIR_${CONF} directory of package (current configuration)
# CND_PACKAGE_NAME_${CONF} name of package (current configuration)
# CND_PACKAGE_PATH_${CONF} path to package (current configuration)
#
# NOCDDL
# Environment
MKDIR=mkdir
CP=cp
CCADMIN=CCadmin
BUILDDIR = BUILD
PLATFORM = {{target}}
ELF2BIN = '{{elf2bin_cmd}}'
TARGET = ${CND_DISTDIR}/${CONF}/${CND_PLATFORM}/{{name}}
# build
build: .build-post
.build-pre:
# Add your pre 'build' code here...
.build-post: .build-impl
# Add your post 'build' code here...
$(ELF2BIN) -O binary ${TARGET}.elf ${TARGET}.bin
+@echo "===== bin file ready to flash: $(TARGET).bin ====="
$(ELF2BIN) -O ihex ${TARGET}.elf ${TARGET}.hex
cp ${TARGET}.* ${CND_BUILDDIR}/${CONF}/${CND_PLATFORM}
# clean
clean: .clean-post
.clean-pre:
# Add your pre 'clean' code here...
.clean-post: .clean-impl
# Add your post 'clean' code here...
# clobber
clobber: .clobber-post
.clobber-pre:
# Add your pre 'clobber' code here...
.clobber-post: .clobber-impl
# Add your post 'clobber' code here...
# all
all: .all-post
.all-pre:
# Add your pre 'all' code here...
.all-post: .all-impl
# Add your post 'all' code here...
# build tests
build-tests: .build-tests-post
.build-tests-pre:
# Add your pre 'build-tests' code here...
.build-tests-post: .build-tests-impl
# Add your post 'build-tests' code here...
# run tests
test: .test-post
.test-pre: build-tests
# Add your pre 'test' code here...
.test-post: .test-impl
# Add your post 'test' code here...
# help
help: .help-post
.help-pre:
# Add your pre 'help' code here...
.help-post: .help-impl
# Add your post 'help' code here...
# include project implementation makefile
include nbproject/Makefile-impl.mk
# include project make variables
include nbproject/Makefile-variables.mk
CND_BUILDDIR = ${BUILDDIR}
CND_PLATFORM = ${PLATFORM}

392
tools/export/nb/__init__.py Normal file
View File

@ -0,0 +1,392 @@
import os
import copy
from os.path import relpath, join, exists, dirname, basename
from os import makedirs
from json import load
from tools.export.exporters import Exporter, apply_supported_whitelist
from tools.targets import TARGET_MAP
from tools.utils import NotSupportedException
from tools.build_api import prepare_toolchain
POST_BINARY_WHITELIST = set([
"TEENSY3_1Code.binary_hook",
"MCU_NRF51Code.binary_hook",
"LPCTargetCode.lpc_patch",
"LPC4088Code.binary_hook"
])
class GNUARMNetbeans(Exporter):
NAME = 'GNU ARM Netbeans'
TOOLCHAIN = 'GCC_ARM'
@classmethod
def is_target_supported(cls, target_name):
target = TARGET_MAP[target_name]
return apply_supported_whitelist(
cls.TOOLCHAIN, POST_BINARY_WHITELIST, target)
@staticmethod
def prepare_sys_lib(libname):
return "-l" + libname
def toolchain_flags(self, toolchain):
"""Returns a dictionary of toolchain flags.
Keys of the dictionary are:
cxx_flags - c++ flags
c_flags - c flags
ld_flags - linker flags
asm_flags - assembler flags
common_flags - common options
The difference from the above is that it takes a parameter.
"""
# Note: use the config options from the currently selected toolchain.
config_header = self.toolchain.get_config_header()
flags = {key + "_flags": copy.deepcopy(value) for key, value
in toolchain.flags.iteritems()}
if config_header:
config_header = relpath(config_header,
self.resources.file_basepath[config_header])
header_options = self.toolchain.get_config_option(config_header)
flags['c_flags'] += header_options
flags['cxx_flags'] += header_options
return flags
@staticmethod
def get_defines_and_remove_from_flags(flags_in, str_key):
defines = []
flags_temp = copy.deepcopy(flags_in)
for f in flags_temp[str_key]:
f = f.strip()
if f.startswith('-D'):
defines.append(f[2:])
flags_in[str_key].remove(f)
return defines
@staticmethod
def get_includes_and_remove_from_flags(flags_in, str_key):
includes = []
flags_temp = copy.deepcopy(flags_in)
next_is_include = False
for f in flags_temp[str_key]:
f = f.strip()
if next_is_include:
includes.append(f)
flags_in[str_key].remove(f)
next_is_include = False
continue
if f == "-include":
flags_in[str_key].remove(f)
next_is_include = True
return includes
@staticmethod
def get_c_std_and_remove_from_flag(flags_in, str_key):
comp_std = ''
c_std = {
'c90': 'c90', 'c89': 'c90', 'gnu90': 'gnu90', 'gnu89': 'gnu90',
'c99': 'c99', 'c9x': 'c99', 'gnu99': 'gnu99', 'gnu9x': 'gnu98',
'c11': 'c11', 'c1x': 'c11', 'gnu11': 'gnu11', 'gnu1x': 'gnu11'
}
cpp_std = {
'c++98': 'cpp98', 'c++03': 'cpp98',
'gnu++98': 'gnucpp98', 'gnu++03': 'gnucpp98',
'c++0x': 'cpp0x', 'gnu++0x': 'gnucpp0x',
'c++11': 'cpp11', 'gnu++11': 'gnucpp11',
'c++1y': 'cpp1y', 'gnu++1y': 'gnucpp1y',
'c++14': 'cpp14', 'gnu++14': 'gnucpp14',
'c++1z': 'cpp1z', 'gnu++1z': 'gnucpp1z',
}
flags_temp = copy.deepcopy(flags_in)
for f in flags_temp[str_key]:
f = f.strip()
if f.startswith('-std='):
comp_std = f[len('-std='):]
flags_in[str_key].remove(f)
elif f.startswith('-'):
std = f[len('-'):]
if std in c_std or std in cpp_std:
comp_std = std
flags_in[str_key].remove(f)
return comp_std
def validate_resources(self):
if not self.resources.linker_script:
raise NotSupportedException("No linker script found.")
def create_jinja_ctx(self):
self.options = {}
flags = {}
self.validate_resources()
# Convert all Backslashes to Forward Slashes
self.resources.win_to_unix()
print 'Include folders: {0}'.format(len(self.resources.inc_dirs))
print 'Symbols: {0}'.format(len(self.toolchain.get_symbols()))
self.ld_script = self.filter_dot(
self.resources.linker_script)
print 'Linker script: {0}'.format(self.ld_script)
# Read in all profiles, we'll extract compiler options.
profiles = self.get_all_profiles()
profile_ids = [s.lower() for s in profiles]
profile_ids.sort()
for prof_id in profile_ids:
# There are 4 categories of options, a category common too
# all tools and a specific category for each of the tools.
opts = {}
opts['defines'] = {}
opts['common'] = {}
opts['as'] = {}
opts['c'] = {}
opts['cpp'] = {}
opts['ld'] = {}
opts['id'] = prof_id
opts['name'] = opts['id'].capitalize()
print
print 'Build configuration: {0}'.format(opts['name'])
profile = profiles[prof_id]
# A small hack, do not bother with src_path again,
# pass an empty string to avoid crashing.
src_paths = ['']
target_name = self.toolchain.target.name
toolchain = prepare_toolchain(
src_paths, "", target_name, self.TOOLCHAIN, build_profile=[profile])
flags = self.toolchain_flags(toolchain)
print 'Common flags:', ' '.join(flags['common_flags'])
print 'C++ flags:', ' '.join(flags['cxx_flags'])
print 'C flags:', ' '.join(flags['c_flags'])
print 'ASM flags:', ' '.join(flags['asm_flags'])
print 'Linker flags:', ' '.join(flags['ld_flags'])
opts['defines'] = self.get_defines_and_remove_from_flags(flags, 'common_flags')
opts['forced_includes'] = self.get_includes_and_remove_from_flags(flags, 'common_flags')
opts['common'] = flags['common_flags']
opts['as'] = flags['asm_flags']
opts['c'] = flags['c_flags']
opts['cpp'] = flags['cxx_flags']
opts['ld'] = flags['ld_flags']
self.options[prof_id] = opts
sources = [] # list of strings
forced_includes = self.get_includes_and_remove_from_flags(flags, 'c_flags')
forced_includes += self.get_includes_and_remove_from_flags(flags, 'cxx_flags')
# Remove Duplicates
forced_includes = list(set(forced_includes))
c_std = self.get_c_std_and_remove_from_flag(flags, 'c_flags')
cpp_std = self.get_c_std_and_remove_from_flag(flags, 'cxx_flags')
# Make one list of all resources
for r_type in ['c_sources', 's_sources', 'cpp_sources']:
sources.extend(getattr(self.resources, r_type))
# Remove all leading './'
c_sources = [self.filter_dot(field) for field in self.resources.c_sources]
cpp_sources = [self.filter_dot(field) for field in self.resources.cpp_sources]
s_sources = [self.filter_dot(field) for field in self.resources.s_sources]
headers = [self.filter_dot(field) for field in self.resources.headers]
sources = [self.filter_dot(field) for field in sources]
include_paths = [self.filter_dot(field) for field in self.resources.inc_dirs]
sys_libs = [self.prepare_sys_lib(lib) for lib
in self.toolchain.sys_libs]
preproc = " ".join([basename(self.toolchain.preproc[0])] +
self.toolchain.preproc[1:] +
self.toolchain.ld[1:])
if 'nbproject' in include_paths:
include_paths.remove('nbproject')
jinja_ctx = {
'name': self.project_name,
'target': self.toolchain.target.name,
'elf_location': join('BUILD', self.project_name) + '.elf',
'c_symbols': self.toolchain.get_symbols(),
'asm_symbols': self.toolchain.get_symbols(True),
'c_flags': flags['c_flags'],
'cxx_flags': flags['cxx_flags'],
'ld_flags': self.flags['ld_flags'],
'asm_flags': self.flags['asm_flags'],
'common_flags': self.flags['common_flags'],
'include_paths': include_paths,
'forced_includes': forced_includes,
'c_sources': c_sources,
'cpp_sources': cpp_sources,
's_sources': s_sources,
'headers': headers,
'headers_folder': self.get_netbeans_file_list(sorted(headers)),
'sources_folder': self.get_netbeans_file_list(sorted(sources)),
'options': self.options,
'c_std': self.get_netbeans_c_std(c_std),
'cpp_std': self.get_netbeans_cpp_std(cpp_std),
'linker_script': self.ld_script,
'linker_libs': sys_libs,
'pp_cmd': preproc,
'cc_cmd': self.toolchain.cc[0],
'cppc_cmd': self.toolchain.cppc[0],
'asm_cmd': self.toolchain.asm[0],
'ld_cmd': self.toolchain.ld[0],
'elf2bin_cmd': self.toolchain.elf2bin
}
return jinja_ctx
def generate(self):
"""Generate Makefile, configurations.xml & project.xml Netbeans project file
"""
jinja_ctx = self.create_jinja_ctx()
print
print 'Create a GNU ARM Netbeans C++ managed project'
print 'Project name: {0}'.format(self.project_name)
print 'Target: {0}'.format(self.toolchain.target.name)
print 'Toolchain: {0}'.format(self.TOOLCHAIN)
if not exists(join(self.export_dir, 'nbproject')):
makedirs(join(self.export_dir, 'nbproject'))
self.gen_file('nb/configurations.tmpl', jinja_ctx, 'nbproject/configurations.xml')
self.gen_file('nb/project.tmpl', jinja_ctx, 'nbproject/project.xml')
self.gen_file('nb/mbedignore.tmpl', jinja_ctx, '.mbedignore')
self.gen_file('nb/Makefile.tmpl', jinja_ctx, 'Makefile')
print
print 'Done. Import the \'{0}\' project in Netbeans.'.format(self.project_name)
# -------------------------------------------------------------------------
@staticmethod
def filter_dot(str_in):
"""
Remove the './' prefix, if present.
This function assumes that resources.win_to_unix()
replaced all windows backslashes with slashes.
"""
if str_in is None:
return None
if str_in[:2] == './':
return str_in[2:]
return str_in
# -------------------------------------------------------------------------
@staticmethod
def get_all_profiles():
tools_path = dirname(dirname(dirname(__file__)))
file_names = [join(tools_path, "profiles", fn) for fn in os.listdir(
join(tools_path, "profiles")) if fn.endswith(".json")]
profiles = {}
for fn in file_names:
content = load(open(fn))
profile_name = basename(fn).replace(".json", "")
profiles[profile_name] = content
return profiles
@staticmethod
def get_netbeans_file_list(file_list):
cur_dir = ''
prev_dir = ''
output = []
folder_count = 1
dir_depth = 0
for item in file_list:
cur_dir = os.path.dirname(item)
dir_temp = os.path.normpath(cur_dir)
prev_dir_temp = os.path.normpath(prev_dir)
dir_list = dir_temp.split(os.sep)
prev_dir_list = prev_dir_temp.split(os.sep)
dir_depth = len(dir_list)
# Current File is in Directory: Compare the given dir with previous Dir
if cur_dir and prev_dir != cur_dir:
# evaluate all matched items (from current and previous list)
matched = []
for element in dir_list:
if element in prev_dir_list:
matched.append(element)
# calculate difference between matched and length
diff = dir_depth - len(matched)
# if previous dir was not root
if prev_dir != '':
# if the elements count is not equal we calculate the difference
if len(dir_list) != len(prev_dir_list):
dir_depth_prev = len(prev_dir_list)
delta = dir_depth_prev - len(matched)
for i in range(dir_depth_prev - delta, dir_depth_prev):
output.append('</logicalFolder>')
# if the elements count is equal, we subtract the matched length from the total length
else:
for i in range(len(matched), len(dir_list)):
output.append('</logicalFolder>')
for i in range(dir_depth - diff, dir_depth):
output.append('<logicalFolder name="f' + str(folder_count) + '" displayName="' + str(
dir_list[i]) + '" projectFiles="true">')
folder_count += 1
# Current File is in root
else:
# Close Tag if we are in root and the previous dir wasn't
if cur_dir == '' and prev_dir != '':
for i in range(0, len(prev_dir_list)):
output.append('</logicalFolder>')
# Save the Current Dir
prev_dir = cur_dir
output.append('<itemPath>' + str(item) + '</itemPath>')
if cur_dir != '':
# close all open tags
output.append('</logicalFolder>' * dir_depth)
return output
@staticmethod
def get_netbeans_c_std(c_std):
c_std_netbeans = 0
if '89' in c_std:
c_std_netbeans = 2
elif '99' in c_std:
c_std_netbeans = 3
elif '11' in c_std:
c_std_netbeans = 10
return c_std_netbeans
@staticmethod
def get_netbeans_cpp_std(cpp_std):
cpp_std_netbeans = 0
if '98' in cpp_std:
cpp_std_netbeans = 4
elif '11' in cpp_std:
cpp_std_netbeans = 8
elif '14' in cpp_std:
cpp_std_netbeans = 11
return cpp_std_netbeans

View File

@ -0,0 +1,177 @@
<?xml version="1.0" encoding="UTF-8"?>
<configurationDescriptor version="100">
<logicalFolder name="root" displayName="root" projectFiles="true" kind="ROOT">
<logicalFolder name="HeaderFiles"
displayName="Header Files"
projectFiles="true">
{% for header in headers_folder -%}
{{ header }}
{% endfor %}
</logicalFolder>
<logicalFolder name="LinkerScript"
displayName="Linker Files"
projectFiles="true">
<itemPath>{{ linker_script }}</itemPath>
</logicalFolder>
<logicalFolder name="ResourceFiles"
displayName="Resource Files"
projectFiles="true">
</logicalFolder>
<logicalFolder name="SourceFiles"
displayName="Source Files"
projectFiles="true">
{% for source in sources_folder -%}
{{ source }}
{% endfor %}
</logicalFolder>
<logicalFolder name="OtherFiles"
displayName="Other Files"
projectFiles="true">
</logicalFolder>
<logicalFolder name="TestFiles"
displayName="Test Files"
projectFiles="false"
kind="TEST_LOGICAL_FOLDER">
</logicalFolder>
<logicalFolder name="ExternalFiles"
displayName="Important Files"
projectFiles="false"
kind="IMPORTANT_FILES_FOLDER">
<itemPath>Makefile</itemPath>
</logicalFolder>
</logicalFolder>
<sourceFolderFilter>^(nbproject)$</sourceFolderFilter>
<sourceRootList>
<Elem>.</Elem>
</sourceRootList>
<projectmakefile>Makefile</projectmakefile>
<confs>
{% for id in options -%}
{% set opts = options[id] %}
<conf name="{{opts['id']}}" type="1">
<toolsSet>
<compilerSet>default</compilerSet>
<dependencyChecking>true</dependencyChecking>
<rebuildPropChanged>false</rebuildPropChanged>
</toolsSet>
<compileType>
<cTool>
<standard>{{ c_std }}</standard>
<incDir>
{% for inc_dir in include_paths -%}{% if inc_dir -%}
<pElem>{{ inc_dir }}</pElem>
{% endif -%}
{% endfor -%}
</incDir>
<incFile>
{% for inc_file in forced_includes -%}
<pElem>{{ inc_file }}</pElem>
{% endfor -%}
</incFile>
<commandLine>{%- for flag in c_flags -%}{{ flag+" "}}{%- endfor -%}
{%- for item in opts['common'] -%}{{ item+" "}}{%- endfor -%}
</commandLine>
<preprocessorList>
{% for item in opts['defines'] -%}
<Elem>{{ item }}</Elem>
{% endfor -%}
{% for symbol in c_symbols -%}
<Elem>{{ symbol }}</Elem>
{% endfor -%}
</preprocessorList>
<commandlineTool>{{cc_cmd}}</commandlineTool>
</cTool>
<ccTool>
<standard>{{ cpp_std }}</standard>
<incDir>
{% for inc_dir in include_paths -%}{% if inc_dir -%}
<pElem>{{ inc_dir }}</pElem>
{% endif -%}
{% endfor -%}
</incDir>
<incFile>
{% for inc_file in forced_includes -%}
<pElem>{{ inc_file }}</pElem>
{% endfor -%}
</incFile>
<commandLine>{%- for flag in cxx_flags -%}{{ flag+" "}}{%- endfor -%}
{%- for item in opts['common'] -%}{{ item+" "}}{%- endfor -%}
</commandLine>
<preprocessorList>
{% for item in opts['defines'] -%}
<Elem>{{ item }}</Elem>
{% endfor -%}
{% for symbol in c_symbols -%}
<Elem>{{ symbol }}</Elem>
{% endfor -%}
</preprocessorList>
<commandlineTool>{{cppc_cmd}}</commandlineTool>
</ccTool>
<fortranCompilerTool>
<developmentMode>5</developmentMode>
</fortranCompilerTool>
<asmTool>
<developmentMode>5</developmentMode>
<incDir>
{% for inc_dir in include_paths -%}{% if inc_dir -%}
<pElem>{{ inc_dir }}</pElem>
{% endif -%}
{% endfor -%}
</incDir>
<incFile>
{% for inc_file in forced_includes -%}
<pElem>{{ inc_file }}</pElem>
{% endfor -%}
</incFile>
<commandLine>{%- for flag in asm_flags -%}{{ flag+" "}}{%- endfor -%}
{%- for item in opts['common'] -%}{{ item+" "}}{%- endfor -%}
</commandLine>
<preprocessorList>
{% for symbol in asm_symbols -%}
<Elem>{{ symbol }}</Elem>
{% endfor -%}
</preprocessorList>
<commandlineTool>{{asm_cmd}}</commandlineTool>
</asmTool>
<linkerTool>
<output>${CND_DISTDIR}/${CND_CONF}/{{target}}/{{name}}.elf</output>
<additionalDep>${CND_BUILDDIR}/${CND_CONF}/{{target}}/.link_script.ld</additionalDep>
<commandlineTool>{{ld_cmd}}</commandlineTool>
<commandLine>-T ${CND_BUILDDIR}/${CND_CONF}/{{target}}/.link_script.ld {%- for symbol in opts['ld'] -%}{{" "+symbol}}{%- endfor -%} {%- for item in linker_libs -%}{{" "+item}}{%- endfor -%} </commandLine>
</linkerTool>
</compileType>
{% for h in headers -%}
<item path="{{h}}" ex="false" tool="3" flavor2="0">
</item>
{% endfor -%}
{% for s in c_sources -%}
<item path="{{s}}" ex="false" tool="0" flavor2="3">
<cTool flags="1">
</cTool>
</item>
{% endfor -%}
{% for s in cpp_sources -%}
<item path="{{s}}" ex="false" tool="1" flavor2="0">
<ccTool flags="0">
</ccTool>
</item>
{% endfor -%}
{% for s in s_sources -%}
<item path="{{s}}" ex="false" tool="0" flavor2="0">
</item>
{% endfor -%}
<item path="{{linker_script }}" ex="false" tool="3" flavor2="0">
<customTool>
<customToolCommandline>{{pp_cmd}} -o $@ $&lt;</customToolCommandline>
<customToolDescription>Create ELF File using Link Script</customToolDescription>
<customToolOutputs>${CND_BUILDDIR}/${CND_CONF}/{{target}}/.link_script.ld</customToolOutputs>
</customTool>
</item>
<item path="/nbproject/private/c_standard_headers_indexer.c" ex="true" tool="0" flavor2="0">
</item>
<item path="/nbproject/private/c_standard_headers_indexer.cpp" ex="true" tool="1" flavor2="0">
</item>
</conf>
{% endfor -%}
</confs>
</configurationDescriptor>

View File

@ -0,0 +1,2 @@
nbproject/private/*.cpp
nbproject/private/*.c

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.cnd.makeproject</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/make-project/1">
<name>{{name}}</name>
<c-extensions>c</c-extensions>
<cpp-extensions>cpp</cpp-extensions>
<header-extensions>h</header-extensions>
<sourceEncoding>UTF-8</sourceEncoding>
<make-dep-projects/>
<sourceRootList/>
<confList>
<confElem>
<name>Debug</name>
<type>1</type>
</confElem>
<confElem>
<name>Release</name>
<type>1</type>
</confElem>
</confList>
<formatting>
<project-formatting-style>false</project-formatting-style>
</formatting>
</data>
</configuration>
</project>