742 lines
22 KiB
Markdown
742 lines
22 KiB
Markdown
# 属性
|
|
|
|
## scopeinfo
|
|
|
|
xmake.lua 生成属性信息,再根据类型生成
|
|
|
|
```lua
|
|
local _instance = scopeinfo
|
|
--[[
|
|
kind : scopetype {root , target , rule , package , task}
|
|
info : scopeconfig {come from xmake.lua}
|
|
opt : unknown
|
|
]]
|
|
-- new an instance
|
|
function _instance.new(kind, info, opt)
|
|
opt = opt or {}
|
|
local instance = table.inherit(_instance)
|
|
instance._KIND = kind or "root"
|
|
instance._INFO = info
|
|
instance._INTERPRETER = opt.interpreter
|
|
instance._DEDUPLICATE = opt.deduplicate
|
|
instance._ENABLE_FILTER = opt.enable_filter
|
|
--print("scope", kind , info.__scriptdir , info.kind)
|
|
return instance
|
|
end
|
|
```
|
|
|
|
## Target
|
|
|
|
```lua
|
|
--[[
|
|
name : scopename
|
|
info : scopeinfo
|
|
]]
|
|
-- new a target instance
|
|
function _instance.new(name, info)
|
|
local instance = table.inherit(_instance)
|
|
instance._NAME = name
|
|
instance._INFO = info
|
|
instance._CACHEID = 1
|
|
return instance
|
|
end
|
|
```
|
|
|
|
|
|
|
|
## Rule
|
|
|
|
```lua
|
|
|
|
-- new a rule instance
|
|
function rule.new(name, info, opt)
|
|
opt = opt or {}
|
|
local instance = table.inherit(_instance)
|
|
instance._NAME = name
|
|
instance._INFO = info
|
|
instance._PACKAGE = opt.package
|
|
if opt.package then
|
|
local deps = {}
|
|
for _, depname in ipairs(table.wrap(instance:get("deps"))) do
|
|
-- @xxx -> @package/xxx
|
|
if depname:startswith("@") and not depname:find("/", 1, true) then
|
|
depname = "@" .. opt.package:name() .. "/" .. depname:sub(2)
|
|
end
|
|
table.insert(deps, depname)
|
|
end
|
|
deps = table.unwrap(deps)
|
|
if deps and #deps > 0 then
|
|
instance:set("deps", deps)
|
|
end
|
|
for depname, extraconf in pairs(table.wrap(instance:extraconf("deps"))) do
|
|
if depname:startswith("@") and not depname:find("/", 1, true) then
|
|
depname = "@" .. opt.package:name() .. "/" .. depname:sub(2)
|
|
instance:extraconf_set("deps", depname, extraconf)
|
|
end
|
|
end
|
|
end
|
|
return instance
|
|
end
|
|
```
|
|
|
|
|
|
|
|
## Package
|
|
|
|
```lua
|
|
-- new an instance
|
|
function _instance.new(name, info, opt)
|
|
opt = opt or {}
|
|
local instance = table.inherit(_instance)
|
|
instance._NAME = name
|
|
instance._INFO = info
|
|
instance._REPO = opt.repo
|
|
instance._SCRIPTDIR = opt.scriptdir and path.absolute(opt.scriptdir)
|
|
return instance
|
|
end
|
|
```
|
|
|
|
|
|
|
|
## Task
|
|
|
|
```lua
|
|
-- new a task instance
|
|
function task.new(name, info)
|
|
local instance = table.inherit(task)
|
|
instance._NAME = name
|
|
instance._INFO = info
|
|
return instance
|
|
end
|
|
```
|
|
|
|
# 事件
|
|
|
|
只触发一次
|
|
|
|
## Project
|
|
|
|
- targets
|
|
- _load_targets
|
|
- t:_load_before()
|
|
- r:_load_before()
|
|
- t:_load()
|
|
- r:_load()
|
|
- t:_load_after()
|
|
- r:_load_after()
|
|
|
|
```lua
|
|
local _instance = Project
|
|
function project.targets()
|
|
if project._memcache():get("targets", targets) then
|
|
return
|
|
end
|
|
local targets, errors = project._load_targets()
|
|
project._memcache():set("targets", targets)
|
|
for _, t in ipairs(project.ordertargets()) do
|
|
local ok, errors = t:_load_after()
|
|
end
|
|
end
|
|
-- load targets
|
|
function project._load_targets()
|
|
-- load all requires first and reload the project file to ensure has_package() works for targets
|
|
local requires = project.required_packages()
|
|
local ok, errors = project._load(true)
|
|
|
|
-- load targets
|
|
local results, errors = project._load_scope("target", true, true)
|
|
|
|
-- make targets
|
|
local targets = {}
|
|
for targetname, targetinfo in pairs(results) do
|
|
local t = target.new(targetname, targetinfo)
|
|
if t and (t:get("enabled") == nil or t:get("enabled") == true) then
|
|
targets[targetname] = t
|
|
end
|
|
end
|
|
|
|
-- load and attach target deps, rules and packages
|
|
for _, t in pairs(targets) do
|
|
|
|
-- load rules from target and language
|
|
t._RULES = t._RULES or {}
|
|
local rulenames = {}
|
|
for _, sourcefile in ipairs(table.wrap(t:get("files"))) do
|
|
local extension = path.extension((sourcefile:gsub("|.*$", "")))
|
|
local lang = language.load_ex(extension)
|
|
table.join2(rulenames, lang:rules())
|
|
end
|
|
rulenames = table.unique(rulenames)
|
|
for _, rulename in ipairs(rulenames) do
|
|
local r = project.rule(rulename) or rule.rule(rulename)
|
|
-- only add target rules
|
|
if r:kind() == "target" then
|
|
t._RULES[rulename] = r
|
|
for _, deprule in ipairs(r:orderdeps()) do
|
|
t._RULES[deprule:name()] = deprule
|
|
end
|
|
end
|
|
-- we need ignore `@package/rulename`, it will be loaded later
|
|
end
|
|
|
|
-- @note it's deprecated, please use on_load instead of before_load
|
|
ok, errors = t:_load_before()
|
|
|
|
-- we need call on_load() before building deps/rules,
|
|
-- so we can use `target:add("deps", "xxx")` to add deps in on_load
|
|
ok, errors = t:_load()
|
|
end
|
|
return targets
|
|
end
|
|
```
|
|
|
|
## Target
|
|
|
|
- _load_before
|
|
- _load_rules
|
|
- _load
|
|
- _load_rules
|
|
- on_load
|
|
- _load_after
|
|
- _load_rules
|
|
-
|
|
|
|
```lua
|
|
local _instance = Target
|
|
-- load rules suffix = {before nil after}
|
|
function _instance:_load_rules(suffix)
|
|
for k, r in ipairs(self:orderules()) do
|
|
local ok, errors = self:_load_rule(r, suffix)
|
|
end
|
|
return true
|
|
end
|
|
-- do before_load for rules
|
|
-- @note it's deprecated, please use on_load instead of before_load
|
|
function _instance:_load_before()
|
|
local ok, errors = self:_load_rules("before")
|
|
return true
|
|
end
|
|
-- do load target and rules
|
|
function _instance:_load()
|
|
|
|
-- do load with target rules
|
|
local ok, errors = self:_load_rules()
|
|
|
|
-- do load for target
|
|
local on_load = self:script("load")
|
|
ok, errors = sandbox.load(on_load, self)
|
|
|
|
-- mark as loaded
|
|
return true
|
|
end
|
|
-- do after_load target and rules
|
|
function _instance:_load_after()
|
|
-- enter the environments of the target packages
|
|
local oldenvs = os.addenvs(self:pkgenvs())
|
|
|
|
-- do load for target
|
|
local after_load = self:script("load_after")
|
|
if after_load then
|
|
local ok, errors = sandbox.load(after_load, self)
|
|
end
|
|
-- do after_load with target rules
|
|
local ok, errors = self:_load_rules("after")
|
|
|
|
-- leave the environments of the target packages
|
|
os.setenvs(oldenvs)
|
|
return true
|
|
end
|
|
|
|
```
|
|
|
|
## Language
|
|
|
|
# 任务
|
|
|
|
## Build
|
|
|
|
- load
|
|
|
|
- before_load
|
|
|
|
- on_load
|
|
|
|
- after_load
|
|
|
|
- build
|
|
|
|
- before_build
|
|
|
|
- on_build
|
|
|
|
- after_build
|
|
|
|
```lua
|
|
function main()
|
|
-- lock the whole project
|
|
project.lock()
|
|
|
|
-- config it first
|
|
task.run("config", {}, {disable_dump = true})
|
|
|
|
-- enter project directory
|
|
local oldir = os.cd(project.directory())
|
|
|
|
-- clean up temporary files once a day
|
|
cleaner.cleanup()
|
|
|
|
-- do rules before building
|
|
_do_project_rules("build_before")
|
|
|
|
-- do build
|
|
_do_build(targetname, group_pattern)
|
|
|
|
-- dump cache stats
|
|
if option.get("diagnosis") then
|
|
build_cache.dump_stats()
|
|
end
|
|
-- do rules after building
|
|
_do_project_rules("build_after")
|
|
-- unlock the whole project
|
|
project.unlock()
|
|
end
|
|
```
|
|
|
|
## Project
|
|
|
|
- install
|
|
|
|
- before_install
|
|
|
|
- on_install
|
|
|
|
- after_install
|
|
|
|
- load
|
|
|
|
- before_load
|
|
- on_load
|
|
- after_load
|
|
|
|
```lua
|
|
|
|
-- make target info
|
|
function getinfo._make_targetinfo(mode, arch, target)
|
|
|
|
-- init target info
|
|
local targetinfo =
|
|
{
|
|
mode = mode
|
|
, arch = arch
|
|
, plat = config.get("plat")
|
|
, vsarch = vsutils.vsarch(arch)
|
|
, sdkver = config.get("vs_sdkver")
|
|
}
|
|
|
|
-- write only if not default
|
|
-- use target:get("xxx") rather than target:xxx()
|
|
|
|
-- save target kind
|
|
targetinfo.kind = target:kind()
|
|
|
|
-- is default?
|
|
targetinfo.default = tostring(target:is_default())
|
|
|
|
-- save target file
|
|
targetinfo.basename = vsutils.escape(target:basename())
|
|
targetinfo.filename = vsutils.escape(target: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(table.join(_get_values_from_target(target, "includedirs") or {}, _get_values_from_target(target, "sysincludedirs")))
|
|
targetinfo.linkdirs = _make_dirs(_get_values_from_target(target, "linkdirs"))
|
|
targetinfo.sourcedirs = _make_dirs(_get_values_from_target(target, "values.project.vsxmake.sourcedirs"))
|
|
targetinfo.pcheaderfile = target:pcheaderfile("cxx") or target:pcheaderfile("c")
|
|
|
|
-- save defines
|
|
targetinfo.defines = _make_arrs(_get_values_from_target(target, "defines"))
|
|
|
|
-- save languages
|
|
targetinfo.languages = _make_arrs(_get_values_from_target(target, "languages"))
|
|
if targetinfo.languages then
|
|
-- fix c++17 to cxx17 for Xmake.props
|
|
targetinfo.languages = targetinfo.languages:replace("c++", "cxx", {plain = true})
|
|
end
|
|
if target:is_phony() or target:is_headeronly() then
|
|
return targetinfo
|
|
end
|
|
|
|
-- save subsystem
|
|
local linkflags = linker.linkflags(target:kind(), target:sourcekinds(), {target = target})
|
|
for _, linkflag in ipairs(linkflags) do
|
|
if linkflag:lower():find("[%-/]subsystem:windows") then
|
|
targetinfo.subsystem = "windows"
|
|
end
|
|
end
|
|
if not targetinfo.subsystem then
|
|
targetinfo.subsystem = "console"
|
|
end
|
|
|
|
-- save runenvs
|
|
local runenvs = {}
|
|
local addrunenvs, setrunenvs = make_runenvs(target)
|
|
for k, v in table.orderpairs(target:pkgenvs()) do
|
|
addrunenvs = addrunenvs or {}
|
|
addrunenvs[k] = table.join(table.wrap(addrunenvs[k]), path.splitenv(v))
|
|
end
|
|
for _, dep in ipairs(target:orderdeps()) do
|
|
for k, v in table.orderpairs(dep:pkgenvs()) do
|
|
addrunenvs = addrunenvs or {}
|
|
addrunenvs[k] = table.join(table.wrap(addrunenvs[k]), path.splitenv(v))
|
|
end
|
|
end
|
|
for k, v in table.orderpairs(addrunenvs) do
|
|
if k:upper() == "PATH" then
|
|
runenvs[k] = _make_dirs(v) .. ";$([System.Environment]::GetEnvironmentVariable('" .. k .. "'))"
|
|
else
|
|
runenvs[k] = path.joinenv(v) .. ";$([System.Environment]::GetEnvironmentVariable('" .. k .."'))"
|
|
end
|
|
end
|
|
for k, v in table.orderpairs(setrunenvs) do
|
|
if #v == 1 then
|
|
v = v[1]
|
|
if path.is_absolute(v) and v:startswith(project.directory()) then
|
|
runenvs[k] = _make_dirs(v)
|
|
else
|
|
runenvs[k] = v[1]
|
|
end
|
|
else
|
|
runenvs[k] = path.joinenv(v)
|
|
end
|
|
end
|
|
local runenvstr = {}
|
|
for k, v in table.orderpairs(runenvs) do
|
|
table.insert(runenvstr, k .. "=" .. v)
|
|
end
|
|
targetinfo.runenvs = table.concat(runenvstr, "\n")
|
|
|
|
local runargs = target:get("runargs")
|
|
if runargs then
|
|
targetinfo.runargs = os.args(table.wrap(runargs))
|
|
end
|
|
|
|
-- 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
|
|
return targetinfo
|
|
end
|
|
-- make vstudio project
|
|
function getinfo.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 = _make_dirs(xmake.programdir())
|
|
vsinfo.projectdir = project.directory()
|
|
vsinfo.sln_projectfile = path.relative(project.rootfile(), vsinfo.solution_dir)
|
|
local projectfile = path.filename(project.rootfile())
|
|
vsinfo.slnfile = project.name() or path.filename(project.directory())
|
|
-- write only if not default
|
|
|
|
vsinfo.xmake_info = format("xmake version %s", xmake.version())
|
|
vsinfo.solution_id = hash.uuid4(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()
|
|
|
|
-- init groups
|
|
local groups, group_deps = _make_vsinfo_groups()
|
|
vsinfo.groups = table.orderkeys(groups)
|
|
vsinfo.group_deps = table.orderkeys(group_deps)
|
|
vsinfo._groups = groups
|
|
vsinfo._group_deps = group_deps
|
|
|
|
-- init config flags
|
|
local flags = {}
|
|
for k, v in table.orderpairs(localcache.get("config", "options")) do
|
|
if k ~= "plat" and k ~= "mode" and k ~= "arch" and k ~= "clean" and k ~= "buildir" then
|
|
table.insert(flags, "--" .. k .. "=" .. tostring(v))
|
|
end
|
|
end
|
|
vsinfo.configflags = os.args(flags)
|
|
|
|
-- load targets
|
|
local targets = {}
|
|
vsinfo._arch_modes = {}
|
|
for _, mode in ipairs(vsinfo.modes) do
|
|
vsinfo._arch_modes[mode] = {}
|
|
for _, arch in ipairs(vsinfo.archs) do
|
|
vsinfo._arch_modes[mode][arch] = { mode = mode, arch = arch }
|
|
|
|
-- trace
|
|
print("checking for %s.%s ...", mode, arch)
|
|
|
|
-- reload config, project and platform
|
|
-- 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 all options
|
|
for _, opt in ipairs(project.options()) do
|
|
opt:clear()
|
|
end
|
|
|
|
-- clear cache
|
|
memcache.clear()
|
|
|
|
-- check platform
|
|
platform.load(config.plat(), arch):check()
|
|
|
|
-- check project options
|
|
project.check()
|
|
|
|
-- install and update requires
|
|
install_requires()
|
|
|
|
-- load package rules for targets
|
|
_load_package_rules_for_targets()
|
|
|
|
-- config targets
|
|
_config_targets()
|
|
|
|
-- update config files
|
|
generate_configfiles()
|
|
generate_configheader()
|
|
|
|
-- ensure to enter project directory
|
|
os.cd(project.directory())
|
|
|
|
-- save targets
|
|
for targetname, target in table.orderpairs(project.targets()) do
|
|
|
|
-- https://github.com/xmake-io/xmake/issues/2337
|
|
target:data_set("plugin.project.kind", "vsxmake")
|
|
|
|
-- 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.uuid4(targetname)
|
|
_target.kind = target:kind()
|
|
_target.absscriptdir = target:scriptdir()
|
|
_target.scriptdir = path.relative(target:scriptdir(), _target.vcxprojdir)
|
|
_target.projectdir = path.relative(project.directory(), _target.vcxprojdir)
|
|
local targetdir = target:get("targetdir")
|
|
if targetdir then _target.targetdir = path.relative(targetdir, _target.vcxprojdir) end
|
|
_target._targets = _target._targets or {}
|
|
_target._targets[mode] = _target._targets[mode] or {}
|
|
local targetinfo = _make_targetinfo(mode, arch, target)
|
|
_target._targets[mode][arch] = targetinfo
|
|
_target.sdkver = targetinfo.sdkver
|
|
_target.default = targetinfo.default
|
|
|
|
-- 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())))
|
|
|
|
-- sort them to stabilize generation
|
|
table.sort(_target.sourcefiles)
|
|
table.sort(_target.headerfiles)
|
|
|
|
-- save file groups
|
|
_target.filegroups = target:get("filegroups")
|
|
_target.filegroups_extraconf = target:extraconf("filegroups")
|
|
|
|
-- save deps
|
|
_target.deps = table.unique(table.join(_target.deps or {}, table.orderkeys(target:deps()), nil))
|
|
end
|
|
end
|
|
end
|
|
os.cd(oldir)
|
|
for _, target in table.orderpairs(targets) do
|
|
target._paths = {}
|
|
local dirs = {}
|
|
local projectdir = project.directory()
|
|
local root = target.absscriptdir or projectdir
|
|
target.sourcefiles = table.imap(target.sourcefiles, function(_, v) return path.relative(v, projectdir) end)
|
|
target.headerfiles = table.imap(target.headerfiles, function(_, v) return path.relative(v, projectdir) end)
|
|
for _, f in ipairs(table.join(target.sourcefiles, target.headerfiles)) do
|
|
local dir = _make_filter(f, target, root)
|
|
local escaped_f = vsutils.escape(f)
|
|
target._paths[f] =
|
|
{
|
|
-- @see https://github.com/xmake-io/xmake/issues/2077
|
|
path = path.is_absolute(escaped_f) and escaped_f or "$(XmakeProjectDir)\\" .. escaped_f,
|
|
dir = vsutils.escape(dir)
|
|
}
|
|
while dir and dir ~= "." do
|
|
if not dirs[dir] then
|
|
dirs[dir] =
|
|
{
|
|
dir = vsutils.escape(dir),
|
|
dir_id = hash.uuid4(dir)
|
|
}
|
|
end
|
|
dir = path.directory(dir) or "."
|
|
end
|
|
end
|
|
target._dirs = dirs
|
|
target.dirs = table.orderkeys(dirs)
|
|
target._deps = {}
|
|
for _, v in ipairs(target.deps) do
|
|
target._deps[v] = targets[v]
|
|
end
|
|
end
|
|
|
|
-- we need set startup project for default or binary target
|
|
-- @see https://github.com/xmake-io/xmake/issues/1249
|
|
local targetnames = {}
|
|
for targetname, target in table.orderpairs(project.targets()) do
|
|
if target:get("default") == true then
|
|
table.insert(targetnames, 1, targetname)
|
|
elseif target:is_binary() then
|
|
local first_target = targetnames[1] and project.target(targetnames[1])
|
|
if not first_target or first_target:is_default() then
|
|
table.insert(targetnames, 1, targetname)
|
|
else
|
|
table.insert(targetnames, targetname)
|
|
end
|
|
else
|
|
table.insert(targetnames, targetname)
|
|
end
|
|
end
|
|
vsinfo.targets = targetnames
|
|
vsinfo._targets = targets
|
|
return vsinfo
|
|
end
|
|
```
|
|
|
|
|
|
|
|
```lua
|
|
-- make
|
|
function make(version)
|
|
return function(outputdir)
|
|
-- trace
|
|
vprint("using project kind vs%d", version)
|
|
|
|
-- get info and params
|
|
local info = getinfo(outputdir, vsinfo(version))
|
|
local paramsprovidersln = _buildparams(info)
|
|
|
|
-- write solution file
|
|
local sln = path.join(info.solution_dir, info.slnfile .. ".sln")
|
|
_writefileifneeded(sln, render(template_sln, "#([A-Za-z0-9_,%.%*%(%)]+)#", "@([^@]+)@", paramsprovidersln))
|
|
|
|
-- add solution custom file
|
|
_trycp(template_props, info.solution_dir)
|
|
_trycp(template_targets, info.solution_dir)
|
|
|
|
for _, target in ipairs(info.targets) do
|
|
local paramsprovidertarget = _buildparams(info, target, "<!-- nil -->")
|
|
local proj_dir = info._targets[target].vcxprojdir
|
|
|
|
-- write project file
|
|
local proj = path.join(proj_dir, target .. ".vcxproj")
|
|
_writefileifneeded(proj, render(template_vcx, "#([A-Za-z0-9_,%.%*%(%)]+)#", "@([^@]+)@", paramsprovidertarget))
|
|
|
|
local projfil = path.join(proj_dir, target .. ".vcxproj.filters")
|
|
_writefileifneeded(projfil, render(template_fil, "#([A-Za-z0-9_,%.%*%(%)]+)#", "@([^@]+)@", paramsprovidertarget))
|
|
|
|
-- add project custom file
|
|
_trycp(template_props, proj_dir)
|
|
_trycp(template_targets, proj_dir)
|
|
_trycp(template_items, proj_dir)
|
|
_trycp(template_itemfil, proj_dir)
|
|
end
|
|
|
|
-- clear config and local cache
|
|
_clear_cache()
|
|
|
|
-- save plugin arguments for autoupdate
|
|
_save_plugin_arguments()
|
|
end
|
|
end
|
|
-- main
|
|
function main()
|
|
|
|
-- in project generator?
|
|
os.setenv("XMAKE_IN_PROJECT_GENERATOR", "true")
|
|
|
|
-- config it first
|
|
task.run("config")
|
|
|
|
-- make project
|
|
_make[option.get("kind")](option.get("outputdir"))
|
|
|
|
-- trace
|
|
cprint("${color.success}create ok!")
|
|
os.setenv("XMAKE_IN_PROJECT_GENERATOR", nil)
|
|
end
|
|
```
|
|
|
|
|
|
|
|
# 库依赖
|
|
|
|
## Package
|
|
|
|
```lua
|
|
-- register the required local package
|
|
function _register_required_package(instance, required_package)
|
|
|
|
-- disable it if this package is missing
|
|
if not instance:exists() then
|
|
required_package:enable(false)
|
|
else
|
|
-- clear require info first
|
|
required_package:clear()
|
|
|
|
-- add packages info with all dependencies
|
|
local envs = {}
|
|
_register_required_package_base(instance, required_package)
|
|
_register_required_package_libs(instance, required_package)
|
|
_register_required_package_envs(instance, envs)
|
|
for _, dep in ipairs(instance:librarydeps()) do
|
|
if instance:is_library() then
|
|
_register_required_package_libs(dep, required_package, true)
|
|
end
|
|
end
|
|
for _, dep in ipairs(instance:orderdeps()) do
|
|
if not dep:is_private() then
|
|
_register_required_package_envs(dep, envs)
|
|
end
|
|
end
|
|
if #table.keys(envs) > 0 then
|
|
required_package:add({envs = envs})
|
|
end
|
|
|
|
-- enable this require info
|
|
required_package:enable(true)
|
|
end
|
|
|
|
-- save this require info and flush the whole cache file
|
|
required_package:save()
|
|
end
|
|
```
|
|
|