diff --git a/lang/mips.mti.gcc.verify.json b/lang/mips.mti.gcc.verify.json new file mode 100644 index 00000000..e6f31967 --- /dev/null +++ b/lang/mips.mti.gcc.verify.json @@ -0,0 +1,376 @@ +{ + "title": "MIPS GCC Options", + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "definitions": { + "FLAGS": { + "markdownDescription": "Other Options", + "description.zh-cn": "其他选项", + "size": "huge", + "type": [ + "string", + "array" + ], + "items": { + "type": "string" + }, + "default": [] + } + }, + "properties": { + "beforeBuildTasks": { + "markdownDescription": "List of commands to execute before build", + "description.zh-cn": "构建前要执行的命令列表", + "type": "array", + "default": [ + { + "name": "clean", + "command": "del /Q \"${OutDir}\\*.*\"" + } + ], + "items": { + "type": "object", + "required": [ + "name", + "command" + ], + "properties": { + "name": { + "markdownDescription": "A readable name for display", + "description.zh-cn": "用于显示的可读名称", + "type": "string" + }, + "command": { + "markdownDescription": "Shell command line", + "description.zh-cn": "Shell 命令行", + "type": "string" + }, + "disable": { + "markdownDescription": "Disable this command", + "description.zh-cn": "禁用此命令", + "type": "boolean", + "enum": [ + true, + false + ] + }, + "abortAfterFailed": { + "markdownDescription": "Whether to skip subsequent commands if this command failed", + "description.zh-cn": "是否在此命令失败时,跳过后续的命令", + "type": "boolean", + "enum": [ + true, + false + ] + }, + "stopBuildAfterFailed": { + "markdownDescription": "Whether to stop compiling directly when this command failed", + "description.zh-cn": "是否在此命令失败时,直接停止编译", + "type": "boolean", + "enum": [ + true, + false + ] + } + } + } + }, + "afterBuildTasks": { + "markdownDescription": "List of commands to execute after build", + "description.zh-cn": "构建结束后要执行的命令列表", + "type": "array", + "default": [ + { + "name": "clean", + "command": "del \"${OutDir}\\*._*\"" + } + ], + "items": { + "type": "object", + "required": [ + "name", + "command" + ], + "properties": { + "name": { + "markdownDescription": "A readable name for display", + "description.zh-cn": "用于显示的可读名称", + "type": "string" + }, + "command": { + "markdownDescription": "Shell command line", + "description.zh-cn": "Shell 命令行", + "type": "string" + }, + "disable": { + "markdownDescription": "Disable this command", + "description.zh-cn": "禁用此命令", + "type": "boolean", + "enum": [ + true, + false + ] + }, + "abortAfterFailed": { + "markdownDescription": "Whether to skip subsequent commands if this command failed", + "description.zh-cn": "是否在此命令失败时,跳过后续的命令", + "type": "boolean", + "enum": [ + true, + false + ] + } + } + } + }, + "global": { + "markdownDescription": "Global Options", + "description.zh-cn": "全局选项", + "type": "object", + "properties": { + "output-debug-info": { + "markdownDescription": "Output debug information", + "description.zh-cn": "输出调试信息", + "type": "string", + "default": "disable", + "enum": [ + "disable", + "enable", + "dwarf-2", + "dwarf-3" + ] + }, + "$float-abi-type": { + "markdownDescription": "Hardware floating-point ABI", + "description.zh-cn": "硬件浮点 ABI", + "type": "string", + "default": "softfp", + "enum": [ + "soft-float", + "hard-float" + ] + }, + "arch": { + "markdownDescription": "Arch", + "description.zh-cn": "指令集(arch)", + "size": "small", + "type": "string", + "auto_complete_ctx": "gcc.compiler.archs" + }, + "abi": { + "readable_name": "ABI", + "readable_name.zh-cn": "调用约定(abi)", + "markdownDescription": "Integer and floating-point calling convention", + "description.zh-cn": "整数和浮点调用约定", + "size": "small", + "auto_complete_ctx": "gcc.compiler.abis" + }, + "misc-control": { + "markdownDescription": "Other Global Options", + "description.zh-cn": "编译器附加选项(全局)", + "$ref": "#/definitions/FLAGS", + "default": "" + } + } + }, + "c/cpp-compiler": { + "markdownDescription": "C/C++ Compiler Options", + "description.zh-cn": "C/C++ 编译器选项", + "type": "object", + "properties": { + "language-c": { + "markdownDescription": "C Standard", + "description.zh-cn": "C 标准", + "type": "string", + "default": "c11", + "enum": [ + "c89", + "c90", + "c99", + "c11", + "c17", + "gnu89", + "gnu90", + "gnu99", + "gnu11", + "gnu17" + ] + }, + "language-cpp": { + "markdownDescription": "C++ Standard", + "description.zh-cn": "C++ 标准", + "type": "string", + "default": "c++11", + "enum": [ + "c++98", + "gnu++98", + "c++11", + "gnu++11", + "c++14", + "gnu++14", + "c++17", + "gnu++17" + ] + }, + "optimization": { + "markdownDescription": "Optimization Level", + "description.zh-cn": "代码优化级别", + "type": "string", + "default": "level-0", + "enum": [ + "level-0", + "level-1", + "level-2", + "level-3", + "level-size", + "level-fast", + "level-debug" + ], + "enumDescriptions": [ + "-O0 (default)", + "-O1", + "-O2", + "-O3", + "-Os", + "-Ofast", + "-Og" + ] + }, + "warnings": { + "markdownDescription": "Warning Level", + "description.zh-cn": "警告等级", + "type": "string", + "default": "all-warnings", + "enum": [ + "no-warnings", + "all-warnings" + ] + }, + "turn-warning-into-errors": { + "markdownDescription": "Turn warnings into errors", + "description.zh-cn": "将警告转化为错误", + "type": "boolean" + }, + "one-elf-section-per-function": { + "markdownDescription": "One ELF Section per Function", + "type": "boolean" + }, + "one-elf-section-per-data": { + "markdownDescription": "One ELF Section per Data", + "type": "boolean" + }, + "C_FLAGS": { + "markdownDescription": "Other C Compiler Options", + "description.zh-cn": "C 编译器附加选项", + "$ref": "#/definitions/FLAGS", + "default": "" + }, + "CXX_FLAGS": { + "markdownDescription": "Other C++ Compiler Options", + "description.zh-cn": "C++ 编译器附加选项", + "$ref": "#/definitions/FLAGS", + "default": "" + } + } + }, + "asm-compiler": { + "markdownDescription": "Assembler Options", + "description.zh-cn": "汇编器选项", + "type": "object", + "properties": { + "defines": { + "readable_name": "Preprocessor Definitions", + "readable_name.zh-cn": "预处理器定义", + "markdownDescription": "Preprocessor Definitions", + "description.zh-cn": "预处理器定义", + "type": "array", + "items": { + "type": "string" + } + }, + "ASM_FLAGS": { + "markdownDescription": "Other Assembler Options", + "description.zh-cn": "汇编器附加选项", + "$ref": "#/definitions/FLAGS", + "default": "" + } + } + }, + "linker": { + "markdownDescription": "Linker Options", + "description.zh-cn": "链接器选项", + "type": "object", + "properties": { + "output-format": { + "type": "string", + "default": "elf", + "description": "Output Format", + "description.zh-cn": "输出格式", + "enum": [ + "elf", + "lib" + ], + "enumDescriptions": [ + "ELF", + "LIB" + ] + }, + "$disableOutputTask": { + "type": "boolean", + "markdownDescription": "Not Output Hex/Bin File", + "description.zh-cn": "不生成 Hex/Bin 文件", + "enum": [ + true, + false + ] + }, + "remove-unused-input-sections": { + "markdownDescription": "Remove Unused Input Sections", + "type": "boolean" + }, + "not-print-mem-usage": { + "markdownDescription": "Not Print Memory Usage (disable: -Wl,--print-memory-usage)", + "type": "boolean" + }, + "LD_FLAGS": { + "readable_name": "Other Linker Options", + "readable_name.zh-cn": "链接器附加选项", + "markdownDescription": "Use '-Wl[,option]...' pass options to the linker", + "description.zh-cn": "使用 '-Wl[,option]...' 传递链接器选项", + "$ref": "#/definitions/FLAGS", + "default": "" + }, + "LIB_FLAGS": { + "readable_name": "Lib Flags", + "readable_name.zh-cn": "链接库选项", + "markdownDescription": "Lib Flags, like: -lxxx", + "description.zh-cn": "链接库选项,例如:-lxxx", + "$ref": "#/definitions/FLAGS", + "default": "" + }, + "object-order": { + "type": "array", + "readable_name": "Object Order", + "readable_name.zh-cn": "Object Order", + "markdownDescription": "Object Order (used to determine the order in which object files are linked)", + "description.zh-cn": "Object Order(用于决定某些 obj 文件的链接顺序)", + "default": [], + "properties": { + "pattern": { + "type": "string", + "readable_name": "Pattern", + "description": "A glob pattern (https://github.com/dazinator/DotNet.Glob) to match a object (*.o) file", + "default": "**/your/pattern/for/object/file/path/*.o" + }, + "order": { + "type": "number", + "readable_name": "Order", + "description": "An integer number (The smaller the value, the higher the priority)", + "default": 0 + } + } + } + } + } + } +} \ No newline at end of file diff --git a/package.json b/package.json index 0a1c3ee2..3e120228 100644 --- a/package.json +++ b/package.json @@ -442,6 +442,18 @@ "markdownDescription": "%settings.riscv.gcc.prefix%", "default": "riscv-none-embed-" }, + "EIDE.MIPS.InstallDirectory": { + "type": "string", + "scope": "resource", + "markdownDescription": "%settings.mips.gcc.install.folder%", + "default": "${userRoot}/.eide/tools/mips_mti" + }, + "EIDE.MIPS.ToolPrefix": { + "type": "string", + "scope": "resource", + "markdownDescription": "%settings.mips.gcc.prefix%", + "default": "mips-mti-elf-" + }, "EIDE.Toolchain.AnyGcc.InstallDirectory": { "type": "string", "scope": "resource", @@ -1566,6 +1578,10 @@ "fileMatch": "**/*riscv.gcc.options.json", "url": "./lang/riscv.gcc.verify.json" }, + { + "fileMatch": "**/*mips.mti.gcc.options.json", + "url": "./lang/mips.mti.gcc.verify.json" + }, { "fileMatch": "**/*.any.gcc.json", "url": "./lang/any.gcc.verify.json" diff --git a/package.nls.json b/package.nls.json index e596668d..96d4dbd0 100644 --- a/package.nls.json +++ b/package.nls.json @@ -136,7 +136,10 @@ "settings.armcc.ini": "Keil MDK-ARM `UV4.exe` or `TOOLS.INI` file path [`example: C:\\Keil_v5\\UV4\\UV4.exe`]", "settings.armcc.convert.axf": "Convert `.axf` to `.elf` for ARMCC compiler", - + + "settings.mips.gcc.install.folder": "MIPS toolchain install folder [`example: D:\\mips-mti-elf-mingw64`]", + "settings.mips.gcc.prefix": "MIPS toolchain prefix, like: `mips-mti-elf-`", + "settings.riscv.gcc.install.folder": "RISC-V toolchain install folder [`example: D:\\xpack-riscv-none-embed-gcc-8.3.0-2.3`]", "settings.riscv.gcc.prefix": "RISC-V toolchain prefix, like: `riscv-none-embed-`", diff --git a/package.nls.zh-CN.json b/package.nls.zh-CN.json index 584af732..9f5adb3b 100644 --- a/package.nls.zh-CN.json +++ b/package.nls.zh-CN.json @@ -127,6 +127,9 @@ "settings.armcc.ini": "Keil MDK-ARM `UV4.exe` 或 `TOOLS.INI` 文件路径 [`example: C:\\Keil_v5\\UV4\\UV4.exe`]", "settings.armcc.convert.axf": "编译完成后将 `.axf` 转换为 `.elf`", + "settings.mips.gcc.install.folder": "MIPS Toolchain 安装目录 [`example: D:\\mips-mti-elf-mingw64`]", + "settings.mips.gcc.prefix": "MIPS toolchain 编译器前缀,例如:`mips-mti-elf-`", + "settings.riscv.gcc.install.folder": "RISC-V Toolchain 安装目录 [`example: D:\\xpack-riscv-none-embed-gcc-8.3.0-2.3`]", "settings.riscv.gcc.prefix": "RISC-V Toolchain 编译器前缀,例如:`riscv-none-embed-`", diff --git a/res/data/models/unix/arm.iar.model.json b/res/data/models/unix/arm.iar.model.json index 97355900..d2427b3c 100644 --- a/res/data/models/unix/arm.iar.model.json +++ b/res/data/models/unix/arm.iar.model.json @@ -332,9 +332,6 @@ }, "asm": { "$path": "bin/iasmarm", - "$includes": { - "body": "-I${value}" - }, "$invoke": { "useFile": true, "body": "-f ${value}" diff --git a/res/data/models/unix/mips.mti.gcc.model.json b/res/data/models/unix/mips.mti.gcc.model.json new file mode 100644 index 00000000..bc8b7598 --- /dev/null +++ b/res/data/models/unix/mips.mti.gcc.model.json @@ -0,0 +1,305 @@ +{ + "name": "MIPS GCC", + "id": "GCC", + "toolPrefix": "mips-mti-elf-", + "useUnixPath": true, + "version": { + "args": "--version", + "matcher": "\\((?.*?)\\) (?\\d+\\.\\d+\\.\\d+)" + }, + "global": { + "arch": { + "type": "value", + "command": "-march=", + "group": [ + "c", + "cpp", + "asm", + "linker" + ], + "location": "first" + }, + "abi": { + "type": "value", + "command": "-mabi=", + "group": [ + "c", + "cpp", + "asm", + "linker" + ], + "location": "first" + }, + "optimization": { + "type": "selectable", + "command": { + "false": "-O0", + "level-0": "-O0", + "level-1": "-O1", + "level-2": "-O2", + "level-3": "-O3", + "level-size": "-Os", + "level-fast": "-Ofast", + "level-debug": "-Og" + }, + "group": [ + "c", + "cpp" + ] + }, + "turn-warning-into-errors": { + "type": "selectable", + "command": { + "true": "-Werror", + "false": "" + }, + "group": [ + "c", + "cpp" + ] + }, + "warnings": { + "type": "selectable", + "command": { + "false": "", + "no-warnings": "-w", + "all-warnings": "-Wall" + }, + "group": [ + "c", + "cpp" + ] + }, + "output-debug-info": { + "type": "selectable", + "command": { + "enable": "-g", + "disable": "", + "dwarf-2": "-g -gdwarf-2", + "dwarf-3": "-g -gdwarf-3", + "false": "" + }, + "group": [ + "c", + "cpp", + "asm" + ] + }, + "C_FLAGS": { + "type": "list", + "command": "", + "group": [ + "c" + ] + }, + "CXX_FLAGS": { + "type": "list", + "command": "", + "group": [ + "cpp" + ] + }, + "ASM_FLAGS": { + "type": "list", + "command": "", + "group": [ + "asm" + ] + }, + "LD_FLAGS": { + "type": "list", + "command": "", + "group": [ + "linker" + ] + }, + "misc-control": { + "type": "list", + "command": "", + "group": [ + "c", + "cpp", + "asm", + "linker" + ] + }, + "one-elf-section-per-function": { + "type": "selectable", + "command": { + "true": "-ffunction-sections", + "false": "" + }, + "group": [ + "c", + "cpp" + ] + }, + "one-elf-section-per-data": { + "type": "selectable", + "command": { + "true": "-fdata-sections", + "false": "" + }, + "group": [ + "c", + "cpp" + ] + }, + "remove-unused-input-sections": { + "type": "selectable", + "command": { + "true": "-Wl,--gc-sections", + "false": "" + }, + "group": [ + "linker" + ] + } + }, + "groups": { + "c": { + "$path": "bin/${toolPrefix}gcc", + "$includes": { + "body": "-I${value}" + }, + "$defines": { + "body": "-D${key}=\"${value}\"" + }, + "$invoke": { + "useFile": true, + "body": "@${value}" + }, + "$output": "-o ${out} -MMD ${in}", + "$default": [ + "-c", + "-xc" + ], + "$language-c": { + "type": "keyValue", + "command": "-std=", + "enum": { + "default": "c11", + "c89": "c89", + "c90": "c90", + "c99": "c99", + "c11": "c11", + "c1x": "c1x", + "c17": "c17", + "gnu89": "gnu89", + "gnu90": "gnu90", + "gnu99": "gnu99", + "gnu11": "gnu11", + "gnu1x": "gnu1x", + "gnu17": "gnu17" + } + } + }, + "cpp": { + "$path": "bin/${toolPrefix}gcc", + "$includes": { + "body": "-I${value}" + }, + "$defines": { + "body": "-D${key}=\"${value}\"" + }, + "$invoke": { + "useFile": true, + "body": "@${value}" + }, + "$output": "-o ${out} -MMD ${in}", + "$default": [ + "-c", + "-xc++" + ], + "$language-cpp": { + "type": "keyValue", + "command": "-std=", + "enum": { + "default": "c++11", + "c++98": "c++98", + "gnu++98": "gnu++98", + "c++11": "c++11", + "gnu++11": "gnu++11", + "c++14": "c++14", + "gnu++14": "gnu++14", + "c++17": "c++17", + "gnu++17": "gnu++17" + } + } + }, + "asm": { + "$path": "bin/${toolPrefix}gcc", + "$includes": { + "body": "-I${value}" + }, + "$output": "-o ${out} -MMD ${in}", + "$invoke": { + "useFile": true, + "body": "@${value}" + }, + "$default": [ + "-c", + "-x assembler-with-cpp" + ], + "defines": { + "type": "list", + "command": "-D" + } + }, + "linker": { + "$path": "bin/${toolPrefix}gcc", + "$libs": { + "body": "-L${value}" + }, + "$invoke": { + "useFile": true, + "body": "@${value}" + }, + "$default": [], + "$output": "-o ${out} ${in} ${lib_flags}", + "$outputSuffix": ".elf", + "$linkMap": { + "type": "value", + "command": "-Wl,-Map=${mapPath}" + }, + "$LIB_FLAGS": { + "type": "list", + "command": "" + }, + "linker-script": { + "type": "list", + "command": "-T " + }, + "not-print-mem-usage": { + "type": "selectable", + "command": { + "true": "", + "false": "-Wl,--print-memory-usage" + } + }, + "$outputBin": [ + { + "name": "output hex file", + "toolPath": "bin/${toolPrefix}objcopy", + "outputSuffix": ".hex", + "command": "-O ihex ${linkerOutput} ${output}" + }, + { + "name": "output bin file", + "toolPath": "bin/${toolPrefix}objcopy", + "outputSuffix": ".bin", + "command": "-O binary ${linkerOutput} ${output}" + } + ] + }, + "linker-lib": { + "$path": "bin/${toolPrefix}ar", + "$invoke": { + "useFile": true, + "body": "@${value}" + }, + "$output": "-rcv ${out} ${in}", + "$outputSuffix": ".a" + } + } +} \ No newline at end of file diff --git a/res/data/models/win32/arm.iar.model.json b/res/data/models/win32/arm.iar.model.json index 96632608..1d642fa3 100644 --- a/res/data/models/win32/arm.iar.model.json +++ b/res/data/models/win32/arm.iar.model.json @@ -332,9 +332,6 @@ }, "asm": { "$path": "bin\\iasmarm.exe", - "$includes": { - "body": "-I${value}" - }, "$invoke": { "useFile": true, "body": "-f ${value}" diff --git a/res/data/models/win32/mips.mti.gcc.model.json b/res/data/models/win32/mips.mti.gcc.model.json new file mode 100644 index 00000000..2df7c3ac --- /dev/null +++ b/res/data/models/win32/mips.mti.gcc.model.json @@ -0,0 +1,305 @@ +{ + "name": "MIPS GCC", + "id": "GCC", + "toolPrefix": "mips-mti-elf-", + "useUnixPath": true, + "version": { + "args": "--version", + "matcher": "\\((?.*?)\\) (?\\d+\\.\\d+\\.\\d+)" + }, + "global": { + "arch": { + "type": "value", + "command": "-march=", + "group": [ + "c", + "cpp", + "asm", + "linker" + ], + "location": "first" + }, + "abi": { + "type": "value", + "command": "-mabi=", + "group": [ + "c", + "cpp", + "asm", + "linker" + ], + "location": "first" + }, + "optimization": { + "type": "selectable", + "command": { + "false": "-O0", + "level-0": "-O0", + "level-1": "-O1", + "level-2": "-O2", + "level-3": "-O3", + "level-size": "-Os", + "level-fast": "-Ofast", + "level-debug": "-Og" + }, + "group": [ + "c", + "cpp" + ] + }, + "turn-warning-into-errors": { + "type": "selectable", + "command": { + "true": "-Werror", + "false": "" + }, + "group": [ + "c", + "cpp" + ] + }, + "warnings": { + "type": "selectable", + "command": { + "false": "", + "no-warnings": "-w", + "all-warnings": "-Wall" + }, + "group": [ + "c", + "cpp" + ] + }, + "output-debug-info": { + "type": "selectable", + "command": { + "enable": "-g", + "disable": "", + "dwarf-2": "-g -gdwarf-2", + "dwarf-3": "-g -gdwarf-3", + "false": "" + }, + "group": [ + "c", + "cpp", + "asm" + ] + }, + "C_FLAGS": { + "type": "list", + "command": "", + "group": [ + "c" + ] + }, + "CXX_FLAGS": { + "type": "list", + "command": "", + "group": [ + "cpp" + ] + }, + "ASM_FLAGS": { + "type": "list", + "command": "", + "group": [ + "asm" + ] + }, + "LD_FLAGS": { + "type": "list", + "command": "", + "group": [ + "linker" + ] + }, + "misc-control": { + "type": "list", + "command": "", + "group": [ + "c", + "cpp", + "asm", + "linker" + ] + }, + "one-elf-section-per-function": { + "type": "selectable", + "command": { + "true": "-ffunction-sections", + "false": "" + }, + "group": [ + "c", + "cpp" + ] + }, + "one-elf-section-per-data": { + "type": "selectable", + "command": { + "true": "-fdata-sections", + "false": "" + }, + "group": [ + "c", + "cpp" + ] + }, + "remove-unused-input-sections": { + "type": "selectable", + "command": { + "true": "-Wl,--gc-sections", + "false": "" + }, + "group": [ + "linker" + ] + } + }, + "groups": { + "c": { + "$path": "bin\\${toolPrefix}gcc.exe", + "$includes": { + "body": "-I${value}" + }, + "$defines": { + "body": "-D${key}=\"${value}\"" + }, + "$invoke": { + "useFile": true, + "body": "@${value}" + }, + "$output": "-o ${out} -MMD ${in}", + "$default": [ + "-c", + "-xc" + ], + "$language-c": { + "type": "keyValue", + "command": "-std=", + "enum": { + "default": "c11", + "c89": "c89", + "c90": "c90", + "c99": "c99", + "c11": "c11", + "c1x": "c1x", + "c17": "c17", + "gnu89": "gnu89", + "gnu90": "gnu90", + "gnu99": "gnu99", + "gnu11": "gnu11", + "gnu1x": "gnu1x", + "gnu17": "gnu17" + } + } + }, + "cpp": { + "$path": "bin\\${toolPrefix}gcc.exe", + "$includes": { + "body": "-I${value}" + }, + "$defines": { + "body": "-D${key}=\"${value}\"" + }, + "$invoke": { + "useFile": true, + "body": "@${value}" + }, + "$output": "-o ${out} -MMD ${in}", + "$default": [ + "-c", + "-xc++" + ], + "$language-cpp": { + "type": "keyValue", + "command": "-std=", + "enum": { + "default": "c++11", + "c++98": "c++98", + "gnu++98": "gnu++98", + "c++11": "c++11", + "gnu++11": "gnu++11", + "c++14": "c++14", + "gnu++14": "gnu++14", + "c++17": "c++17", + "gnu++17": "gnu++17" + } + } + }, + "asm": { + "$path": "bin\\${toolPrefix}gcc.exe", + "$includes": { + "body": "-I${value}" + }, + "$output": "-o ${out} -MMD ${in}", + "$invoke": { + "useFile": true, + "body": "@${value}" + }, + "$default": [ + "-c", + "-x assembler-with-cpp" + ], + "defines": { + "type": "list", + "command": "-D" + } + }, + "linker": { + "$path": "bin\\${toolPrefix}gcc.exe", + "$libs": { + "body": "-L${value}" + }, + "$invoke": { + "useFile": true, + "body": "@${value}" + }, + "$default": [], + "$output": "-o ${out} ${in} ${lib_flags}", + "$outputSuffix": ".elf", + "$linkMap": { + "type": "value", + "command": "-Wl,-Map=${mapPath}" + }, + "$LIB_FLAGS": { + "type": "list", + "command": "" + }, + "linker-script": { + "type": "list", + "command": "-T " + }, + "not-print-mem-usage": { + "type": "selectable", + "command": { + "true": "", + "false": "-Wl,--print-memory-usage" + } + }, + "$outputBin": [ + { + "name": "output hex file", + "toolPath": "bin\\${toolPrefix}objcopy.exe", + "outputSuffix": ".hex", + "command": "-O ihex ${linkerOutput} ${output}" + }, + { + "name": "output bin file", + "toolPath": "bin\\${toolPrefix}objcopy.exe", + "outputSuffix": ".bin", + "command": "-O binary ${linkerOutput} ${output}" + } + ] + }, + "linker-lib": { + "$path": "bin\\${toolPrefix}ar.exe", + "$invoke": { + "useFile": true, + "body": "@${value}" + }, + "$output": "-rcv ${out} ${in}", + "$outputSuffix": ".a" + } + } +} \ No newline at end of file diff --git a/res/icon/icon.png b/res/icon/icon.png index 630fb811..29a17dd1 100644 Binary files a/res/icon/icon.png and b/res/icon/icon.png differ diff --git a/res/icon/icon.svg b/res/icon/icon.svg index e2f477cd..70ef2225 100644 --- a/res/icon/icon.svg +++ b/res/icon/icon.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/res/tools/linux/7z/7za b/res/tools/linux/7z/7za old mode 100644 new mode 100755 diff --git a/src/CodeBuilder.ts b/src/CodeBuilder.ts index 0937e3d8..473e37ac 100644 --- a/src/CodeBuilder.ts +++ b/src/CodeBuilder.ts @@ -577,6 +577,8 @@ export abstract class CodeBuilder { return new AnyGccCodeBuilder(_project); case 'C51': return new C51CodeBuilder(_project); + case 'MIPS': + return new MipsCodeBuilder(_project); default: throw new Error(`not support this project type: '${_project.GetConfiguration().config.type}'`); } @@ -1057,6 +1059,32 @@ class RiscvCodeBuilder extends CodeBuilder { } } +class MipsCodeBuilder extends CodeBuilder { + + protected getMcuMemorySize(): MemorySize | undefined { + return undefined; + } + + protected preHandleOptions(options: ICompileOptions) { + + const config = this.project.GetConfiguration().config; + + const ldFileList: string[] = []; + config.compileConfig.linkerScriptPath.split(',') + .filter(s => s.trim() != '') + .forEach((sctPath) => { + ldFileList.push(`"${File.ToUnixPath(this.project.ToAbsolutePath(sctPath))}"`); + }); + + if (!options['linker']) { + options.linker = Object.create(null); + } + + // set linker script + options.linker['linker-script'] = ldFileList; + } +} + class AnyGccCodeBuilder extends CodeBuilder { protected getMcuMemorySize(): MemorySize | undefined { diff --git a/src/EIDEProject.ts b/src/EIDEProject.ts index 7ffd066f..f71b5325 100644 --- a/src/EIDEProject.ts +++ b/src/EIDEProject.ts @@ -1421,8 +1421,9 @@ export abstract class AbstractProject implements CustomConfigurationProvider, Pr targets[targetName] = prjConfig.cloneCurrentTarget(); } - const oldBuilderOptsFile = prjConfig.compileConfigModel + const prevBuilderOptsFile = prjConfig.compileConfigModel .getOptionsFile(this.getEideDir().path, prjConfig.config); + const prevSourcesOptsFile = this.getSourceExtraArgsCfgFile(true); // update current target name prjConfigData.mode = targetName; @@ -1485,12 +1486,24 @@ export abstract class AbstractProject implements CustomConfigurationProvider, Pr .getOptionsFile(this.getEideDir().path, prjConfig.config, true); if (!optsFile.IsFile()) { try { - fs.copyFileSync(oldBuilderOptsFile.path, optsFile.path); + fs.copyFileSync(prevBuilderOptsFile.path, optsFile.path); } catch (error) { // nothing todo } } + // if source options file is not existed, copy it. + if (prevSourcesOptsFile.IsFile()) { + const srcOptsFile = File.fromArray([this.getEideDir().path, `${targetName.toLowerCase()}.files.options.yml`]); + if (!srcOptsFile.IsFile()) { + try { + fs.copyFileSync(prevSourcesOptsFile.path, srcOptsFile.path); + } catch (error) { + // nothing todo + } + } + } + this.sourceRoots.forceUpdateAllFolders(); this.virtualSource.forceUpdateAllFolders(); @@ -2246,6 +2259,14 @@ export abstract class AbstractProject implements CustomConfigurationProvider, Pr this.registerBuiltinVar('ConfigName', () => this.GetConfiguration().config.mode); this.registerBuiltinVar('ProjectRoot', () => this.getRootDir().path); this.registerBuiltinVar('ExecutableName', () => this.getExecutablePathWithoutSuffix()); + + // system vars + this.registerBuiltinVar('SYS_Platform', () => platform.osType()); + this.registerBuiltinVar('SYS_DirSep', () => File.sep); + this.registerBuiltinVar('SYS_DirSeparator', () => File.sep); + this.registerBuiltinVar('SYS_PathSep', () => platform.osType() != 'win32' ? ':' : ';'); + this.registerBuiltinVar('SYS_PathSeparator', () => platform.osType() != 'win32' ? ':' : ';'); + this.registerBuiltinVar('SYS_EOL', () => os.EOL); } private RegisterEvent(): void { @@ -2973,7 +2994,8 @@ class EIDEProject extends AbstractProject { settings['C_Cpp.default.configurationProvider'] = this.extensionId; } - if (settings['C_Cpp.errorSquiggles'] === undefined) { + if (settings['C_Cpp.errorSquiggles'] == undefined || + settings['C_Cpp.errorSquiggles'] == 'Disabled') { settings['C_Cpp.errorSquiggles'] = "disabled"; } diff --git a/src/EIDEProjectExplorer.ts b/src/EIDEProjectExplorer.ts index a4de289c..f64dd0f4 100644 --- a/src/EIDEProjectExplorer.ts +++ b/src/EIDEProjectExplorer.ts @@ -3100,37 +3100,6 @@ class ProjectDataProvider implements vscode.TreeDataProvider, vsco targetDir.CreateDir(true); - let templateShaStr: string | undefined; - let isVerified: boolean | undefined; - - // get template sha str - const li = templateFile.noSuffixName.split('.'); - if (li.length > 1) { - templateShaStr = li[li.length - 1]; - } - - // verify template zip - if (templateShaStr) { - const sha256 = compresser.sha256(templateFile); - if (sha256) { - const sha = md5(sha256); - isVerified = templateShaStr == sha; - } - } - - // if verify failed, notify to user - if (templateShaStr && !isVerified) { - if (templateFile.suffix != '.ewt') { // it's eide template project - const selTxt = await vscode.window.showWarningMessage( - view_str$msg$err_ept_hash, 'Yes', 'No'); - if (selTxt !== 'Yes') { - return; // user canceled - } - } else { // it's eide template workspace - vscode.window.showWarningMessage(view_str$msg$err_ewt_hash); - } - } - const err = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: `Creating project` @@ -3163,17 +3132,6 @@ class ProjectDataProvider implements vscode.TreeDataProvider, vsco // convert .EIDE to .eide this.toLowercaseEIDEFolder(targetDir); - // if not verified, del *.sh - if (!isVerified) { - const eideFolder = File.fromArray([targetDir.path, AbstractProject.EIDE_DIR]); - if (eideFolder.IsDir()) { - eideFolder.GetList([/\-install\.sh$/i], File.EXCLUDE_ALL_FILTER) - .forEach((f) => { - try { fs.unlinkSync(f.path); } catch (err) { } - }); - } - } - // init project { const prjFile = File.fromArray([targetDir.path, AbstractProject.EIDE_DIR, AbstractProject.prjConfigName]); @@ -3751,9 +3709,12 @@ export class ProjectExplorer implements CustomConfigurationProvider { return; } + // close and reopen project this.dataProvider.Close(idx); - this.dataProvider.OpenProject(workspaceFile.path, true); + + // refresh explorer tree view + this.Refresh(); } private async onProjectClosed(uid: string | undefined) { @@ -4488,16 +4449,10 @@ export class ProjectExplorer implements CustomConfigurationProvider { progress.report({ message: 'zipping ...' }); const err = await compresser.Zip(prjRootDir, option, distDir); - if (!err) { // export done, set hash str - const sha256 = compresser.sha256(tFile); - if (sha256) { - const hash = md5(sha256); - const name = `${tFile.dir}/${tFile.noSuffixName}.${hash}${tFile.suffix}`; - try { fs.renameSync(tFile.path, name); } catch (err) { } - } - progress.report({ message: 'export done !' }); - } else { // export failed + if (err) { GlobalEvent.emit('msg', ExceptionToMessage(err, 'Warning')); + } else { + progress.report({ message: 'export done !' }); } setTimeout(() => resolve(err), 1500); @@ -4713,9 +4668,14 @@ export class ProjectExplorer implements CustomConfigurationProvider { } async Virtual_removeFolder(item: ProjTreeItem) { + const project = this.dataProvider.GetProjectByIndex(item.val.projectIndex); const curFolder = item.val.obj; - project.getVirtualSourceManager().removeFolder(curFolder.path); + + const answer = await vscode.window.showInformationMessage(view_str$prompt$removeSrcDir.replace('{}', curFolder.path), txt_yes, txt_no); + if (answer == txt_yes) { + project.getVirtualSourceManager().removeFolder(curFolder.path); + } } async Virtual_renameFolder(item: ProjTreeItem) { @@ -6556,13 +6516,22 @@ export class ProjectExplorer implements CustomConfigurationProvider { let needReload = false; if (tarFlasher.resources[osType()]) { - if (cancel.isCancellationRequested) return; + if (cancel.isCancellationRequested) + return; const res = tarFlasher.resources[osType()]; - let installDir = res.locationType == 'global' ? new File(resManager.getEideToolsInstallDir()) : project.getRootDir(); - if (res.locationType == 'workspace') installDir = File.fromArray([project.getRootDir().path, res.location]); - if (res.zipType != 'none') { + let installDir: File; + let isFirstInstall: boolean = false; + + if (res.locationType == 'workspace') + installDir = File.fromArray([project.getRootDir().path, res.location]); + else // global + installDir = File.fromArray([resManager.getEideToolsInstallDir(), res.location]); + + // if have a resource and not install, download it + if (res.zipType != 'none' && installDir.IsDir() == false) { + reporter.report({ message: 'downloading resources' }); const buf = await downloadFile(redirectHost(res.url)); if (!(buf instanceof Buffer)) throw buf || new Error('Cannot download resource'); @@ -6574,6 +6543,8 @@ export class ProjectExplorer implements CustomConfigurationProvider { const szip = new SevenZipper(); const r = szip.UnzipSync(new File(tmpPath), installDir); GlobalEvent.emit('globalLog', newMessage('Info', r)); + + isFirstInstall = true; } if (res.setupCommand) { @@ -6589,7 +6560,7 @@ export class ProjectExplorer implements CustomConfigurationProvider { } } - needReload = res.locationType == 'global'; + needReload = isFirstInstall && res.locationType == 'global'; } if (cancel.isCancellationRequested) { diff --git a/src/EIDEProjectModules.ts b/src/EIDEProjectModules.ts index f7fa3147..93ec9659 100644 --- a/src/EIDEProjectModules.ts +++ b/src/EIDEProjectModules.ts @@ -432,6 +432,8 @@ export abstract class CompileConfigModel extends ConfigModel { return new AnyGccCompileConfigModel(prjConfigData); case 'GNU_SDCC_STM8': return new SdccGnuStm8CompileConfigModel(prjConfigData); + case 'MTI_GCC': + return new MipsCompileConfigModel(prjConfigData); default: throw new Error('Unsupported toolchain: ' + prjConfigData.toolchain); } @@ -1169,6 +1171,106 @@ export class RiscvCompileConfigModel extends CompileConfigModel { + + GetKeyDescription(key: string): string { + switch (key) { + case 'linkerScriptPath': + return view_str$compile$scatterFilePath; + case 'options': + return view_str$compile$options; + default: + return view_str$compile$deprecated; + } + } + + getKeyValue(key: string): string { + switch (key) { + case 'options': + return 'Object {...}'; + default: + return (this.data)[key] || 'null'; + } + } + + getKeyIcon(key: string): KeyIcon | undefined { + switch (key) { + case 'options': + return 'ConfigurationEditor_16x.svg'; + default: + return 'Property_16x.svg'; + } + } + + protected GetKeyType(key: string): FieldType { + switch (key) { + case 'linkerScriptPath': + return 'INPUT'; + case 'options': + return 'EVENT'; + default: + return 'Disable'; + } + } + + protected IsOpenFileCanSelectMany(key: string): boolean { + switch (key) { + case 'linkerScriptPath': + return true; + default: + return super.IsOpenFileCanSelectMany(key); + } + } + + protected GetOpenFileFilters(key: string): OpenFileFilter | undefined { + switch (key) { + case 'linkerScriptPath': + return { + 'linker script': ['ld', 'lds'], + 'any files': ['*'] + }; + default: + return undefined; + } + } + + protected VerifyString(key: string, input: string): string | undefined { + return undefined; + } + + protected GetSelectionList(key: string): CompileConfigPickItem[] | undefined { + return undefined; + } + + protected getEventData(key: string): EventData | undefined { + switch (key) { + case 'options': + return { + event: 'openCompileOptions' + }; + default: + return undefined; + } + } + + static getDefaultConfig(): MipsCompileData { + return { + linkerScriptPath: '', + options: 'null' + }; + } + + GetDefault(): MipsCompileData { + return MipsCompileConfigModel.getDefaultConfig(); + } +} + // -------- ANY-GCC --------- // deprecated diff --git a/src/EIDETypeDefine.ts b/src/EIDETypeDefine.ts index d7ee0eea..fa96c27f 100644 --- a/src/EIDETypeDefine.ts +++ b/src/EIDETypeDefine.ts @@ -1,25 +1,25 @@ /* - MIT License - - Copyright (c) 2019 github0null - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. + MIT License + + Copyright (c) 2019 github0null + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. */ import * as events from 'events'; @@ -42,7 +42,7 @@ import { ToolchainName } from './ToolchainManager'; import { HexUploaderType } from "./HexUploader"; import { VirtualSource } from "./EIDEProject"; import * as utility from './utility'; -import { CompileConfigModel, UploadConfigModel, SdccCompileConfigModel, GccCompileConfigModel, RiscvCompileConfigModel, AnyGccCompileConfigModel } from './EIDEProjectModules'; +import { CompileConfigModel, UploadConfigModel, SdccCompileConfigModel, GccCompileConfigModel, RiscvCompileConfigModel, AnyGccCompileConfigModel, MipsCompileConfigModel } from './EIDEProjectModules'; //////////////////////////////////////////////////////// @@ -77,7 +77,7 @@ export interface ProjectFileGroup extends FileGroup { // 'RISC-V': RISCV Project // 'ANY-GCC': Any GCC Toolchain Project // -export type ProjectType = 'C51' | 'ARM' | 'RISC-V' | 'ANY-GCC'; +export type ProjectType = 'C51' | 'ARM' | 'RISC-V' | 'ANY-GCC' | 'MIPS'; export interface CreateOptions { name: string; // project folder name @@ -245,7 +245,21 @@ export abstract class Configuration { } Save(force?: boolean): void { - this.cfgFile.Write(this.ToJson()); + + let oldContent: string | undefined; + let newContent: string | undefined = this.ToJson(); + + try { + if (this.cfgFile.IsExist()) { + oldContent = this.cfgFile.Read(); + } + } catch (error) { + GlobalEvent.emit('globalLog', ExceptionToMessage(error, 'Warning')); + } + + if (oldContent != newContent) { + this.cfgFile.Write(newContent); + } } protected afterInitConfigData() { @@ -351,7 +365,7 @@ export interface ProjectConfigData { type: ProjectType; // cur target info (virtual node) - mode: string; // target name + mode: string; // target name (And for historical reasons, that's what it's called) excludeList: string[]; toolchain: ToolchainName; compileConfig: T; @@ -573,6 +587,27 @@ export class ProjectConfiguration targets: {}, version: EIDE_CONF_VERSION }; + case 'MIPS': + return { + name: 'undefined', + type: type, + mode: 'Debug', + toolchain: 'MTI_GCC', + dependenceList: [], + compileConfig: MipsCompileConfigModel.getDefaultConfig(), + uploader: 'Custom', + srcDirs: [], + virtualFolder: { name: VirtualSource.rootName, files: [], folders: [] }, + excludeList: [], + outDir: 'build', + deviceName: null, + packDir: null, + uploadConfig: null, + uploadConfigMap: {}, + miscInfo: {}, + targets: {}, + version: EIDE_CONF_VERSION + }; case 'ANY-GCC': return { name: 'undefined', @@ -1221,10 +1256,25 @@ export class ProjectConfiguration }; setProjectUsrCtx(data: ProjectUserContextData) { + + const usrCtxFile = this.getProjectUsrCtxFile(); + + let oldUsrCtxCont: string | undefined; + if (usrCtxFile.IsExist()) { + try { + oldUsrCtxCont = usrCtxFile.Read(); + } catch (error) { + GlobalEvent.emit('globalLog', ExceptionToMessage(error, 'Warning')); + } + } + try { - this.getProjectUsrCtxFile().Write(JSON.stringify(data, undefined, 4)); + let newUsrCtxCont = JSON.stringify(data, undefined, 4); + if (oldUsrCtxCont != newUsrCtxCont) { + usrCtxFile.Write(newUsrCtxCont); + } } catch (error) { - GlobalEvent.emit('globalLog', ExceptionToMessage(error, 'Warning')); + GlobalEvent.emit('globalLog', ExceptionToMessage(error, 'Error')); } } diff --git a/src/OperationExplorer.ts b/src/OperationExplorer.ts index 5139ee38..37f2b98c 100644 --- a/src/OperationExplorer.ts +++ b/src/OperationExplorer.ts @@ -46,7 +46,8 @@ import { view_str$prompt$setupToolchainPrefix, view_str$prompt$needReloadToUpdateEnv, view_str$operation$create_prj_done, - view_str$prompt$requestAndActivateLicence + view_str$prompt$requestAndActivateLicence, + view_str$operation$empty_mips_prj } from './StringTable'; import { CreateOptions, ImportOptions, ProjectType } from './EIDETypeDefine'; import { File } from '../lib/node-utility/File'; @@ -355,6 +356,11 @@ export class OperationExplorer { detail: 'for risc-v chips', type: 'RISC-V' }, + { + label: view_str$operation$empty_mips_prj, + detail: 'for mips chips', + type: 'MIPS' + }, { label: view_str$operation$empty_anygcc_prj, detail: 'for any gcc famliy toolchains', @@ -715,6 +721,13 @@ export class OperationExplorer { } ] }, + { + label: 'MIPS MTI GCC Compiler', + type: 'MTI_GCC', + description: this.getStatusTxt(toolchainManager.isToolchainPathReady('MTI_GCC')) + + ` Loc: ${toolchainManager.getToolchainExecutableFolder('MTI_GCC')?.path}`, + detail: view_str$operation$setToolchainInstallDir.replace('${name}', 'MTI_GCC'), + }, /* { label: 'SDCC With GNU Patch For STM8 (Only for stm8)', type: 'GNU_SDCC_STM8', diff --git a/src/SettingManager.ts b/src/SettingManager.ts index c78ede83..39d93224 100644 --- a/src/SettingManager.ts +++ b/src/SettingManager.ts @@ -591,6 +591,20 @@ export class SettingManager { return this.getConfiguration().get('RISCV.ToolPrefix') || ''; } + //------------------------------- MTI GCC ---------------------------------- + + getMipsToolFolder(): File { + return new File( + this.getFullPathByPluginConfig('MIPS.InstallDirectory') || + this.findGccCompilerRootInSystemEnv(`${this.getMipsToolPrefix()}gcc`) || + 'null' + ); + } + + getMipsToolPrefix(): string { + return this.getConfiguration().get('MIPS.ToolPrefix') || ''; + } + //------------------------------- Any GCC ---------------------------------- getAnyGccToolFolder(): File { diff --git a/src/StringTable.ts b/src/StringTable.ts index 82933ca9..f00b6570 100644 --- a/src/StringTable.ts +++ b/src/StringTable.ts @@ -431,7 +431,7 @@ export const view_str$prompt$setupToolchainPrefix = [ export const view_str$prompt$requestAndActivateLicence = [ `获取并激活许可证`, - `Obtain And Active Licence` + `Obtain And Activate Licence` ][langIndex]; export const view_str$prompt$requestAndActivateLicence_warn_setupPath = [ @@ -754,6 +754,11 @@ export const view_str$operation$empty_riscv_prj = [ 'RISC-V Project' ][langIndex]; +export const view_str$operation$empty_mips_prj = [ + 'MIPS 项目', + 'MIPS Project' +][langIndex]; + export const view_str$operation$empty_anygcc_prj = [ '通用的 GCC 项目', 'Universal GCC Project' diff --git a/src/ToolchainManager.ts b/src/ToolchainManager.ts index e21fd8a6..e38f0a14 100644 --- a/src/ToolchainManager.ts +++ b/src/ToolchainManager.ts @@ -42,7 +42,7 @@ import { ICompileOptions, ArmBaseBuilderConfigData } from "./EIDEProjectModules" export type ToolchainName = 'SDCC' | 'Keil_C51' | 'IAR_STM8' | 'GNU_SDCC_STM8' | 'COSMIC_STM8' | 'AC5' | 'AC6' | 'GCC' | 'IAR_ARM' | - 'RISCV_GCC' | 'ANY_GCC' | 'None'; + 'RISCV_GCC' | 'ANY_GCC' | 'MTI_GCC' | 'None'; export interface IProjectInfo { @@ -160,6 +160,7 @@ export class ToolchainManager { 'C51': ['Keil_C51', 'SDCC', 'IAR_STM8', 'COSMIC_STM8'], 'ARM': ['AC5', 'AC6', 'GCC', 'IAR_ARM'], 'RISC-V': ['RISCV_GCC'], + 'MIPS': ['MTI_GCC'], 'ANY-GCC': ['ANY_GCC'] }; @@ -191,6 +192,7 @@ export class ToolchainManager { this.add(new RISCV_GCC()); this.add(new AnyGcc()); this.add(new IARARM()); + this.add(new MTI_GCC()); } on(event: 'onChanged', listener: (toolchainName: ToolchainName) => void): void; @@ -250,6 +252,9 @@ export class ToolchainManager { } } break; + case 'MIPS': + res = this.toolchainMap.get('MTI_GCC'); + break; default: throw new Error('Invalid project type \'' + prjType + '\''); } @@ -293,6 +298,8 @@ export class ToolchainManager { return 'Any GNU Toolchain'; case 'COSMIC_STM8': return 'COSMIC STM8 C Compiler'; + case 'MTI_GCC': + return 'MIPS MTI GCC Compiler'; default: return ''; } @@ -415,6 +422,8 @@ export class ToolchainManager { return File.fromArray([settingManager.getSdccDir().path, 'bin']); case 'RISCV_GCC': return File.fromArray([settingManager.getRiscvToolFolder().path, 'bin']); + case 'MTI_GCC': + return File.fromArray([settingManager.getMipsToolFolder().path, 'bin']); case 'GNU_SDCC_STM8': return File.fromArray([settingManager.getGnuSdccStm8Dir().path, 'bin']); case 'ANY_GCC': @@ -1088,7 +1097,7 @@ class COSMIC_STM8 implements IToolchian { } updateCppIntellisenceCfg(builderOpts: ICompileOptions, cppToolsConfig: CppConfigItem): void { - cppToolsConfig.cStandard = 'c99'; + cppToolsConfig.cStandard = 'c99'; cppToolsConfig.cppStandard = 'c++98'; } @@ -2141,6 +2150,230 @@ class IARSTM8 implements IToolchian { } } +class MTI_GCC implements IToolchian { + readonly version = 1; + + readonly settingName: string = 'EIDE.MIPS.InstallDirectory'; + + readonly categoryName: string = 'GCC'; + + readonly name: ToolchainName = 'MTI_GCC'; + + readonly modelName: string = 'mips.mti.gcc.model.json'; + + readonly configName: string = 'mips.mti.gcc.options.json'; + + readonly verifyFileName: string = 'mips.mti.gcc.verify.json'; + + constructor() { + // nothing todo + } + + private getToolPrefix(): string { + return SettingManager.GetInstance().getMipsToolPrefix(); + } + + //----------- + + newInstance(): IToolchian { + return new MTI_GCC(); + } + + private __lastActivedTargetInfo: ToolchainTargetSupportedInfo | undefined; + getGccCompilerTargetInfo(): ToolchainTargetSupportedInfo | undefined { + + if (this.__lastActivedTargetInfo) + return this.__lastActivedTargetInfo; + + const compilerPath = this.getGccFamilyCompilerPathForCpptools(); + if (!compilerPath) + return undefined; + + try { + const machine = child_process.execFileSync(compilerPath, ['-dumpmachine']).toString().trim(); + const sysroot = child_process.execFileSync(compilerPath, ['-print-sysroot']).toString().trim(); + const libpath = `${sysroot}/lib`; + + const archs: string[] = fs.readdirSync(libpath) + .filter(n => n.startsWith('micromipsel-r2') || n.startsWith('mips-r2') || n.startsWith('mipsel-r2')) + .map(n => n.toLowerCase()); + + const lines = child_process.execFileSync(compilerPath, ['-Q', '--help=target']) + .toString().trim().split(/\r\n|\n/); + + let abis: string[] = []; + let mods: string[] = []; + + for (let index = 0; index < lines.length; index++) { + const line = lines[index]; + if (/^\s* Known MIPS ABIs/.test(line)) { + abis = lines[index + 1].trim().split(/\s+/); + } else if (/^\s*Known code models/.test(line)) { + mods = lines[index + 1].trim().split(/\s+/); + } + } + + const targetInfo: ToolchainTargetSupportedInfo = { + machine: machine, + archs: archs, + abis: abis, + rv_codeModels: mods + }; + + this.__lastActivedTargetInfo = targetInfo; + + return targetInfo; + + } catch (error) { + GlobalEvent.emit('msg', ExceptionToMessage(error, 'Hidden')); + return undefined; + } + } + + getGccFamilyCompilerPathForCpptools(): string | undefined { + const gcc = File.fromArray([this.getToolchainDir().path, 'bin', this.getToolPrefix() + `gcc${platform.exeSuffix()}`]); + return gcc.path; + } + + getToolchainPrefix(): string { + return this.getToolPrefix(); + } + + updateCppIntellisenceCfg(builderOpts: ICompileOptions, cppToolsConfig: CppConfigItem): void { + + cppToolsConfig.cStandard = 'c11'; + cppToolsConfig.cppStandard = 'c++11'; + + cppToolsConfig.compilerArgs = ['-std=${c_cppStandard}']; + + if (builderOpts.global) { + + if (builderOpts.global['arch']) { + cppToolsConfig.compilerArgs.push(`-march=${builderOpts.global['arch']}`); + } + + if (builderOpts.global['abi']) { + cppToolsConfig.compilerArgs.push(`-mabi=${builderOpts.global['abi']}`); + } + + if (typeof builderOpts.global['$float-abi-type'] == 'string') { + const abiType = builderOpts.global['$float-abi-type']; + if (abiType === 'soft-float') { + cppToolsConfig.compilerArgs.push("-msoft-float"); + } else if (abiType === 'hard-float') { + cppToolsConfig.compilerArgs.push("-mhard-float"); + } + } + + + // pass global args for cpptools + if (typeof builderOpts.global['misc-control'] == 'string') { + const pList = builderOpts.global['misc-control'].trim().split(/\s+/); + pList.forEach((p) => cppToolsConfig.compilerArgs?.push(p)); + } + } + + if (builderOpts["c/cpp-compiler"]) { + + if (builderOpts["c/cpp-compiler"]['language-c']) { + cppToolsConfig.cStandard = builderOpts["c/cpp-compiler"]['language-c']; + } + + if (builderOpts["c/cpp-compiler"]['language-cpp']) { + cppToolsConfig.cppStandard = builderOpts["c/cpp-compiler"]['language-cpp']; + } + + if (typeof builderOpts["c/cpp-compiler"]['C_FLAGS'] == 'string') { + const pList = builderOpts['c/cpp-compiler']['C_FLAGS'].trim().split(/\s+/); + cppToolsConfig.cCompilerArgs = pList; + } + + if (typeof builderOpts["c/cpp-compiler"]['CXX_FLAGS'] == 'string') { + const pList = builderOpts['c/cpp-compiler']['CXX_FLAGS'].trim().split(/\s+/); + cppToolsConfig.cppCompilerArgs = pList; + } + } + } + + preHandleOptions(prjInfo: IProjectInfo, options: ICompileOptions): void { + + // convert output lib commmand + if (options['linker'] && options['linker']['output-format'] === 'lib') { + options['linker']['$use'] = 'linker-lib'; + } + + // if region 'global' is not exist, create it + if (typeof options['global'] !== 'object') { + options['global'] = {}; + } + + // set tool prefix + options['global'].toolPrefix = this.getToolPrefix(); + } + + getToolchainDir(): File { + return SettingManager.GetInstance().getMipsToolFolder(); + } + + getInternalDefines(builderCfg: T, builderOpts: ICompileOptions): string[] { + return []; + } + + getCustomDefines(): string[] | undefined { + return undefined; + } + + getSystemIncludeList(builderOpts: ICompileOptions): string[] { + return []; + } + + getForceIncludeHeaders(): string[] | undefined { + return [ + ResManager.GetInstance().getGccForceIncludeHeaders().path + ]; + } + + getDefaultIncludeList(): string[] { + return []; + } + + getLibDirs(): string[] { + return []; + } + + getDefaultConfig(): ICompileOptions { + return { + version: this.version, + beforeBuildTasks: [], + afterBuildTasks: [], + global: { + "output-debug-info": 'enable', + "arch": "mips32r5", + "abi": "32" + }, + 'c/cpp-compiler': { + "language-c": "c11", + "language-cpp": "c++11", + "optimization": 'level-debug', + "warnings": "all-warnings", + "one-elf-section-per-function": false, + "one-elf-section-per-data": false, + "C_FLAGS": "-EL", + "CXX_FLAGS": "" + }, + 'asm-compiler': { + "ASM_FLAGS": "" + }, + linker: { + "output-format": "elf", + "remove-unused-input-sections": true, + "LD_FLAGS": "-EL", + "LIB_FLAGS": "-lm -lgcc" + } + }; + } +} + class RISCV_GCC implements IToolchian { readonly version = 1; @@ -2160,6 +2393,7 @@ class RISCV_GCC implements IToolchian { constructor() { // nothing todo } + /* private getIncludeList(gccDir: string): string[] | undefined { try { diff --git a/src/WebInterface/WebInterface.ts b/src/WebInterface/WebInterface.ts index 0ae12700..f14c7eec 100644 --- a/src/WebInterface/WebInterface.ts +++ b/src/WebInterface/WebInterface.ts @@ -163,9 +163,9 @@ export interface ShellFlasherIndexItem { locationType: 'workspace' | 'global'; /** - * if 'locationType' == 'workspace', this field means tool install path + * if 'locationType' == 'workspace', Install Dir is '${workspaceFolder}/' * - * if 'locationType' == 'global', this field means tool exe file dir path + * if 'locationType' == 'global', Install Dir is '${userHome}/.eide/tools/' */ location: string; diff --git a/src/extension.ts b/src/extension.ts index caddc241..56add36f 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -932,7 +932,7 @@ async function checkAndInstallRuntime() { if (pkgReady && pkgFile.IsFile()) { try { ChildProcess.execFileSync(pkgFile.path); - const sel = await vscode.window.showInformationMessage(`Ok ! Now you need relaunch VsCode !`, txt_yes); + const sel = await vscode.window.showInformationMessage(`Ok ! Now you need to relaunch VsCode !`, txt_yes); if (sel) { vscode.commands.executeCommand('workbench.action.reloadWindow'); }