summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2022-08-21 18:57:59 +0800
committerGitHub <[email protected]>2022-08-21 18:57:59 +0800
commit3d3126d92d084b90ba0941675d580bd663d7297c (patch)
tree4f722c328ba5ab695d2417b12fef420d358f04ad
parent1eebadef123f6c110a671fe041fd110899340bb4 (diff)
parent65d76e06cce13ab16e76aeee73b034f4adf89fa7 (diff)
Merge pull request #2704 from xmake-io/rcdeps
improve rc deps parser
-rw-r--r--CHANGELOG.md2
-rw-r--r--xmake/modules/core/tools/rc.lua55
2 files changed, 51 insertions, 6 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6f0143dbd..da3aef858 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,6 +19,7 @@
* [#2410](https://github.com/xmake-io/xmake/issues/2410): Improve cmakelists generator
* [#2690](https://github.com/xmake-io/xmake/issues/2690): Improve to pass toolchains to packages
* [#2686](https://github.com/xmake-io/xmake/issues/2686): Support for incremental compilation and parse header file deps for keil/armcc/armclang
+* [#2562](https://github.com/xmake-io/xmake/issues/2562): Improve include deps for rc.exe
### Bugs fixed
@@ -1379,6 +1380,7 @@
* [#2410](https://github.com/xmake-io/xmake/issues/2410): 改进 cmakelists 生成
* [#2690](https://github.com/xmake-io/xmake/issues/2690): 改机传递 toolchains 到包
* [#2686](https://github.com/xmake-io/xmake/issues/2686): 改进 armcc/armclang 支持增量编译
+* [#2562](https://github.com/xmake-io/xmake/issues/2562): 改进 rx.exe 对引用文件依赖的解析和增量编译支持
### Bugs 修复
diff --git a/xmake/modules/core/tools/rc.lua b/xmake/modules/core/tools/rc.lua
index 6796c0fe0..65612bd38 100644
--- a/xmake/modules/core/tools/rc.lua
+++ b/xmake/modules/core/tools/rc.lua
@@ -20,9 +20,36 @@
-- imports
import("core.base.option")
+import("core.base.hashset")
import("core.project.project")
import("private.tools.vstool")
+-- normailize path of a dependecy
+function _normailize_dep(dep, projectdir)
+ if path.is_absolute(dep) then
+ dep = path.translate(dep)
+ else
+ dep = path.absolute(dep, projectdir)
+ end
+ if dep:startswith(projectdir) then
+ return path.relative(dep, projectdir)
+ else
+ return deps
+ end
+end
+
+-- parse include file
+function _parse_includefile(line)
+ if line:startswith("#line") then
+ return line:match("#line %d+ \"(.+)\"")
+ elseif line:find("ICON", 1, true) and line:find(".ico", 1, true) then
+ -- 101 ICON "xxx.ico"
+ return line:match("ICON%s+\"(.+.ico)\"")
+ elseif line:find("BITMAP", 1, true) and line:find(".bmp", 1, true) then
+ return line:match("BITMAP%s+\"(.+.bmp)\"")
+ end
+end
+
-- init it
function init(self)
if self:has_flags("-nologo", "mrcflags") then
@@ -95,17 +122,33 @@ function compile(self, sourcefile, objectfile, dependinfo, flags)
}
}
- -- parse includes
- local sourcedata = io.readfile(sourcefile)
- if sourcedata then
+ -- try to use cl.exe to parse includes
+ -- @see https://github.com/xmake-io/xmake/issues/2562
+ local outfile = os.tmpfile() .. ".rc.out"
+ local errfile = os.tmpfile() .. ".rc.err"
+ local cl = assert(self:toolchain():tool("cxx"), "cl.exe not found!")
+ local ok = try {function () os.execv(cl, {"-E", sourcefile}, {stdout = outfile, stderr = errfile, envs = self:runenvs()}); return true end}
+ if ok and os.isfile(outfile) then
local depfiles_rc
- local sourcedir = path.directory(sourcefile)
- for headerfile in sourcedata:gmatch("#include%s+[\"<](.-)[\">]") do
- depfiles_rc = (depfiles_rc or "") .. "\n" .. path.join(sourcedir, headerfile)
+ local includeset = hashset.new()
+ local file = io.open(outfile)
+ local projectdir = os.projectdir()
+ for line in file:lines() do
+ local includefile = _parse_includefile(line)
+ if includefile then
+ includefile = _normailize_dep(includefile, projectdir)
+ if includefile and not includeset:has(includefile) and path.absolute(includefile) ~= path.absolute(sourcefile) then
+ depfiles_rc = (depfiles_rc or "") .. "\n" .. includefile
+ includeset:insert(includefile)
+ end
+ end
end
+ file:close()
if dependinfo then
dependinfo.depfiles_rc = depfiles_rc
end
end
+ os.tryrm(outfile)
+ os.tryrm(errfile)
end