diff options
| author | ruki <[email protected]> | 2022-05-10 15:08:59 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-05-10 15:08:59 +0800 |
| commit | 4ceb56296bccbefeab9568b4391cf8f01b114ff7 (patch) | |
| tree | 72977d2ee347ff4a73b39333cd72db73e853f046 | |
| parent | 8cbd906643c7034ff53f44660ef84ee0f3f449ff (diff) | |
| parent | 1f87afd7f19f754ae2206d0cfabdc739f81ff412 (diff) | |
Merge pull request #2349 from DawnMagnet/dev
add keil-c51 toolchain & rules & review
| -rw-r--r-- | tests/projects/embed/c51/hello/src/main.c | 50 | ||||
| -rw-r--r-- | tests/projects/embed/c51/hello/xmake.lua | 4 | ||||
| -rw-r--r-- | xmake/modules/core/tools/bl51.lua | 39 | ||||
| -rw-r--r-- | xmake/modules/core/tools/c51.lua | 93 | ||||
| -rw-r--r-- | xmake/modules/detect/sdks/find_c51.lua | 124 | ||||
| -rw-r--r-- | xmake/modules/detect/tools/find_bl51.lua | 76 | ||||
| -rw-r--r-- | xmake/modules/detect/tools/find_c51.lua | 69 | ||||
| -rw-r--r-- | xmake/modules/detect/tools/find_oh51.lua | 80 | ||||
| -rw-r--r-- | xmake/rules/c51/xmake.lua | 23 | ||||
| -rw-r--r-- | xmake/toolchains/c51/xmake.lua | 42 |
10 files changed, 600 insertions, 0 deletions
diff --git a/tests/projects/embed/c51/hello/src/main.c b/tests/projects/embed/c51/hello/src/main.c new file mode 100644 index 000000000..bdab759d9 --- /dev/null +++ b/tests/projects/embed/c51/hello/src/main.c @@ -0,0 +1,50 @@ +#include <reg52.h> + +#define REP(i, j) for(i = 0; i < j; ++i) +sbit control = P3 ^ 2; + +void delay_ms(unsigned int n) { + unsigned int i, j; + for (j = n; j > 0; j--) + for (i = 112; i > 0; i--); +} + + +int i; + +void set(unsigned int x) { + P1 = x; + delay_ms(100); +} + +void left_fill() { + REP(i, 8) set(0xFF >> i); +} + +void right_fill() { + REP(i, 8) set((0xFF >> (7 - i)) ^ 0xFF); +} + +void left_erase() { + REP(i, 8) set((0xFF >> (7 - i))); +} + +void right_erase() { + REP(i, 8) set((0xFF >> i) ^ 0xFF); +} + +int main() { + P1 = 0xFF; + P3 = 0xFF; + while (1) { + if (control == 0) { + left_fill(); + left_erase(); + right_fill(); + right_erase(); + } else { + set(0x55); + set(0xAA); + } + } +}
\ No newline at end of file diff --git a/tests/projects/embed/c51/hello/xmake.lua b/tests/projects/embed/c51/hello/xmake.lua new file mode 100644 index 000000000..be1e170df --- /dev/null +++ b/tests/projects/embed/c51/hello/xmake.lua @@ -0,0 +1,4 @@ +target("hello") + add_rules("c51.binary") + set_toolchains("c51") + add_files("src/main.c")
\ No newline at end of file diff --git a/xmake/modules/core/tools/bl51.lua b/xmake/modules/core/tools/bl51.lua new file mode 100644 index 000000000..70c04385b --- /dev/null +++ b/xmake/modules/core/tools/bl51.lua @@ -0,0 +1,39 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015-present, TBOOX Open Source Group. +-- +-- @author DawnMagnet +-- @file bl51.lua +-- + +-- imports +import("core.base.option") +import("core.base.global") +import("utils.progress") + +function init(self) +end + +-- make the link arguments list +function linkargv(self, objectfiles, targetkind, targetfile, flags) + return self:program(), table.join(objectfiles, "TO", targetfile) +end + +-- link the target file +function link(self, objectfiles, targetkind, targetfile, flags) + os.mkdir(path.directory(targetfile)) + os.runv(linkargv(self, objectfiles, targetkind, targetfile, flags)) +end + diff --git a/xmake/modules/core/tools/c51.lua b/xmake/modules/core/tools/c51.lua new file mode 100644 index 000000000..1c87bbb28 --- /dev/null +++ b/xmake/modules/core/tools/c51.lua @@ -0,0 +1,93 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015-present, TBOOX Open Source Group. +-- +-- @author DawnMagnet +-- @file c51.lua +-- + +-- imports +import("core.base.option") +import("core.base.global") +import("core.language.language") +import("utils.progress") + +-- init it +function init(self) +end + +-- make the compile arguments list +function compargv(self, sourcefile, objectfile, flags) + return self:program(), table.join(sourcefile, flags) +end + +-- compile the source file +function compile(self, sourcefile, objectfile, dependinfo, flags) + + -- ensure the object directory + os.mkdir(path.directory(objectfile)) + + -- compile it + try + { + function () + local realsourcefile = objectfile:gsub("\\.obj$", "") + os.cp(sourcefile, realsourcefile) + local outdata, errdata = os.iorunv(compargv(self, realsourcefile, objectfile, dependinfo, flags)) + return (outdata or "") .. (errdata or "") + end, + catch + { + function (errors) + + -- try removing the old object file for forcing to rebuild this source file + os.tryrm(objectfile) + + -- find the start line of error + local lines = tostring(errors):split("\n") + local start = 0 + for index, line in ipairs(lines) do + if line:find("error:", 1, true) or line:find("错误:", 1, true) then + start = index + break + end + end + + -- get 16 lines of errors + if start > 0 or not option.get("verbose") then + if start == 0 then start = 1 end + errors = table.concat(table.slice(lines, start, start + ((#lines - start > 16) and 16 or (#lines - start))), "\n") + end + + -- raise compiling errors + raise(errors) + end + }, + finally + { + function (ok, warnings) + + -- print some warnings + if warnings and #warnings > 0 and (option.get("verbose") or option.get("warning") or global.get("build_warning")) then + if progress.showing_without_scroll() then + print("") + end + cprint("${color.warning}%s", table.concat(table.slice(warnings:split('\n'), 1, 8), '\n')) + end + end + } + } +end + diff --git a/xmake/modules/detect/sdks/find_c51.lua b/xmake/modules/detect/sdks/find_c51.lua new file mode 100644 index 000000000..3de478507 --- /dev/null +++ b/xmake/modules/detect/sdks/find_c51.lua @@ -0,0 +1,124 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015-present, TBOOX Open Source Group. +-- Based On template file xmake\modules\detect\sdks\find_mdk.lua +-- +-- @author DawnMagnet +-- @file find_c51.lua +-- + +-- imports +import("lib.detect.find_path") +import("core.base.option") +import("core.base.semver") +import("core.project.config") +import("core.cache.detectcache") + +-- find C51 directory +function _find_sdkdir(sdkdir) + local paths = { + "$(reg HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Keil\\Products\\C51;Path)" + } + if sdkdir then + table.insert(paths, 1, sdkdir) + end + local result = find_path("C51", paths) + if not result then + -- find it from some logical drives paths + paths = {} + for _, logical_drive in ipairs(winos.logical_drives()) do + table.insert(paths, path.join(logical_drive, "Keil_v5", "C51", "BIN")) + end + result = find_path("C51.exe", paths) + end + return result +end + +-- find C51 toolchains +function _find_c51(sdkdir) + -- find C51 directory + sdkdir = _find_sdkdir(sdkdir) + if not sdkdir or not os.isdir(sdkdir) then + return nil + end + local result = {sdkdir = sdkdir} + + -- get sdk version + local sdkver = winos.registry_query("HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Keil\\Products\\C51;Version") + if sdkver then + sdkver = semver.match(sdkver, 1, "V%d+%.%d+") + if sdkver then + result.sdkver = sdkver:rawstr() + end + end + + -- c51(exe) sdk directory + local sdkdir_c51 = path.join(sdkdir, "c51") + if os.isdir(sdkdir_c51) and os.isfile(path.join(sdkdir_c51, "bin", "c51.exe")) then + result.sdkdir_c51 = sdkdir_c51 + end + + -- a51 sdk directory + local sdkdir_a51 = path.join(sdkdir, "a51") + if os.isdir(sdkdir_a51) and os.isfile(path.join(sdkdir_a51, "bin", "a51.exe")) then + result.sdkdir_a51 = sdkdir_a51 + end + return result +end + +-- find c51 toolchains +-- +-- @param sdkdir the C51 directory +-- @param opt the argument options, e.g. {verbose = true, force = false} +-- +-- @return the C51 toolchains. e.g. {sdkver = ..., sdkdir, sdkdir_armcc, sdkdir_armclang, sdkdir_c51} +-- +-- @code +-- +-- local toolchains = find_c51("~/c51") +-- +-- @endcode +-- +function main(sdkdir, opt) + + -- init arguments + opt = opt or {} + + -- attempt to load cache first + local key = "detect.sdks.find_c51" + + local cacheinfo = detectcache:get(key) or {} + if not opt.force and cacheinfo.c51 and cacheinfo.c51.sdkdir and os.isdir(cacheinfo.c51.sdkdir) then + return cacheinfo.c51 + end + + -- find c51 + local c51 = _find_c51(sdkdir or config.get("sdk")) + if c51 then + if opt.verbose or option.get("verbose") then + cprint("checking for c51 directory ... ${color.success}%s", c51.sdkdir) + end + else + if opt.verbose or option.get("verbose") then + cprint("checking for c51 directory ... ${color.nothing}${text.nothing}") + end + end + + -- save to cache + cacheinfo.c51 = c51 or false + detectcache:set(key, cacheinfo) + detectcache:save() + return c51 +end
\ No newline at end of file diff --git a/xmake/modules/detect/tools/find_bl51.lua b/xmake/modules/detect/tools/find_bl51.lua new file mode 100644 index 000000000..563db1271 --- /dev/null +++ b/xmake/modules/detect/tools/find_bl51.lua @@ -0,0 +1,76 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015-present, TBOOX Open Source Group. +-- +-- @author DawnMagnet +-- @file find_bl51.lua + +-- imports +import("lib.detect.find_program") +import("lib.detect.find_programver") +import("detect.sdks.find_c51") +import("lib.detect.find_tool") + +function _check(program) + local c51 = assert(find_tool("c51"), "c51 not found") + + -- make temp source file + local tmpdir = os.tmpfile() .. ".dir" + local cfile = path.join(tmpdir, "test.c") + local objfile = path.join(tmpdir, "test.obj") + local binfile = path.join(tmpdir, "test") + + -- write test code + io.writefile(cfile, "void main() {}") + + -- archive it + os.runv(c51.program, {"test.c"}, {curdir = tmpdir}) + os.runv(program, {objfile, "TO", binfile}) + + -- remove files + os.rmdir(tmpdir) +end +-- find bl51 +-- +-- @param opt the argument options, e.g. {version = true} +-- +-- @return program, version +-- +-- @code +-- +-- local bl51 = find_bl51() +-- local bl51, version = find_bl51() +-- +-- @endcode +-- +function main(opt) + + -- init options + opt = opt or {} + opt.check = opt.check or _check + local program = find_program(opt.program or "bl51.exe", opt) + if not program then + local c51 = find_c51() + if c51 then + if c51.sdkdir_c51 then + program = find_program(path.join(c51.sdkdir_c51, "bin", "bl51.exe"), opt) + end + if not program and c51.sdkdir_a51 then + program = find_program(path.join(c51.sdkdir_a51, "bin", "bl51.exe"), opt) + end + end + end + return program, nil +end
\ No newline at end of file diff --git a/xmake/modules/detect/tools/find_c51.lua b/xmake/modules/detect/tools/find_c51.lua new file mode 100644 index 000000000..743784f1a --- /dev/null +++ b/xmake/modules/detect/tools/find_c51.lua @@ -0,0 +1,69 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015-present, TBOOX Open Source Group. +-- +-- @author DawnMagnet +-- @file find_c51.lua +-- + +-- imports +import("lib.detect.find_program") +import("lib.detect.find_programver") +import("detect.sdks.find_c51") + +function _check(program) + -- make temp source file + local tmpdir = os.tmpfile() .. ".dir" + local cfile = path.join(tmpdir, "test.c") + + -- write test code + io.writefile(cfile, "void main() {}") + -- archive it + os.runv(program, {"test.c"}, {curdir = tmpdir}) + -- remove files + os.rmdir(tmpdir) +end +-- find c51 +-- +-- @param opt the argument options, e.g. {version = true} +-- +-- @return program, version +-- +-- @code +-- +-- local c51 = find_c51() +-- local c51, version = find_c51() +-- +-- @endcode +-- +function main(opt) + + -- init options + opt = opt or {} + opt.check = opt.check or _check + local program = find_program(opt.program or "c51", opt) + if not program then + local c51 = find_c51() + if c51 then + if c51.sdkdir_c51 then + program = find_program(path.join(c51.sdkdir_c51, "bin", "c51"), opt) + end + if not program and c51.sdkdir_a51 then + program = find_program(path.join(c51.sdkdir_a51, "bin", "c51"), opt) + end + end + end + return program, nil +end
\ No newline at end of file diff --git a/xmake/modules/detect/tools/find_oh51.lua b/xmake/modules/detect/tools/find_oh51.lua new file mode 100644 index 000000000..f81002a3e --- /dev/null +++ b/xmake/modules/detect/tools/find_oh51.lua @@ -0,0 +1,80 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015-present, TBOOX Open Source Group. +-- +-- @author DawnMagnet +-- @file find_oh51.lua +-- OBJECT TO HEX FILE CONVERTER OH51 + +-- imports +import("lib.detect.find_program") +import("lib.detect.find_programver") +import("detect.sdks.find_c51") +import("lib.detect.find_tool") + +function _check(program) + local c51 = assert(find_tool("c51"), "c51 not found") + local bl51 = assert(find_tool("bl51"), "bl51 not found") + + -- make temp source file + local tmpdir = os.tmpfile() .. ".dir" + os.mkdir(tmpdir) + local cfile = path.join(tmpdir, "test.c") + local objfile = path.join(tmpdir, "test.obj") + local binfile = path.join(tmpdir, "test") + + -- write test code + io.writefile(cfile, "void main() {}") + + -- archive it + os.runv(c51.program, {"test.c"}, {curdir = tmpdir}) + os.runv(bl51.program, {objfile, "TO", binfile}) + os.runv(program, {binfile}) + + -- remove files + os.rmdir(tmpdir) +end +-- find oh51 +-- +-- @param opt the argument options, e.g. {version = true} +-- +-- @return program, version +-- +-- @code +-- +-- local oh51 = find_oh51() +-- local oh51, version = find_oh51() +-- +-- @endcode +-- +function main(opt) + + -- init options + opt = opt or {} + opt.check = opt.check or _check + local program = find_program(opt.program or "oh51.exe", opt) + if not program then + local c51 = find_c51() + if c51 then + if c51.sdkdir_c51 then + program = find_program(path.join(c51.sdkdir_c51, "bin", "oh51.exe"), opt) + end + if not program and c51.sdkdir_a51 then + program = find_program(path.join(c51.sdkdir_a51, "bin", "oh51.exe"), opt) + end + end + end + return program, nil +end
\ No newline at end of file diff --git a/xmake/rules/c51/xmake.lua b/xmake/rules/c51/xmake.lua new file mode 100644 index 000000000..6e4654082 --- /dev/null +++ b/xmake/rules/c51/xmake.lua @@ -0,0 +1,23 @@ +rule("c51.binary") + on_load(function (target) + -- we disable checking flags for cross toolchain automatically + target:set("policy", "check.auto_ignore_flags", false) + target:set("policy", "check.auto_map_flags", false) + + -- set default output binary + target:set("kind", "binary") + if not target:get("extension") then + target:set("extension", "") + end + end) + + after_link(function(target, opt) + import("core.project.depend") + import("lib.detect.find_tool") + import("utils.progress") + depend.on_changed(function() + local oh = assert(find_tool("oh51"), "oh51 not found") + os.iorunv(oh.program, {target:targetfile()}) + progress.show(opt.progress, "${color.build.target}generating.$(mode) %s", target:targetfile() .. ".hex") + end, {files = {target:targetfile()}}) + end)
\ No newline at end of file diff --git a/xmake/toolchains/c51/xmake.lua b/xmake/toolchains/c51/xmake.lua new file mode 100644 index 000000000..d0af24907 --- /dev/null +++ b/xmake/toolchains/c51/xmake.lua @@ -0,0 +1,42 @@ +--!A cross-platform build utility based on Lua +-- +-- Licensed under the Apache License, Version 2.0 (the "License"); +-- you may not use this file except in compliance with the License. +-- You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. +-- +-- Copyright (C) 2015-present, TBOOX Open Source Group. +-- +-- @author DawnMagnet +-- @file xmake.lua +-- + +toolchain("c51") + + set_homepage("https://www.keil.com/c51/") + set_description("Keil development tools for the 8051 Microcontroller Architecture") + + set_kind("cross") + set_kind("standalone") + + set_toolset("cc", "c51") + set_toolset("cxx", "c51") + set_toolset("ld", "bl51") + + on_check(function (toolchain) + import("lib.detect.find_tool") + import("detect.sdks.find_c51") + local c51 = find_c51() + if c51 and c51.sdkdir and find_tool("c51") then + toolchain:config_set("sdkdir", c51.sdkdir) + toolchain:configs_save() + return true + end + end)
\ No newline at end of file |
