first commit for chrg

This commit is contained in:
wmano
2025-08-16 22:58:22 +08:00
commit 52a3ed5862
2306 changed files with 1021208 additions and 0 deletions
+79
View File
@@ -0,0 +1,79 @@
# -*- coding: utf-8 -*-
#
# File : __init__.py
# This file is part of RT-Thread RTOS
# COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Change Logs:
# Date Author Notes
# 2025-01-XX Bernard Create targets module for IDE project generators
# Import all target generators
from . import keil
from . import iar
from . import vs
from . import vs2012
from . import codeblocks
from . import ua
from . import vsc
from . import cdk
from . import ses
from . import eclipse
from . import codelite
from . import cmake
from . import xmake
from . import esp_idf
from . import zigbuild
from . import makefile
from . import rt_studio
# Export all target generator functions
__all__ = [
# Keil MDK
'keil',
# IAR
'iar',
# Visual Studio
'vs',
'vs2012',
# Code::Blocks
'codeblocks',
# Universal ARM
'ua',
# VSCode
'vsc',
# CDK
'cdk',
# SEGGER Embedded Studio
'ses',
# Eclipse
'eclipse',
# CodeLite
'codelite',
# CMake
'cmake',
# XMake
'xmake',
# ESP-IDF
'esp_idf',
# Zig
'zigbuild',
# Make
'makefile',
# RT-Studio
'rt_studio'
]
+137
View File
@@ -0,0 +1,137 @@
#
# File : keil.py
# This file is part of RT-Thread RTOS
# COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Change Logs:
# Date Author Notes
# 2017-10-16 Tanek Add CDK IDE support
#
import os
import sys
import string
import xml.etree.ElementTree as etree
from xml.etree.ElementTree import SubElement
from utils import _make_path_relative
from utils import xml_indent
def SDKAddGroup(ProjectFiles, parent, name, files, project_path):
# don't add an empty group
if len(files) == 0:
return
group = SubElement(parent, 'VirtualDirectory', attrib={'Name': name})
for f in files:
fn = f.rfile()
name = fn.name
path = os.path.dirname(fn.abspath)
basename = os.path.basename(path)
path = _make_path_relative(project_path, path)
elm_attr_name = os.path.join(path, name)
file = SubElement(group, 'File', attrib={'Name': elm_attr_name})
return group
def _CDKProject(tree, target, script):
project_path = os.path.dirname(os.path.abspath(target))
root = tree.getroot()
out = open(target, 'w')
out.write('<?xml version="1.0" encoding="UTF-8"?>\n')
CPPPATH = []
CPPDEFINES = []
LINKFLAGS = ''
CCFLAGS = ''
LIBS = []
ProjectFiles = []
for child in root:
if child.tag == 'VirtualDirectory':
root.remove(child)
for group in script:
group_tree = SDKAddGroup(ProjectFiles, root, group['name'], group['src'], project_path)
# get each include path
if 'CPPPATH' in group and group['CPPPATH']:
if CPPPATH:
CPPPATH += group['CPPPATH']
else:
CPPPATH += group['CPPPATH']
# get each group's definitions
if 'CPPDEFINES' in group and group['CPPDEFINES']:
if CPPDEFINES:
CPPDEFINES += group['CPPDEFINES']
else:
CPPDEFINES += group['CPPDEFINES']
# get each group's cc flags
if 'CCFLAGS' in group and group['CCFLAGS']:
if CCFLAGS:
CCFLAGS += ' ' + group['CCFLAGS']
else:
CCFLAGS += group['CCFLAGS']
# get each group's link flags
if 'LINKFLAGS' in group and group['LINKFLAGS']:
if LINKFLAGS:
LINKFLAGS += ' ' + group['LINKFLAGS']
else:
LINKFLAGS += group['LINKFLAGS']
# todo: cdk add lib
if 'LIBS' in group and group['LIBS']:
LIBS += group['LIBS']
# write include path, definitions and link flags
text = ';'.join([_make_path_relative(project_path, os.path.normpath(i)) for i in CPPPATH])
IncludePath = tree.find('BuildConfigs/BuildConfig/Compiler/IncludePath')
IncludePath.text = text
IncludePath = tree.find('BuildConfigs/BuildConfig/Asm/IncludePath')
IncludePath.text = text
Define = tree.find('BuildConfigs/BuildConfig/Compiler/Define')
Define.text = '; '.join(set(CPPDEFINES))
CC_Misc = tree.find('BuildConfigs/BuildConfig/Compiler/OtherFlags')
CC_Misc.text = CCFLAGS
LK_Misc = tree.find('BuildConfigs/BuildConfig/Linker/OtherFlags')
LK_Misc.text = LINKFLAGS
LibName = tree.find('BuildConfigs/BuildConfig/Linker/LibName')
if LibName.text:
LibName.text=LibName.text+';'+';'.join(LIBS)
else:
LibName.text=';'.join(LIBS)
xml_indent(root)
out.write(etree.tostring(root, encoding='utf-8'))
out.close()
def CDKProject(target, script):
template_tree = etree.parse('template.cdkproj')
_CDKProject(template_tree, target, script)
+345
View File
@@ -0,0 +1,345 @@
"""
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-05-24 klivelinux first version
* 2021-04-19 liukangcc add c++ support and libpath
* 2021-06-25 Guozhanxin fix path issue
* 2021-06-30 Guozhanxin add scons --target=cmake-armclang
* 2022-03-16 liukangcc 通过 SCons生成 CMakefile.txt 使用相对路径
* 2022-04-12 mysterywolf rtconfig.CROSS_TOOL->rtconfig.PLATFORM
* 2022-04-29 SunJun8 默认开启生成编译数据库
* 2024-03-18 wirano fix the issue of the missing link flags added in Sconscript
* 2024-07-04 kaidegit Let cmake generator get more param from `rtconfig.py`
* 2024-08-07 imi415 Updated CMake generator handles private macros, using OBJECT and INTERFACE libraries.
* 2024-11-18 kaidegit fix processing groups with similar name
* 2025-02-22 kaidegit fix missing some flags added in Sconscript
* 2025-02-24 kaidegit remove some code that is unnecessary but takes time, get them from env
"""
import os
import sys
import re
import utils
import rtconfig
from utils import _make_path_relative
from collections import defaultdict, Counter
def GenerateCFiles(env, project, project_name):
"""
Generate CMakeLists.txt files
"""
PROJECT_NAME = project_name if project_name != "project" else "rtthread"
tool_path_conv = defaultdict(lambda : {"name":"", "path": ""})
tool_path_conv_helper = lambda tool: {"name": tool, "path": os.path.join(rtconfig.EXEC_PATH, tool).replace('\\', "/")}
tool_path_conv["CMAKE_C_COMPILER"] = tool_path_conv_helper(rtconfig.CC)
if 'CXX' in dir(rtconfig):
tool_path_conv["CMAKE_CXX_COMPILER"] = tool_path_conv_helper(rtconfig.CXX)
tool_path_conv["CMAKE_ASM_COMPILER"] = tool_path_conv_helper(rtconfig.AS)
tool_path_conv["CMAKE_AR"] = tool_path_conv_helper(rtconfig.AR)
tool_path_conv["CMAKE_LINKER"] = tool_path_conv_helper(rtconfig.LINK)
if rtconfig.PLATFORM in ['gcc']:
tool_path_conv["CMAKE_SIZE"] = tool_path_conv_helper(rtconfig.SIZE)
tool_path_conv["CMAKE_OBJDUMP"] = tool_path_conv_helper(rtconfig.OBJDUMP)
tool_path_conv["CMAKE_OBJCOPY"] = tool_path_conv_helper(rtconfig.OBJCPY)
elif rtconfig.PLATFORM in ['armcc', 'armclang']:
tool_path_conv["CMAKE_FROMELF"] = tool_path_conv_helper(rtconfig.FROMELF)
CC = tool_path_conv["CMAKE_C_COMPILER"]["path"]
CXX = tool_path_conv["CMAKE_CXX_COMPILER"]["path"]
AS = tool_path_conv["CMAKE_ASM_COMPILER"]["path"]
AR = tool_path_conv["CMAKE_AR"]["path"]
LINK = tool_path_conv["CMAKE_LINKER"]["path"]
SIZE = tool_path_conv["CMAKE_SIZE"]["path"]
OBJDUMP = tool_path_conv["CMAKE_OBJDUMP"]["path"]
OBJCOPY = tool_path_conv["CMAKE_OBJCOPY"]["path"]
FROMELF = tool_path_conv["CMAKE_FROMELF"]["path"]
CFLAGS = env['CFLAGS'].replace('\\', "/").replace('\"', "\\\"")
if 'CXXFLAGS' in dir(rtconfig):
cflag_str=''.join(env['CXXFLAGS'])
CXXFLAGS = cflag_str.replace('\\', "/").replace('\"', "\\\"")
else:
CXXFLAGS = CFLAGS
AFLAGS = env['ASFLAGS'].replace('\\', "/").replace('\"', "\\\"")
LFLAGS = env['LINKFLAGS'].replace('\\', "/").replace('\"', "\\\"")
POST_ACTION = rtconfig.POST_ACTION
# replace the tool name with the cmake variable
for cmake_var, each_tool in tool_path_conv.items():
tool_name = each_tool['name']
if tool_name == "": continue
if "win32" in sys.platform:
while f"{tool_name}.exe" in POST_ACTION: # find the tool with `.exe` suffix first
POST_ACTION = POST_ACTION.replace(tool_name, "string_to_replace")
while tool_name in POST_ACTION:
POST_ACTION = POST_ACTION.replace(tool_name, "string_to_replace")
while "string_to_replace" in POST_ACTION:
POST_ACTION = POST_ACTION.replace("string_to_replace", f"${{{cmake_var}}}")
# replace the `$TARGET` with `${CMAKE_PROJECT_NAME}.elf`
while "$TARGET" in POST_ACTION:
POST_ACTION = POST_ACTION.replace("$TARGET", "${CMAKE_PROJECT_NAME}.elf")
# add COMMAAND before each command
POST_ACTION = POST_ACTION.split('\n')
POST_ACTION = [each_line.strip() for each_line in POST_ACTION]
POST_ACTION = [f"\tCOMMAND {each_line}" for each_line in POST_ACTION if each_line != '']
POST_ACTION = "\n".join(POST_ACTION)
if "win32" in sys.platform:
CC += ".exe"
if CXX != '':
CXX += ".exe"
AS += ".exe"
AR += ".exe"
LINK += ".exe"
if rtconfig.PLATFORM in ['gcc']:
SIZE += ".exe"
OBJDUMP += ".exe"
OBJCOPY += ".exe"
elif rtconfig.PLATFORM in ['armcc', 'armclang']:
FROMELF += ".exe"
if not os.path.exists(CC) or not os.path.exists(AS) or not os.path.exists(AR) or not os.path.exists(LINK):
print("'Cannot found toolchain directory, please check RTT_CC and RTT_EXEC_PATH'")
sys.exit(-1)
with open("CMakeLists.txt", "w") as cm_file:
cm_file.write("CMAKE_MINIMUM_REQUIRED(VERSION 3.10)\n\n")
cm_file.write("SET(CMAKE_SYSTEM_NAME Generic)\n")
cm_file.write("SET(CMAKE_SYSTEM_PROCESSOR " + rtconfig.CPU +")\n")
cm_file.write("#SET(CMAKE_VERBOSE_MAKEFILE ON)\n\n")
cm_file.write("SET(CMAKE_EXPORT_COMPILE_COMMANDS ON)\n\n")
cm_file.write("SET(CMAKE_C_COMPILER \""+ CC + "\")\n")
cm_file.write("SET(CMAKE_ASM_COMPILER \""+ AS + "\")\n")
cm_file.write("SET(CMAKE_C_FLAGS \""+ CFLAGS + "\")\n")
cm_file.write("SET(CMAKE_ASM_FLAGS \""+ AFLAGS + "\")\n")
cm_file.write("SET(CMAKE_C_COMPILER_WORKS TRUE)\n\n")
if CXX != '':
cm_file.write("SET(CMAKE_CXX_COMPILER \""+ CXX + "\")\n")
cm_file.write("SET(CMAKE_CXX_FLAGS \""+ CXXFLAGS + "\")\n")
cm_file.write("SET(CMAKE_CXX_COMPILER_WORKS TRUE)\n\n")
if rtconfig.PLATFORM in ['gcc']:
cm_file.write("SET(CMAKE_OBJCOPY \""+ OBJCOPY + "\")\n")
cm_file.write("SET(CMAKE_SIZE \""+ SIZE + "\")\n\n")
elif rtconfig.PLATFORM in ['armcc', 'armclang']:
cm_file.write("SET(CMAKE_FROMELF \""+ FROMELF + "\")\n\n")
LINKER_FLAGS = ''
LINKER_LIBS = ''
if rtconfig.PLATFORM in ['gcc']:
LINKER_FLAGS += '-T'
elif rtconfig.PLATFORM in ['armcc', 'armclang']:
LINKER_FLAGS += '--scatter'
for group in project:
if 'LIBPATH' in group.keys():
for f in group['LIBPATH']:
LINKER_LIBS += ' --userlibpath ' + f.replace("\\", "/")
for group in project:
if 'LIBS' in group.keys():
for f in group['LIBS']:
LINKER_LIBS += ' ' + f.replace("\\", "/") + '.lib'
cm_file.write("SET(CMAKE_EXE_LINKER_FLAGS \""+ re.sub(LINKER_FLAGS + r'(\s*)', LINKER_FLAGS + r' ${CMAKE_SOURCE_DIR}/', LFLAGS) + LINKER_LIBS + "\")\n\n")
# get the c/cpp standard version from compilation flags
# not support the version with alphabet in `-std` param yet
pattern = re.compile(r'-std=[\w+]+')
c_standard = 11
if '-std=' in CFLAGS:
c_standard = re.search(pattern, CFLAGS).group(0)
c_standard = "".join([each for each in c_standard if each.isdigit()])
else:
print(f"Cannot find the param of the c standard in build flag, set to default {c_standard}")
cm_file.write(f"SET(CMAKE_C_STANDARD {c_standard})\n")
if CXX != '':
cpp_standard = 17
if '-std=' in CXXFLAGS:
cpp_standard = re.search(pattern, CXXFLAGS).group(0)
cpp_standard = "".join([each for each in cpp_standard if each.isdigit()])
else:
print(f"Cannot find the param of the cpp standard in build flag, set to default {cpp_standard}")
cm_file.write(f"SET(CMAKE_CXX_STANDARD {cpp_standard})\n")
cm_file.write('\n')
cm_file.write(f"PROJECT({PROJECT_NAME} C {'CXX' if CXX != '' else ''} ASM)\n")
cm_file.write('\n')
cm_file.write("INCLUDE_DIRECTORIES(\n")
for i in env['CPPPATH']:
# use relative path
path = _make_path_relative(os.getcwd(), i)
cm_file.write( "\t" + path.replace("\\", "/") + "\n")
cm_file.write(")\n\n")
cm_file.write("ADD_DEFINITIONS(\n")
for i in env['CPPDEFINES']:
cm_file.write("\t-D" + i + "\n")
cm_file.write(")\n\n")
libgroups = []
interfacelibgroups = []
for group in project:
if group['name'] == 'Applications':
continue
# When a group is provided without sources, add it to the <INTERFACE> library list
if len(group['src']) == 0:
interfacelibgroups.append(group)
else:
libgroups.append(group)
# Process groups whose names differ only in capitalization.
# (Groups have same name should be merged into one before)
for group in libgroups:
group['alias'] = group['name'].lower()
names = [group['alias'] for group in libgroups]
counter = Counter(names)
names = [name for name in names if counter[name] > 1]
for group in libgroups:
if group['alias'] in names:
counter[group['alias']] -= 1
group['alias'] = f"{group['name']}_{counter[group['alias']]}"
print(f"Renamed {group['name']} to {group['alias']}")
group['name'] = group['alias']
cm_file.write("# Library source files\n")
for group in project:
cm_file.write("SET(RT_{:s}_SOURCES\n".format(group['name'].upper()))
for f in group['src']:
# use relative path
path = _make_path_relative(os.getcwd(), os.path.normpath(f.rfile().abspath))
cm_file.write( "\t" + path.replace("\\", "/") + "\n" )
cm_file.write(")\n\n")
cm_file.write("# Library search paths\n")
for group in libgroups + interfacelibgroups:
if not 'LIBPATH' in group.keys():
continue
if len(group['LIBPATH']) == 0:
continue
cm_file.write("SET(RT_{:s}_LINK_DIRS\n".format(group['name'].upper()))
for f in group['LIBPATH']:
cm_file.write("\t"+ f.replace("\\", "/") + "\n" )
cm_file.write(")\n\n")
cm_file.write("# Library local macro definitions\n")
for group in libgroups:
if not 'LOCAL_CPPDEFINES' in group.keys():
continue
if len(group['LOCAL_CPPDEFINES']) == 0:
continue
cm_file.write("SET(RT_{:s}_DEFINES\n".format(group['name'].upper()))
for f in group['LOCAL_CPPDEFINES']:
cm_file.write("\t"+ f.replace("\\", "/") + "\n" )
cm_file.write(")\n\n")
cm_file.write("# Library dependencies\n")
for group in libgroups + interfacelibgroups:
if not 'LIBS' in group.keys():
continue
if len(group['LIBS']) == 0:
continue
cm_file.write("SET(RT_{:s}_LIBS\n".format(group['name'].upper()))
for f in group['LIBS']:
cm_file.write("\t"+ "{}\n".format(f.replace("\\", "/")))
cm_file.write(")\n\n")
cm_file.write("# Libraries\n")
for group in libgroups:
cm_file.write("ADD_LIBRARY(rtt_{:s} OBJECT ${{RT_{:s}_SOURCES}})\n"
.format(group['name'], group['name'].upper()))
cm_file.write("\n")
cm_file.write("# Interface libraries\n")
for group in interfacelibgroups:
cm_file.write("ADD_LIBRARY(rtt_{:s} INTERFACE)\n".format(group['name']))
cm_file.write("\n")
cm_file.write("# Private macros\n")
for group in libgroups:
if not 'LOCAL_CPPDEFINES' in group.keys():
continue
if len(group['LOCAL_CPPDEFINES']) == 0:
continue
cm_file.write("TARGET_COMPILE_DEFINITIONS(rtt_{:s} PRIVATE ${{RT_{:s}_DEFINES}})\n"
.format(group['name'], group['name'].upper()))
cm_file.write("\n")
cm_file.write("# Interface library search paths\n")
if rtconfig.PLATFORM in ['gcc']:
for group in libgroups:
if not 'LIBPATH' in group.keys():
continue
if len(group['LIBPATH']) == 0:
continue
cm_file.write("TARGET_LINK_DIRECTORIES(rtt_{:s} INTERFACE ${{RT_{:s}_LINK_DIRS}})\n"
.format(group['name'], group['name'].upper()))
for group in libgroups:
if not 'LIBS' in group.keys():
continue
if len(group['LIBS']) == 0:
continue
cm_file.write("TARGET_LINK_LIBRARIES(rtt_{:s} INTERFACE ${{RT_{:s}_LIBS}})\n"
.format(group['name'], group['name'].upper()))
cm_file.write("\n")
cm_file.write("ADD_EXECUTABLE(${CMAKE_PROJECT_NAME}.elf ${RT_APPLICATIONS_SOURCES})\n")
cm_file.write("TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME}.elf\n")
for group in libgroups + interfacelibgroups:
cm_file.write("\trtt_{:s}\n".format(group['name']))
cm_file.write(")\n\n")
cm_file.write("ADD_CUSTOM_COMMAND(TARGET ${CMAKE_PROJECT_NAME}.elf POST_BUILD \n" + POST_ACTION + '\n)\n')
# auto inclue `custom.cmake` for user custom settings
custom_cmake = \
'''
# if custom.cmake is exist, add it
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/custom.cmake)
include(${CMAKE_CURRENT_SOURCE_DIR}/custom.cmake)
endif()
'''
custom_cmake = custom_cmake.split('\n')
custom_cmake = [each.strip() for each in custom_cmake]
custom_cmake = "\n".join(custom_cmake)
cm_file.write(custom_cmake)
return
def CMakeProject(env, project, project_name):
print('Update setting files for CMakeLists.txt...')
GenerateCFiles(env, project, project_name)
print('Done!')
return
+143
View File
@@ -0,0 +1,143 @@
#
# File : codeblocks.py
# This file is part of RT-Thread RTOS
# COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Change Logs:
# Date Author Notes
# 2015-01-20 Bernard Add copyright information
#
import os
import sys
import string
import uuid
import utils
from xml.etree.ElementTree import SubElement
from utils import _make_path_relative
from utils import xml_indent
# Add parent directory to path to import building
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import building
import xml.etree.ElementTree as etree
fs_encoding = sys.getfilesystemencoding()
def CB_AddHeadFiles(program, elem, project_path):
utils.source_ext = []
utils.source_ext = ["h"]
for item in program:
utils.walk_children(item)
utils.source_list.sort()
# print utils.source_list
for f in utils.source_list:
path = _make_path_relative(project_path, f)
Unit = SubElement(elem, 'Unit')
Unit.set('filename', path.decode(fs_encoding))
def CB_AddCFiles(ProjectFiles, parent, gname, files, project_path):
for f in files:
fn = f.rfile()
name = fn.name
path = os.path.dirname(fn.abspath)
path = _make_path_relative(project_path, path)
path = os.path.join(path, name)
Unit = SubElement(parent, 'Unit')
Unit.set('filename', path.decode(fs_encoding))
Option = SubElement(Unit, 'Option')
Option.set('compilerVar', "CC")
def CBProject(target, script, program):
project_path = os.path.dirname(os.path.abspath(target))
if os.path.isfile('template.cbp'):
tree = etree.parse('template.cbp')
else:
tree = etree.parse(os.path.join(os.path.dirname(__file__), 'template.cbp'))
root = tree.getroot()
out = open(target, 'w')
out.write('<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>\n')
ProjectFiles = []
# SECTION 1. add "*.c|*.h" files group
for elem in tree.iter(tag='Project'):
# print elem.tag, elem.attrib
break
# add c files
for group in script:
group_xml = CB_AddCFiles(ProjectFiles, elem, group['name'], group['src'], project_path)
# add h files
CB_AddHeadFiles(program, elem, project_path)
# SECTION 2.
# write head include path
if 'CPPPATH' in building.Env:
cpp_path = building.Env['CPPPATH']
paths = set()
for path in cpp_path:
inc = _make_path_relative(project_path, os.path.normpath(path))
paths.add(inc) #.replace('\\', '/')
paths = [i for i in paths]
paths.sort()
# write include path, definitions
for elem in tree.iter(tag='Compiler'):
break
for path in paths:
Add = SubElement(elem, 'Add')
Add.set('directory', path)
for macro in building.Env.get('CPPDEFINES', []):
Add = SubElement(elem, 'Add')
for d in macro:
Add.set('option', "-D"+d)
# write link flags
'''
# write lib dependence
if 'LIBS' in building.Env:
for elem in tree.iter(tag='Tool'):
if elem.attrib['Name'] == 'VCLinkerTool':
break
libs_with_extention = [i+'.lib' for i in building.Env['LIBS']]
libs = ' '.join(libs_with_extention)
elem.set('AdditionalDependencies', libs)
# write lib include path
if 'LIBPATH' in building.Env:
lib_path = building.Env['LIBPATH']
paths = set()
for path in lib_path:
inc = _make_path_relative(project_path, os.path.normpath(path))
paths.add(inc) #.replace('\\', '/')
paths = [i for i in paths]
paths.sort()
lib_paths = ';'.join(paths)
elem.set('AdditionalLibraryDirectories', lib_paths)
'''
xml_indent(root)
out.write(etree.tostring(root, encoding='utf-8'))
out.close()
+217
View File
@@ -0,0 +1,217 @@
#
# File : codelite.py
# This file is part of RT-Thread RTOS
# COPYRIGHT (C) 2006 - 2020, RT-Thread Development Team
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Change Logs:
# Date Author Notes
# 2020-10-14 LiuMin Add copyright information
#
import os
import sys
import string
import uuid
import utils
from xml.etree.ElementTree import SubElement
from utils import _make_path_relative
from utils import xml_indent
# Add parent directory to path to import building
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import building
import xml.etree.ElementTree as etree
fs_encoding = sys.getfilesystemencoding()
def CLSetCFlags(root, flags):
node = root.find('Settings').find('Configuration').find('Compiler')
node.attrib['C_Options'] = flags
def CLSetCxxFlags(root, flags):
node = root.find('Settings').find('Configuration').find('Compiler')
node.attrib['Options'] = flags
def CLSetAsFlags(root, flags):
node = root.find('Settings').find('Configuration').find('Compiler')
node.attrib['Assembler'] = flags
def CLAddIncludePath(root, path):
node = root.find('Settings').find('Configuration').find('Compiler')
node = SubElement(node, 'IncludePath')
node.attrib['Value'] = path
def CLAddPreprocessor(root, value):
node = root.find('Settings').find('Configuration').find('Compiler')
node = SubElement(node, 'Preprocessor')
node.attrib['Value'] = value
def CLSetLdFlags(root, flags):
node = root.find('Settings').find('Configuration').find('Linker')
node.attrib['Options'] = flags
def CLAddLibrary_path(root, path):
node = root.find('Settings').find('Configuration').find('Linker')
node = SubElement(node, 'LibraryPath')
node.attrib['Value'] = path
def CLAddLibrary(root, lib):
node = root.find('Settings').find('Configuration').find('Linker')
node = SubElement(node, 'Library')
node.attrib['Value'] = lib
def CLAddFile(root, file_path):
file_path = file_path.replace('\\', '/')
dir_list = file_path.split('/')
dir_list.pop()
if not len(dir_list):
dir_list.append(os.path.abspath('.').replace('\\', '/').split('/')[-1])
parent = root
for dir_name in dir_list:
if dir_name == '..':
continue
node = None
nodes = parent.findall('VirtualDirectory')
for iter in nodes:
if iter.attrib['Name'] == dir_name:
node = iter
break
if node is None:
node = SubElement(parent, 'VirtualDirectory')
node.attrib['Name'] = dir_name
parent = node
if parent != root:
node = SubElement(parent, 'File')
node.attrib['Name'] = file_path
def CLAddHeaderFiles(parent, program, project_path):
utils.source_ext = []
utils.source_ext = ["h"]
for item in program:
utils.walk_children(item)
utils.source_list.sort()
for f in utils.source_list:
path = _make_path_relative(project_path, f)
CLAddFile(parent, path)
def CLAddCFiles(parent, files, project_path):
for f in files:
fn = f.rfile()
name = fn.name
path = os.path.dirname(fn.abspath)
path = _make_path_relative(project_path, path)
path = os.path.join(path, name)
CLAddFile(parent, path)
def CLGenWorkspace(project_name, project_path):
if os.path.isfile('codelite_template.workspace'):
tree = etree.parse('codelite_template.workspace')
else:
tree = etree.parse(os.path.join(os.path.dirname(__file__), 'codelite_template.workspace'))
root = tree.getroot()
root.attrib['Name'] = project_name
node = root.find('Project')
node.attrib['Name'] = project_name
node.attrib['Path'] = project_name + '.project'
node = root.find('BuildMatrix').find('WorkspaceConfiguration').find('Project')
node.attrib['Name'] = project_name
out = open(project_name + '.workspace', 'w')
out.write('<?xml version="1.0" encoding="UTF-8"?>\n')
xml_indent(root)
out.write(etree.tostring(root, encoding='utf-8'))
out.close()
def TargetCodelite(script, program):
project_name = os.path.abspath('.').replace('\\', '/').split('/')[-1]
#project_name.replace('-', '_')
project_path = os.path.abspath('.')
CLGenWorkspace(project_name, project_path)
if os.path.isfile('codelite_template.project'):
tree = etree.parse('codelite_template.project')
else:
tree = etree.parse(os.path.join(os.path.dirname(__file__), 'codelite_template.project'))
root = tree.getroot()
root.attrib['Name'] = project_name
out = open(project_name + '.project', 'w')
out.write('<?xml version="1.0" encoding="UTF-8"?>\n')
# add files
for group in script:
CLAddCFiles(root, group['src'], project_path)
# add header file
CLAddHeaderFiles(root, program, project_path)
# SECTION 2.
# write head include path
if 'CPPPATH' in building.Env:
cpp_path = building.Env['CPPPATH']
paths = set()
for path in cpp_path:
inc = _make_path_relative(project_path, os.path.normpath(path))
paths.add(inc) #.replace('\\', '/')
paths = [i for i in paths]
paths.sort()
# write include path, definitions
for elem in tree.iter(tag='Compiler'):
break
for path in paths:
CLAddIncludePath(root, path)
#print building.Env.get('LIBPATH', [])
#print building.Env.get('LIBS', [])
CLSetCFlags(root, building.Env.get('CFLAGS', []))
CLSetCxxFlags(root, building.Env.get('CFLAGS', []))
asflags = building.Env.get('ASFLAGS', [])
asflags = asflags.replace('-ffunction-sections', '')
asflags = asflags.replace('-fdata-sections', '')
asflags = asflags.replace('-x', '')
asflags = asflags.replace('-Wa,', '')
asflags = asflags.replace('assembler-with-cpp', '')
CLSetAsFlags(root, asflags)
CLSetLdFlags(root, building.Env.get('LINKFLAGS', []))
for macro in building.Env.get('CPPDEFINES', []):
for d in macro:
CLAddPreprocessor(root, d)
xml_indent(root)
out.write(etree.tostring(root, encoding='utf-8'))
out.close()
@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<CodeLite_Project Name="project" Version="11000" InternalType="">
<Description/>
<Dependencies/>
<Settings Type="Executable">
<GlobalSettings>
<Compiler Options="" C_Options="" Assembler="">
<IncludePath Value="."/>
</Compiler>
<Linker Options="">
<LibraryPath Value="."/>
</Linker>
<ResourceCompiler Options=""/>
</GlobalSettings>
<Configuration Name="Debug" CompilerType="Cross GCC ( arm-none-eabi )" DebuggerType="GNU gdb debugger" Type="Executable" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
<Compiler Options="" C_Options="" Assembler="" Required="yes" PreCompiledHeader="" PCHInCommandLine="no" PCHFlags="" PCHFlagsPolicy="0">
</Compiler>
<Linker Options="" Required="yes">
</Linker>
<ResourceCompiler Options="" Required="no"/>
<General OutputFile="$(IntermediateDirectory)/$(ProjectName).elf" IntermediateDirectory="$(ConfigurationName)" Command="$(OutputFile)" CommandArguments="" UseSeparateDebugArgs="no" DebugArguments="" WorkingDirectory="" PauseExecWhenProcTerminates="yes" IsGUIProgram="no" IsEnabled="yes"/>
<BuildSystem Name="Default"/>
<Environment EnvVarSetName="&lt;Use Defaults&gt;" DbgSetName="&lt;Use Defaults&gt;">
<![CDATA[]]>
</Environment>
<Debugger IsRemote="yes" RemoteHostName="127.0.0.1" RemoteHostPort="2331" DebuggerPath="" IsExtended="no">
<DebuggerSearchPaths/>
<PostConnectCommands>monitor reset
monitor halt
load</PostConnectCommands>
<StartupCommands/>
</Debugger>
<PreBuild/>
<PostBuild>
<Command Enabled="yes">arm-none-eabi-objcopy -O ihex $(IntermediateDirectory)/$(ProjectName).elf $(IntermediateDirectory)/$(ProjectName).hex</Command>
<Command Enabled="yes">arm-none-eabi-objcopy -I ihex -O binary $(IntermediateDirectory)/$(ProjectName).hex $(IntermediateDirectory)/$(ProjectName).bin</Command>
<Command Enabled="yes">arm-none-eabi-size $(IntermediateDirectory)/$(ProjectName).elf</Command>
</PostBuild>
<CustomBuild Enabled="no">
<RebuildCommand/>
<CleanCommand/>
<BuildCommand/>
<PreprocessFileCommand/>
<SingleFileCommand/>
<MakefileGenerationCommand/>
<ThirdPartyToolName/>
<WorkingDirectory/>
</CustomBuild>
<AdditionalRules>
<CustomPostBuild/>
<CustomPreBuild/>
</AdditionalRules>
<Completion EnableCpp11="no" EnableCpp14="no">
<ClangCmpFlagsC/>
<ClangCmpFlags/>
<ClangPP/>
<SearchPaths/>
</Completion>
</Configuration>
</Settings>
</CodeLite_Project>
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<CodeLite_Workspace Name="project" Database="" Version="10000">
<Project Name="project" Path="project.project" Active="Yes"/>
<BuildMatrix>
<WorkspaceConfiguration Name="Debug" Selected="yes">
<Environment/>
<Project Name="project" ConfigName="Debug"/>
</WorkspaceConfiguration>
</BuildMatrix>
</CodeLite_Workspace>
+587
View File
@@ -0,0 +1,587 @@
#
# Copyright (c) 2006-2022, RT-Thread Development Team
#
# SPDX-License-Identifier: Apache-2.0
#
# Change Logs:
# Date Author Notes
# 2019-03-21 Bernard the first version
# 2019-04-15 armink fix project update error
#
import glob
import xml.etree.ElementTree as etree
from xml.etree.ElementTree import SubElement
from . import rt_studio
import sys
import os
# Add parent directory to path to import building and utils
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from building import *
from utils import *
from utils import _make_path_relative
from utils import xml_indent
MODULE_VER_NUM = 6
source_pattern = ['*.c', '*.cpp', '*.cxx', '*.cc', '*.s', '*.S', '*.asm','*.cmd']
def OSPath(path):
import platform
if type(path) == type('str'):
if platform.system() == 'Windows':
return path.replace('/', '\\')
else:
return path.replace('\\', '/')
else:
if platform.system() == 'Windows':
return [item.replace('/', '\\') for item in path]
else:
return [item.replace('\\', '/') for item in path]
# collect the build source code path and parent path
def CollectPaths(paths):
all_paths = []
def ParentPaths(path):
ret = os.path.dirname(path)
if ret == path or ret == '':
return []
return [ret] + ParentPaths(ret)
for path in paths:
# path = os.path.abspath(path)
path = path.replace('\\', '/')
all_paths = all_paths + [path] + ParentPaths(path)
cwd = os.getcwd()
for path in os.listdir(cwd):
temp_path = cwd.replace('\\', '/') + '/' + path
if os.path.isdir(temp_path):
all_paths = all_paths + [temp_path]
all_paths = list(set(all_paths))
return sorted(all_paths)
'''
Collect all of files under paths
'''
def CollectFiles(paths, pattern):
files = []
for path in paths:
if type(pattern) == type(''):
files = files + glob.glob(path + '/' + pattern)
else:
for item in pattern:
# print('--> %s' % (path + '/' + item))
files = files + glob.glob(path + '/' + item)
return sorted(files)
def CollectAllFilesinPath(path, pattern):
files = []
for item in pattern:
files += glob.glob(path + '/' + item)
list = os.listdir(path)
if len(list):
for item in list:
if item.startswith('.'):
continue
if item == 'bsp':
continue
if os.path.isdir(os.path.join(path, item)):
files = files + CollectAllFilesinPath(os.path.join(path, item), pattern)
return files
'''
Exclude files from infiles
'''
def ExcludeFiles(infiles, files):
in_files = set([OSPath(file) for file in infiles])
exl_files = set([OSPath(file) for file in files])
exl_files = in_files - exl_files
return exl_files
# caluclate the exclude path for project
def ExcludePaths(rootpath, paths):
ret = []
files = os.listdir(OSPath(rootpath))
for file in files:
if file.startswith('.'):
continue
fullname = os.path.join(OSPath(rootpath), file)
if os.path.isdir(fullname):
# print(fullname)
if not fullname in paths:
ret = ret + [fullname]
else:
ret = ret + ExcludePaths(fullname, paths)
return ret
rtt_path_prefix = '"${workspace_loc://${ProjName}//'
def ConverToRttEclipsePathFormat(path):
return rtt_path_prefix + path + '}"'
def IsRttEclipsePathFormat(path):
if path.startswith(rtt_path_prefix):
return True
else:
return False
# all libs added by scons should be ends with five whitespace as a flag
rtt_lib_flag = 5 * " "
def ConverToRttEclipseLibFormat(lib):
return str(lib) + str(rtt_lib_flag)
def IsRttEclipseLibFormat(path):
if path.endswith(rtt_lib_flag):
return True
else:
return False
def IsCppProject():
return GetDepend('RT_USING_CPLUSPLUS')
def HandleToolOption(tools, env, project, reset):
is_cpp_prj = IsCppProject()
BSP_ROOT = os.path.abspath(env['BSP_ROOT'])
CPPDEFINES = project['CPPDEFINES']
paths = [ConverToRttEclipsePathFormat(RelativeProjectPath(env, os.path.normpath(i)).replace('\\', '/')) for i in project['CPPPATH']]
compile_include_paths_options = []
compile_include_files_options = []
compile_defs_options = []
linker_scriptfile_option = None
linker_script_option = None
linker_nostart_option = None
linker_libs_option = None
linker_paths_option = None
linker_newlib_nano_option = None
for tool in tools:
if tool.get('id').find('compile') != 1:
options = tool.findall('option')
# find all compile options
for option in options:
option_id = option.get('id')
if ('compiler.include.paths' in option_id) or ('compiler.option.includepaths' in option_id) or ('compiler.tasking.include' in option_id):
compile_include_paths_options += [option]
elif option.get('id').find('compiler.include.files') != -1 or option.get('id').find('compiler.option.includefiles') != -1 :
compile_include_files_options += [option]
elif option.get('id').find('compiler.defs') != -1 or option.get('id').find('compiler.option.definedsymbols') != -1:
compile_defs_options += [option]
if tool.get('id').find('linker') != -1:
options = tool.findall('option')
# find all linker options
for option in options:
# the project type and option type must equal
if is_cpp_prj != (option.get('id').find('cpp.linker') != -1):
continue
if option.get('id').find('linker.scriptfile') != -1:
linker_scriptfile_option = option
elif option.get('id').find('linker.option.script') != -1:
linker_script_option = option
elif option.get('id').find('linker.nostart') != -1:
linker_nostart_option = option
elif option.get('id').find('linker.libs') != -1:
linker_libs_option = option
elif option.get('id').find('linker.paths') != -1 and 'LIBPATH' in env:
linker_paths_option = option
elif option.get('id').find('linker.usenewlibnano') != -1:
linker_newlib_nano_option = option
# change the inclue path
for option in compile_include_paths_options:
# find all of paths in this project
include_paths = option.findall('listOptionValue')
for item in include_paths:
if reset is True or IsRttEclipsePathFormat(item.get('value')) :
# clean old configuration
option.remove(item)
# print('c.compiler.include.paths')
paths = sorted(paths)
for item in paths:
SubElement(option, 'listOptionValue', {'builtIn': 'false', 'value': item})
# change the inclue files (default) or definitions
for option in compile_include_files_options:
# add '_REENT_SMALL' to CPPDEFINES when --specs=nano.specs has select
if linker_newlib_nano_option is not None and linker_newlib_nano_option.get('value') == 'true' and '_REENT_SMALL' not in CPPDEFINES:
CPPDEFINES += ['_REENT_SMALL']
file_header = '''
#ifndef RTCONFIG_PREINC_H__
#define RTCONFIG_PREINC_H__
/* Automatically generated file; DO NOT EDIT. */
/* RT-Thread pre-include file */
'''
file_tail = '\n#endif /*RTCONFIG_PREINC_H__*/\n'
rtt_pre_inc_item = '"${workspace_loc:/${ProjName}/rtconfig_preinc.h}"'
# save the CPPDEFINES in to rtconfig_preinc.h
with open('rtconfig_preinc.h', mode = 'w+') as f:
f.write(file_header)
for cppdef in CPPDEFINES:
f.write("#define " + cppdef.replace('=', ' ') + '\n')
f.write(file_tail)
# change the c.compiler.include.files
files = option.findall('listOptionValue')
find_ok = False
for item in files:
if item.get('value') == rtt_pre_inc_item:
find_ok = True
break
if find_ok is False:
SubElement(option, 'listOptionValue', {'builtIn': 'false', 'value': rtt_pre_inc_item})
if len(compile_include_files_options) == 0:
for option in compile_defs_options:
defs = option.findall('listOptionValue')
project_defs = []
for item in defs:
if reset is True:
# clean all old configuration
option.remove(item)
else:
project_defs += [item.get('value')]
if len(project_defs) > 0:
cproject_defs = set(CPPDEFINES) - set(project_defs)
else:
cproject_defs = CPPDEFINES
# print('c.compiler.defs')
cproject_defs = sorted(cproject_defs)
for item in cproject_defs:
SubElement(option, 'listOptionValue', {'builtIn': 'false', 'value': item})
# update linker script config
if linker_scriptfile_option is not None :
option = linker_scriptfile_option
linker_script = 'link.lds'
items = env['LINKFLAGS'].split(' ')
if '-T' in items:
linker_script = items[items.index('-T') + 1]
linker_script = ConverToRttEclipsePathFormat(linker_script)
listOptionValue = option.find('listOptionValue')
if listOptionValue != None:
if reset is True or IsRttEclipsePathFormat(listOptionValue.get('value')):
listOptionValue.set('value', linker_script)
else:
SubElement(option, 'listOptionValue', {'builtIn': 'false', 'value': linker_script})
# scriptfile in stm32cubeIDE
if linker_script_option is not None :
option = linker_script_option
items = env['LINKFLAGS'].split(' ')
if '-T' in items:
linker_script = ConverToRttEclipsePathFormat(items[items.index('-T') + 1]).strip('"')
option.set('value', linker_script)
# update nostartfiles config
if linker_nostart_option is not None :
option = linker_nostart_option
if env['LINKFLAGS'].find('-nostartfiles') != -1:
option.set('value', 'true')
else:
option.set('value', 'false')
# update libs
if linker_libs_option is not None:
option = linker_libs_option
# remove old libs
for item in option.findall('listOptionValue'):
if IsRttEclipseLibFormat(item.get("value")):
option.remove(item)
# add new libs
if 'LIBS' in env:
for lib in env['LIBS']:
lib_name = os.path.basename(str(lib))
if lib_name.endswith('.a'):
if lib_name.startswith('lib'):
lib = lib_name[3:].split('.')[0]
else:
lib = ':' + lib_name
formatedLib = ConverToRttEclipseLibFormat(lib)
SubElement(option, 'listOptionValue', {
'builtIn': 'false', 'value': formatedLib})
# update lib paths
if linker_paths_option is not None:
option = linker_paths_option
# remove old lib paths
for item in option.findall('listOptionValue'):
if IsRttEclipsePathFormat(item.get('value')):
# clean old configuration
option.remove(item)
# add new old lib paths
for path in env['LIBPATH']:
SubElement(option, 'listOptionValue', {'builtIn': 'false', 'value': ConverToRttEclipsePathFormat(RelativeProjectPath(env, path).replace('\\', '/'))})
return
def UpdateProjectStructure(env, prj_name):
bsp_root = env['BSP_ROOT']
rtt_root = env['RTT_ROOT']
project = etree.parse('.project')
root = project.getroot()
if rtt_root.startswith(bsp_root):
linkedResources = root.find('linkedResources')
if linkedResources == None:
linkedResources = SubElement(root, 'linkedResources')
links = linkedResources.findall('link')
# delete all RT-Thread folder links
for link in links:
if link.find('name').text.startswith('rt-thread'):
linkedResources.remove(link)
if prj_name:
name = root.find('name')
if name == None:
name = SubElement(root, 'name')
name.text = prj_name
out = open('.project', 'w')
out.write('<?xml version="1.0" encoding="UTF-8"?>\n')
xml_indent(root)
out.write(etree.tostring(root, encoding='utf-8').decode('utf-8'))
out.close()
return
def GenExcluding(env, project):
rtt_root = os.path.abspath(env['RTT_ROOT'])
bsp_root = os.path.abspath(env['BSP_ROOT'])
coll_dirs = CollectPaths(project['DIRS'])
all_paths_temp = [OSPath(path) for path in coll_dirs]
all_paths = []
# add used path
for path in all_paths_temp:
if path.startswith(rtt_root) or path.startswith(bsp_root):
all_paths.append(path)
if bsp_root.startswith(rtt_root):
# bsp folder is in the RT-Thread root folder, such as the RT-Thread source code on GitHub
exclude_paths = ExcludePaths(rtt_root, all_paths)
elif rtt_root.startswith(bsp_root):
# RT-Thread root folder is in the bsp folder, such as project folder which generate by 'scons --dist' cmd
check_path = []
exclude_paths = []
# analyze the primary folder which relative to BSP_ROOT and in all_paths
for path in all_paths:
if path.startswith(bsp_root):
folders = RelativeProjectPath(env, path).split('\\')
if folders[0] != '.' and '\\' + folders[0] not in check_path:
check_path += ['\\' + folders[0]]
# exclue the folder which has managed by scons
for path in check_path:
exclude_paths += ExcludePaths(bsp_root + path, all_paths)
else:
exclude_paths = ExcludePaths(rtt_root, all_paths)
exclude_paths += ExcludePaths(bsp_root, all_paths)
paths = exclude_paths
exclude_paths = []
# remove the folder which not has source code by source_pattern
for path in paths:
# add bsp and libcpu folder and not collect source files (too more files)
if path.endswith('rt-thread\\bsp') or path.endswith('rt-thread\\libcpu'):
exclude_paths += [path]
continue
set = CollectAllFilesinPath(path, source_pattern)
if len(set):
exclude_paths += [path]
exclude_paths = [RelativeProjectPath(env, path).replace('\\', '/') for path in exclude_paths]
all_files = CollectFiles(all_paths, source_pattern)
src_files = project['FILES']
exclude_files = ExcludeFiles(all_files, src_files)
exclude_files = [RelativeProjectPath(env, file).replace('\\', '/') for file in exclude_files]
env['ExPaths'] = exclude_paths
env['ExFiles'] = exclude_files
return exclude_paths + exclude_files
def RelativeProjectPath(env, path):
project_root = os.path.abspath(env['BSP_ROOT'])
rtt_root = os.path.abspath(env['RTT_ROOT'])
if path.startswith(project_root):
return _make_path_relative(project_root, path)
if path.startswith(rtt_root):
return 'rt-thread/' + _make_path_relative(rtt_root, path)
# TODO add others folder
print('ERROR: the ' + path + ' not support')
return path
def HandleExcludingOption(entry, sourceEntries, excluding):
old_excluding = []
if entry != None:
exclud = entry.get('excluding')
if exclud != None:
old_excluding = entry.get('excluding').split('|')
sourceEntries.remove(entry)
value = ''
for item in old_excluding:
if item.startswith('//'):
old_excluding.remove(item)
else:
if value == '':
value = item
else:
value += '|' + item
for item in excluding:
# add special excluding path prefix for RT-Thread
item = '//' + item
if value == '':
value = item
else:
value += '|' + item
SubElement(sourceEntries, 'entry', {'excluding': value, 'flags': 'VALUE_WORKSPACE_PATH|RESOLVED', 'kind':'sourcePath', 'name':""})
def UpdateCproject(env, project, excluding, reset, prj_name):
excluding = sorted(excluding)
cproject = etree.parse('.cproject')
root = cproject.getroot()
cconfigurations = root.findall('storageModule/cconfiguration')
for cconfiguration in cconfigurations:
tools = cconfiguration.findall('storageModule/configuration/folderInfo/toolChain/tool')
HandleToolOption(tools, env, project, reset)
sourceEntries = cconfiguration.find('storageModule/configuration/sourceEntries')
if sourceEntries != None:
entry = sourceEntries.find('entry')
HandleExcludingOption(entry, sourceEntries, excluding)
# update refreshScope
if prj_name:
prj_name = '/' + prj_name
configurations = root.findall('storageModule/configuration')
for configuration in configurations:
resource = configuration.find('resource')
configuration.remove(resource)
SubElement(configuration, 'resource', {'resourceType': "PROJECT", 'workspacePath': prj_name})
# write back to .cproject
out = open('.cproject', 'w')
out.write('<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n')
out.write('<?fileVersion 4.0.0?>')
xml_indent(root)
out.write(etree.tostring(root, encoding='utf-8').decode('utf-8'))
out.close()
def TargetEclipse(env, reset=False, prj_name=None):
global source_pattern
print('Update eclipse setting...')
# generate cproject file
if not os.path.exists('.cproject'):
if rt_studio.gen_cproject_file(os.path.abspath(".cproject")) is False:
print('Fail!')
return
# generate project file
if not os.path.exists('.project'):
if rt_studio.gen_project_file(os.path.abspath(".project")) is False:
print('Fail!')
return
# generate projcfg.ini file
if not os.path.exists('.settings/projcfg.ini'):
# if search files with uvprojx or uvproj suffix
file = ""
items = os.listdir(".")
if len(items) > 0:
for item in items:
if item.endswith(".uvprojx") or item.endswith(".uvproj"):
file = os.path.abspath(item)
break
chip_name = rt_studio.get_mcu_info(file)
if rt_studio.gen_projcfg_ini_file(chip_name, prj_name, os.path.abspath(".settings/projcfg.ini")) is False:
print('Fail!')
return
# enable lowwer .s file compiled in eclipse cdt
if not os.path.exists('.settings/org.eclipse.core.runtime.prefs'):
if rt_studio.gen_org_eclipse_core_runtime_prefs(
os.path.abspath(".settings/org.eclipse.core.runtime.prefs")) is False:
print('Fail!')
return
# add clean2 target to fix issues when files too many
if not os.path.exists('makefile.targets'):
if rt_studio.gen_makefile_targets(os.path.abspath("makefile.targets")) is False:
print('Fail!')
return
project = ProjectInfo(env)
# update the project file structure info on '.project' file
UpdateProjectStructure(env, prj_name)
# generate the exclude paths and files
excluding = GenExcluding(env, project)
# update the project configuration on '.cproject' file
UpdateCproject(env, project, excluding, reset, prj_name)
print('done!')
return
+58
View File
@@ -0,0 +1,58 @@
import os
import re
import utils
from utils import _make_path_relative
def GenerateCFiles(env,project):
"""
Generate CMakeLists.txt files
"""
info = utils.ProjectInfo(env)
init_export = []
main_component_dir = os.path.join(os.getcwd(), 'main')
cm_file = open(os.path.join(main_component_dir, 'CMakeLists.txt'), 'w')
if cm_file:
cm_file.write("idf_component_register(\n")
cm_file.write("\tSRCS\n")
for group in project:
for f in group['src']:
path = _make_path_relative(main_component_dir, os.path.normpath(f.rfile().abspath))
cm_file.write( "\t" + path.replace("\\", "/") + "\n" )
src = open(f.rfile().abspath, 'r')
for line in src.readlines():
if re.match(r'INIT_(BOARD|PREV|DEVICE|COMPONENT|ENV|APP)_EXPORT\(.+\)', line):
init_export.append(re.search(r'\(.+\)', line).group(0)[1:-1])
src.close()
cm_file.write("\n")
cm_file.write("\tINCLUDE_DIRS\n")
for i in info['CPPPATH']:
path = _make_path_relative(main_component_dir, i)
cm_file.write( "\t" + path.replace("\\", "/") + "\n")
cm_file.write(")\n\n")
n = len(init_export)
if n:
cm_file.write("target_link_libraries(${COMPONENT_LIB}\n")
for i in range(n):
cm_file.write("\tINTERFACE \"-u __rt_init_" + init_export[i] + "\"\n")
cm_file.write(")\n")
cm_file.close()
cm_file = open('CMakeLists.txt', 'w')
if cm_file:
cm_file.write("cmake_minimum_required(VERSION 3.16)\n")
cm_file.write("set(COMPONENTS esptool_py main)\n")
cm_file.write("include($ENV{IDF_PATH}/tools/cmake/project.cmake)\n")
freertos_root = os.getcwd().replace('\\', '/') + '/packages/FreeRTOS_Wrapper-latest/FreeRTOS'
cm_file.write("set(freertos_root " + freertos_root + ')\n')
cm_file.write("project(rtthread)\n")
cm_file.close()
def ESPIDFProject(env,project):
print('Update setting files for CMakeLists.txt...')
GenerateCFiles(env,project)
print('Done!')
+209
View File
@@ -0,0 +1,209 @@
#
# File : iar.py
# This file is part of RT-Thread RTOS
# COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Change Logs:
# Date Author Notes
# 2015-01-20 Bernard Add copyright information
#
import os
import sys
import string
import utils
from SCons.Script import *
import xml.etree.ElementTree as etree
from xml.etree.ElementTree import SubElement
from utils import _make_path_relative
from utils import xml_indent
fs_encoding = sys.getfilesystemencoding()
iar_workspace = r'''<?xml version="1.0" encoding="iso-8859-1"?>
<workspace>
<project>
<path>$WS_DIR$\%s</path>
</project>
<batchBuild/>
</workspace>
'''
def IARAddGroup(parent, name, files, project_path):
group = SubElement(parent, 'group')
group_name = SubElement(group, 'name')
group_name.text = name
for f in files:
fn = f.rfile()
name = fn.name
path = os.path.dirname(fn.abspath)
basename = os.path.basename(path)
path = _make_path_relative(project_path, path)
path = os.path.join(path, name)
file = SubElement(group, 'file')
file_name = SubElement(file, 'name')
if os.path.isabs(path):
file_name.text = path # path.decode(fs_encoding)
else:
file_name.text = '$PROJ_DIR$\\' + path # ('$PROJ_DIR$\\' + path).decode(fs_encoding)
def IARWorkspace(target):
# make an workspace
workspace = target.replace('.ewp', '.eww')
out = open(workspace, 'w')
xml = iar_workspace % target
out.write(xml)
out.close()
def IARProject(env, target, script):
project_path = os.path.dirname(os.path.abspath(target))
tree = etree.parse('template.ewp')
root = tree.getroot()
out = open(target, 'w')
CPPPATH = []
CPPDEFINES = env.get('CPPDEFINES', [])
LOCAL_CPPDEFINES = []
LINKFLAGS = ''
CFLAGS = ''
Libs = []
lib_prefix = ['lib', '']
lib_suffix = ['.a', '.o', '']
def searchLib(group):
for path_item in group['LIBPATH']:
for prefix_item in lib_prefix:
for suffix_item in lib_suffix:
lib_full_path = os.path.join(path_item, prefix_item + item + suffix_item)
if os.path.isfile(lib_full_path):
return lib_full_path
else:
return ''
# add group
for group in script:
IARAddGroup(root, group['name'], group['src'], project_path)
# get each include path
if 'CPPPATH' in group and group['CPPPATH']:
CPPPATH += group['CPPPATH']
if 'LOCAL_CPPDEFINES' in group and group['LOCAL_CPPDEFINES']:
LOCAL_CPPDEFINES += group['LOCAL_CPPDEFINES']
# get each group's link flags
if 'LINKFLAGS' in group and group['LINKFLAGS']:
LINKFLAGS += group['LINKFLAGS']
if 'LIBS' in group and group['LIBS']:
for item in group['LIBS']:
lib_path = searchLib(group)
if lib_path != '':
lib_path = _make_path_relative(project_path, lib_path)
Libs += [lib_path]
# print('found lib isfile: ' + lib_path)
else:
print('not found LIB: ' + item)
# make relative path
paths = set()
for path in CPPPATH:
inc = _make_path_relative(project_path, os.path.normpath(path))
paths.add(inc) #.replace('\\', '/')
# setting options
options = tree.findall('configuration/settings/data/option')
for option in options:
# print option.text
name = option.find('name')
if name.text == 'CCIncludePath2' or name.text == 'newCCIncludePaths':
for path in paths:
state = SubElement(option, 'state')
if os.path.isabs(path) or path.startswith('$'):
state.text = path
else:
state.text = '$PROJ_DIR$\\' + path
if name.text == 'CCDefines':
for define in CPPDEFINES:
state = SubElement(option, 'state')
state.text = define
for define in LOCAL_CPPDEFINES:
state = SubElement(option, 'state')
state.text = define
if name.text == 'IlinkAdditionalLibs':
for path in Libs:
state = SubElement(option, 'state')
if os.path.isabs(path) or path.startswith('$'):
path = path.decode(fs_encoding)
else:
path = ('$PROJ_DIR$\\' + path).decode(fs_encoding)
state.text = path
xml_indent(root)
out.write(etree.tostring(root, encoding='utf-8').decode())
out.close()
IARWorkspace(target)
def IARPath():
import rtconfig
# backup environ
old_environ = os.environ
os.environ['RTT_CC'] = 'iar'
# get iar path
path = rtconfig.EXEC_PATH
# restore environ
os.environ = old_environ
return path
def IARVersion():
import subprocess
import re
path = IARPath()
if os.path.exists(path):
cmd = os.path.join(path, 'iccarm.exe')
else:
return "0.0"
child = subprocess.Popen([cmd, '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
stdout, stderr = child.communicate()
if not isinstance(stdout, str):
stdout = str(stdout, 'utf8') # Patch for Python 3
# example stdout: IAR ANSI C/C++ Compiler V8.20.1.14183/W32 for ARM
iar_version = re.search(r'[\d\.]+', stdout).group(0)
return iar_version
+513
View File
@@ -0,0 +1,513 @@
#
# File : keil.py
# This file is part of RT-Thread RTOS
# COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Change Logs:
# Date Author Notes
# 2015-01-20 Bernard Add copyright information
#
import os
import sys
import string
import shutil
import xml.etree.ElementTree as etree
from xml.etree.ElementTree import SubElement
from utils import _make_path_relative
from utils import xml_indent
fs_encoding = sys.getfilesystemencoding()
def _get_filetype(fn):
if fn.rfind('.cpp') != -1 or fn.rfind('.cxx') != -1:
return 8
if fn.rfind('.c') != -1 or fn.rfind('.C') != -1:
return 1
# assemble file type
if fn.rfind('.s') != -1 or fn.rfind('.S') != -1:
return 2
# header type
if fn.rfind('.h') != -1:
return 5
if fn.rfind('.lib') != -1:
return 4
if fn.rfind('.o') != -1:
return 3
# other filetype
return 5
def MDK4AddGroupForFN(ProjectFiles, parent, name, filename, project_path):
group = SubElement(parent, 'Group')
group_name = SubElement(group, 'GroupName')
group_name.text = name
name = os.path.basename(filename)
path = os.path.dirname (filename)
basename = os.path.basename(path)
path = _make_path_relative(project_path, path)
path = os.path.join(path, name)
files = SubElement(group, 'Files')
file = SubElement(files, 'File')
file_name = SubElement(file, 'FileName')
name = os.path.basename(path)
if name.find('.cpp') != -1:
obj_name = name.replace('.cpp', '.o')
elif name.find('.c') != -1:
obj_name = name.replace('.c', '.o')
elif name.find('.s') != -1:
obj_name = name.replace('.s', '.o')
elif name.find('.S') != -1:
obj_name = name.replace('.s', '.o')
else:
obj_name = name
if ProjectFiles.count(obj_name):
name = basename + '_' + name
ProjectFiles.append(obj_name)
try: # python 2
file_name.text = name.decode(fs_encoding)
except: # python 3
file_name.text = name
file_type = SubElement(file, 'FileType')
file_type.text = '%d' % _get_filetype(name)
file_path = SubElement(file, 'FilePath')
try: # python 2
file_path.text = path.decode(fs_encoding)
except: # python 3
file_path.text = path
return group
def MDK4AddLibToGroup(ProjectFiles, group, name, filename, project_path):
name = os.path.basename(filename)
path = os.path.dirname (filename)
basename = os.path.basename(path)
path = _make_path_relative(project_path, path)
path = os.path.join(path, name)
files = SubElement(group, 'Files')
file = SubElement(files, 'File')
file_name = SubElement(file, 'FileName')
name = os.path.basename(path)
if name.find('.cpp') != -1:
obj_name = name.replace('.cpp', '.o')
elif name.find('.c') != -1:
obj_name = name.replace('.c', '.o')
elif name.find('.s') != -1:
obj_name = name.replace('.s', '.o')
elif name.find('.S') != -1:
obj_name = name.replace('.s', '.o')
else:
obj_name = name
if ProjectFiles.count(obj_name):
name = basename + '_' + name
ProjectFiles.append(obj_name)
try:
file_name.text = name.decode(fs_encoding)
except:
file_name.text = name
file_type = SubElement(file, 'FileType')
file_type.text = '%d' % _get_filetype(name)
file_path = SubElement(file, 'FilePath')
try:
file_path.text = path.decode(fs_encoding)
except:
file_path.text = path
return group
def MDK4AddGroup(ProjectFiles, parent, name, files, project_path, group_scons):
# don't add an empty group
if len(files) == 0:
return
group = SubElement(parent, 'Group')
group_name = SubElement(group, 'GroupName')
group_name.text = name
for f in files:
fn = f.rfile()
name = fn.name
path = os.path.dirname(fn.abspath)
basename = os.path.basename(path)
path = _make_path_relative(project_path, path)
path = os.path.join(path, name)
files = SubElement(group, 'Files')
file = SubElement(files, 'File')
file_name = SubElement(file, 'FileName')
name = os.path.basename(path)
if name.find('.cpp') != -1:
obj_name = name.replace('.cpp', '.o')
elif name.find('.c') != -1:
obj_name = name.replace('.c', '.o')
elif name.find('.s') != -1:
obj_name = name.replace('.s', '.o')
elif name.find('.S') != -1:
obj_name = name.replace('.s', '.o')
if ProjectFiles.count(obj_name):
name = basename + '_' + name
ProjectFiles.append(obj_name)
file_name.text = name # name.decode(fs_encoding)
file_type = SubElement(file, 'FileType')
file_type.text = '%d' % _get_filetype(name)
file_path = SubElement(file, 'FilePath')
file_path.text = path # path.decode(fs_encoding)
# for local LOCAL_CFLAGS/LOCAL_CXXFLAGS/LOCAL_CCFLAGS/LOCAL_CPPPATH/LOCAL_CPPDEFINES
MiscControls_text = ' '
if file_type.text == '1' and 'LOCAL_CFLAGS' in group_scons:
MiscControls_text = MiscControls_text + group_scons['LOCAL_CFLAGS']
elif file_type.text == '8' and 'LOCAL_CXXFLAGS' in group_scons:
MiscControls_text = MiscControls_text + group_scons['LOCAL_CXXFLAGS']
if 'LOCAL_CCFLAGS' in group_scons:
MiscControls_text = MiscControls_text + group_scons['LOCAL_CCFLAGS']
if MiscControls_text != ' ' or ('LOCAL_CPPDEFINES' in group_scons):
FileOption = SubElement(file, 'FileOption')
FileArmAds = SubElement(FileOption, 'FileArmAds')
Cads = SubElement(FileArmAds, 'Cads')
VariousControls = SubElement(Cads, 'VariousControls')
MiscControls = SubElement(VariousControls, 'MiscControls')
MiscControls.text = MiscControls_text
Define = SubElement(VariousControls, 'Define')
if 'LOCAL_CPPDEFINES' in group_scons:
Define.text = ', '.join(set(group_scons['LOCAL_CPPDEFINES']))
else:
Define.text = ' '
Undefine = SubElement(VariousControls, 'Undefine')
Undefine.text = ' '
IncludePath = SubElement(VariousControls, 'IncludePath')
if 'LOCAL_CPPPATH' in group_scons:
IncludePath.text = ';'.join([_make_path_relative(project_path, os.path.normpath(i)) for i in group_scons['LOCAL_CPPPATH']])
else:
IncludePath.text = ' '
return group
# The common part of making MDK4/5 project
def MDK45Project(env, tree, target, script):
project_path = os.path.dirname(os.path.abspath(target))
root = tree.getroot()
out = open(target, 'w')
out.write('<?xml version="1.0" encoding="UTF-8" standalone="no" ?>\n')
CPPPATH = []
CPPDEFINES = env.get('CPPDEFINES', [])
LINKFLAGS = ''
CXXFLAGS = ''
CCFLAGS = ''
CFLAGS = ''
ProjectFiles = []
# add group
groups = tree.find('Targets/Target/Groups')
if groups is None:
groups = SubElement(tree.find('Targets/Target'), 'Groups')
groups.clear() # clean old groups
for group in script:
group_tree = MDK4AddGroup(ProjectFiles, groups, group['name'], group['src'], project_path, group)
# get each include path
if 'CPPPATH' in group and group['CPPPATH']:
if CPPPATH:
CPPPATH += group['CPPPATH']
else:
CPPPATH += group['CPPPATH']
# get each group's link flags
if 'LINKFLAGS' in group and group['LINKFLAGS']:
if LINKFLAGS:
LINKFLAGS += ' ' + group['LINKFLAGS']
else:
LINKFLAGS += group['LINKFLAGS']
# get each group's CXXFLAGS flags
if 'CXXFLAGS' in group and group['CXXFLAGS']:
if CXXFLAGS:
CXXFLAGS += ' ' + group['CXXFLAGS']
else:
CXXFLAGS += group['CXXFLAGS']
# get each group's CCFLAGS flags
if 'CCFLAGS' in group and group['CCFLAGS']:
if CCFLAGS:
CCFLAGS += ' ' + group['CCFLAGS']
else:
CCFLAGS += group['CCFLAGS']
# get each group's CFLAGS flags
if 'CFLAGS' in group and group['CFLAGS']:
if CFLAGS:
CFLAGS += ' ' + group['CFLAGS']
else:
CFLAGS += group['CFLAGS']
# get each group's LIBS flags
if 'LIBS' in group and group['LIBS']:
for item in group['LIBPATH']:
full_path = os.path.join(item, group['name'] + '.lib')
if os.path.isfile(full_path): # has this library
if group_tree != None:
MDK4AddLibToGroup(ProjectFiles, group_tree, group['name'], full_path, project_path)
else:
group_tree = MDK4AddGroupForFN(ProjectFiles, groups, group['name'], full_path, project_path)
# write include path, definitions and link flags
IncludePath = tree.find('Targets/Target/TargetOption/TargetArmAds/Cads/VariousControls/IncludePath')
IncludePath.text = ';'.join([_make_path_relative(project_path, os.path.normpath(i)) for i in set(CPPPATH)])
Define = tree.find('Targets/Target/TargetOption/TargetArmAds/Cads/VariousControls/Define')
Define.text = ', '.join(set(CPPDEFINES))
if 'c99' in CXXFLAGS or 'c99' in CCFLAGS or 'c99' in CFLAGS:
uC99 = tree.find('Targets/Target/TargetOption/TargetArmAds/Cads/uC99')
uC99.text = '1'
if 'gnu' in CXXFLAGS or 'gnu' in CCFLAGS or 'gnu' in CFLAGS:
uGnu = tree.find('Targets/Target/TargetOption/TargetArmAds/Cads/uGnu')
uGnu.text = '1'
Misc = tree.find('Targets/Target/TargetOption/TargetArmAds/LDads/Misc')
Misc.text = LINKFLAGS
xml_indent(root)
out.write(etree.tostring(root, encoding='utf-8').decode())
out.close()
def MDK4Project(env, target, script):
if os.path.isfile('template.uvproj') is False:
print ('Warning: The template project file [template.uvproj] not found!')
return
template_tree = etree.parse('template.uvproj')
MDK45Project(env, template_tree, target, script)
# remove project.uvopt file
project_uvopt = os.path.abspath(target).replace('uvproj', 'uvopt')
if os.path.isfile(project_uvopt):
os.unlink(project_uvopt)
# copy uvopt file
if os.path.exists('template.uvopt'):
import shutil
shutil.copy2('template.uvopt', '{}.uvopt'.format(os.path.splitext(target)[0]))
import threading
import time
def monitor_log_file(log_file_path):
if not os.path.exists(log_file_path):
open(log_file_path, 'w').close()
empty_line_count = 0
with open(log_file_path, 'r') as log_file:
while True:
line = log_file.readline()
if line:
print(line.strip())
if 'Build Time Elapsed' in line:
break
empty_line_count = 0
else:
empty_line_count += 1
time.sleep(1)
if empty_line_count > 30:
print("Timeout reached or too many empty lines, exiting log monitoring thread.")
break
def MDK5Project(env, target, script):
if os.path.isfile('template.uvprojx') is False:
print ('Warning: The template project file [template.uvprojx] not found!')
return
template_tree = etree.parse('template.uvprojx')
MDK45Project(env, template_tree, target, script)
# remove project.uvopt file
project_uvopt = os.path.abspath(target).replace('uvprojx', 'uvoptx')
if os.path.isfile(project_uvopt):
os.unlink(project_uvopt)
# copy uvopt file
if os.path.exists('template.uvoptx'):
import shutil
shutil.copy2('template.uvoptx', '{}.uvoptx'.format(os.path.splitext(target)[0]))
# build with UV4.exe
if shutil.which('UV4.exe') is not None:
target_name = template_tree.find('Targets/Target/TargetName')
print('target_name:', target_name.text)
log_file_path = 'keil.log'
if os.path.exists(log_file_path):
os.remove(log_file_path)
log_thread = threading.Thread(target=monitor_log_file, args=(log_file_path,))
log_thread.start()
cmd = 'UV4.exe -b project.uvprojx -q -j0 -t '+ target_name.text +' -o '+log_file_path
print('Start to build keil project')
print(cmd)
os.system(cmd)
else:
print('UV4.exe is not available, please check your keil installation')
def MDK2Project(env, target, script):
template = open(os.path.join(os.path.dirname(__file__), 'template.Uv2'), 'r')
lines = template.readlines()
project = open(target, "w")
project_path = os.path.dirname(os.path.abspath(target))
line_index = 5
# write group
for group in script:
lines.insert(line_index, 'Group (%s)\r\n' % group['name'])
line_index += 1
lines.insert(line_index, '\r\n')
line_index += 1
# write file
ProjectFiles = []
CPPPATH = []
CPPDEFINES = env.get('CPPDEFINES', [])
LINKFLAGS = ''
CFLAGS = ''
# number of groups
group_index = 1
for group in script:
# print group['name']
# get each include path
if 'CPPPATH' in group and group['CPPPATH']:
if CPPPATH:
CPPPATH += group['CPPPATH']
else:
CPPPATH += group['CPPPATH']
# get each group's link flags
if 'LINKFLAGS' in group and group['LINKFLAGS']:
if LINKFLAGS:
LINKFLAGS += ' ' + group['LINKFLAGS']
else:
LINKFLAGS += group['LINKFLAGS']
# generate file items
for node in group['src']:
fn = node.rfile()
name = fn.name
path = os.path.dirname(fn.abspath)
basename = os.path.basename(path)
path = _make_path_relative(project_path, path)
path = os.path.join(path, name)
if ProjectFiles.count(name):
name = basename + '_' + name
ProjectFiles.append(name)
lines.insert(line_index, 'File %d,%d,<%s><%s>\r\n'
% (group_index, _get_filetype(name), path, name))
line_index += 1
group_index = group_index + 1
lines.insert(line_index, '\r\n')
line_index += 1
# remove repeat path
paths = set()
for path in CPPPATH:
inc = _make_path_relative(project_path, os.path.normpath(path))
paths.add(inc) #.replace('\\', '/')
paths = [i for i in paths]
CPPPATH = string.join(paths, ';')
definitions = [i for i in set(CPPDEFINES)]
CPPDEFINES = string.join(definitions, ', ')
while line_index < len(lines):
if lines[line_index].startswith(' ADSCINCD '):
lines[line_index] = ' ADSCINCD (' + CPPPATH + ')\r\n'
if lines[line_index].startswith(' ADSLDMC ('):
lines[line_index] = ' ADSLDMC (' + LINKFLAGS + ')\r\n'
if lines[line_index].startswith(' ADSCDEFN ('):
lines[line_index] = ' ADSCDEFN (' + CPPDEFINES + ')\r\n'
line_index += 1
# write project
for line in lines:
project.write(line)
project.close()
def ARMCC_Version():
import rtconfig
import subprocess
import re
path = rtconfig.EXEC_PATH
if(rtconfig.PLATFORM == 'armcc'):
path = os.path.join(path, 'armcc.exe')
elif(rtconfig.PLATFORM == 'armclang'):
path = os.path.join(path, 'armlink.exe')
if os.path.exists(path):
cmd = path
else:
return "0.0"
child = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
stdout, stderr = child.communicate()
'''
example stdout:
Product: MDK Plus 5.24
Component: ARM Compiler 5.06 update 5 (build 528)
Tool: armcc [4d3621]
return version: MDK Plus 5.24/ARM Compiler 5.06 update 5 (build 528)/armcc [4d3621]
'''
if not isinstance(stdout, str):
stdout = str(stdout, 'utf8') # Patch for Python 3
version_Product = re.search(r'Product: (.+)', stdout).group(1)
version_Product = version_Product[:-1]
version_Component = re.search(r'Component: (.*)', stdout).group(1)
version_Component = version_Component[:-1]
version_Tool = re.search(r'Tool: (.*)', stdout).group(1)
version_Tool = version_Tool[:-1]
version_str_format = '%s/%s/%s'
version_str = version_str_format % (version_Product, version_Component, version_Tool)
return version_str
+159
View File
@@ -0,0 +1,159 @@
#
# File : makefile.py
# This file is part of RT-Thread RTOS
# COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Change Logs:
# Date Author Notes
# 2015-01-20 Bernard Add copyright information
import os
import sys
# Add parent directory to path to import utils
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from utils import *
from utils import _make_path_relative
import rtconfig
makefile = '''phony := all
all:
include config.mk
ifneq ($(MAKE_LIB),1)
TARGET := rtthread.elf
include src.mk
endif
$(if $(strip $(RTT_ROOT)),,$(error RTT_ROOT not defined))
include $(RTT_ROOT)/tools/rtthread.mk
'''
def TargetMakefile(env):
project = ProjectInfo(env)
BSP_ROOT = os.path.abspath(env['BSP_ROOT'])
RTT_ROOT = os.path.abspath(env['RTT_ROOT'])
match_bsp = False
if BSP_ROOT.startswith(RTT_ROOT):
match_bsp = True
make = open('config.mk', 'w')
make.write('BSP_ROOT ?= %s\n' % BSP_ROOT.replace('\\', '/'))
make.write('RTT_ROOT ?= %s\n' % RTT_ROOT.replace('\\', '/'))
make.write('\n')
cross = os.path.abspath(rtconfig.EXEC_PATH)
cross = os.path.join(cross, rtconfig.PREFIX)
make.write('CROSS_COMPILE ?=%s' % cross.replace('\\', '\\\\'))
make.write('\n')
make.write('\n')
make.write('CFLAGS :=%s' % (rtconfig.CFLAGS))
make.write('\n')
make.write('AFLAGS :=%s' % (rtconfig.AFLAGS))
make.write('\n')
make.write('LFLAGS :=%s' % (rtconfig.LFLAGS))
make.write('\n')
if 'CXXFLAGS' in dir(rtconfig):
make.write('CXXFLAGS :=%s' % (rtconfig.CXXFLAGS))
make.write('\n')
if ('LIBS' in env):
make.write('EXTERN_LIB := ')
for tlib in env['LIBS']:
make.write('-l%s ' % (tlib))
if ('LIBPATH' in env):
for tlibpath in env['LIBPATH']:
make.write('-L%s ' % (tlibpath))
make.write('\n')
make.write('\n')
Files = project['FILES']
Headers = project['HEADERS']
CPPDEFINES = project['CPPDEFINES']
paths = [os.path.normpath(i) for i in project['CPPPATH']]
CPPPATH = []
for path in paths:
fn = os.path.normpath(path)
if match_bsp:
if fn.startswith(BSP_ROOT):
fn = '$(BSP_ROOT)' + fn.replace(BSP_ROOT, '')
elif fn.startswith(RTT_ROOT):
fn = '$(RTT_ROOT)' + fn.replace(RTT_ROOT, '')
else:
if fn.startswith(RTT_ROOT):
fn = '$(RTT_ROOT)' + fn.replace(RTT_ROOT, '')
elif fn.startswith(BSP_ROOT):
fn = '$(BSP_ROOT)' + fn.replace(BSP_ROOT, '')
CPPPATH.append(fn)
path = ''
paths = CPPPATH
for item in paths:
path += '\t-I%s \\\n' % item
make.write('CPPPATHS :=')
if path[0] == '\t': path = path[1:]
length = len(path)
if path[length - 2] == '\\': path = path[:length - 2]
make.write(path)
make.write('\n')
make.write('\n')
defines = ''
for item in project['CPPDEFINES']:
defines += ' -D%s' % item
make.write('DEFINES :=')
make.write(defines)
make.write('\n')
files = Files
Files = []
for file in files:
fn = os.path.normpath(file)
if match_bsp:
if fn.startswith(BSP_ROOT):
fn = '$(BSP_ROOT)' + fn.replace(BSP_ROOT, '')
elif fn.startswith(RTT_ROOT):
fn = '$(RTT_ROOT)' + fn.replace(RTT_ROOT, '')
else:
if fn.startswith(RTT_ROOT):
fn = '$(RTT_ROOT)' + fn.replace(RTT_ROOT, '')
elif fn.startswith(BSP_ROOT):
fn = '$(BSP_ROOT)' + fn.replace(BSP_ROOT, '')
Files.append(fn)
# print(fn)
src = open('src.mk', 'w')
files = Files
src.write('SRC_FILES :=\n')
for item in files:
src.write('SRC_FILES +=%s\n' % item.replace('\\', '/'))
make = open('Makefile', 'w')
make.write(makefile)
make.close()
return
+357
View File
@@ -0,0 +1,357 @@
import os
import re
from string import Template
try:
import rtconfig
except ImportError:
# Mock rtconfig for testing
class MockRtconfig:
pass
rtconfig = MockRtconfig()
import shutil
import time
# version
MODULE_VER_NUM = 1
cproject_temp = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><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.553091094">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.553091094" moduleId="org.eclipse.cdt.core.settings" name="Debug">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="rtthread" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="${cross_rm} -rf" description="" id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.553091094" name="Debug" parent="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug">
<folderInfo id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.553091094." name="/" resourcePath="">
<toolChain id="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.debug.1201710416" name="ARM Cross GCC" superClass="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.debug">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash.251260409" name="Create flash image" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createflash" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createlisting.1365878149" name="Create extended listing" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.createlisting" useByScannerDiscovery="false"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize.709136944" name="Print size" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.addtools.printsize" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.1986446770" name="Optimization Level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.none" valueType="enumerated"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength.1312975261" name="Message length (-fmessage-length=0)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.messagelength" useByScannerDiscovery="true" value="false" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar.1538128212" name="'char' is signed (-fsigned-char)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.signedchar" useByScannerDiscovery="true" value="false" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections.2136804218" name="Function sections (-ffunction-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.functionsections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections.244767666" name="Data sections (-fdata-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.datasections" useByScannerDiscovery="true" value="true" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.1055848773" name="Debug level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.level.default" valueType="enumerated"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format.501941135" name="Debug format" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.debugging.format.dwarf2" valueType="enumerated"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.name.1696308067" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.name" useByScannerDiscovery="false" value="GNU Tools for ARM Embedded Processors" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.1558403188" name="Architecture" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.architecture" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.architecture.arm" valueType="enumerated"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family.749415257" name="ARM family" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.family" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.mcpu.cortex-m4" valueType="enumerated"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.2114153533" name="Instruction set" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.instructionset.thumb" valueType="enumerated"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix.1600865811" name="Prefix" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.prefix" useByScannerDiscovery="false" value="arm-none-eabi-" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.c.1109963929" name="C compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.c" useByScannerDiscovery="false" value="gcc" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp.1040883831" name="C++ compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.cpp" useByScannerDiscovery="false" value="g++" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar.1678200391" name="Archiver" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.ar" useByScannerDiscovery="false" value="ar" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy.1171840296" name="Hex/Bin converter" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objcopy" useByScannerDiscovery="false" value="objcopy" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump.342604837" name="Listing generator" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.objdump" useByScannerDiscovery="false" value="objdump" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.size.898269225" name="Size command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.size" useByScannerDiscovery="false" value="size" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.make.2016398076" name="Build command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.make" useByScannerDiscovery="false" value="make" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm.1606171496" name="Remove command" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.command.rm" useByScannerDiscovery="false" value="rm" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.id.540792084" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.toolchain.id" useByScannerDiscovery="false" value="1287942917" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.architecture.430121817" name="Architecture" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.architecture" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.arch.none" valueType="enumerated"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.abi.966735324" name="Float ABI" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.abi" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.abi.hard" valueType="enumerated"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn.1381561249" name="Enable all common warnings (-Wall)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.warnings.allwarn" useByScannerDiscovery="true" value="true" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.target.other.2041717463" name="Other target flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.target.other" useByScannerDiscovery="true" value="" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.unit.1463655269" name="FPU Type" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.unit" useByScannerDiscovery="true" value="ilg.gnuarmeclipse.managedbuild.cross.option.arm.target.fpu.unit.fpv4spd16" valueType="enumerated"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform.1798638225" isAbstract="false" osList="all" superClass="ilg.gnuarmeclipse.managedbuild.cross.targetPlatform"/>
<builder buildPath="${workspace_loc:/${ProjName}/Debug" cleanBuildTarget="clean2" id="ilg.gnuarmeclipse.managedbuild.cross.builder.1736709688" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="ilg.gnuarmeclipse.managedbuild.cross.builder"/>
<tool commandLinePattern="${COMMAND} ${cross_toolchain_flags} ${FLAGS} -c ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.1810966071" name="GNU ARM Cross Assembler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor.1072524326" name="Use preprocessor" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.usepreprocessor" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.include.paths.161242639" name="Include paths (-I)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.include.paths" useByScannerDiscovery="true"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.defs.1521934876" name="Defined symbols (-D)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.defs" useByScannerDiscovery="true"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.flags.1325367962" name="Assembler flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.flags" useByScannerDiscovery="false" valueType="stringList">
<listOptionValue builtIn="false" value="-mimplicit-it=thumb"/>
</option>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.other.647856572" name="Other assembler flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.assembler.other" useByScannerDiscovery="false" value="a_misc_flag" valueType="string"/>
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input.1843333483" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.assembler.input"/>
</tool>
<tool commandLinePattern="${COMMAND} ${cross_toolchain_flags} ${FLAGS} -c ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.1570350559" name="GNU ARM Cross C Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.paths.634882052" name="Include paths (-I)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.paths" useByScannerDiscovery="true"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.defs.100549972" name="Defined symbols (-D)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.defs" useByScannerDiscovery="true"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.other.2133065240" name="Other compiler flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.other" useByScannerDiscovery="true" value="c_misc_flag" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.files.714348818" name="Include files (-include)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.compiler.include.files" useByScannerDiscovery="true"/>
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input.992053063" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input"/>
</tool>
<tool commandLinePattern="${COMMAND} ${cross_toolchain_flags} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.869072473" name="Cross ARM C Linker" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.gcsections.1167322178" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.gcsections" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nostart.351692886" name="Do not use standard start files (-nostartfiles)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nostart" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nostdlibs.1009243715" name="No startup or default libs (-nostdlib)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nostdlibs" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nodeflibs.2016026082" name="Do not use default libraries (-nodefaultlibs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.nodeflibs" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnano.923990336" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.usenewlibnano" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option defaultValue="true" id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.shared.548869459" name="Shared (-shared)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.shared" useByScannerDiscovery="false" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.scriptfile.1818777301" name="Script files (-T)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.scriptfile" useByScannerDiscovery="false"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.libs.1135656995" name="Libraries (-l)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.libs" useByScannerDiscovery="false"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.paths.36884122" name="Library search path (-L)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.paths" useByScannerDiscovery="false"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.other.396049466" name="Other linker flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.other" useByScannerDiscovery="false" value="c_link_misc_flag" valueType="string"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.cref.1645737861" name="Cross reference (-Xlinker --cref)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.c.linker.cref" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.input.334732222" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool commandLinePattern="${COMMAND} ${cross_toolchain_flags} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.1601059928" name="GNU ARM Cross C++ Linker" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.gcsections.437759352" name="Remove unused sections (-Xlinker --gc-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.gcsections" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.scriptfile.1101974459" name="Script files (-T)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.scriptfile" useByScannerDiscovery="false"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.cref.2007675975" name="Cross reference (-Xlinker --cref)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.cref" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnano.2105838438" name="Use newlib-nano (--specs=nano.specs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnano" useByScannerDiscovery="false" value="true" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.libs.934137837" name="Libraries (-l)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.libs" useByScannerDiscovery="false"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nostart.2118356996" name="Do not use standard start files (-nostartfiles)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nostart" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nodeflibs.1427884346" name="Do not use default libraries (-nodefaultlibs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nodeflibs" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nostdlibs.1433863653" name="No startup or default libs (-nostdlib)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.nostdlibs" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.printgcsections.1387745410" name="Print removed sections (-Xlinker --print-gc-sections)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.printgcsections" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.strip.1230158061" name="Omit all symbol information (-s)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.strip" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.printmap.1307581821" name="Print link map (-Xlinker --print-map)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.printmap" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.useprintffloat.960778920" name="Use float with nano printf (-u _printf_float)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.useprintffloat" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usescanffloat.637205035" name="Use float with nano scanf (-u _scanf_float)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usescanffloat" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnosys.1948314201" name="Do not use syscalls (--specs=nosys.specs)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.usenewlibnosys" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.verbose.273162112" name="Verbose (-v)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.verbose" useByScannerDiscovery="false" value="false" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.paths.1399535143" name="Library search path (-L)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.paths" useByScannerDiscovery="false"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.other.882307902" name="Other linker flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.linker.other" useByScannerDiscovery="false" value="cpp_link_misc_flag" valueType="string"/>
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.input.262373798" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.archiver.506412204" name="GNU ARM Cross Archiver" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.archiver"/>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.createflash.1461589245" name="GNU ARM Cross Create Flash Image" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.createflash">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createflash.choice.1937707052" name="Output file format (-O)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createflash.choice" useByScannerDiscovery="false" value="ilg.gnuarmeclipse.managedbuild.cross.option.createflash.choice.binary" valueType="enumerated"/>
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.createlisting.82359725" name="GNU ARM Cross Create Listing" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.createlisting">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.source.601724476" name="Display source (--source|-S)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.source" value="true" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.allheaders.692505279" name="Display all headers (--all-headers|-x)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.allheaders" value="true" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.demangle.97345172" name="Demangle names (--demangle|-C)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.demangle" value="true" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.linenumbers.1342893377" name="Display line numbers (--line-numbers|-l)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.linenumbers" value="true" valueType="boolean"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.wide.1533725981" name="Wide lines (--wide|-w)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.createlisting.wide" value="true" valueType="boolean"/>
</tool>
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.printsize.1073550295" name="GNU ARM Cross Print Size" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.printsize">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.format.946451386" name="Size format" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.printsize.format" useByScannerDiscovery="false"/>
</tool>
<tool commandLinePattern="${COMMAND} ${cross_toolchain_flags} ${FLAGS} -c ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}" id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.1302177015" name="GNU ARM Cross C++ Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.defs.704468062" name="Defined symbols (-D)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.defs" useByScannerDiscovery="true"/>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.include.paths.302877723" name="Include paths (-I)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.include.paths" useByScannerDiscovery="true"/>
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.include.files.343249373" name="Include files (-include)" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.include.files" useByScannerDiscovery="true" valueType="includeFiles">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/rtconfig_preinc.h}&quot;"/>
</option>
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.other.465079095" name="Other compiler flags" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.cpp.compiler.other" useByScannerDiscovery="true" value="cpp_misc_flag" valueType="string"/>
<inputType id="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.input.45918001" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.input"/>
</tool>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="|" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="qemu-vexpress-a9.ilg.gnuarmeclipse.managedbuild.cross.target.elf.860020518" name="Executable" projectType="ilg.gnuarmeclipse.managedbuild.cross.target.elf"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.553091094;ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.553091094.;ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.1570350559;ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input.992053063">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Debug">
<resource resourceType="PROJECT" workspacePath="/f429_tmp"/>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings">
<doc-comment-owner id="org.eclipse.cdt.ui.doxygen">
<path value=""/>
</doc-comment-owner>
</storageModule>
</cproject>"""
project_temp = """<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>__project_name_flag__</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.rt-thread.studio.rttnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>"""
projcfg_ini_temp = """#RT-Thread Studio Project Configuration
# $time
cfg_version=v3.0
board_name=
bsp_version=
bsp_path=
chip_name=
project_base_rtt_bsp=true
is_use_scons_build=true
hardware_adapter=
selected_rtt_version=latest
board_base_nano_proj=false
is_base_example_project=false
example_name=
project_type=rt-thread
os_branch=master
os_version=latest
project_name=$project_name
output_project_path=$output_project_path"""
eclipse_core_runtime_temp = """content-types/enabled=true
content-types/org.eclipse.cdt.core.asmSource/file-extensions=s
eclipse.preferences.version=1"""
makefile_targets_temp = """clean2:
\t-$(RM) $(CC_DEPS)$(C++_DEPS)$(C_UPPER_DEPS)$(CXX_DEPS)$(SECONDARY_FLASH)$(SECONDARY_SIZE)$(ASM_DEPS)$(S_UPPER_DEPS)$(C_DEPS)$(CPP_DEPS)
\t-$(RM) $(OBJS) *.elf
\t-@echo ' '
*.elf: $(wildcard ../linkscripts/*/*.lds) $(wildcard ../linkscripts/*/*/*.lds)"""
def get_mcu_info(uvproj_file_path):
if os.path.exists(uvproj_file_path):
with open(uvproj_file_path, mode='r') as f:
data = f.read()
result = re.search("<Device>(.*)</Device>", data)
if result:
return result.group(1)
else:
return "unknown"
else:
return "unknown"
def gen_makefile_targets(output_file_path):
try:
w_str = makefile_targets_temp
dir_name = os.path.dirname(output_file_path)
if not os.path.exists(dir_name):
os.makedirs(dir_name)
with open(output_file_path, 'w') as f:
f.write(w_str)
return True
except Exception as e:
print(e)
return False
def gen_org_eclipse_core_runtime_prefs(output_file_path):
try:
w_str = eclipse_core_runtime_temp
dir_name = os.path.dirname(output_file_path)
if not os.path.exists(dir_name):
os.makedirs(dir_name)
with open(output_file_path, 'w') as f:
f.write(w_str)
return True
except Exception as e:
print(e)
return False
def gen_cproject_file(output_file_path):
template_file_path = os.path.join(os.path.dirname(__file__), 'template.cproject')
if os.path.exists(template_file_path):
try:
shutil.copy(template_file_path, output_file_path)
except Exception as e:
print(e)
return True
else:
CFLAGS = rtconfig.CFLAGS
AFLAGS = rtconfig.AFLAGS
LFLAGS = rtconfig.LFLAGS
if 'CXXFLAGS' in dir(rtconfig):
CXXFLAGS = rtconfig.CXXFLAGS
else:
CXXFLAGS = ""
if "-T" in LFLAGS:
items = str(LFLAGS).split()
t_index = items.index("-T")
items[t_index] = ""
items[t_index + 1] = ""
LFLAGS = " ".join(items)
try:
w_str = cproject_temp
if "a_misc_flag" in w_str:
w_str = w_str.replace("a_misc_flag", AFLAGS)
if "c_misc_flag" in w_str:
w_str = w_str.replace("c_misc_flag", CFLAGS)
if "cpp_misc_flag" in w_str:
w_str = w_str.replace("cpp_misc_flag", CXXFLAGS)
if "c_link_misc_flag" in w_str:
w_str = w_str.replace("c_link_misc_flag", LFLAGS)
if "cpp_link_misc_flag" in w_str:
w_str = w_str.replace("cpp_link_misc_flag", LFLAGS)
dir_name = os.path.dirname(output_file_path)
if not os.path.exists(dir_name):
os.makedirs(dir_name)
with open(output_file_path, 'w') as f:
f.write(w_str)
return True
except Exception as e:
return False
def gen_project_file(output_file_path):
try:
w_str = project_temp
dir_name = os.path.dirname(output_file_path)
if not os.path.exists(dir_name):
os.makedirs(dir_name)
with open(output_file_path, 'w') as f:
f.write(w_str)
return True
except Exception as e:
return False
def gen_projcfg_ini_file(chip_name, project_name, output_file_path):
try:
projcfg_file_tmp = Template(projcfg_ini_temp)
w_str = projcfg_file_tmp.substitute(time=time.strftime("%a %b %d %H:%M:%S %Y", time.localtime()),
project_name=project_name,
output_project_path=os.path.abspath(""))
dir_name = os.path.dirname(output_file_path)
if not os.path.exists(dir_name):
os.makedirs(dir_name)
with open(output_file_path, 'w') as f:
f.write(w_str)
return True
except Exception as e:
return False
+92
View File
@@ -0,0 +1,92 @@
# SEGGER Embedded Studio Project Generator
import os
import sys
import xml.etree.ElementTree as etree
from xml.etree.ElementTree import SubElement
from utils import _make_path_relative
from utils import xml_indent
from utils import ProjectInfo
def SDKAddGroup(parent, name, files, project_path):
# don't add an empty group
if len(files) == 0:
return
group = SubElement(parent, 'folder', attrib={'Name': name})
for f in files:
fn = f.rfile()
name = fn.name
path = os.path.dirname(fn.abspath)
basename = os.path.basename(path)
path = _make_path_relative(project_path, path)
elm_attr_name = os.path.join(path, name)
file = SubElement(group, 'file', attrib={'file_name': elm_attr_name})
return group
def SESProject(env) :
target = 'project.emProject'
tree = etree.parse('template.emProject')
# print(etree.dump(tree.getroot()))
# etree.dump(tree.getroot())
project = ProjectInfo(env)
# print(project)
# return
project_path = os.path.abspath(env['BSP_ROOT'])
script = env['project']
root = tree.getroot()
out = file(target, 'w')
out.write('<!DOCTYPE CrossStudio_Project_File>\n')
CPPPATH = []
CPPDEFINES = []
LINKFLAGS = ''
CFLAGS = ''
project_node = tree.find('project')
for group in script:
# print(group)
group_tree = SDKAddGroup(project_node, group['name'], group['src'], project_path)
# get each group's cc flags
if 'CFLAGS' in group and group['CFLAGS']:
if CFLAGS:
CFLAGS += ' ' + group['CFLAGS']
else:
CFLAGS += group['CFLAGS']
# get each group's link flags
if 'LINKFLAGS' in group and group['LINKFLAGS']:
if LINKFLAGS:
LINKFLAGS += ' ' + group['LINKFLAGS']
else:
LINKFLAGS += group['LINKFLAGS']
# write include path, definitions and link flags
path = ';'.join([_make_path_relative(project_path, os.path.normpath(i)) for i in project['CPPPATH']])
path = path.replace('\\', '/')
defines = ';'.join(set(project['CPPDEFINES']))
node = tree.findall('project/configuration')
for item in node:
if item.get('c_preprocessor_definitions'):
item.set('c_preprocessor_definitions', defines)
if item.get('c_user_include_directories'):
item.set('c_user_include_directories', path)
xml_indent(root)
out.write(etree.tostring(root, encoding='utf-8'))
out.close()
return
+41
View File
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="project" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="build/bin/Debug/project" prefix_auto="1" extension_auto="1" />
<Option object_output="build/obj/Debug/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
</Compiler>
</Target>
<Target title="Release">
<Option output="build/bin/Release/project" prefix_auto="1" extension_auto="1" />
<Option object_output="build/obj/Release/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-Wall" />
</Compiler>
<Extensions>
<code_completion />
<envvars />
<debugger />
<lib_finder disable_auto="1" />
</Extensions>
</Project>
</CodeBlocks_project_file>
+101
View File
@@ -0,0 +1,101 @@
#
# File : ua.py
# This file is part of RT-Thread RTOS
# COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Change Logs:
# Date Author Notes
# 2015-01-20 Bernard Add copyright information
#
import os
import sys
from utils import _make_path_relative
def PrefixPath(prefix, path):
path = os.path.abspath(path)
prefix = os.path.abspath(prefix)
if sys.platform == 'win32':
prefix = prefix.lower()
path = path.lower()
if path.startswith(prefix):
return True
return False
def PrepareUA(project, RTT_ROOT, BSP_ROOT):
with open('rtua.py', 'w') as ua:
# ua.write('import os\n')
# ua.write('import sys\n')
ua.write('\n')
print(RTT_ROOT)
CPPPATH = []
CPPDEFINES = []
for group in project:
# get each include path
if 'CPPPATH' in group and group['CPPPATH']:
CPPPATH += group['CPPPATH']
# get each group's definitions
if 'CPPDEFINES' in group and group['CPPDEFINES']:
CPPDEFINES += group['CPPDEFINES']
if len(CPPPATH):
# use absolute path
for i in range(len(CPPPATH)):
CPPPATH[i] = os.path.abspath(CPPPATH[i])
# remove repeat path
paths = [i for i in set(CPPPATH)]
CPPPATH = []
for path in paths:
if PrefixPath(RTT_ROOT, path):
CPPPATH += ['RTT_ROOT + "/%s",' % _make_path_relative(RTT_ROOT, path).replace('\\', '/')]
elif PrefixPath(BSP_ROOT, path):
CPPPATH += ['BSP_ROOT + "/%s",' % _make_path_relative(BSP_ROOT, path).replace('\\', '/')]
else:
CPPPATH += ['"%s",' % path.replace('\\', '/')]
CPPPATH.sort()
ua.write('def GetCPPPATH(BSP_ROOT, RTT_ROOT):\n')
ua.write('\tCPPPATH=[\n')
for path in CPPPATH:
ua.write('\t\t%s\n' % path)
ua.write('\t]\n\n')
ua.write('\treturn CPPPATH\n\n')
else:
ua.write('def GetCPPPATH(BSP_ROOT, RTT_ROOT):\n')
ua.write('\tCPPPATH=[]\n\n')
ua.write('\treturn CPPPATH\n\n')
if len(CPPDEFINES):
CPPDEFINES = [i for i in set(CPPDEFINES)]
ua.write('def GetCPPDEFINES():\n')
ua.write('\tCPPDEFINES=%s\n' % str(CPPDEFINES))
ua.write('\treturn CPPDEFINES\n\n')
else:
ua.write('def GetCPPDEFINES():\n')
ua.write('\tCPPDEFINES=""\n\n')
ua.write('\treturn CPPDEFINES\n\n')
+189
View File
@@ -0,0 +1,189 @@
#
# File : vs.py
# This file is part of RT-Thread RTOS
# COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Change Logs:
# Date Author Notes
# 2015-01-20 Bernard Add copyright information
#
import os
import sys
import string
import uuid
import utils
from xml.etree.ElementTree import SubElement
from utils import _make_path_relative
from utils import xml_indent
# Add parent directory to path to import building
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import building
import xml.etree.ElementTree as etree
fs_encoding = sys.getfilesystemencoding()
def VS_AddGroup(ProjectFiles, parent, name, files, libs, project_path):
Filter = SubElement(parent, 'Filter')
Filter.set('Name', name) #set group name to group
for f in files:
fn = f.rfile()
name = fn.name
path = os.path.dirname(fn.abspath)
path = _make_path_relative(project_path, path)
path = os.path.join(path, name)
try:
path = path.decode(fs_encoding)
except:
path = path
File = SubElement(Filter, 'File')
File.set('RelativePath', path)
for lib in libs:
name = os.path.basename(lib)
path = os.path.dirname(lib)
path = _make_path_relative(project_path, path)
path = os.path.join(path, name)
File = SubElement(Filter, 'File')
try:
path = path.decode(fs_encoding)
except:
path = path
File.set('RelativePath', path)
def VS_AddHeadFilesGroup(program, elem, project_path):
utils.source_ext = []
utils.source_ext = ["h"]
for item in program:
utils.walk_children(item)
utils.source_list.sort()
# print utils.source_list
for f in utils.source_list:
path = _make_path_relative(project_path, f)
File = SubElement(elem, 'File')
try:
path = path.decode(fs_encoding)
except:
path = path
File.set('RelativePath', path)
def VSProject(target, script, program):
project_path = os.path.dirname(os.path.abspath(target))
tree = etree.parse('template_vs2005.vcproj')
root = tree.getroot()
out = open(target, 'w')
out.write('<?xml version="1.0" encoding="UTF-8"?>\r\n')
ProjectFiles = []
# add "*.c" files group
for elem in tree.iter(tag='Filter'):
if elem.attrib['Name'] == 'Source Files':
#print elem.tag, elem.attrib
break
for group in script:
libs = []
if 'LIBS' in group and group['LIBS']:
for item in group['LIBS']:
lib_path = ''
for path_item in group['LIBPATH']:
full_path = os.path.join(path_item, item + '.lib')
if os.path.isfile(full_path): # has this library
lib_path = full_path
if lib_path != '':
libs.append(lib_path)
group_xml = VS_AddGroup(ProjectFiles, elem, group['name'], group['src'], libs, project_path)
# add "*.h" files group
for elem in tree.iter(tag='Filter'):
if elem.attrib['Name'] == 'Header Files':
break
VS_AddHeadFilesGroup(program, elem, project_path)
# write head include path
if 'CPPPATH' in building.Env:
cpp_path = building.Env['CPPPATH']
paths = set()
for path in cpp_path:
inc = _make_path_relative(project_path, os.path.normpath(path))
paths.add(inc) #.replace('\\', '/')
paths = [i for i in paths]
paths.sort()
cpp_path = ';'.join(paths)
# write include path, definitions
for elem in tree.iter(tag='Tool'):
if elem.attrib['Name'] == 'VCCLCompilerTool':
#print elem.tag, elem.attrib
break
elem.set('AdditionalIncludeDirectories', cpp_path)
# write cppdefinitons flags
if 'CPPDEFINES' in building.Env:
CPPDEFINES = building.Env['CPPDEFINES']
definitions = []
if type(CPPDEFINES[0]) == type(()):
for item in CPPDEFINES:
definitions += [i for i in item]
definitions = ';'.join(definitions)
else:
definitions = ';'.join(building.Env['CPPDEFINES'])
elem.set('PreprocessorDefinitions', definitions)
# write link flags
# write lib dependence
if 'LIBS' in building.Env:
for elem in tree.iter(tag='Tool'):
if elem.attrib['Name'] == 'VCLinkerTool':
break
libs_with_extention = [i+'.lib' for i in building.Env['LIBS']]
libs = ' '.join(libs_with_extention)
elem.set('AdditionalDependencies', libs)
# write lib include path
if 'LIBPATH' in building.Env:
lib_path = building.Env['LIBPATH']
paths = set()
for path in lib_path:
inc = _make_path_relative(project_path, os.path.normpath(path))
paths.add(inc) #.replace('\\', '/')
paths = [i for i in paths]
paths.sort()
lib_paths = ';'.join(paths)
elem.set('AdditionalLibraryDirectories', lib_paths)
xml_indent(root)
text = etree.tostring(root, encoding='utf-8')
try:
text = text.decode(encoding="utf-8")
except:
text = text
out.write(text)
out.close()
+284
View File
@@ -0,0 +1,284 @@
#
# File : vs2012.py
# This file is part of RT-Thread RTOS
# COPYRIGHT (C) 2006 - 2015, RT-Thread Development Team
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Change Logs:
# Date Author Notes
# 2015-01-20 Bernard Add copyright information
#
import os
import sys
import string
import uuid
import utils
from xml.etree.ElementTree import SubElement
from utils import _make_path_relative
from utils import xml_indent
# Add parent directory to path to import building
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import building
import xml.etree.ElementTree as etree
fs_encoding = sys.getfilesystemencoding()
#reference
# http://woodpecker.org.cn/diveintopython3/xml.html
# https://pycoders-weekly-chinese.readthedocs.org/en/latest/issue6/processing-xml-in-python-with-element-tree.html
# http://www.cnblogs.com/ifantastic/archive/2013/04/12/3017110.html
filter_project = etree.Element('Project', attrib={'ToolsVersion':'4.0'})
def get_uuid():
id = uuid.uuid1() # UUID('3e5526c0-2841-11e3-a376-20cf3048bcb3')
if sys.version > '3':
idstr = id.urn[9:] #'urn:uuid:3e5526c0-2841-11e3-a376-20cf3048bcb3'[9:]
else:
# python3 is no decode function
idstr = id.get_urn()[9:] #'urn:uuid:3e5526c0-2841-11e3-a376-20cf3048bcb3'[9:]
return '{'+idstr+'}'
def VS2012_AddGroup(parent, group_name, files, project_path):
for f in files:
fn = f.rfile()
name = fn.name
path = os.path.dirname(fn.abspath)
path = _make_path_relative(project_path, path)
path = os.path.join(path, name)
ClCompile = SubElement(parent, 'ClCompile')
if sys.version > '3':
ClCompile.set('Include', path)
else:
# python3 is no decode function
ClCompile.set('Include', path.decode(fs_encoding))
Filter = SubElement(ClCompile, 'Filter')
Filter.text='Source Files\\'+group_name
def VS2012_CreateFilter(script, project_path):
c_ItemGroup = SubElement(filter_project, 'ItemGroup')
filter_ItemGroup = SubElement(filter_project, 'ItemGroup')
Filter = SubElement(filter_ItemGroup, 'Filter')
Filter.set('Include', 'Source Files')
UniqueIdentifier = SubElement(Filter, 'UniqueIdentifier')
UniqueIdentifier.text = get_uuid()
Extensions = SubElement(Filter, 'Extensions')
Extensions.text = 'cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx'
Filter = SubElement(filter_ItemGroup, 'Filter')
Filter.set('Include', 'Header Files')
UniqueIdentifier = SubElement(Filter, 'UniqueIdentifier')
UniqueIdentifier.text = get_uuid()
Extensions = SubElement(Filter, 'Extensions')
Extensions.text = 'h;hpp;hxx;hm;inl;inc;xsd'
for group in script:
VS2012_AddGroup(c_ItemGroup, group['name'], group['src'], project_path)
Filter = SubElement(filter_ItemGroup, 'Filter')
Filter.set('Include', 'Source Files\\'+group['name'])
UniqueIdentifier = SubElement(Filter, 'UniqueIdentifier')
UniqueIdentifier.text = get_uuid()
#program: object from scons
# parent: xml node
# file_type: C or H
# files: c/h list
# project_path
def VS_add_ItemGroup(parent, file_type, files, project_path):
from building import Rtt_Root
RTT_ROOT = os.path.normpath(Rtt_Root)
file_dict = {'C':"ClCompile", 'H':'ClInclude'}
item_tag = file_dict[file_type]
ItemGroup = SubElement(parent, 'ItemGroup')
for f in files:
fn = f.rfile()
name = fn.name
path = os.path.dirname(fn.abspath)
objpath = path.lower()
if len(project_path) >= len(RTT_ROOT) :
if objpath.startswith(project_path.lower()) :
objpath = ''.join('bsp'+objpath[len(project_path):])
else :
objpath = ''.join('kernel'+objpath[len(RTT_ROOT):])
else :
if objpath.startswith(RTT_ROOT.lower()) :
objpath = ''.join('kernel'+objpath[len(RTT_ROOT):])
else :
objpath = ''.join('bsp'+objpath[len(project_path):])
path = _make_path_relative(project_path, path)
path = os.path.join(path, name)
File = SubElement(ItemGroup, item_tag)
if sys.version > '3':
File.set('Include', path)
else:
# python3 is no decode function
File.set('Include', path.decode(fs_encoding))
if file_type == 'C' :
ObjName = SubElement(File, 'ObjectFileName')
ObjName.text = ''.join('$(IntDir)'+objpath+'\\')
def VS_add_HeadFiles(program, elem, project_path):
utils.source_ext = []
utils.source_ext = ["h"]
for item in program:
utils.walk_children(item)
utils.source_list.sort()
# print utils.source_list
ItemGroup = SubElement(elem, 'ItemGroup')
filter_h_ItemGroup = SubElement(filter_project, 'ItemGroup')
for f in utils.source_list:
path = _make_path_relative(project_path, f)
File = SubElement(ItemGroup, 'ClInclude')
if sys.version > '3':
File.set('Include', path)
else:
# python3 is no decode function
File.set('Include', path.decode(fs_encoding))
# add project.vcxproj.filter
ClInclude = SubElement(filter_h_ItemGroup, 'ClInclude')
if sys.version > '3':
ClInclude.set('Include', path)
else:
# python3 is no decode function
ClInclude.set('Include', path.decode(fs_encoding))
Filter = SubElement(ClInclude, 'Filter')
Filter.text='Header Files'
def VS2012Project(target, script, program):
project_path = os.path.dirname(os.path.abspath(target))
tree = etree.parse('template_vs2012.vcxproj')
root = tree.getroot()
elem = root
out = open(target, 'w')
out.write('<?xml version="1.0" encoding="UTF-8"?>\r\n')
ProjectFiles = []
# add "*.c or *.h" files
VS2012_CreateFilter(script, project_path)
# add "*.c" files
for group in script:
VS_add_ItemGroup(elem, 'C', group['src'], project_path)
# add "*.h" files
VS_add_HeadFiles(program, elem, project_path)
# write head include path
if 'CPPPATH' in building.Env:
cpp_path = building.Env['CPPPATH']
paths = set()
for path in cpp_path:
inc = _make_path_relative(project_path, os.path.normpath(path))
paths.add(inc) #.replace('\\', '/')
paths = [i for i in paths]
paths.sort()
cpp_path = ';'.join(paths) + ';%(AdditionalIncludeDirectories)'
# write include path
for elem in tree.iter(tag='AdditionalIncludeDirectories'):
elem.text = cpp_path
break
# write cppdefinitons flags
if 'CPPDEFINES' in building.Env:
for elem in tree.iter(tag='PreprocessorDefinitions'):
CPPDEFINES = building.Env['CPPDEFINES']
definitions = []
if type(CPPDEFINES[0]) == type(()):
for item in CPPDEFINES:
definitions += [i for i in item]
definitions = ';'.join(definitions)
else:
definitions = ';'.join(building.Env['CPPDEFINES'])
definitions = definitions + ';%(PreprocessorDefinitions)'
elem.text = definitions
break
# write link flags
# write lib dependence (Link)
if 'LIBS' in building.Env:
for elem in tree.iter(tag='AdditionalDependencies'):
libs_with_extention = [i+'.lib' for i in building.Env['LIBS']]
libs = ';'.join(libs_with_extention) + ';%(AdditionalDependencies)'
elem.text = libs
break
# write lib include path
if 'LIBPATH' in building.Env:
lib_path = building.Env['LIBPATH']
paths = set()
for path in lib_path:
inc = _make_path_relative(project_path, os.path.normpath(path))
paths.add(inc)
paths = [i for i in paths]
paths.sort()
lib_paths = ';'.join(paths) + ';%(AdditionalLibraryDirectories)'
for elem in tree.iter(tag='AdditionalLibraryDirectories'):
elem.text = lib_paths
break
xml_indent(root)
if sys.version > '3':
vcxproj_string = etree.tostring(root, encoding='unicode')
else:
# python3 is no decode function
vcxproj_string = etree.tostring(root, encoding='utf-8')
root_node=r'<Project DefaultTargets="Build" ToolsVersion="4.0">'
out.write(r'<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">')
out.write(vcxproj_string[len(root_node):])
out.close()
xml_indent(filter_project)
if sys.version > '3':
filter_string = etree.tostring(filter_project, encoding='unicode')
else:
# python3 is no decode function
filter_string = etree.tostring(filter_project, encoding='utf-8')
out = open('project.vcxproj.filters', 'w')
out.write('<?xml version="1.0" encoding="UTF-8"?>\r\n')
root_node=r'<Project ToolsVersion="4.0">'
out.write(r'<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">')
out.write(filter_string[len(root_node):])
out.close()
+478
View File
@@ -0,0 +1,478 @@
#
# File : vsc.py
# This file is part of RT-Thread RTOS
# COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Change Logs:
# Date Author Notes
# 2018-05-30 Bernard The first version
# 2023-03-03 Supperthomas Add the vscode workspace config file
# 2024-12-13 Supperthomas covert compile_commands.json to vscode workspace file
# 2025-07-05 Bernard Add support for generating .vscode/c_cpp_properties.json
# and .vscode/settings.json files
"""
Utils for VSCode
"""
import os
import json
import utils
import rtconfig
from SCons.Script import GetLaunchDir
from utils import _make_path_relative
def find_first_node_with_two_children(tree):
for key, subtree in tree.items():
if len(subtree) >= 2:
return key, subtree
result = find_first_node_with_two_children(subtree)
if result:
return result
return None, None
def filt_tree(tree):
key, subtree = find_first_node_with_two_children(tree)
if key:
return {key: subtree}
return {}
def add_path_to_tree(tree, path):
parts = path.split(os.sep)
current_level = tree
for part in parts:
if part not in current_level:
current_level[part] = {}
current_level = current_level[part]
def build_tree(paths):
tree = {}
current_working_directory = os.getcwd()
current_folder_name = os.path.basename(current_working_directory)
# Filter out invalid and non-existent paths
relative_dirs = []
for path in paths:
normalized_path = os.path.normpath(path)
try:
rel_path = os.path.relpath(normalized_path, start=current_working_directory)
add_path_to_tree(tree, normalized_path)
except ValueError:
print(f"Remove unexcpect dir:{path}")
return tree
def print_tree(tree, indent=''):
for key, subtree in sorted(tree.items()):
print(indent + key)
print_tree(subtree, indent + ' ')
def extract_source_dirs(compile_commands):
source_dirs = set()
for entry in compile_commands:
file_path = os.path.abspath(entry['file'])
if file_path.endswith('.c'):
dir_path = os.path.dirname(file_path)
source_dirs.add(dir_path)
# command or arguments
command = entry.get('command') or entry.get('arguments')
if isinstance(command, str):
parts = command.split()
else:
parts = command
# 读取-I或者/I
for i, part in enumerate(parts):
if part.startswith('-I'):
include_dir = part[2:] if len(part) > 2 else parts[i + 1]
source_dirs.add(os.path.abspath(include_dir))
elif part.startswith('/I'):
include_dir = part[2:] if len(part) > 2 else parts[i + 1]
source_dirs.add(os.path.abspath(include_dir))
return sorted(source_dirs)
def is_path_in_tree(path, tree):
parts = path.split(os.sep)
current_level = tree
found_first_node = False
root_key = list(tree.keys())[0]
index_start = parts.index(root_key)
length = len(parts)
try:
for i in range(index_start, length):
current_level = current_level[parts[i]]
return True
except KeyError:
return False
def generate_code_workspace_file(source_dirs,command_json_path,root_path):
current_working_directory = os.getcwd()
current_folder_name = os.path.basename(current_working_directory)
relative_dirs = []
for dir_path in source_dirs:
try:
rel_path = os.path.relpath(dir_path, root_path)
relative_dirs.append(rel_path)
except ValueError:
continue
root_rel_path = os.path.relpath(root_path, current_working_directory)
command_json_path = os.path.relpath(current_working_directory, root_path) + os.sep
workspace_data = {
"folders": [
{
"path": f"{root_rel_path}"
}
],
"settings": {
"clangd.arguments": [
f"--compile-commands-dir={command_json_path}",
"--header-insertion=never"
],
"files.exclude": {dir.replace('\\','/'): True for dir in sorted(relative_dirs)}
}
}
workspace_filename = f'{current_folder_name}.code-workspace'
with open(workspace_filename, 'w') as f:
json.dump(workspace_data, f, indent=4)
print(f'Workspace file {workspace_filename} created.')
def command_json_to_workspace(root_path,command_json_path):
with open('build/compile_commands.json', 'r') as f:
compile_commands = json.load(f)
source_dirs = extract_source_dirs(compile_commands)
tree = build_tree(source_dirs)
#print_tree(tree)
filtered_tree = filt_tree(tree)
print("Filtered Directory Tree:")
#print_tree(filtered_tree)
# 打印filtered_tree的root节点的相对路径
root_key = list(filtered_tree.keys())[0]
print(f"Root node relative path: {root_key}")
# 初始化exclude_fold集合
exclude_fold = set()
# os.chdir(root_path)
# 轮询root文件夹下面的每一个文件夹和子文件夹
for root, dirs, files in os.walk(root_path):
# 检查当前root是否在filtered_tree中
if not is_path_in_tree(root, filtered_tree):
exclude_fold.add(root)
dirs[:] = [] # 不往下轮询子文件夹
continue
for dir in dirs:
dir_path = os.path.join(root, dir)
if not is_path_in_tree(dir_path, filtered_tree):
exclude_fold.add(dir_path)
generate_code_workspace_file(exclude_fold,command_json_path,root_path)
def delete_repeatelist(data):
temp_dict = set([str(item) for item in data])
data = [eval(i) for i in temp_dict]
return data
def GenerateCFiles(env):
"""
Generate c_cpp_properties.json and build/compile_commands.json files
"""
if not os.path.exists('.vscode'):
os.mkdir('.vscode')
with open('.vscode/c_cpp_properties.json', 'w') as vsc_file:
info = utils.ProjectInfo(env)
cc = os.path.join(rtconfig.EXEC_PATH, rtconfig.CC)
cc = os.path.abspath(cc).replace('\\', '/')
config_obj = {}
config_obj['name'] = 'Linux'
config_obj['defines'] = info['CPPDEFINES']
intelliSenseMode = 'linux-gcc-arm'
if cc.find('aarch64') != -1:
intelliSenseMode = 'linux-gcc-arm64'
elif cc.find('arm') != -1:
intelliSenseMode = 'linux-gcc-arm'
config_obj['intelliSenseMode'] = intelliSenseMode
config_obj['compilerPath'] = cc
config_obj['cStandard'] = "c99"
config_obj['cppStandard'] = "c++11"
config_obj['compileCommands'] ="build/compile_commands.json"
# format "a/b," to a/b. remove first quotation mark("),and remove end (",)
includePath = []
for i in info['CPPPATH']:
if i[0] == '\"' and i[len(i) - 2:len(i)] == '\",':
includePath.append(_make_path_relative(os.getcwd(), i[1:len(i) - 2]))
else:
includePath.append(_make_path_relative(os.getcwd(), i))
config_obj['includePath'] = includePath
json_obj = {}
json_obj['configurations'] = [config_obj]
vsc_file.write(json.dumps(json_obj, ensure_ascii=False, indent=4))
"""
Generate vscode.code-workspace files by build/compile_commands.json
"""
if os.path.exists('build/compile_commands.json'):
command_json_to_workspace(env['RTT_ROOT'],'build/compile_commands.json')
return
"""
Generate vscode.code-workspace files
"""
with open('vscode.code-workspace', 'w') as vsc_space_file:
info = utils.ProjectInfo(env)
path_list = []
for i in info['CPPPATH']:
if _make_path_relative(os.getcwd(), i)[0] == '.':
if i[0] == '\"' and i[len(i) - 2:len(i)] == '\",':
path_list.append({'path':_make_path_relative(os.getcwd(), i[1:len(i) - 2])})
else:
path_list.append({'path':_make_path_relative(os.getcwd(), i)})
for i in info['DIRS']:
if _make_path_relative(os.getcwd(), i)[0] == '.':
if i[0] == '\"' and i[len(i) - 2:len(i)] == '\",':
path_list.append({'path':_make_path_relative(os.getcwd(), i[1:len(i) - 2])})
else:
path_list.append({'path':_make_path_relative(os.getcwd(), i)})
json_obj = {}
path_list = delete_repeatelist(path_list)
path_list = sorted(path_list, key=lambda x: x["path"])
for path in path_list:
if path['path'] != '.':
normalized_path = path['path'].replace('\\', os.path.sep)
segments = [p for p in normalized_path.split(os.path.sep) if p != '..']
path['name'] = 'rtthread/' + '/'.join(segments)
json_obj['folders'] = path_list
if os.path.exists('build/compile_commands.json'):
json_obj['settings'] = {
"clangd.arguments": [
"--compile-commands-dir=.",
"--header-insertion=never"
]
}
vsc_space_file.write(json.dumps(json_obj, ensure_ascii=False, indent=4))
return
def GenerateProjectFiles(env):
"""
Generate project.json file
"""
if not os.path.exists('.vscode'):
os.mkdir('.vscode')
project = env['project']
with open('.vscode/project.json', 'w') as vsc_file:
groups = []
for group in project:
if len(group['src']) > 0:
item = {}
item['name'] = group['name']
item['path'] = _make_path_relative(os.getcwd(), group['path'])
item['files'] = []
for fn in group['src']:
item['files'].append(str(fn))
# append SConscript if exist
if os.path.exists(os.path.join(item['path'], 'SConscript')):
item['files'].append(os.path.join(item['path'], 'SConscript'))
groups.append(item)
json_dict = {}
json_dict['RT-Thread'] = env['RTT_ROOT']
json_dict['Groups'] = groups
# write groups to project.json
vsc_file.write(json.dumps(json_dict, ensure_ascii=False, indent=4))
return
def GenerateVSCode(env):
print('Update setting files for VSCode...')
GenerateProjectFiles(env)
GenerateCFiles(env)
print('Done!')
return
import os
def find_rtconfig_dirs(bsp_dir, project_dir):
"""
Search for subdirectories containing 'rtconfig.h' under 'bsp_dir' (up to 4 levels deep), excluding 'project_dir'.
Args:
bsp_dir (str): The root directory to search (absolute path).
project_dir (str): The subdirectory to exclude from the search (absolute path).
Returns
list: A list of absolute paths to subdirectories containing 'rtconfig.h'.
"""
result = []
project_dir = os.path.normpath(project_dir)
# list the bsp_dir to add result
list = os.listdir(bsp_dir)
for item in list:
item = os.path.join(bsp_dir, item)
# if item is a directory
if not os.path.isdir(item):
continue
# print(item, project_dir)
if not project_dir.startswith(item):
result.append(os.path.abspath(item))
parent_dir = os.path.dirname(project_dir)
if parent_dir != bsp_dir:
list = os.listdir(parent_dir)
for item in list:
item = os.path.join(parent_dir, item)
rtconfig_path = os.path.join(item, 'rtconfig.h')
if os.path.isfile(rtconfig_path):
abs_path = os.path.abspath(item)
if abs_path != project_dir:
result.append(abs_path)
# print(result)
return result
def GenerateVSCodeWorkspace(env):
"""
Generate vscode.code files
"""
print('Update workspace files for VSCode...')
# get the launch directory
cwd = GetLaunchDir()
# get .vscode/workspace.json file
workspace_file = os.path.join(cwd, '.vscode', 'workspace.json')
if not os.path.exists(workspace_file):
print('Workspace file not found, skip generating.')
return
try:
# read the workspace file
with open(workspace_file, 'r') as f:
workspace_data = json.load(f)
# get the bsp directories from the workspace data, bsps/folder
bsp_dir = os.path.join(cwd, workspace_data.get('bsps', {}).get('folder', ''))
if not bsp_dir:
print('No BSP directories found in the workspace file, skip generating.')
return
except Exception as e:
print('Error reading workspace file, skip generating.')
return
# check if .vscode folder exists, if not, create it
if not os.path.exists(os.path.join(cwd, '.vscode')):
os.mkdir(os.path.join(cwd, '.vscode'))
with open(os.path.join(cwd, '.vscode/c_cpp_properties.json'), 'w') as vsc_file:
info = utils.ProjectInfo(env)
cc = os.path.join(rtconfig.EXEC_PATH, rtconfig.CC)
cc = os.path.abspath(cc).replace('\\', '/')
config_obj = {}
config_obj['name'] = 'Linux'
config_obj['defines'] = info['CPPDEFINES']
intelliSenseMode = 'linux-gcc-arm'
if cc.find('aarch64') != -1:
intelliSenseMode = 'linux-gcc-arm64'
elif cc.find('arm') != -1:
intelliSenseMode = 'linux-gcc-arm'
config_obj['intelliSenseMode'] = intelliSenseMode
config_obj['compilerPath'] = cc
config_obj['cStandard'] = "c99"
config_obj['cppStandard'] = "c++11"
# format "a/b," to a/b. remove first quotation mark("),and remove end (",)
includePath = []
for i in info['CPPPATH']:
if i[0] == '\"' and i[len(i) - 2:len(i)] == '\",':
includePath.append(_make_path_relative(cwd, i[1:len(i) - 2]))
else:
includePath.append(_make_path_relative(cwd, i))
# make sort for includePath
includePath = sorted(includePath, key=lambda x: x.lower())
config_obj['includePath'] = includePath
json_obj = {}
json_obj['configurations'] = [config_obj]
vsc_file.write(json.dumps(json_obj, ensure_ascii=False, indent=4))
# generate .vscode/settings.json
vsc_settings = {}
settings_path = os.path.join(cwd, '.vscode/settings.json')
if os.path.exists(settings_path):
with open(settings_path, 'r') as f:
# read the existing settings file and load to vsc_settings
vsc_settings = json.load(f)
with open(settings_path, 'w') as vsc_file:
vsc_settings['files.exclude'] = {
"**/__pycache__": True,
"tools/kconfig-frontends": True,
}
result = find_rtconfig_dirs(bsp_dir, os.getcwd())
if result:
# sort the result
result = sorted(result, key=lambda x: x.lower())
for item in result:
# make the path relative to the current working directory
rel_path = os.path.relpath(item, cwd)
# add the path to files.exclude
vsc_settings['files.exclude'][rel_path] = True
vsc_settings['search.exclude'] = vsc_settings['files.exclude']
# write the settings to the file
vsc_file.write(json.dumps(vsc_settings, ensure_ascii=False, indent=4))
print('Done!')
return
+145
View File
@@ -0,0 +1,145 @@
add_rules("mode.debug", "mode.release")
toolchain("arm-none-eabi")
set_kind("standalone")
set_sdkdir("/home/bernard/.env/tools/scripts/packages/arm-none-eabi-gcc-v13.2.rel1")
toolchain_end()
target("rt-thread")
set_kind("binary")
set_toolchains("arm-none-eabi")
add_files(
"applications/main.c",
"../../../components/libc/compilers/common/cctype.c",
"../../../components/libc/compilers/common/cstdlib.c",
"../../../components/libc/compilers/common/cstring.c",
"../../../components/libc/compilers/common/ctime.c",
"../../../components/libc/compilers/common/cunistd.c",
"../../../components/libc/compilers/common/cwchar.c",
"../../../components/libc/compilers/newlib/syscalls.c",
"../../../components/drivers/core/device.c",
"../../../components/drivers/ipc/completion_comm.c",
"../../../components/drivers/ipc/completion_up.c",
"../../../components/drivers/ipc/condvar.c",
"../../../components/drivers/ipc/dataqueue.c",
"../../../components/drivers/ipc/pipe.c",
"../../../components/drivers/ipc/ringblk_buf.c",
"../../../components/drivers/ipc/ringbuffer.c",
"../../../components/drivers/ipc/waitqueue.c",
"../../../components/drivers/ipc/workqueue.c",
"../../../components/drivers/pin/dev_pin.c",
"../../../components/drivers/serial/dev_serial.c",
"../libraries/HAL_Drivers/drivers/drv_gpio.c",
"../libraries/HAL_Drivers/drivers/drv_usart.c",
"../libraries/HAL_Drivers/drv_common.c",
"board/CubeMX_Config/Src/stm32f4xx_hal_msp.c",
"board/board.c",
"../../../components/finsh/shell.c",
"../../../components/finsh/msh.c",
"../../../components/finsh/msh_parse.c",
"../../../components/finsh/cmd.c",
"../../../src/clock.c",
"../../../src/components.c",
"../../../src/cpu_up.c",
"../../../src/defunct.c",
"../../../src/idle.c",
"../../../src/ipc.c",
"../../../src/irq.c",
"../../../src/kservice.c",
"../../../src/mem.c",
"../../../src/mempool.c",
"../../../src/object.c",
"../../../src/scheduler_comm.c",
"../../../src/scheduler_up.c",
"../../../src/thread.c",
"../../../src/timer.c",
"../../../src/klibc/kstring.c",
"../../../src/klibc/rt_vsscanf.c",
"../../../src/klibc/kstdio.c",
"../../../src/klibc/rt_vsnprintf_tiny.c",
"../../../src/klibc/kerrno.c",
"../../../libcpu/arm/common/atomic_arm.c",
"../../../libcpu/arm/common/div0.c",
"../../../libcpu/arm/common/showmem.c",
"../../../libcpu/arm/cortex-m4/context_gcc.S",
"../../../libcpu/arm/cortex-m4/cpuport.c",
"packages/stm32f4_cmsis_driver-latest/Source/Templates/gcc/startup_stm32f412zx.s",
"packages/stm32f4_cmsis_driver-latest/Source/Templates/system_stm32f4xx.c",
"packages/stm32f4_hal_driver-latest/Src/stm32f4xx_hal_dma_ex.c",
"packages/stm32f4_hal_driver-latest/Src/stm32f4xx_hal_usart.c",
"packages/stm32f4_hal_driver-latest/Src/stm32f4xx_hal_pwr_ex.c",
"packages/stm32f4_hal_driver-latest/Src/stm32f4xx_hal_cryp.c",
"packages/stm32f4_hal_driver-latest/Src/stm32f4xx_hal_gpio.c",
"packages/stm32f4_hal_driver-latest/Src/stm32f4xx_hal_rcc.c",
"packages/stm32f4_hal_driver-latest/Src/stm32f4xx_hal.c",
"packages/stm32f4_hal_driver-latest/Src/stm32f4xx_hal_cortex.c",
"packages/stm32f4_hal_driver-latest/Src/stm32f4xx_hal_pwr.c",
"packages/stm32f4_hal_driver-latest/Src/stm32f4xx_hal_cec.c",
"packages/stm32f4_hal_driver-latest/Src/stm32f4xx_hal_cryp_ex.c",
"packages/stm32f4_hal_driver-latest/Src/stm32f4xx_hal_dma.c",
"packages/stm32f4_hal_driver-latest/Src/stm32f4xx_hal_uart.c",
"packages/stm32f4_hal_driver-latest/Src/stm32f4xx_hal_rcc_ex.c",
"packages/stm32f4_hal_driver-latest/Src/stm32f4xx_hal_crc.c",
"packages/stm32f4_hal_driver-latest/Src/stm32f4xx_hal_rng.c"
)
add_includedirs(
"applications",
"packages/CMSIS-Core-latest/Include",
"../../../components/libc/compilers/newlib",
"../../../components/libc/compilers/common/include",
"../../../components/drivers/include",
"../../../components/drivers/smp_call",
"../../../components/drivers/phy",
"board",
"board/CubeMX_Config/Inc",
"../libraries/HAL_Drivers/drivers",
"../libraries/HAL_Drivers/drivers/config",
"../libraries/HAL_Drivers",
"../../../components/finsh",
".",
"../../../include",
"../../../libcpu/arm/common",
"../../../libcpu/arm/cortex-m4",
"../../../components/libc/posix/ipc",
"../../../components/libc/posix/io/poll",
"../../../components/libc/posix/io/eventfd",
"../../../components/libc/posix/io/epoll",
"packages/stm32f4_cmsis_driver-latest/Include",
"packages/stm32f4_hal_driver-latest/Inc",
"packages/stm32f4_hal_driver-latest/Inc/Legacy"
)
add_defines(
"RT_USING_LIBC",
"RT_USING_NEWLIBC",
"STM32F412Zx",
"USE_HAL_DRIVER",
"_POSIX_C_SOURCE=1",
"__RTTHREAD__"
)
add_cflags(
" -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g" ,{force = true}
)
add_cxxflags(
" -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g" ,{force = true}
)
add_asflags(
" -c -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -x assembler-with-cpp -Wa,-mimplicit-it=thumb -gdwarf-2" ,{force = true}
)
add_ldflags(
" -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=rt-thread.map,-cref,-u,Reset_Handler -T board/linker_scripts/link.lds" ,{force = true}
)
set_targetdir("./")
set_filename("rtthread.elf")
after_build(function(target)
os.exec("/home/bernard/.env/tools/scripts/packages/arm-none-eabi-gcc-v13.2.rel1/bin/arm-none-eabi-objcopy -O ihex rtthread.elf rtthread.hex")
os.exec("/home/bernard/.env/tools/scripts/packages/arm-none-eabi-gcc-v13.2.rel1/bin/arm-none-eabi-objcopy -O binary rtthread.elf rtthread.bin")
os.exec("/home/bernard/.env/tools/scripts/packages/arm-none-eabi-gcc-v13.2.rel1/bin/arm-none-eabi-size rtthread.elf")
end)
+93
View File
@@ -0,0 +1,93 @@
"""
Utils for CMake
Author: https://github.com/klivelinux
"""
import os
import utils
from string import Template
import rtconfig
from utils import _make_path_relative
class XmakeProject:
def __init__(self, env, project):
self.env = env
self.project = project
self.sdkdir = ""
self.bindir = ""
self.toolchain = ""
self.src_path = ""
self.inc_path = ""
self.cflags = ""
self.cxxflags = ""
self.ldflags = ""
self.asflags = ""
self.define = ""
def set_toolchain_path(self):
self.bindir = os.path.abspath(rtconfig.EXEC_PATH).replace('\\', "/")
self.sdkdir = self.bindir[:-4]
# delete -
self.toolchain = rtconfig.PREFIX[:-1]
def set_target_config(self):
info = utils.ProjectInfo(self.env)
# 1. config src path
for group in self.project:
for f in group['src']:
# use relative path
path = _make_path_relative(os.getcwd(), os.path.normpath(f.rfile().abspath))
self.src_path += "\t\"{0}\",\n".format(path.replace("\\", "/"))
self.src_path = self.src_path[:-2]
# 2. config dir path
for i in info['CPPPATH']:
# use relative path
path = _make_path_relative(os.getcwd(), i)
self.inc_path += "\t\"{0}\",\n".format(path.replace("\\", "/"))
self.inc_path = self.inc_path[:-2]
# 3. config cflags
self.cflags = rtconfig.CFLAGS.replace('\\', "/").replace('\"', "\\\"")
# 4. config cxxflags
if 'CXXFLAGS' in dir(rtconfig):
self.cxxflags = rtconfig.CXXFLAGS.replace('\\', "/").replace('\"', "\\\"")
else:
self.cxxflags = self.cflags
# 5. config asflags
self.asflags = rtconfig.AFLAGS.replace('\\', "/").replace('\"', "\\\"")
# 6. config lflags
self.ldflags = rtconfig.LFLAGS.replace('\\', "/").replace('\"', "\\\"")
# 7. config define
for i in info['CPPDEFINES']:
self.define += "\t\"{0}\",\n".format(i)
self.define = self.define[:-2]
def generate_xmake_file(self):
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
else:
RTT_ROOT = os.path.normpath(os.getcwd() + '/../../..')
template_path = os.path.join(RTT_ROOT, "tools", "targets", "xmake.lua")
with open(template_path, "r") as f:
data = f.read()
data = Template(data)
data = data.safe_substitute(toolchain=self.toolchain, sdkdir=self.sdkdir, bindir=self.bindir, src_path=self.src_path, inc_path=self.inc_path,
define=self.define, cflags=self.cflags, cxxflags=self.cxxflags, asflags=self.asflags,
ldflags=self.ldflags, target="rt-thread")
with open(os.path.join(os.path.dirname(__file__), "xmake.lua"), "w") as f:
f.write(data)
def XMakeProject(env,project):
print('Update setting files for xmake.lua...')
xmake_project = XmakeProject(env, project)
xmake_project.set_toolchain_path()
xmake_project.set_target_config()
xmake_project.generate_xmake_file()
print('Done!')
return
+100
View File
@@ -0,0 +1,100 @@
"""
Utils for CMake
Author: https://github.com/klivelinux
"""
import os
import sys
import re
import utils
import rtconfig
from utils import _make_path_relative
def GenerateCFiles(env,project):
info = utils.ProjectInfo(env)
ARCH = ".thumb" if rtconfig.CPU in ['cortex-m0', 'cortex-m3', 'cortex-m4', 'cortex-m7','cortex-m23','cortex-m33','cortex-m85'] else ".arm"
CFLAGS = rtconfig.CFLAGS.replace('\\', "/").replace('\"', "\\\"")
LFLAGS = rtconfig.LFLAGS.replace('\\', "/").replace('\"', "\\\"")
zig_file = open('build.zig', 'w')
if zig_file:
zig_file.write("const std = @import(\"std\");\n\n")
zig_file.write("const target = std.zig.CrossTarget{\n")
zig_file.write(" .cpu_arch = {},\n".format(ARCH))
zig_file.write(" .cpu_model = .{{ .explicit = &std.Target.{}.cpu.{} }},\n".format(rtconfig.ARCH, rtconfig.CPU.replace('-', '_')))
zig_file.write(" .os_tag = .freestanding,\n")
zig_file.write(" .abi = .eabi,\n")
zig_file.write("};\n\n")
zig_file.write("const c_includes = [_][]const u8{\n")
for i in info['CPPPATH']:
# use relative path
path = _make_path_relative(os.getcwd(), i)
zig_file.write("\t\"{}\",\n".format(path.replace("\\", "/")))
zig_file.write("};\n\n")
zig_file.write("const c_sources = [_][]const u8{\n")
for group in project:
for f in group['src']:
# use relative path
path = _make_path_relative(os.getcwd(), os.path.normpath(f.rfile().abspath))
zig_file.write("\t\"{}\",\n".format(path.replace("\\", "/")))
zig_file.write("};\n\n")
zig_file.write("const c_flags = [_][]const u8{\n")
zig_file.write("\t\"-std=c99\",\n")
zig_file.write("\t\"-ffunction-sections\",\n")
zig_file.write("\t\"-fdata-sections\",\n")
# conver CDefines to CFlags
for i in info['CPPDEFINES']:
zig_file.write("\t\"-D{}\",\n".format(i))
# conver LocalCDefines to CFlags
for group in project:
if 'LOCAL_CPPDEFINES' in group and group['LOCAL_CPPDEFINES']:
for i in group['LOCAL_CPPDEFINES']:
zig_file.write("\t\"-D{}\",\n".format(i))
zig_file.write("};\n\n")
zig_file.write("pub fn build(b: *std.Build) void {\n")
zig_file.write(" const optimize = .ReleaseSafe;\n\n")
zig_file.write(" const elf = b.addExecutable(.{\n")
zig_file.write(" .name = \"rtthread.elf\",\n")
zig_file.write(" .target = b.resolveTargetQuery(target),\n")
zig_file.write(" .optimize = optimize,\n")
zig_file.write(" .strip = false,\n")
zig_file.write(" });\n\n")
zig_file.write(" elf.entry = .{ .symbol_name = \"Reset_Handler\" };\n\n")
zig_file.write(" elf.addCSourceFiles(.{ .files = &c_sources, .flags = &c_flags });\n")
zig_file.write(" for (c_includes) |include| {\n")
zig_file.write(" elf.addIncludePath(b.path(include));\n")
zig_file.write(" }\n\n")
# find link script in rtconfig.LFLAGS
LINK_SCRIPT = re.search(r'-T\s*(\S+)', LFLAGS)
zig_file.write(" elf.setLinkerScript(b.path(\"{}\"));\n".format(LINK_SCRIPT.group(1)))
zig_file.write(" const copy_elf = b.addInstallArtifact(elf, .{});\n")
zig_file.write(" b.default_step.dependOn(&copy_elf.step);\n\n")
zig_file.write(" const bin = b.addObjCopy(elf.getEmittedBin(), .{ .format = .bin });\n")
zig_file.write(" bin.step.dependOn(&elf.step);\n")
zig_file.write(" const copy_bin = b.addInstallBinFile(bin.getOutput(), \"rtthread.bin\");\n")
zig_file.write(" b.default_step.dependOn(&copy_bin.step);\n")
zig_file.write("}\n")
zig_file.close()
return
def ZigBuildProject(env,project):
print('Update setting files for build.zig...')
GenerateCFiles(env,project)
print('Done!')
return