From d1b1492b07d370f9cf06414490fc489c1dda6ed8 Mon Sep 17 00:00:00 2001 From: ruki Date: Sat, 25 Jan 2025 00:57:44 +0800 Subject: move parse_deps.lua --- .../modules/core/tools/cl6x/parse_deps.lua | 77 +++++++++++ .../modules/private/tools/cl6x/parse_deps.lua | 77 ----------- xmake/modules/core/project/depend.lua | 2 +- xmake/modules/core/tools/armcc/parse_deps.lua | 82 ++++++++++++ xmake/modules/core/tools/cl/parse_deps.lua | 96 ++++++++++++++ xmake/modules/core/tools/cl/parse_deps_json.lua | 144 +++++++++++++++++++++ xmake/modules/core/tools/cl/parse_include.lua | 104 +++++++++++++++ xmake/modules/core/tools/cl2000/parse_deps.lua | 23 ++++ xmake/modules/core/tools/cl6x/parse_deps.lua | 77 +++++++++++ xmake/modules/core/tools/cl_json/parse_deps.lua | 144 +++++++++++++++++++++ xmake/modules/core/tools/gcc/parse_deps.lua | 143 ++++++++++++++++++++ xmake/modules/core/tools/rc/parse_deps.lua | 52 ++++++++ xmake/modules/private/tools/armcc/parse_deps.lua | 82 ------------ xmake/modules/private/tools/cl/parse_deps.lua | 96 -------------- xmake/modules/private/tools/cl/parse_deps_json.lua | 144 --------------------- xmake/modules/private/tools/cl/parse_include.lua | 104 --------------- xmake/modules/private/tools/cl2000/parse_deps.lua | 23 ---- xmake/modules/private/tools/cl6x/parse_deps.lua | 77 ----------- xmake/modules/private/tools/cl_json/parse_deps.lua | 144 --------------------- xmake/modules/private/tools/gcc/parse_deps.lua | 143 -------------------- xmake/modules/private/tools/rc/parse_deps.lua | 52 -------- 21 files changed, 943 insertions(+), 943 deletions(-) create mode 100644 tests/apis/custom_toolchain/toolchains/modules/core/tools/cl6x/parse_deps.lua delete mode 100644 tests/apis/custom_toolchain/toolchains/modules/private/tools/cl6x/parse_deps.lua create mode 100644 xmake/modules/core/tools/armcc/parse_deps.lua create mode 100644 xmake/modules/core/tools/cl/parse_deps.lua create mode 100644 xmake/modules/core/tools/cl/parse_deps_json.lua create mode 100644 xmake/modules/core/tools/cl/parse_include.lua create mode 100644 xmake/modules/core/tools/cl2000/parse_deps.lua create mode 100644 xmake/modules/core/tools/cl6x/parse_deps.lua create mode 100644 xmake/modules/core/tools/cl_json/parse_deps.lua create mode 100644 xmake/modules/core/tools/gcc/parse_deps.lua create mode 100644 xmake/modules/core/tools/rc/parse_deps.lua delete mode 100644 xmake/modules/private/tools/armcc/parse_deps.lua delete mode 100644 xmake/modules/private/tools/cl/parse_deps.lua delete mode 100644 xmake/modules/private/tools/cl/parse_deps_json.lua delete mode 100644 xmake/modules/private/tools/cl/parse_include.lua delete mode 100644 xmake/modules/private/tools/cl2000/parse_deps.lua delete mode 100644 xmake/modules/private/tools/cl6x/parse_deps.lua delete mode 100644 xmake/modules/private/tools/cl_json/parse_deps.lua delete mode 100644 xmake/modules/private/tools/gcc/parse_deps.lua delete mode 100644 xmake/modules/private/tools/rc/parse_deps.lua diff --git a/tests/apis/custom_toolchain/toolchains/modules/core/tools/cl6x/parse_deps.lua b/tests/apis/custom_toolchain/toolchains/modules/core/tools/cl6x/parse_deps.lua new file mode 100644 index 000000000..a5d5ecd40 --- /dev/null +++ b/tests/apis/custom_toolchain/toolchains/modules/core/tools/cl6x/parse_deps.lua @@ -0,0 +1,77 @@ +--!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.lua +-- + +-- imports +import("core.project.config") +import("core.project.project") +import("core.base.hashset") + +-- normailize path of a dependecy +function _normailize_dep(dep, projectdir) + -- escape characters, e.g. \#Qt.Widget_pch.h -> #Qt.Widget_pch.h + -- @see https://github.com/xmake-io/xmake/issues/4134 + -- https://github.com/xmake-io/xmake/issues/4273 + if not is_host("windows") then + dep = dep:gsub("\\(.)", "%1") + end + 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 + -- 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 +-- +-- parse_deps(io.readfile(depfile, {continuation = "\\"})) +-- +-- eg. +-- +-- build/.objs/foo/linux/x86_64/release/src/foo.c.o: src/foo.c +-- build/.objs/foo/linux/x86_64/release/src/foo.c.o: src/foo.h +-- +-- build/.objs/tests/linux/x86_64/release/src/main.c.o: src/main.c +-- build/.objs/tests/linux/x86_64/release/src/main.c.o: src/foo.h +-- build/.objs/tests/linux/x86_64/release/src/main.c.o: src/bar.h +-- build/.objs/tests/linux/x86_64/release/src/main.c.o: src/zoo.h +-- +function main(depsdata, opt) + local results = hashset.new() + local projectdir = os.projectdir() + local line = depsdata:rtrim() -- maybe there will be an empty newline at the end. so we trim it first + local plain = {plain = true} + for _, includefile in ipairs(line:split('\n', plain)) do -- it will trim all internal spaces without `{strict = true}` + includefile = includefile:split(": ", plain)[2] + if includefile and #includefile > 0 then + includefile = _normailize_dep(includefile, projectdir) + if includefile then + results:insert(includefile) + end + end + end + return results:to_array() +end diff --git a/tests/apis/custom_toolchain/toolchains/modules/private/tools/cl6x/parse_deps.lua b/tests/apis/custom_toolchain/toolchains/modules/private/tools/cl6x/parse_deps.lua deleted file mode 100644 index a5d5ecd40..000000000 --- a/tests/apis/custom_toolchain/toolchains/modules/private/tools/cl6x/parse_deps.lua +++ /dev/null @@ -1,77 +0,0 @@ ---!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.lua --- - --- imports -import("core.project.config") -import("core.project.project") -import("core.base.hashset") - --- normailize path of a dependecy -function _normailize_dep(dep, projectdir) - -- escape characters, e.g. \#Qt.Widget_pch.h -> #Qt.Widget_pch.h - -- @see https://github.com/xmake-io/xmake/issues/4134 - -- https://github.com/xmake-io/xmake/issues/4273 - if not is_host("windows") then - dep = dep:gsub("\\(.)", "%1") - end - 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 - -- 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 --- --- parse_deps(io.readfile(depfile, {continuation = "\\"})) --- --- eg. --- --- build/.objs/foo/linux/x86_64/release/src/foo.c.o: src/foo.c --- build/.objs/foo/linux/x86_64/release/src/foo.c.o: src/foo.h --- --- build/.objs/tests/linux/x86_64/release/src/main.c.o: src/main.c --- build/.objs/tests/linux/x86_64/release/src/main.c.o: src/foo.h --- build/.objs/tests/linux/x86_64/release/src/main.c.o: src/bar.h --- build/.objs/tests/linux/x86_64/release/src/main.c.o: src/zoo.h --- -function main(depsdata, opt) - local results = hashset.new() - local projectdir = os.projectdir() - local line = depsdata:rtrim() -- maybe there will be an empty newline at the end. so we trim it first - local plain = {plain = true} - for _, includefile in ipairs(line:split('\n', plain)) do -- it will trim all internal spaces without `{strict = true}` - includefile = includefile:split(": ", plain)[2] - if includefile and #includefile > 0 then - includefile = _normailize_dep(includefile, projectdir) - if includefile then - results:insert(includefile) - end - end - end - return results:to_array() -end diff --git a/xmake/modules/core/project/depend.lua b/xmake/modules/core/project/depend.lua index 4f81481bb..05b93acf1 100644 --- a/xmake/modules/core/project/depend.lua +++ b/xmake/modules/core/project/depend.lua @@ -44,7 +44,7 @@ function _get_depfiles_parser(depfiles_format) end local parser = depfiles_parsers[depfiles_format] if parser == nil then - parser = import("private.tools." .. depfiles_format .. ".parse_deps", {anonymous = true}) + parser = import("core.tools." .. depfiles_format .. ".parse_deps", {anonymous = true}) depfiles_parsers[depfiles_format] = parser or false end return parser or nil diff --git a/xmake/modules/core/tools/armcc/parse_deps.lua b/xmake/modules/core/tools/armcc/parse_deps.lua new file mode 100644 index 000000000..afde0a575 --- /dev/null +++ b/xmake/modules/core/tools/armcc/parse_deps.lua @@ -0,0 +1,82 @@ +--!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 smalli +-- @file parse_deps_armcc.lua +-- + +-- imports +import("core.project.project") +import("core.base.hashset") + +-- a placeholder for spaces in path +local space_placeholder = "\001" + +-- 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 dep + end +end + +-- parse depsfiles from string +-- +-- parse_deps(io.readfile(depfile, {continuation = "\\"})) +-- +-- eg. +-- build\\.objs\\apps\\cross\\cortex-m3\\release\\APPS\\main.c.o: APPS\\main.c\ +-- build\\.objs\\apps\\cross\\cortex-m3\\release\\APPS\\main.c.o: D:\\Keil533\\ARM\\ARMCC\\bin\\..\\include\\stdarg.h\ +-- build\\.objs\\apps\\cross\\cortex-m3\\release\\APPS\\main.c.o: D:\\Keil533\\ARM\\ARMCC\\bin\\..\\include\\stdio.h\ +-- build\\.objs\\apps\\cross\\cortex-m3\\release\\APPS\\main.c.o: D:\\Keil533\\ARM\\ARMCC\\bin\\..\\include\\string.h\ +-- build\\.objs\\apps\\cross\\cortex-m3\\release\\APPS\\main.c.o: APPS\\main.h\ +-- +-- +function main(depsdata) + local block = 0 + local results = hashset.new() + local projectdir = os.projectdir() + local line = depsdata:rtrim() -- maybe there will be an empty newline at the end. so we trim it first + local plain = {plain = true} + line = line:replace("\\ ", space_placeholder, plain) + for _, includefile in ipairs(line:split('\n', plain)) do + if is_host("windows") and includefile:match("^%w\\:") then + includefile = includefile:replace("\\:", ":", plain) + end + includefile = includefile:replace(space_placeholder, ' ', plain) + local splitinfo = includefile:split(".o:", {plain = true}) + if #splitinfo < 2 then + splitinfo = includefile:split(".obj:", {plain = true}) + end + includefile = splitinfo[2] + if includefile then + includefile = includefile:replace(' ', '', plain) + if #includefile > 0 then + includefile = _normailize_dep(includefile, projectdir) + if includefile then + results:insert(includefile) + end + end + end + end + return results:to_array() +end diff --git a/xmake/modules/core/tools/cl/parse_deps.lua b/xmake/modules/core/tools/cl/parse_deps.lua new file mode 100644 index 000000000..187d655cd --- /dev/null +++ b/xmake/modules/core/tools/cl/parse_deps.lua @@ -0,0 +1,96 @@ +--!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.lua +-- + +-- imports +import("core.project.project") +import("core.base.hashset") +import("parse_include") +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 + _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 + _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 + 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 +function main(depsdata) + local results = hashset.new() + for _, line in ipairs(depsdata:split("\n", {plain = true})) do + local includefile = parse_include(line:trim()) + if includefile then + includefile = _normailize_dep(includefile, os.projectdir()) + if includefile then + results:insert(includefile) + end + end + end + return results:to_array() +end + diff --git a/xmake/modules/core/tools/cl/parse_deps_json.lua b/xmake/modules/core/tools/cl/parse_deps_json.lua new file mode 100644 index 000000000..50f728815 --- /dev/null +++ b/xmake/modules/core/tools/cl/parse_deps_json.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/modules/core/tools/cl/parse_include.lua b/xmake/modules/core/tools/cl/parse_include.lua new file mode 100644 index 000000000..700f9823f --- /dev/null +++ b/xmake/modules/core/tools/cl/parse_include.lua @@ -0,0 +1,104 @@ +--!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_include.lua +-- + +-- imports +import("core.project.project") +import("core.base.hashset") +import("core.tool.toolchain") +import("core.cache.detectcache") +import("lib.detect.find_tool") +import("private.tools.vstool") + +-- probe include note prefix from cl +function probe_include_note_from_cl() + local key = "cldeps.parse_include.note" + local note = detectcache:get(key) + if not note then + local cl = find_tool("cl") + if cl then + local projectdir = os.tmpfile() .. ".cldeps" + local sourcefile = path.join(projectdir, "main.c") + local headerfile = path.join(projectdir, "foo.h") + local objectfile = sourcefile .. ".obj" + local outdata = try { function() + local runenvs = toolchain.load("msvc"):runenvs() + local argv = {"-nologo", "-showIncludes", "-c", "-Fo" .. objectfile, sourcefile} + io.writefile(headerfile, "\n") + io.writefile(sourcefile, [[ + #include "foo.h" + int main (int argc, char** argv) { + return 0; + } + ]]) + return vstool.iorunv(cl.program, argv, {envs = runenvs, curdir = projectdir}) + end} + if outdata then + for _, line in ipairs(outdata:split('\n', {plain = true})) do + note = line:match("^(.-:.-: )") + if note then + break + end + end + end + os.tryrm(projectdir) + end + detectcache:set(key, note) + detectcache:save() + end + return note +end + +-- get include notes prefix, e.g. "Note: including file: " +-- +-- @note we cannot get better solution to distinguish between `includes` and `error infos` +-- +function get_include_notes() + local notes = _g.notes + if not notes then + notes = {} + local note = probe_include_note_from_cl() + if note then + table.insert(notes, note) + end + table.join2(notes, { + "Note: including file: ", -- en + "注意: 包含文件: ", -- zh + "Remarque : inclusion du fichier : ", -- fr + "メモ: インクルード ファイル: " -- jp + }) + _g.notes = notes + end + return notes +end + +-- main entry +function main(line) + local notes = get_include_notes() + for idx, note in ipairs(notes) do + if line:startswith(note) then + -- optimization: move this note to head + if idx ~= 1 then + table.insert(notes, 1, note) + end + return line:sub(#note):trim() + end + end +end + diff --git a/xmake/modules/core/tools/cl2000/parse_deps.lua b/xmake/modules/core/tools/cl2000/parse_deps.lua new file mode 100644 index 000000000..e02cf0501 --- /dev/null +++ b/xmake/modules/core/tools/cl2000/parse_deps.lua @@ -0,0 +1,23 @@ +--!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.lua +-- + +-- imports +inherit("private.tools.cl6x.parse_deps") + diff --git a/xmake/modules/core/tools/cl6x/parse_deps.lua b/xmake/modules/core/tools/cl6x/parse_deps.lua new file mode 100644 index 000000000..a5d5ecd40 --- /dev/null +++ b/xmake/modules/core/tools/cl6x/parse_deps.lua @@ -0,0 +1,77 @@ +--!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.lua +-- + +-- imports +import("core.project.config") +import("core.project.project") +import("core.base.hashset") + +-- normailize path of a dependecy +function _normailize_dep(dep, projectdir) + -- escape characters, e.g. \#Qt.Widget_pch.h -> #Qt.Widget_pch.h + -- @see https://github.com/xmake-io/xmake/issues/4134 + -- https://github.com/xmake-io/xmake/issues/4273 + if not is_host("windows") then + dep = dep:gsub("\\(.)", "%1") + end + 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 + -- 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 +-- +-- parse_deps(io.readfile(depfile, {continuation = "\\"})) +-- +-- eg. +-- +-- build/.objs/foo/linux/x86_64/release/src/foo.c.o: src/foo.c +-- build/.objs/foo/linux/x86_64/release/src/foo.c.o: src/foo.h +-- +-- build/.objs/tests/linux/x86_64/release/src/main.c.o: src/main.c +-- build/.objs/tests/linux/x86_64/release/src/main.c.o: src/foo.h +-- build/.objs/tests/linux/x86_64/release/src/main.c.o: src/bar.h +-- build/.objs/tests/linux/x86_64/release/src/main.c.o: src/zoo.h +-- +function main(depsdata, opt) + local results = hashset.new() + local projectdir = os.projectdir() + local line = depsdata:rtrim() -- maybe there will be an empty newline at the end. so we trim it first + local plain = {plain = true} + for _, includefile in ipairs(line:split('\n', plain)) do -- it will trim all internal spaces without `{strict = true}` + includefile = includefile:split(": ", plain)[2] + if includefile and #includefile > 0 then + includefile = _normailize_dep(includefile, projectdir) + if includefile then + results:insert(includefile) + end + end + end + return results:to_array() +end diff --git a/xmake/modules/core/tools/cl_json/parse_deps.lua b/xmake/modules/core/tools/cl_json/parse_deps.lua new file mode 100644 index 000000000..21b3c9a9d --- /dev/null +++ b/xmake/modules/core/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.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/modules/core/tools/gcc/parse_deps.lua b/xmake/modules/core/tools/gcc/parse_deps.lua new file mode 100644 index 000000000..b4b5cba7f --- /dev/null +++ b/xmake/modules/core/tools/gcc/parse_deps.lua @@ -0,0 +1,143 @@ +--!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.lua +-- + +-- imports +import("core.project.config") +import("core.project.project") +import("core.base.hashset") + +-- a placeholder for spaces in path +local space_placeholder = "\001" + +-- normailize path of a dependecy +function _normailize_dep(dep, projectdir) + -- escape characters, e.g. \#Qt.Widget_pch.h -> #Qt.Widget_pch.h + -- @see https://github.com/xmake-io/xmake/issues/4134 + -- https://github.com/xmake-io/xmake/issues/4273 + if not is_host("windows") then + dep = dep:gsub("\\(.)", "%1") + end + 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 + -- we also need to check header files outside project + -- https://github.com/xmake-io/xmake/issues/1154 + return dep + end +end + +-- load module mapper +function _load_module_mapper(target) + local mapper = {} + local mapperfile = path.join(config.buildir(), target:name(), "mapper.txt") + for line in io.lines(mapperfile) do + local moduleinfo = line:split(" ", {plain = true}) + if #moduleinfo == 2 then + mapper[moduleinfo[1]] = moduleinfo[2] + end + end + return mapper +end + +-- parse depsfiles from string +-- +-- parse_deps(io.readfile(depfile, {continuation = "\\"})) +-- +-- eg. +-- strcpy.o: src/tbox/libc/string/strcpy.c src/tbox/libc/string/string.h \ +-- src/tbox/libc/string/prefix.h src/tbox/libc/string/../prefix.h \ +-- src/tbox/libc/string/../../prefix.h \ +-- src/tbox/libc/string/../../prefix/prefix.h \ +-- src/tbox/libc/string/../../prefix/config.h \ +-- src/tbox/libc/string/../../prefix/../config.h \ +-- build/iphoneos/x86_64/release/tbox.config.h \ +-- +-- with c++ modules (gcc): +-- build/.objs/dependence/linux/x86_64/release/src/foo.mpp.o: src/foo.mpp\ +-- build/.objs/dependence/linux/x86_64/release/src/foo.mpp.o gcm.cache/foo.gcm: bar.c++m cat.c++m\ +-- foo.c++m: gcm.cache/foo.gcm\ +-- .PHONY: foo.c++m\ +-- gcm.cache/foo.gcm:| build/.objs/dependence/linux/x86_64/release/src/foo.mpp.o\ +-- CXX_IMPORTS += bar.c++m cat.c++m\ +-- +function main(depsdata, opt) + + -- we assume there is only one valid line + local block = 0 + local results = hashset.new() + local projectdir = os.projectdir() + local line = depsdata:rtrim() -- maybe there will be an empty newline at the end. so we trim it first + local plain = {plain = true} + line = line:replace("\\ ", space_placeholder, plain) + for _, includefile in ipairs(line:split(' ', plain)) do -- it will trim all internal spaces without `{strict = true}` + -- some gcc toolchains will some invalid paths (e.g. `d\:\xxx`), we need to fix it + -- https://github.com/xmake-io/xmake/issues/1196 + if is_host("windows") and includefile:match("^%w\\:") then + includefile = includefile:replace("\\:", ":", plain) + end + if includefile:endswith(":") then -- ignore "xxx.o:" prefix + block = block + 1 + if block > 1 then + -- skip other `xxx.o:` block + break + end + else + includefile = includefile:replace(space_placeholder, ' ', plain) + includefile = includefile:split("\n", plain)[1] + if #includefile > 0 then + includefile = _normailize_dep(includefile, projectdir) + if includefile then + results:insert(includefile) + end + end + end + end + + -- translate .c++m module file path + -- with c++ modules (gcc): + -- CXX_IMPORTS += bar.c++m cat.c++m\ + -- + -- @see https://github.com/xmake-io/xmake/issues/3000 + -- https://github.com/xmake-io/xmake/issues/4215 + local target = opt and opt.target + if target and line:find("CXX_IMPORTS += ", 1, true) then + local mapper = _load_module_mapper(target) + local modulefiles = line:split("CXX_IMPORTS += ", plain)[2] + if modulefiles then + for _, modulefile in ipairs(modulefiles:split(' ', plain)) do + if modulefile:endswith(".c++m") then + local modulekey = modulefile:sub(1, #modulefile - 5) + local modulepath = mapper[modulekey] + if modulepath then + modulepath = _normailize_dep(modulepath, projectdir) + results:insert(modulepath) + end + end + end + end + end + + return results:to_array() +end diff --git a/xmake/modules/core/tools/rc/parse_deps.lua b/xmake/modules/core/tools/rc/parse_deps.lua new file mode 100644 index 000000000..778f7b03f --- /dev/null +++ b/xmake/modules/core/tools/rc/parse_deps.lua @@ -0,0 +1,52 @@ +--!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.lua +-- + +-- imports +import("core.project.project") +import("core.base.hashset") + +-- 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 depsfiles from string +function main(depsdata) + local results = hashset.new() + local projectdir = os.projectdir() + for _, includefile in ipairs(depsdata:split('\n', {plain = true})) do + if #includefile > 0 then + includefile = _normailize_dep(includefile, projectdir) + if includefile then + results:insert(includefile) + end + end + end + return results:to_array() +end diff --git a/xmake/modules/private/tools/armcc/parse_deps.lua b/xmake/modules/private/tools/armcc/parse_deps.lua deleted file mode 100644 index afde0a575..000000000 --- a/xmake/modules/private/tools/armcc/parse_deps.lua +++ /dev/null @@ -1,82 +0,0 @@ ---!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 smalli --- @file parse_deps_armcc.lua --- - --- imports -import("core.project.project") -import("core.base.hashset") - --- a placeholder for spaces in path -local space_placeholder = "\001" - --- 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 dep - end -end - --- parse depsfiles from string --- --- parse_deps(io.readfile(depfile, {continuation = "\\"})) --- --- eg. --- build\\.objs\\apps\\cross\\cortex-m3\\release\\APPS\\main.c.o: APPS\\main.c\ --- build\\.objs\\apps\\cross\\cortex-m3\\release\\APPS\\main.c.o: D:\\Keil533\\ARM\\ARMCC\\bin\\..\\include\\stdarg.h\ --- build\\.objs\\apps\\cross\\cortex-m3\\release\\APPS\\main.c.o: D:\\Keil533\\ARM\\ARMCC\\bin\\..\\include\\stdio.h\ --- build\\.objs\\apps\\cross\\cortex-m3\\release\\APPS\\main.c.o: D:\\Keil533\\ARM\\ARMCC\\bin\\..\\include\\string.h\ --- build\\.objs\\apps\\cross\\cortex-m3\\release\\APPS\\main.c.o: APPS\\main.h\ --- --- -function main(depsdata) - local block = 0 - local results = hashset.new() - local projectdir = os.projectdir() - local line = depsdata:rtrim() -- maybe there will be an empty newline at the end. so we trim it first - local plain = {plain = true} - line = line:replace("\\ ", space_placeholder, plain) - for _, includefile in ipairs(line:split('\n', plain)) do - if is_host("windows") and includefile:match("^%w\\:") then - includefile = includefile:replace("\\:", ":", plain) - end - includefile = includefile:replace(space_placeholder, ' ', plain) - local splitinfo = includefile:split(".o:", {plain = true}) - if #splitinfo < 2 then - splitinfo = includefile:split(".obj:", {plain = true}) - end - includefile = splitinfo[2] - if includefile then - includefile = includefile:replace(' ', '', plain) - if #includefile > 0 then - includefile = _normailize_dep(includefile, projectdir) - if includefile then - results:insert(includefile) - end - end - end - end - return results:to_array() -end diff --git a/xmake/modules/private/tools/cl/parse_deps.lua b/xmake/modules/private/tools/cl/parse_deps.lua deleted file mode 100644 index 187d655cd..000000000 --- a/xmake/modules/private/tools/cl/parse_deps.lua +++ /dev/null @@ -1,96 +0,0 @@ ---!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.lua --- - --- imports -import("core.project.project") -import("core.base.hashset") -import("parse_include") -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 - _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 - _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 - 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 -function main(depsdata) - local results = hashset.new() - for _, line in ipairs(depsdata:split("\n", {plain = true})) do - local includefile = parse_include(line:trim()) - if includefile then - includefile = _normailize_dep(includefile, os.projectdir()) - if includefile then - results:insert(includefile) - end - end - end - return results:to_array() -end - diff --git a/xmake/modules/private/tools/cl/parse_deps_json.lua b/xmake/modules/private/tools/cl/parse_deps_json.lua deleted file mode 100644 index 50f728815..000000000 --- a/xmake/modules/private/tools/cl/parse_deps_json.lua +++ /dev/null @@ -1,144 +0,0 @@ ---!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/modules/private/tools/cl/parse_include.lua b/xmake/modules/private/tools/cl/parse_include.lua deleted file mode 100644 index 700f9823f..000000000 --- a/xmake/modules/private/tools/cl/parse_include.lua +++ /dev/null @@ -1,104 +0,0 @@ ---!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_include.lua --- - --- imports -import("core.project.project") -import("core.base.hashset") -import("core.tool.toolchain") -import("core.cache.detectcache") -import("lib.detect.find_tool") -import("private.tools.vstool") - --- probe include note prefix from cl -function probe_include_note_from_cl() - local key = "cldeps.parse_include.note" - local note = detectcache:get(key) - if not note then - local cl = find_tool("cl") - if cl then - local projectdir = os.tmpfile() .. ".cldeps" - local sourcefile = path.join(projectdir, "main.c") - local headerfile = path.join(projectdir, "foo.h") - local objectfile = sourcefile .. ".obj" - local outdata = try { function() - local runenvs = toolchain.load("msvc"):runenvs() - local argv = {"-nologo", "-showIncludes", "-c", "-Fo" .. objectfile, sourcefile} - io.writefile(headerfile, "\n") - io.writefile(sourcefile, [[ - #include "foo.h" - int main (int argc, char** argv) { - return 0; - } - ]]) - return vstool.iorunv(cl.program, argv, {envs = runenvs, curdir = projectdir}) - end} - if outdata then - for _, line in ipairs(outdata:split('\n', {plain = true})) do - note = line:match("^(.-:.-: )") - if note then - break - end - end - end - os.tryrm(projectdir) - end - detectcache:set(key, note) - detectcache:save() - end - return note -end - --- get include notes prefix, e.g. "Note: including file: " --- --- @note we cannot get better solution to distinguish between `includes` and `error infos` --- -function get_include_notes() - local notes = _g.notes - if not notes then - notes = {} - local note = probe_include_note_from_cl() - if note then - table.insert(notes, note) - end - table.join2(notes, { - "Note: including file: ", -- en - "注意: 包含文件: ", -- zh - "Remarque : inclusion du fichier : ", -- fr - "メモ: インクルード ファイル: " -- jp - }) - _g.notes = notes - end - return notes -end - --- main entry -function main(line) - local notes = get_include_notes() - for idx, note in ipairs(notes) do - if line:startswith(note) then - -- optimization: move this note to head - if idx ~= 1 then - table.insert(notes, 1, note) - end - return line:sub(#note):trim() - end - end -end - diff --git a/xmake/modules/private/tools/cl2000/parse_deps.lua b/xmake/modules/private/tools/cl2000/parse_deps.lua deleted file mode 100644 index e02cf0501..000000000 --- a/xmake/modules/private/tools/cl2000/parse_deps.lua +++ /dev/null @@ -1,23 +0,0 @@ ---!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.lua --- - --- imports -inherit("private.tools.cl6x.parse_deps") - diff --git a/xmake/modules/private/tools/cl6x/parse_deps.lua b/xmake/modules/private/tools/cl6x/parse_deps.lua deleted file mode 100644 index a5d5ecd40..000000000 --- a/xmake/modules/private/tools/cl6x/parse_deps.lua +++ /dev/null @@ -1,77 +0,0 @@ ---!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.lua --- - --- imports -import("core.project.config") -import("core.project.project") -import("core.base.hashset") - --- normailize path of a dependecy -function _normailize_dep(dep, projectdir) - -- escape characters, e.g. \#Qt.Widget_pch.h -> #Qt.Widget_pch.h - -- @see https://github.com/xmake-io/xmake/issues/4134 - -- https://github.com/xmake-io/xmake/issues/4273 - if not is_host("windows") then - dep = dep:gsub("\\(.)", "%1") - end - 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 - -- 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 --- --- parse_deps(io.readfile(depfile, {continuation = "\\"})) --- --- eg. --- --- build/.objs/foo/linux/x86_64/release/src/foo.c.o: src/foo.c --- build/.objs/foo/linux/x86_64/release/src/foo.c.o: src/foo.h --- --- build/.objs/tests/linux/x86_64/release/src/main.c.o: src/main.c --- build/.objs/tests/linux/x86_64/release/src/main.c.o: src/foo.h --- build/.objs/tests/linux/x86_64/release/src/main.c.o: src/bar.h --- build/.objs/tests/linux/x86_64/release/src/main.c.o: src/zoo.h --- -function main(depsdata, opt) - local results = hashset.new() - local projectdir = os.projectdir() - local line = depsdata:rtrim() -- maybe there will be an empty newline at the end. so we trim it first - local plain = {plain = true} - for _, includefile in ipairs(line:split('\n', plain)) do -- it will trim all internal spaces without `{strict = true}` - includefile = includefile:split(": ", plain)[2] - if includefile and #includefile > 0 then - includefile = _normailize_dep(includefile, projectdir) - if includefile then - results:insert(includefile) - end - end - end - return results:to_array() -end diff --git a/xmake/modules/private/tools/cl_json/parse_deps.lua b/xmake/modules/private/tools/cl_json/parse_deps.lua deleted file mode 100644 index 21b3c9a9d..000000000 --- a/xmake/modules/private/tools/cl_json/parse_deps.lua +++ /dev/null @@ -1,144 +0,0 @@ ---!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.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/modules/private/tools/gcc/parse_deps.lua b/xmake/modules/private/tools/gcc/parse_deps.lua deleted file mode 100644 index b4b5cba7f..000000000 --- a/xmake/modules/private/tools/gcc/parse_deps.lua +++ /dev/null @@ -1,143 +0,0 @@ ---!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.lua --- - --- imports -import("core.project.config") -import("core.project.project") -import("core.base.hashset") - --- a placeholder for spaces in path -local space_placeholder = "\001" - --- normailize path of a dependecy -function _normailize_dep(dep, projectdir) - -- escape characters, e.g. \#Qt.Widget_pch.h -> #Qt.Widget_pch.h - -- @see https://github.com/xmake-io/xmake/issues/4134 - -- https://github.com/xmake-io/xmake/issues/4273 - if not is_host("windows") then - dep = dep:gsub("\\(.)", "%1") - end - 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 - -- we also need to check header files outside project - -- https://github.com/xmake-io/xmake/issues/1154 - return dep - end -end - --- load module mapper -function _load_module_mapper(target) - local mapper = {} - local mapperfile = path.join(config.buildir(), target:name(), "mapper.txt") - for line in io.lines(mapperfile) do - local moduleinfo = line:split(" ", {plain = true}) - if #moduleinfo == 2 then - mapper[moduleinfo[1]] = moduleinfo[2] - end - end - return mapper -end - --- parse depsfiles from string --- --- parse_deps(io.readfile(depfile, {continuation = "\\"})) --- --- eg. --- strcpy.o: src/tbox/libc/string/strcpy.c src/tbox/libc/string/string.h \ --- src/tbox/libc/string/prefix.h src/tbox/libc/string/../prefix.h \ --- src/tbox/libc/string/../../prefix.h \ --- src/tbox/libc/string/../../prefix/prefix.h \ --- src/tbox/libc/string/../../prefix/config.h \ --- src/tbox/libc/string/../../prefix/../config.h \ --- build/iphoneos/x86_64/release/tbox.config.h \ --- --- with c++ modules (gcc): --- build/.objs/dependence/linux/x86_64/release/src/foo.mpp.o: src/foo.mpp\ --- build/.objs/dependence/linux/x86_64/release/src/foo.mpp.o gcm.cache/foo.gcm: bar.c++m cat.c++m\ --- foo.c++m: gcm.cache/foo.gcm\ --- .PHONY: foo.c++m\ --- gcm.cache/foo.gcm:| build/.objs/dependence/linux/x86_64/release/src/foo.mpp.o\ --- CXX_IMPORTS += bar.c++m cat.c++m\ --- -function main(depsdata, opt) - - -- we assume there is only one valid line - local block = 0 - local results = hashset.new() - local projectdir = os.projectdir() - local line = depsdata:rtrim() -- maybe there will be an empty newline at the end. so we trim it first - local plain = {plain = true} - line = line:replace("\\ ", space_placeholder, plain) - for _, includefile in ipairs(line:split(' ', plain)) do -- it will trim all internal spaces without `{strict = true}` - -- some gcc toolchains will some invalid paths (e.g. `d\:\xxx`), we need to fix it - -- https://github.com/xmake-io/xmake/issues/1196 - if is_host("windows") and includefile:match("^%w\\:") then - includefile = includefile:replace("\\:", ":", plain) - end - if includefile:endswith(":") then -- ignore "xxx.o:" prefix - block = block + 1 - if block > 1 then - -- skip other `xxx.o:` block - break - end - else - includefile = includefile:replace(space_placeholder, ' ', plain) - includefile = includefile:split("\n", plain)[1] - if #includefile > 0 then - includefile = _normailize_dep(includefile, projectdir) - if includefile then - results:insert(includefile) - end - end - end - end - - -- translate .c++m module file path - -- with c++ modules (gcc): - -- CXX_IMPORTS += bar.c++m cat.c++m\ - -- - -- @see https://github.com/xmake-io/xmake/issues/3000 - -- https://github.com/xmake-io/xmake/issues/4215 - local target = opt and opt.target - if target and line:find("CXX_IMPORTS += ", 1, true) then - local mapper = _load_module_mapper(target) - local modulefiles = line:split("CXX_IMPORTS += ", plain)[2] - if modulefiles then - for _, modulefile in ipairs(modulefiles:split(' ', plain)) do - if modulefile:endswith(".c++m") then - local modulekey = modulefile:sub(1, #modulefile - 5) - local modulepath = mapper[modulekey] - if modulepath then - modulepath = _normailize_dep(modulepath, projectdir) - results:insert(modulepath) - end - end - end - end - end - - return results:to_array() -end diff --git a/xmake/modules/private/tools/rc/parse_deps.lua b/xmake/modules/private/tools/rc/parse_deps.lua deleted file mode 100644 index 778f7b03f..000000000 --- a/xmake/modules/private/tools/rc/parse_deps.lua +++ /dev/null @@ -1,52 +0,0 @@ ---!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.lua --- - --- imports -import("core.project.project") -import("core.base.hashset") - --- 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 depsfiles from string -function main(depsdata) - local results = hashset.new() - local projectdir = os.projectdir() - for _, includefile in ipairs(depsdata:split('\n', {plain = true})) do - if #includefile > 0 then - includefile = _normailize_dep(includefile, projectdir) - if includefile then - results:insert(includefile) - end - end - end - return results:to_array() -end -- cgit v1.3.1