summaryrefslogtreecommitdiff
path: root/xmake/modules/core/project/depend.lua
blob: 20b63e7e6685b6c2f5755788fb3160569cad9c13 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
--!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-2020, TBOOX Open Source Group.
--
-- @author      ruki
-- @file        depend.lua
--

-- imports
import("private.tools.cl.parse_deps", {alias = "parse_deps_cl"})
import("private.tools.gcc.parse_deps", {alias = "parse_deps_gcc"})

-- load depfiles 
function _load_depfiles(parser, dependinfo, depfiles)
    depfiles = parser(depfiles)
    if depfiles then
        if dependinfo.files then
            table.join2(dependinfo.files, depfiles)
        else
            dependinfo.files = depfiles
        end
    end
end

-- load dependent info from the given file (.d) 
function load(dependfile)

    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)
                dependinfo.depfiles_gcc = nil
            elseif dependinfo.depfiles_cl then
                _load_depfiles(parse_deps_cl, dependinfo, dependinfo.depfiles_cl)
                dependinfo.depfiles_cl = nil
            end
            return dependinfo
        end
    end
end

-- save dependent info to file
function save(dependinfo, dependfile)
    io.save(dependfile, dependinfo)
end

-- the dependent info is changed?
--
-- if not depend.is_changed(dependinfo, {filemtime = os.mtime(objectfile), values = {...}}) then
--      return 
-- end
--
function is_changed(dependinfo, opt)

    -- empty depend info? always be changed
    local files = dependinfo.files or {}
    local values = dependinfo.values or {}
    if #files == 0 and #values == 0 then
        return true
    end

    -- check the dependent files are changed?
    local lastmtime = opt.lastmtime or 0
    _g.files_mtime = _g.files_mtime or {}
    local files_mtime = _g.files_mtime
    for _, file in ipairs(files) do

        -- get and cache the file mtime
        local mtime = files_mtime[file] or os.mtime(file)
        files_mtime[file] = mtime

        -- source and header files have been changed or not exists?
        if mtime == 0 or mtime > lastmtime then
            return true
        end
    end

    -- check the dependent values are changed?
    local depvalues = values
    local optvalues = opt.values or {}
    if #depvalues ~= #optvalues then
        return true
    end
    for idx, depvalue in ipairs(depvalues) do
        local optvalue = optvalues[idx]
        local deptype = type(depvalue) 
        local opttype = type(optvalue)
        if deptype ~= opttype then
            return true
        elseif deptype == "string" and depvalue ~= optvalue then
            return true
        elseif deptype == "table" then
            for subidx, subvalue in ipairs(depvalue) do
                if subvalue ~= optvalue[subidx] then
                    return true
                end
            end
        end
    end

    -- check the dependent files list are changed?
    local optfiles = opt.files
    if optfiles then
        for idx, file in ipairs(files) do
            if file ~= optfiles[idx] then
                return true
            end
        end
    end
end