--!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 configheader.lua -- -- imports import("core.base.option") import("core.project.config") import("core.project.project") -- make configure for the given target name function _make_for_target(target) -- get the target configure file local configheader = target:configheader() if not configheader then return end -- get the config prefix local configprefix = target:configprefix() -- open the file local file = _g.configfiles[configheader] or io.open(path.join(os.tmpdir(), hash.uuid4(configheader)), "w") -- make the head if _g.configfiles[configheader] then file:print("") end file:print("#ifndef %s_H", configprefix) file:print("#define %s_H", configprefix) file:print("") -- make version local version, version_build = target:configversion() if not version or not version_build then local target_version, target_version_build = target:version() if not version then version = target_version end if not version_build then version_build = target_version_build end end if version then file:print("// version") file:print("#define %s_VERSION \"%s\"", configprefix, version) local i = 1 local m = {"MAJOR", "MINOR", "ALTER"} for v in version:gmatch("%d+") do file:print("#define %s_VERSION_%s %s", configprefix, m[i], v) i = i + 1 if i > 3 then break end end if version_build then file:print("#define %s_VERSION_BUILD %s", configprefix, version_build) end file:print("") end -- make the defines local defines = table.copy(target:get("defines_h")) -- make the undefines local undefines = table.copy(target:get("undefines_h")) -- make the defines for options for _, opt in ipairs(target:orderopts()) do table.join2(defines, opt:get("defines_h")) table.join2(defines, opt:get("defines_h_if_ok")) -- deprecated table.join2(undefines, opt:get("undefines_h")) table.join2(undefines, opt:get("undefines_h_if_ok")) -- deprecated end -- make the defines for packages for _, pkg in ipairs(target:orderpkgs()) do table.join2(defines, pkg:get("defines_h")) table.join2(undefines, pkg:get("undefines_h")) end -- make the defines if #defines ~= 0 then file:print("// defines") for _, define in ipairs(defines) do if define:find("=") then file:print("#define %s", define:gsub("=", " "):gsub("%$%((.-)%)", function (w) if w == "prefix" then return configprefix end end)) else file:print("#define %s 1", define:gsub("%$%((.-)%)", function (w) if w == "prefix" then return configprefix end end)) end end file:print("") end -- make the undefines if #undefines ~= 0 then file:print("// undefines") for _, undefine in ipairs(undefines) do file:print("#undef %s", undefine:gsub("%$%((.-)%)", function (w) if w == "prefix" then return configprefix end end)) end file:print("") end -- make the tail file:print("#endif") -- cache the file _g.configfiles[configheader] = file end -- make the configure file for the given target and dependents function _make_for_target_with_deps(targetname) -- the target local target = project.target(targetname) -- make configure for the target _make_for_target(target) -- make configure for the dependent targets? for _, dep in ipairs(target:get("deps")) do _make_for_target_with_deps(dep) end end -- the main entry function function main() -- the target name local targetname = option.get("target") -- enter project directory local oldir = os.cd(project.directory()) -- make configure for the given target name _g.configfiles = {} _g.configpathes = {} if targetname then _make_for_target_with_deps(targetname) else -- make configure for all targets for _, target in pairs(project.targets()) do _make_for_target(target) end end -- close and update files for configpath, configfile_tmp in pairs(_g.configfiles) do -- close the temporary file first configfile_tmp:close() -- update file if the content is changed local configpath_tmp = path.join(os.tmpdir(), hash.uuid4(configpath)) if os.isfile(configpath_tmp) then if os.isfile(configpath) then if io.readfile(configpath_tmp) ~= io.readfile(configpath) then os.cp(configpath_tmp, configpath) end else os.cp(configpath_tmp, configpath) end end end -- leave project directory os.cd(oldir) end