Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for IAR ARM embedded toolchain #6116

Merged
merged 16 commits into from
Jan 26, 2025
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
* [#6054](https://github.com/xmake-io/xmake/issues/6054): Add xmake bundle for linux
* [#6071](https://github.com/xmake-io/xmake/issues/6071): Improve to download package for git url, support for sparse-checkout
* [#5163](https://github.com/xmake-io/xmake/issues/5163): Support TI-CGT C2000/C6000 compiler
* [#5344](https://github.com/xmake-io/xmake/issues/5344): Support IAR ARM C/C++ compiler
* [#5554](https://github.com/xmake-io/xmake/issues/5554): Add custom unknown toolchains support

### Changes
Expand Down Expand Up @@ -1952,6 +1953,7 @@
* [#6054](https://github.com/xmake-io/xmake/issues/6054): 为 linux 添加 xmake bundle 包
* [#6071](https://github.com/xmake-io/xmake/issues/6071): 改进 git 包下载,支持仅仅 clone 指定子目录
* [#5163](https://github.com/xmake-io/xmake/issues/5163): 支持 TI-CGT C2000/C6000 编译器
* [#5344](https://github.com/xmake-io/xmake/issues/5344): 支持 IAR ARM C/C++ 编译器
* [#5554](https://github.com/xmake-io/xmake/issues/5554): 添加自定义未知工具链支持

### 改进
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ cosmocc build-once run-anywhere
hdk Harmony SDK
ti-c2000 TI-CGT C2000 compiler
ti-c6000 TI-CGT C6000 compiler
iararm IAR ARM C/C++ Compiler
```

## Supported languages
Expand Down
1 change: 1 addition & 0 deletions README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ cosmocc build-once run-anywhere
hdk Harmony SDK
ti-c2000 TI-CGT C2000 compiler
ti-c6000 TI-CGT C6000 compiler
iararm IAR ARM C/C++ Compiler
```

## 支持语言
Expand Down
25 changes: 25 additions & 0 deletions xmake/modules/core/tools/iarchive.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
--!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 ruki
-- @file iarchive.lua
--

inherit("ar")

function init(self)
self:set("arflags", "--create")
end
155 changes: 155 additions & 0 deletions xmake/modules/core/tools/iccarm.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
--!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 ruki
-- @file iccarm.lua
--

-- imports
import("core.base.option")
import("core.base.global")
import("core.project.policy")
import("core.language.language")
import("utils.progress")

-- init it
function init(self)
end

-- make the symbol flag
function nf_symbol(self, level)
-- only for source kind
local kind = self:kind()
if language.sourcekinds()[kind] then
local maps = _g.symbol_maps
if not maps then
maps =
{
debug = "--debug"
}
_g.symbol_maps = maps
end
return maps[level .. '_' .. kind] or maps[level]
end
end

-- make the optimize flag
function nf_optimize(self, level)
local maps =
{
none = "-On"
, fast = "-Ol"
, faster = "-Om"
, fastest = "-Oh"
, smallest = "-Ohz"
, aggressive = "-Ohs"
}
return maps[level]
end

-- make the vector extension flag
function nf_vectorext(self, extension)
local maps = {
all = "--vectorize"
}
return maps[extension]
end

-- make the language flag
function nf_language(self, stdname)
if _g.cmaps == nil then
_g.cmaps = {
c89 = "--c89"
}
end
return _g.cmaps[stdname]
end

-- make the define flag
function nf_define(self, macro)
return "-D" .. macro
end

-- make the undefine flag
function nf_undefine(self, macro)
return "-U" .. macro
end

-- make the includedir flag
function nf_includedir(self, dir)
return {"-I" .. dir}
end

-- make the compile arguments list
function compargv(self, sourcefile, objectfile, flags)
return self:program(), table.join("-c", flags, "-o", objectfile, sourcefile)
end

-- compile the source file
function compile(self, sourcefile, objectfile, dependinfo, flags, opt)
os.mkdir(path.directory(objectfile))
try
{
function ()
local compflags = flags
local outdata, errdata = os.iorunv(compargv(self, sourcefile, objectfile, compflags))
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 not warnings:find("Warnings: none", 1, true) and policy.build_warnings(opt) 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



121 changes: 121 additions & 0 deletions xmake/modules/core/tools/iccarm/has_flags.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
--!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 ruki
-- @file has_flags.lua
--

-- imports
import("core.cache.detectcache")
import("core.language.language")

-- is linker?
function _islinker(flags, opt)
local toolkind = opt.toolkind or ""
return toolkind == "ld" or toolkind == "sh" or toolkind:endswith("ld") or toolkind:endswith("sh")
end

-- try running
function _try_running(program, argv, opt)
local errors = nil
return try { function () os.runv(program, argv, opt); return true end, catch { function (errs) errors = (errs or ""):trim() end }}, errors
end

-- attempt to check it from known flags
function _check_from_knownargs(flags, opt, islinker)
local flag = flags[1]
if not islinker then
if flag:startswith("-D") or
flag:startswith("-U") or
flag:startswith("-I") then
return true
end
end
end

-- attempt to check it from the argument list
function _check_from_arglist(flags, opt, islinker)
local key = "core.tools.iccarm." .. (islinker and "has_ldflags" or "has_cflags")
local flagskey = opt.program .. "_" .. (opt.programver or "")
local allflags = detectcache:get2(key, flagskey)
if not allflags then
allflags = {}
local arglist = try {function () return os.iorunv(opt.program, {"--help"}, {envs = opt.envs}) end}
if arglist then
for arg in arglist:gmatch("%s+(%-[%-%a%d]+)%s+") do
allflags[arg] = true
end
end
detectcache:set2(key, flagskey, allflags)
detectcache:save()
end
local flag = flags[1]
return allflags[flag]
end

-- get extension
function _get_extension(opt)
-- @note we need to detect extension for ndk/clang++.exe: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated]
return (opt.program:endswith("++") or opt.flagkind == "cxxflags") and ".cpp" or (table.wrap(language.sourcekinds()[opt.toolkind or "cc"])[1] or ".c")
end

-- try running to check flags
function _check_try_running(flags, opt, islinker)

-- make an stub source file
local snippet = opt.snippet or "int main(int argc, char** argv)\n{return 0;}\n"
local sourcefile = os.tmpfile("iccarm_has_flags:" .. snippet) .. _get_extension(opt)
if not os.isfile(sourcefile) then
io.writefile(sourcefile, snippet)
end

-- check flags for linker
local tmpfile = os.tmpfile()
if islinker then
return _try_running(opt.program, table.join(flags, "-o", tmpfile, sourcefile), opt)
end

-- check flags for compiler
-- @note we cannot use os.nuldev() as the output file, maybe run failed for some flags, e.g. --coverage
return _try_running(opt.program, table.join(flags, "-c", "-o", tmpfile, sourcefile), opt)
end

-- has_flags(flags)?
--
-- @param opt the argument options, e.g. {toolname = "", program = "", programver = "", toolkind = "[cc|cxx|ld|ar|sh|gc|mm|mxx]"}
--
-- @return true or false
--
function main(flags, opt)

-- is linker?
opt = opt or {}
local islinker = _islinker(flags, opt)

-- attempt to check it from the argument list
if not opt.tryrun then
if _check_from_arglist(flags, opt, islinker) then
return true
end
if _check_from_knownargs(flags, opt, islinker) then
return true
end
end

-- try running to check it
return _check_try_running(flags, opt, islinker)
end

Loading
Loading