diff options
| author | OpportunityLiu <[email protected]> | 2019-07-13 09:32:30 +0800 |
|---|---|---|
| committer | OpportunityLiu <[email protected]> | 2019-07-14 00:04:52 +0800 |
| commit | 515a9c3f542ef1b104a3af9a2398335e2d10fe7c (patch) | |
| tree | 43cce985ab728cc7e4290b369cb000a8762fbff5 /xmake/plugins/project/vsxmake/getinfo.lua | |
| parent | 6061930a5c24f9b1ba717a9a39dafda02e8a802a (diff) | |
support call xmake from msbuild
Diffstat (limited to 'xmake/plugins/project/vsxmake/getinfo.lua')
| -rw-r--r-- | xmake/plugins/project/vsxmake/getinfo.lua | 292 |
1 files changed, 292 insertions, 0 deletions
diff --git a/xmake/plugins/project/vsxmake/getinfo.lua b/xmake/plugins/project/vsxmake/getinfo.lua new file mode 100644 index 000000000..4333e71ca --- /dev/null +++ b/xmake/plugins/project/vsxmake/getinfo.lua @@ -0,0 +1,292 @@ +--!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 - 2019, TBOOX Open Source Group. +-- +-- @author OpportunityLiu +-- @file getinfo.lua +-- + +-- imports +import("core.base.option") +import("core.base.semver") +import("core.project.config") +import("core.project.project") +import("core.platform.platform") +import("core.platform.environment") +import("core.tool.compiler") +import("core.tool.linker") +import("lib.detect.find_tool") +import("actions.config.configheader", {alias = "generate_configheader", rootdir = os.programdir()}) + +function _make_dirs(dir) + if dir == nil then + return "" + end + if type(dir) == "string" then + dir = path.translate(dir) + if dir == "" then + return "" + end + if path.is_absolute(dir) then + if dir:startswith(project.directory()) then + return path.join("$(XmakeProjectDir)", path.relative(dir, project.directory())) + end + return dir + end + return path.join("$(XmakeProjectDir)", dir) + end + local r = {} + for k, v in ipairs(dir) do + r[k] = _make_dirs(v) + end + r = table.unique(r) + return table.concat(r, path.envsep()) +end + +function _get_values(target, name) + local values = table.wrap(target:get(name)) + for _, dep in irpairs(target:orderdeps()) do + local depinherit = target:extraconf("deps", dep:name(), "inherit") + if depinherit == nil or depinherit then + table.join2(values, dep:get(name, {interface = true})) + end + end + return values +end + +-- make target info +function _make_targetinfo(mode, arch, target) + + -- init target info + local targetinfo = { mode = mode, arch = arch, plat = config.get("plat"), vsarch = (arch == "x86" and "Win32" or arch) } + + -- write only if not default + -- use target:get("xxx") rather than target:xxx() + + -- save target kind + targetinfo.kind = target:get("kind") + + -- save target file + targetinfo.basename = target:get("basename") + targetinfo.filename = target:get("filename") + + -- save dirs + targetinfo.targetdir = _make_dirs(target:get("targetdir")) + targetinfo.buildir = _make_dirs(config.get("buildir")) + targetinfo.rundir = _make_dirs(target:get("rundir")) + targetinfo.configdir = _make_dirs(os.getenv("XMAKE_CONFIGDIR")) + targetinfo.configfiledir = _make_dirs(target:get("configdir")) + targetinfo.includedirs = _make_dirs(_get_values(target, "includedirs")) + targetinfo.linkdirs = _make_dirs(_get_values(target, "linkdirs")) + + -- save defines + targetinfo.defines = table.concat(_get_values(target, "defines"), ";") + targetinfo.languages = table.concat(_get_values(target, "languages"), ";") + + -- save runenvs + local runenvs = {} + for k, v in pairs(target:get("runenvs")) do + local defs = {} + for _, d in ipairs(v) do + table.insert(defs, vformat(d)) + end + table.insert(runenvs, format("%s=%s", k, table.concat(defs, path.envsep()))) + end + targetinfo.runenvs = table.concat(runenvs, "\n") + + -- use mfc? save the mfc runtime kind + if target:rule("win.sdk.mfc.shared_app") or target:rule("win.sdk.mfc.shared") then + targetinfo.mfckind = "Dynamic" + elseif target:rule("win.sdk.mfc.static_app") or target:rule("win.sdk.mfc.static") then + targetinfo.mfckind = "Static" + end + + -- use cuda? save the cuda runtime version + if target:rule("cuda") then + local nvcc = find_tool("nvcc", { version = true }) + local ver = semver.new(nvcc.version) + targetinfo.cudaver = ver:major() .. "." .. ver:minor() + end + + -- ok + return targetinfo +end + +function _make_vsinfo_modes() + local vsinfo_modes = {} + local modes = option.get("modes") + if modes then + for _, mode in ipairs(modes:split(',')) do + table.insert(vsinfo_modes, mode:trim()) + end + else + vsinfo_modes = project.modes() + end + if not vsinfo_modes or #vsinfo_modes == 0 then + vsinfo_modes = { config.mode() } + end + return vsinfo_modes +end + +function _make_vsinfo_archs() + local vsinfo_archs = {} + local archs = option.get("archs") + if archs then + for _, arch in ipairs(archs:split(',')) do + table.insert(vsinfo_archs, arch:trim()) + end + else + vsinfo_archs = platform.archs() + end + if not vsinfo_archs or #vsinfo_archs == 0 then + vsinfo_archs = { config.arch() } + end + return vsinfo_archs +end + +-- make vstudio project +function main(outputdir, vsinfo) + + -- enter project directory + local oldir = os.cd(project.directory()) + + -- init solution directory + vsinfo.solution_dir = path.absolute(path.join(outputdir, "vsxmake" .. vsinfo.vstudio_version)) + vsinfo.programdir = xmake.programdir() + vsinfo.projectdir = project.directory() + vsinfo.sln_projectfile = path.relative(project.file(), vsinfo.solution_dir) + local projectfile = path.filename(project.file()) + vsinfo.slnfile = path.filename(project.directory()) + -- write only if not default + if projectfile ~= "xmake.lua" then + vsinfo.projectfile = projectfile + vsinfo.slnfile = path.basename(projectfile) + end + + vsinfo.xmake_info = format("xmake version %s", xmake.version()) + vsinfo.solution_id = hash.uuid(project.directory() .. vsinfo.solution_dir) + vsinfo.vs_version = vsinfo.project_version .. ".0" + + -- init modes + vsinfo.modes = _make_vsinfo_modes() + -- init archs + vsinfo.archs = _make_vsinfo_archs() + + -- load targets + local targets = {} + vsinfo._sub2 = {} + for _, mode in ipairs(vsinfo.modes) do + vsinfo._sub2[mode] = {} + for _, arch in ipairs(vsinfo.archs) do + vsinfo._sub2[mode][arch] = { mode = mode, arch = arch } + + -- trace + print("checking for the %s.%s ...", mode, arch) + + -- reload config, project and platform + if mode ~= config.mode() or arch ~= config.arch() then + + -- modify config + config.set("as", nil, {force = true}) -- force to re-check as for ml/ml64 + config.set("mode", mode, {readonly = true, force = true}) + config.set("arch", arch, {readonly = true, force = true}) + + -- clear project to reload and recheck it + project.clear() + + -- check project options + project.check() + + -- reload platform + platform.load(config.plat()) + + -- re-generate configheader + generate_configheader() + end + + -- ensure to enter project directory + os.cd(project.directory()) + + -- enter environment (maybe check flags by calling tools) + environment.enter("toolchains") + + -- save targets + for targetname, target in pairs(project.targets()) do + if not target:isphony() then + + -- make target with the given mode and arch + targets[targetname] = targets[targetname] or {} + local _target = targets[targetname] + + -- init target info + _target.target = targetname + _target.vcxprojdir = path.join(vsinfo.solution_dir, targetname) + _target.target_id = hash.uuid(targetname) + _target.kind = target:targetkind() + _target.scriptdir = path.relative(target:scriptdir(), _target.vcxprojdir) + _target.projectdir = path.relative(project.directory(), _target.vcxprojdir) + local tgtdir = target:get("targetdir") + if tgtdir then _target.targetdir = path.relative(tgtdir, _target.vcxprojdir) end + _target._sub = _target._sub or {} + _target._sub[mode] = _target._sub[mode] or {} + _target._sub[mode][arch] = _make_targetinfo(mode, arch, target) + + -- save all sourcefiles and headerfiles + _target.sourcefiles = table.unique(table.join(_target.sourcefiles or {}, (target:sourcefiles()))) + _target.headerfiles = table.unique(table.join(_target.headerfiles or {}, (target:headerfiles()))) + + _target.deps = table.unique(table.join(_target.deps or {}, table.keys(target:deps()), nil)) + end + end + + -- leave environment + environment.leave("toolchains") + end + end + + -- leave project directory + os.cd(oldir) + for _,target in pairs(targets) do + target._sub2 = {} + local dirs = {} + for _,f in ipairs(target.sourcefiles) do + local dir = path.directory(f) + target._sub2[f] = + { + path = path.join("$(XmakeProjectDir)", f), + dir = dir + } + while dir ~= "." do + if not dirs[dir] then + dirs[dir] = + { + dir = dir, + dir_id = hash.uuid(dir) + } + end + dir = path.directory(dir) + end + end + target._sub3 = dirs + target.dirs = table.keys(dirs) + target._sub4 = {} + for _, v in ipairs(target.deps) do + target._sub4[v] = targets[v] + end + end + vsinfo.targets = table.keys(targets) + vsinfo._sub = targets + return vsinfo +end |
