Skip to content

Commit

Permalink
Merge pull request #6112 from xmake-io/parsedeps
Browse files Browse the repository at this point in the history
improve to parser deps
  • Loading branch information
waruqi authored Jan 24, 2025
2 parents 1b1ed22 + d81a98c commit 2c88aaf
Show file tree
Hide file tree
Showing 13 changed files with 189 additions and 37 deletions.
46 changes: 21 additions & 25 deletions xmake/modules/core/project/depend.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down
3 changes: 2 additions & 1 deletion xmake/modules/core/tools/armcc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions xmake/modules/core/tools/cl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion xmake/modules/core/tools/cl6x.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion xmake/modules/core/tools/clang_cl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 2 additions & 1 deletion xmake/modules/core/tools/dmd.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion xmake/modules/core/tools/gcc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion xmake/modules/core/tools/nvcc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion xmake/modules/core/tools/rc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion xmake/modules/core/tools/sdcc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion xmake/modules/core/tools/tcc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
144 changes: 144 additions & 0 deletions xmake/modules/private/tools/cl_json/parse_deps.lua
Original file line number Diff line number Diff line change
@@ -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

3 changes: 2 additions & 1 deletion xmake/rules/swig/build_module_file.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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))

Expand Down

0 comments on commit 2c88aaf

Please sign in to comment.