summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-01-24 14:57:15 +0800
committerGitHub <[email protected]>2025-01-24 14:57:15 +0800
commit2c88aaf2d2e33f50d0fea774319a2f4d372ee055 (patch)
tree9f8cae93644858690c4762ae44208bfc767e515f
parent1b1ed22d618e6c31ede1cf2f1168476b504f5deb (diff)
parentd81a98cdd167a4a730f4349a84c13609011bc601 (diff)
Merge pull request #6112 from xmake-io/parsedeps
improve to parser deps
-rw-r--r--xmake/modules/core/project/depend.lua46
-rw-r--r--xmake/modules/core/tools/armcc.lua3
-rw-r--r--xmake/modules/core/tools/cl.lua6
-rw-r--r--xmake/modules/core/tools/cl6x.lua3
-rw-r--r--xmake/modules/core/tools/clang_cl.lua3
-rw-r--r--xmake/modules/core/tools/dmd.lua3
-rw-r--r--xmake/modules/core/tools/gcc.lua3
-rw-r--r--xmake/modules/core/tools/nvcc.lua3
-rw-r--r--xmake/modules/core/tools/rc.lua3
-rw-r--r--xmake/modules/core/tools/sdcc.lua3
-rw-r--r--xmake/modules/core/tools/tcc.lua3
-rw-r--r--xmake/modules/private/tools/cl_json/parse_deps.lua144
-rw-r--r--xmake/rules/swig/build_module_file.lua3
13 files changed, 189 insertions, 37 deletions
diff --git a/xmake/modules/core/project/depend.lua b/xmake/modules/core/project/depend.lua
index aea652779..4f81481bb 100644
--- a/xmake/modules/core/project/depend.lua
+++ b/xmake/modules/core/project/depend.lua
@@ -21,12 +21,6 @@
-- imports
import("core.base.option")
import("core.project.project")
-import("private.tools.cl.parse_deps", {alias = "parse_deps_cl"})
-import("private.tools.cl.parse_deps_json", {alias = "parse_deps_cl_json"})
-import("private.tools.rc.parse_deps", {alias = "parse_deps_rc"})
-import("private.tools.gcc.parse_deps", {alias = "parse_deps_gcc"})
-import("private.tools.armcc.parse_deps", {alias = "parse_deps_armcc"})
-import("private.tools.cl6x.parse_deps", {alias = "parse_deps_cl6x"})
-- load depfiles
function _load_depfiles(parser, dependinfo, depfiles, opt)
@@ -40,32 +34,34 @@ function _load_depfiles(parser, dependinfo, depfiles, opt)
end
end
+-- get depfiles parser
+function _get_depfiles_parser(depfiles_format)
+ assert(depfiles_format, "no depfiles format")
+ local depfiles_parsers = _g._depfiles_parsers
+ if depfiles_parsers == nil then
+ depfiles_parsers = {}
+ _g._depfiles_parsers = depfiles_parsers
+ end
+ local parser = depfiles_parsers[depfiles_format]
+ if parser == nil then
+ parser = import("private.tools." .. depfiles_format .. ".parse_deps", {anonymous = true})
+ depfiles_parsers[depfiles_format] = parser or false
+ end
+ return parser or nil
+end
+
-- load dependent info from the given file (.d)
function load(dependfile, opt)
-
if os.isfile(dependfile) then
-- may be the depend file has been incomplete when if the compilation process is abnormally interrupted
local dependinfo = try { function() return io.load(dependfile) end }
if dependinfo then
-- attempt to load depfiles from the compilers
- if dependinfo.depfiles_gcc then
- _load_depfiles(parse_deps_gcc, dependinfo, dependinfo.depfiles_gcc, opt)
- dependinfo.depfiles_gcc = nil
- elseif dependinfo.depfiles_cl_json then
- _load_depfiles(parse_deps_cl_json, dependinfo, dependinfo.depfiles_cl_json, opt)
- dependinfo.depfiles_cl_json = nil
- elseif dependinfo.depfiles_cl then
- _load_depfiles(parse_deps_cl, dependinfo, dependinfo.depfiles_cl, opt)
- dependinfo.depfiles_cl = nil
- elseif dependinfo.depfiles_rc then
- _load_depfiles(parse_deps_rc, dependinfo, dependinfo.depfiles_rc, opt)
- dependinfo.depfiles_rc = nil
- elseif dependinfo.depfiles_armcc then
- _load_depfiles(parse_deps_armcc, dependinfo, dependinfo.depfiles_armcc, opt)
- dependinfo.depfiles_armcc = nil
- elseif dependinfo.depfiles_cl6x then
- _load_depfiles(parse_deps_cl6x, dependinfo, dependinfo.depfiles_cl6x, opt)
- dependinfo.depfiles_cl6x = nil
+ local depfiles = dependinfo.depfiles
+ if depfiles then
+ local depfiles_parser = _get_depfiles_parser(dependinfo.depfiles_format)
+ _load_depfiles(depfiles_parser, dependinfo, depfiles, opt)
+ dependinfo.depfiles = nil
end
return dependinfo
end
diff --git a/xmake/modules/core/tools/armcc.lua b/xmake/modules/core/tools/armcc.lua
index 85aeda98c..3642feceb 100644
--- a/xmake/modules/core/tools/armcc.lua
+++ b/xmake/modules/core/tools/armcc.lua
@@ -186,7 +186,8 @@ function compile(self, sourcefile, objectfile, dependinfo, flags, opt)
-- generate the dependent includes
if depfile and os.isfile(depfile) then
if dependinfo then
- dependinfo.depfiles_armcc = io.readfile(depfile, {continuation = "\\"})
+ dependinfo.depfiles_format = "armcc"
+ dependinfo.depfiles = io.readfile(depfile, {continuation = "\\"})
end
-- remove the temporary dependent file
diff --git a/xmake/modules/core/tools/cl.lua b/xmake/modules/core/tools/cl.lua
index dab766482..8a2971328 100644
--- a/xmake/modules/core/tools/cl.lua
+++ b/xmake/modules/core/tools/cl.lua
@@ -778,10 +778,12 @@ function compile(self, sourcefile, objectfile, dependinfo, flags, opt)
-- generate the dependent includes
if dependinfo then
if depfile and os.isfile(depfile) then
- dependinfo.depfiles_cl_json = io.readfile(depfile)
+ dependinfo.depfiles_format = "cl_json"
+ dependinfo.depfiles = io.readfile(depfile)
os.tryrm(depfile)
elseif outdata then
- dependinfo.depfiles_cl = outdata
+ dependinfo.depfiles_format = "cl"
+ dependinfo.depfiles = outdata
end
end
end
diff --git a/xmake/modules/core/tools/cl6x.lua b/xmake/modules/core/tools/cl6x.lua
index 334df4798..f350808da 100644
--- a/xmake/modules/core/tools/cl6x.lua
+++ b/xmake/modules/core/tools/cl6x.lua
@@ -192,7 +192,8 @@ function compile(self, sourcefile, objectfile, dependinfo, flags, opt)
-- generate the dependent includes
if depfile and os.isfile(depfile) then
if dependinfo then
- dependinfo.depfiles_cl6x = io.readfile(depfile, {continuation = "\\"})
+ dependinfo.depfiles_format = "cl6x"
+ dependinfo.depfiles = io.readfile(depfile, {continuation = "\\"})
end
-- remove the temporary dependent file
diff --git a/xmake/modules/core/tools/clang_cl.lua b/xmake/modules/core/tools/clang_cl.lua
index 694a05fcd..175bcff2a 100644
--- a/xmake/modules/core/tools/clang_cl.lua
+++ b/xmake/modules/core/tools/clang_cl.lua
@@ -216,6 +216,7 @@ function compile(self, sourcefile, objectfile, dependinfo, flags, opt)
-- generate the dependent includes
if dependinfo and outdata then
- dependinfo.depfiles_cl = outdata
+ dependinfo.depfiles_format = "cl"
+ dependinfo.depfiles = outdata
end
end
diff --git a/xmake/modules/core/tools/dmd.lua b/xmake/modules/core/tools/dmd.lua
index 4a14acfac..47378c570 100644
--- a/xmake/modules/core/tools/dmd.lua
+++ b/xmake/modules/core/tools/dmd.lua
@@ -267,7 +267,8 @@ function compile(self, sourcefile, objectfile, dependinfo, flags, opt)
if depfile and os.isfile(depfile) then
if dependinfo then
-- it use makefile/gcc compatiable format
- dependinfo.depfiles_gcc = io.readfile(depfile, {continuation = "\\"})
+ dependinfo.depfiles_format = "gcc"
+ dependinfo.depfiles = io.readfile(depfile, {continuation = "\\"})
end
-- remove the temporary dependent file
diff --git a/xmake/modules/core/tools/gcc.lua b/xmake/modules/core/tools/gcc.lua
index 10ac810f3..4ca8a717c 100644
--- a/xmake/modules/core/tools/gcc.lua
+++ b/xmake/modules/core/tools/gcc.lua
@@ -987,7 +987,8 @@ function compile(self, sourcefile, objectfile, dependinfo, flags, opt)
-- generate the dependent includes
if depfile and os.isfile(depfile) then
if dependinfo then
- dependinfo.depfiles_gcc = io.readfile(depfile, {continuation = "\\"})
+ dependinfo.depfiles_format = "gcc"
+ dependinfo.depfiles = io.readfile(depfile, {continuation = "\\"})
end
-- remove the temporary dependent file
diff --git a/xmake/modules/core/tools/nvcc.lua b/xmake/modules/core/tools/nvcc.lua
index fdb305631..ea8c8704a 100644
--- a/xmake/modules/core/tools/nvcc.lua
+++ b/xmake/modules/core/tools/nvcc.lua
@@ -436,7 +436,8 @@ function compile(self, sourcefile, objectfile, dependinfo, flags, opt)
if depfile and os.isfile(depfile) then
if dependinfo then
-- nvcc uses gcc-style depfiles
- dependinfo.depfiles_gcc = io.readfile(depfile, {continuation = "\\"})
+ dependinfo.depfiles_format = "gcc"
+ dependinfo.depfiles = io.readfile(depfile, {continuation = "\\"})
end
-- remove the temporary dependent file
diff --git a/xmake/modules/core/tools/rc.lua b/xmake/modules/core/tools/rc.lua
index 930fa4942..91c1984ca 100644
--- a/xmake/modules/core/tools/rc.lua
+++ b/xmake/modules/core/tools/rc.lua
@@ -157,7 +157,8 @@ function compile(self, sourcefile, objectfile, dependinfo, flags, opt)
end
file:close()
if dependinfo then
- dependinfo.depfiles_rc = depfiles_rc
+ dependinfo.depfiles_format = "rc"
+ dependinfo.depfiles = depfiles_rc
end
end
os.tryrm(outfile)
diff --git a/xmake/modules/core/tools/sdcc.lua b/xmake/modules/core/tools/sdcc.lua
index 6cbec5d43..ed2d55737 100644
--- a/xmake/modules/core/tools/sdcc.lua
+++ b/xmake/modules/core/tools/sdcc.lua
@@ -243,7 +243,8 @@ function compile(self, sourcefile, objectfile, dependinfo, flags, opt)
-- generate the dependent includes
if depfile and os.isfile(depfile) then
if dependinfo then
- dependinfo.depfiles_gcc = io.readfile(depfile, {continuation = "\\"})
+ dependinfo.depfiles_format = "gcc"
+ dependinfo.depfiles = io.readfile(depfile, {continuation = "\\"})
end
-- remove the temporary dependent file
diff --git a/xmake/modules/core/tools/tcc.lua b/xmake/modules/core/tools/tcc.lua
index 8251f9f64..cb97d4c05 100644
--- a/xmake/modules/core/tools/tcc.lua
+++ b/xmake/modules/core/tools/tcc.lua
@@ -201,7 +201,8 @@ function compile(self, sourcefile, objectfile, dependinfo, flags, opt)
-- generate the dependent includes
if depfile and os.isfile(depfile) then
if dependinfo then
- dependinfo.depfiles_gcc = io.readfile(depfile, {continuation = "\\"})
+ dependinfo.depfiles_format = "gcc"
+ dependinfo.depfiles = io.readfile(depfile, {continuation = "\\"})
end
-- remove the temporary dependent file
diff --git a/xmake/modules/private/tools/cl_json/parse_deps.lua b/xmake/modules/private/tools/cl_json/parse_deps.lua
new file mode 100644
index 000000000..50f728815
--- /dev/null
+++ b/xmake/modules/private/tools/cl_json/parse_deps.lua
@@ -0,0 +1,144 @@
+--!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 parse_deps_json.lua
+--
+
+-- imports
+import("core.project.project")
+import("core.base.hashset")
+import("core.base.json")
+import("core.tool.toolchain")
+
+-- get $VCInstallDir
+function _VCInstallDir()
+ local VCInstallDir = _g.VCInstallDir
+ if not VCInstallDir then
+ local msvc = toolchain.load("msvc")
+ if msvc then
+ local vcvars = msvc:config("vcvars")
+ if vcvars and vcvars.VCInstallDir then
+ VCInstallDir = vcvars.VCInstallDir:lower() -- @note we need lower case for json/deps
+ _g.VCInstallDir = VCInstallDir
+ end
+ end
+ end
+ return VCInstallDir
+end
+
+-- get $WindowsSdkDir
+function _WindowsSdkDir()
+ local WindowsSdkDir = _g.WindowsSdkDir
+ if not WindowsSdkDir then
+ local msvc = toolchain.load("msvc")
+ if msvc then
+ local vcvars = msvc:config("vcvars")
+ if vcvars and vcvars.WindowsSdkDir then
+ WindowsSdkDir = vcvars.WindowsSdkDir:lower() -- @note we need lower case for json/deps
+ _g.WindowsSdkDir = WindowsSdkDir
+ end
+ end
+ end
+ return WindowsSdkDir
+end
+
+-- 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
+ dep = dep:lower()
+ local VCInstallDir = _VCInstallDir()
+ local WindowsSdkDir = _WindowsSdkDir()
+ if (VCInstallDir and dep:startswith(VCInstallDir)) or (WindowsSdkDir and dep:startswith(WindowsSdkDir)) then
+ -- we ignore headerfiles in vc install directory
+ return
+ end
+ if dep:startswith(projectdir) then
+ return path.relative(dep, projectdir)
+ else
+ -- we also need to check header files outside project
+ -- https://github.com/xmake-io/xmake/issues/1154
+ return dep
+ end
+end
+
+-- parse depsfiles from string
+--
+--[[
+{
+ "Version": "1.2",
+ "Data": {
+ "Source": "c:\users\ruki\desktop\user_headerunit\src\main.cpp",
+ "ProvidedModule": "",
+ "Includes": [],
+ "ImportedModules": [
+ {
+ "Name": "hello",
+ "BMI": "c:\users\ruki\desktop\user_headerunit\src\hello.ifc"
+ }
+ ],
+ "ImportedHeaderUnits": [
+ {
+ "Header": "c:\users\ruki\desktop\user_headerunit\src\header.hpp",
+ "BMI": "c:\users\ruki\desktop\user_headerunit\src\header.hpp.ifc"
+ }
+ ]
+ }
+}]]
+function main(depsdata)
+
+ -- decode json data first
+ depsdata = json.decode(depsdata)
+
+ -- get includes
+ local data
+ if depsdata then
+ data = depsdata.Data
+ end
+ if data then
+ includes = data.Includes
+ for _, item in ipairs(data.ImportedModules) do
+ local bmifile = item.BMI
+ if bmifile then
+ includes = includes or {}
+ table.insert(includes, bmifile)
+ end
+ end
+ for _, item in ipairs(data.ImportedHeaderUnits) do
+ local bmifile = item.BMI
+ if bmifile then
+ includes = includes or {}
+ table.insert(includes, bmifile)
+ end
+ end
+ end
+
+ -- translate it
+ local results = hashset.new()
+ local projectdir = os.projectdir():lower() -- we need to generate lower string, because json values are all lower
+ for _, includefile in ipairs(includes) do
+ includefile = _normailize_dep(includefile, projectdir)
+ if includefile then
+ results:insert(includefile)
+ end
+ end
+ return results:to_array()
+end
+
diff --git a/xmake/rules/swig/build_module_file.lua b/xmake/rules/swig/build_module_file.lua
index 3e6af313f..2cb289302 100644
--- a/xmake/rules/swig/build_module_file.lua
+++ b/xmake/rules/swig/build_module_file.lua
@@ -182,7 +182,8 @@ function swig_build_file(target, sourcefile, opt, par)
local deps = io.readfile(swigdep, {continuation = "\\"})
os.tryrm(swigdep)
dependinfo.files = {sourcefile}
- dependinfo.depfiles_gcc = deps
+ dependinfo.depfiles_format = "gcc"
+ dependinfo.depfiles = deps
dependinfo.values = argv
depend.save(dependinfo, target:dependfile(objectfile))