summaryrefslogtreecommitdiff
path: root/xmake
diff options
context:
space:
mode:
authorruki <[email protected]>2020-06-20 16:07:21 +0800
committerruki <[email protected]>2020-06-20 16:07:21 +0800
commitda2e3b83c53752c43b651effeb273cb72090d7b0 (patch)
tree0a66afa1a6b6facc6753e970fe66c17343650516 /xmake
parent281e06a020f7704fe998be52a6ecc2711cfd4fb7 (diff)
add runenvs for cl/link
Diffstat (limited to 'xmake')
-rw-r--r--xmake/core/platform/environment.lua10
-rw-r--r--xmake/core/platform/platform.lua16
-rw-r--r--xmake/core/project/target.lua10
-rw-r--r--xmake/core/tool/compiler.lua8
-rw-r--r--xmake/core/tool/linker.lua6
-rw-r--r--xmake/core/tool/tool.lua95
-rw-r--r--xmake/modules/core/tools/cl.lua3
-rw-r--r--xmake/modules/core/tools/link.lua9
-rw-r--r--xmake/modules/private/tools/vstool.lua12
9 files changed, 116 insertions, 53 deletions
diff --git a/xmake/core/platform/environment.lua b/xmake/core/platform/environment.lua
index 8fc67bfac..888fe2148 100644
--- a/xmake/core/platform/environment.lua
+++ b/xmake/core/platform/environment.lua
@@ -45,16 +45,6 @@ function environment._enter_toolchains()
if os.host() == "windows" then
os.addenv("PATH", path.join(os.programdir(), "winenv", "bin"))
end
-
- --[[
- -- add the runenvs of toolchains
- for name, values in pairs(platform:runenvs()) do
- if not oldenvs[name] then
- oldenvs[name] = os.getenv(name)
- end
- os.addenv(name, table.unpack(table.wrap(values)))
- end]]
-
environment._OLDENVS_TOOLCHAINS = oldenvs
return true
end
diff --git a/xmake/core/platform/platform.lua b/xmake/core/platform/platform.lua
index 39f88645f..d29c4d3a4 100644
--- a/xmake/core/platform/platform.lua
+++ b/xmake/core/platform/platform.lua
@@ -181,7 +181,7 @@ function _instance:tool(toolkind)
end
-- get tool program
- local program, toolname
+ local program, toolname, toolchain_info
local toolinfo = tools[toolkind]
if toolinfo == nil then
toolinfo = {}
@@ -191,15 +191,17 @@ function _instance:tool(toolkind)
if program then
toolinfo[1] = program
toolinfo[2] = toolname
+ toolinfo[3] = {name = toolchain_inst:name(), plat = toolchain_inst:plat(), arch = toolchain_inst:arch()}
break
end
end
tools[toolkind] = toolinfo
else
- program = toolinfo[1]
- toolname = toolinfo[2]
+ program = toolinfo[1]
+ toolname = toolinfo[2]
+ toolchain_info = toolinfo[3]
end
- return program, toolname
+ return program, toolname, toolchain_info
end
-- get tool configuration from the toolchains
@@ -503,6 +505,7 @@ function platform.tool(toolkind, plat)
-- attempt to get program from config first
local program = config.get(toolkind)
local toolname = config.get("__toolname_" .. toolkind)
+ local toolchain_info = config.get("__toolchain_info_" .. toolkind)
if program == nil then
-- get the current platform
@@ -512,10 +515,11 @@ function platform.tool(toolkind, plat)
end
-- get it from the platform toolchains
- program, toolname = instance:tool(toolkind)
+ program, toolname, toolchain_info = instance:tool(toolkind)
if program then
config.set(toolkind, program, {force = true, readonly = true})
config.set("__toolname_" .. toolkind, toolname)
+ config.set("__toolchain_info_" .. toolkind, toolchain_info)
config.save()
end
end
@@ -528,7 +532,7 @@ function platform.tool(toolkind, plat)
program = program:sub(pos + 1)
end
end
- return program, toolname
+ return program, toolname, toolchain_info
end
-- get the given tool configuration
diff --git a/xmake/core/project/target.lua b/xmake/core/project/target.lua
index ad001c559..dc337c8ac 100644
--- a/xmake/core/project/target.lua
+++ b/xmake/core/project/target.lua
@@ -1693,7 +1693,7 @@ function _instance:tool(toolkind)
end
-- get tool program
- local program, toolname
+ local program, toolname, toolchain_info
local toolinfo = tools[toolkind]
if toolinfo == nil then
toolinfo = {}
@@ -1711,19 +1711,19 @@ function _instance:tool(toolkind)
if not program and not self:get("toolchains") then
program = config.get(toolkind)
toolname = config.get("__toolname_" .. toolkind)
+ toolchain_info = config.get("__toolchain_info_" .. toolkind)
end
-- get program from target/toolchains
if not program then
local toolchains = self:toolchains()
- environment.enter("toolchains")
for idx, toolchain_inst in ipairs(toolchains) do
program, toolname = toolchain_inst:tool(toolkind)
if program then
+ toolchain_info = {name = toolchain_inst:name(), plat = toolchain_inst:plat(), arch = toolchain_inst:arch()}
break
end
end
- environment.leave("toolchains")
end
-- contain toolname? parse it, e.g. '[email protected]'
@@ -1738,13 +1738,15 @@ function _instance:tool(toolkind)
if program then
toolinfo[1] = program
toolinfo[2] = toolname
+ toolinfo[3] = toolchain_info
end
tools[toolkind] = toolinfo
else
program = toolinfo[1]
toolname = toolinfo[2]
+ toolchain_info = toolinfo[3]
end
- return program, toolname
+ return program, toolname, toolchain_info
end
-- get tool configuration from the toolchains
diff --git a/xmake/core/tool/compiler.lua b/xmake/core/tool/compiler.lua
index e56f2d300..c47ffb9e1 100644
--- a/xmake/core/tool/compiler.lua
+++ b/xmake/core/tool/compiler.lua
@@ -78,13 +78,13 @@ end
function compiler._load_tool(sourcekind, target)
-- get program from target
- local program, toolname
+ local program, toolname, toolchain_info
if target and target:type() == "target" then
- program, toolname = target:tool(sourcekind)
+ program, toolname, toolchain_info = target:tool(sourcekind)
end
-- load the compiler tool from the source kind
- local result, errors = tool.load(sourcekind, program, toolname)
+ local result, errors = tool.load(sourcekind, {program = program, toolname = toolname, toolchain_info = toolchain_info})
if not result then
return nil, errors
end
@@ -236,7 +236,7 @@ function compiler:compile(sourcefiles, objectfile, opt)
end
-- compile it
- return sandbox.load(self:_tool().compile, self:_tool(), sourcefiles, objectfile, opt.dependinfo, compflags)
+ return sandbox.load(self:_tool().compile, self:_tool(), sourcefiles, objectfile, opt.dependinfo, compflags, opt)
end
-- get the compile arguments list
diff --git a/xmake/core/tool/linker.lua b/xmake/core/tool/linker.lua
index baafde7ae..06ae051cb 100644
--- a/xmake/core/tool/linker.lua
+++ b/xmake/core/tool/linker.lua
@@ -85,13 +85,13 @@ function linker._load_tool(targetkind, sourcekinds, target)
for _, _linkerinfo in ipairs(linkerinfos) do
-- get program from target
- local program, toolname
+ local program, toolname, toolchain_info
if target and target:type() == "target" then
- program, toolname = target:tool(_linkerinfo.linkerkind)
+ program, toolname, toolchain_info = target:tool(_linkerinfo.linkerkind)
end
-- load the linker tool from the linker kind (with cache)
- linkertool, errors = tool.load(_linkerinfo.linkerkind, program, toolname)
+ linkertool, errors = tool.load(_linkerinfo.linkerkind, {program = program, toolname = toolname, toolchain_info = toolchain_info})
if linkertool then
linkerinfo = _linkerinfo
linkerinfo.program = program
diff --git a/xmake/core/tool/tool.lua b/xmake/core/tool/tool.lua
index 5736ded22..b33727114 100644
--- a/xmake/core/tool/tool.lua
+++ b/xmake/core/tool/tool.lua
@@ -30,11 +30,12 @@ local table = require("base/table")
local string = require("base/string")
local config = require("project/config")
local sandbox = require("sandbox/sandbox")
+local toolchain = require("tool/toolchain")
local platform = require("platform/platform")
local import = require("sandbox/modules/import")
-- new an instance
-function _instance.new(kind, name, program)
+function _instance.new(kind, name, program, plat, arch, toolchain_inst)
-- import "core.tools.xxx"
local toolclass = nil
@@ -51,10 +52,13 @@ function _instance.new(kind, name, program)
local instance = table.inherit(_instance, toolclass)
-- save name, kind and program
- instance._NAME = name
- instance._KIND = kind
- instance._PROGRAM = program
- instance._INFO = {}
+ instance._NAME = name
+ instance._KIND = kind
+ instance._PROGRAM = program
+ instance._PLAT = plat
+ instance._ARCH = arch
+ instance._TOOLCHAIN = toolchain_inst
+ instance._INFO = {}
-- init instance
if instance.init then
@@ -78,11 +82,49 @@ function _instance:kind()
return self._KIND
end
+-- get the tool platform
+function _instance:plat()
+ return self._PLAT
+end
+
+-- get the tool architecture
+function _instance:arch()
+ return self._ARCH
+end
+
-- get the tool program
function _instance:program()
return self._PROGRAM
end
+-- get the toolchain of this tool
+function _instance:toolchain()
+ return self._TOOLCHAIN
+end
+
+-- get run environments
+function _instance:runenvs()
+ local runenvs = self._RUNENVS
+ if runenvs == nil then
+ local toolchain = self:toolchain()
+ if toolchain then
+ local toolchain_runenvs = toolchain:get("runenvs")
+ if toolchain_runenvs then
+ runenvs = {}
+ for name, values in pairs(toolchain_runenvs) do
+ if type(values) == "table" then
+ values = path.joinenv(values)
+ end
+ runenvs[name] = values
+ end
+ end
+ end
+ runenvs = runenvs or false
+ self._RUNENVS = runenvs
+ end
+ return runenvs or nil
+end
+
-- set the value to the platform info
function _instance:set(name, ...)
self._INFO[name] = table.unwrap({...})
@@ -129,19 +171,30 @@ end
-- load the given tool from the given kind
--
--- @param kind the tool kind e.g. cc, cxx, mm, mxx, as, ar, ld, sh, ..
--- @param program the tool program, e.g. /xxx/arm-linux-gcc, [email protected], (optional)
--- @param toolname gcc, clang, .. (optional)
+-- @param kind the tool kind e.g. cc, cxx, mm, mxx, as, ar, ld, sh, ..
+-- @param opt.program the tool program, e.g. /xxx/arm-linux-gcc, [email protected], (optional)
+-- @param opt.toolname gcc, clang, .. (optional)
+-- @param opt.toolchain_info the toolchain info (optional)
--
-function tool.load(kind, program, toolname)
+function tool.load(kind, opt)
+
+ -- get tool information
+ opt = opt or {}
+ local program = opt.program
+ local toolname = opt.toolname
+ local toolchain_info = opt.toolchain_info or {}
- -- init key
- local key = kind .. (program or "") .. (config.get("arch") or os.arch())
+ -- get platform and architecture
+ local plat = toolchain_info.plat or config.get("plat") or os.host()
+ local arch = toolchain_info.arch or config.get("arch") or os.arch()
+
+ -- init cachekey
+ local cachekey = kind .. (program or "") .. plat .. arch
-- get it directly from cache dirst
tool._TOOLS = tool._TOOLS or {}
- if tool._TOOLS[key] then
- return tool._TOOLS[key]
+ if tool._TOOLS[cachekey] then
+ return tool._TOOLS[cachekey]
end
-- contain toolname? parse it, e.g. '[email protected]'
@@ -155,7 +208,11 @@ function tool.load(kind, program, toolname)
-- get the tool program and name
if not program then
- program, toolname = platform.tool(kind)
+ program, toolname, toolchain_info = platform.tool(kind)
+ if toolchain_info then
+ assert(toolchain_info.plat == plat)
+ assert(toolchain_info.arch == arch)
+ end
end
if not program then
return nil, string.format("cannot get program for %s", kind)
@@ -176,14 +233,20 @@ function tool.load(kind, program, toolname)
return nil, string.format("cannot find known tool script for %s", toolname or program)
end
+ -- load toolchain instance
+ local toolchain_inst
+ if toolchain_info and toolchain_info.name then
+ toolchain_inst = toolchain.load(toolchain_info.name, plat, arch)
+ end
+
-- new an instance
- local instance, errors = _instance.new(kind, name, program)
+ local instance, errors = _instance.new(kind, name, program, plat, arch, toolchain_inst)
if not instance then
return nil, errors
end
-- save instance to the cache
- tool._TOOLS[key] = instance
+ tool._TOOLS[cachekey] = instance
-- ok
return instance
diff --git a/xmake/modules/core/tools/cl.lua b/xmake/modules/core/tools/cl.lua
index 9f6421c21..3dfa0bb0f 100644
--- a/xmake/modules/core/tools/cl.lua
+++ b/xmake/modules/core/tools/cl.lua
@@ -353,7 +353,8 @@ function compile(self, sourcefile, objectfile, dependinfo, flags, opt)
end
-- use vstool to compile and enable vs_unicode_output @see https://github.com/xmake-io/xmake/issues/528
- return vstool.iorunv(compargv(self, sourcefile, objectfile, compflags, opt))
+ local program, argv = compargv(self, sourcefile, objectfile, compflags, opt)
+ return vstool.iorunv(program, argv, {envs = self:runenvs()})
end,
catch
{
diff --git a/xmake/modules/core/tools/link.lua b/xmake/modules/core/tools/link.lua
index 3bcbb238d..8d1f9083d 100644
--- a/xmake/modules/core/tools/link.lua
+++ b/xmake/modules/core/tools/link.lua
@@ -29,10 +29,10 @@ function init(self)
self:set("ldflags", "-nologo", "-dynamicbase", "-nxcompat")
-- init arflags
- self:set("arflags", "-nologo")
+ self:set("arflags", "-lib", "-nologo")
-- init shflags
- self:set("shflags", "-nologo")
+ self:set("shflags", "-dll", "-nologo")
-- init flags map
self:set("mapflags",
@@ -52,7 +52,7 @@ function get(self, name)
local values = self._INFO[name]
if name == "ldflags" or name == "arflags" or name == "shflags" then
-- switch architecture, @note does cache it in init() for generating vs201x project
- values = table.join(values, "-machine:" .. (config.arch() or "x86"))
+ values = table.join(values, "-machine:" .. (self:arch() or "x86"))
end
return values
end
@@ -108,7 +108,8 @@ function link(self, objectfiles, targetkind, targetfile, flags, opt)
function ()
-- use vstool to link and enable vs_unicode_output @see https://github.com/xmake-io/xmake/issues/528
- vstool.runv(linkargv(self, objectfiles, targetkind, targetfile, flags, opt))
+ local program, argv = linkargv(self, objectfiles, targetkind, targetfile, flags, opt)
+ vstool.runv(program, argv, {envs = self:runenvs()})
end,
catch
{
diff --git a/xmake/modules/private/tools/vstool.lua b/xmake/modules/private/tools/vstool.lua
index e632ed00f..c8f51b11b 100644
--- a/xmake/modules/private/tools/vstool.lua
+++ b/xmake/modules/private/tools/vstool.lua
@@ -31,10 +31,11 @@ function runv(program, argv, opt)
-- enable unicode output for vs toolchains, e.g. cl.exe, link.exe and etc.
-- @see https://github.com/xmake-io/xmake/issues/528
- local envs = {VS_UNICODE_OUTPUT = outfile:rawfd()}
+ opt.envs = opt.envs or {}
+ opt.envs.VS_UNICODE_OUTPUT = outfile:rawfd()
-- execute it
- local ok, syserrors = os.execv(program, argv, table.join(opt, {try = true, stdout = outfile, stderr = errpath, envs = envs}))
+ local ok, syserrors = os.execv(program, argv, table.join(opt, {try = true, stdout = outfile, stderr = errpath}))
-- close outfile first
outfile:close()
@@ -93,10 +94,11 @@ function iorunv(program, argv, opt)
-- enable unicode output for vs toolchains, e.g. cl.exe, link.exe and etc.
-- @see https://github.com/xmake-io/xmake/issues/528
- local envs = {VS_UNICODE_OUTPUT = outfile:rawfd()}
+ opt.envs = opt.envs or {}
+ opt.envs.VS_UNICODE_OUTPUT = outfile:rawfd()
-- run command
- local ok, syserrors = os.execv(program, argv, table.join(opt, {try = true, stdout = outfile, stderr = errpath, envs = envs}))
+ local ok, syserrors = os.execv(program, argv, table.join(opt, {try = true, stdout = outfile, stderr = errpath}))
-- get output and error data
outfile:close()
@@ -132,7 +134,7 @@ function iorunv(program, argv, opt)
errors = string.format("vstool.iorunv(%s), %s", cmd, syserrors and syserrors or "unknown reason")
end
end
-
+
-- raise errors
os.raise({errors = errors, stderr = errdata, stdout = outdata})
end