diff options
| author | ruki <[email protected]> | 2020-06-23 22:37:44 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2020-06-23 22:37:44 +0800 |
| commit | c18d15eb89116a0f3ce96bd56f3ccf861849f6ec (patch) | |
| tree | 52b63db3274349f9a41872414208c7c30058cfd7 /xmake/modules | |
| parent | 53df324acd9c7432336a5894ceef578daa1ce38d (diff) | |
| parent | 18bded45c229f5580c13fc8b4afc5edb6f18819a (diff) | |
Merge pull request #857 from xmake-io/toolchain
Improve toolchain to support host and cross toolchains at same time
Diffstat (limited to 'xmake/modules')
36 files changed, 478 insertions, 98 deletions
diff --git a/xmake/modules/core/tools/ar.lua b/xmake/modules/core/tools/ar.lua index 576d40695..3e520f887 100644 --- a/xmake/modules/core/tools/ar.lua +++ b/xmake/modules/core/tools/ar.lua @@ -71,7 +71,8 @@ function link(self, objectfiles, targetkind, targetfile, flags) os.tryrm(targetfile) -- link it - os.runv(linkargv(self, objectfiles, targetkind, targetfile, flags)) + local program, argv = linkargv(self, objectfiles, targetkind, targetfile, flags) + os.runv(program, argv, {envs = self:runenvs()}) end -- extract the static library to object directory 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/gcc.lua b/xmake/modules/core/tools/gcc.lua index 04839ceaf..7896deab6 100644 --- a/xmake/modules/core/tools/gcc.lua +++ b/xmake/modules/core/tools/gcc.lua @@ -330,7 +330,8 @@ function link(self, objectfiles, targetkind, targetfile, flags) os.mkdir(path.directory(targetfile)) -- link it - os.runv(linkargv(self, objectfiles, targetkind, targetfile, flags)) + local program, argv = linkargv(self, objectfiles, targetkind, targetfile, flags) + os.runv(program, argv, {envs = self:runenvs()}) end -- has color diagnostics? @@ -424,7 +425,8 @@ function compile(self, sourcefile, objectfile, dependinfo, flags) end -- do compile - return os.iorunv(compargv(self, sourcefile, objectfile, compflags)) + local program, argv = compargv(self, sourcefile, objectfile, compflags) + return os.iorunv(program, argv, {envs = self:runenvs()}) end, catch { diff --git a/xmake/modules/core/tools/lib.lua b/xmake/modules/core/tools/lib.lua index 704fe406c..6c07e9d1f 100644 --- a/xmake/modules/core/tools/lib.lua +++ b/xmake/modules/core/tools/lib.lua @@ -28,7 +28,7 @@ function extract(self, libraryfile, objectdir) os.mkdir(objectdir) -- list object files - local objectfiles = vstool.iorunv(self:program(), {"-nologo", "-list", libraryfile}) + local objectfiles = vstool.iorunv(self:program(), {"-nologo", "-list", libraryfile}, {envs = self:runenvs()}) -- extrace all object files for _, objectfile in ipairs(objectfiles:split('\n')) do @@ -50,7 +50,7 @@ function extract(self, libraryfile, objectdir) end -- extract it - vstool.runv(self:program(), {"-nologo", "-extract:" .. objectfile, "-out:" .. outputfile, libraryfile}) + vstool.runv(self:program(), {"-nologo", "-extract:" .. objectfile, "-out:" .. outputfile, libraryfile}, {envs = self:runenvs()}) end end end diff --git a/xmake/modules/core/tools/link.lua b/xmake/modules/core/tools/link.lua index 3bcbb238d..10a242e6d 100644 --- a/xmake/modules/core/tools/link.lua +++ b/xmake/modules/core/tools/link.lua @@ -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 @@ -94,7 +94,16 @@ end function linkargv(self, objectfiles, targetkind, targetfile, flags, opt) opt = opt or {} local argv = table.join(flags, "-out:" .. targetfile, objectfiles) - return self:program(), opt.rawargs and argv or winos.cmdargv(argv) + if not opt.rawargs then + argv = winos.cmdargv(argv) + end + -- @note we cannot put -lib/-dll to @args.txt + if targetkind == "static" then + table.insert(argv, 1, "-lib") + elseif targetkind == "shared" then + table.insert(argv, 1, "-dll") + end + return self:program(), argv end -- link the target file @@ -108,7 +117,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/core/tools/ml.lua b/xmake/modules/core/tools/ml.lua index 4899b46c6..3d6fb7c18 100644 --- a/xmake/modules/core/tools/ml.lua +++ b/xmake/modules/core/tools/ml.lua @@ -91,12 +91,12 @@ function nf_includedir(self, dir) end -- make the compile arguments list -function _compargv1(self, sourcefile, objectfile, flags) +function compargv(self, sourcefile, objectfile, flags) return self:program(), table.join("-c", flags, "-Fo" .. os.args(objectfile), sourcefile) end -- compile the source file -function _compile1(self, sourcefile, objectfile, dependinfo, flags) +function compile(self, sourcefile, objectfile, dependinfo, flags) -- ensure the object directory os.mkdir(path.directory(objectfile)) @@ -105,7 +105,8 @@ function _compile1(self, sourcefile, objectfile, dependinfo, flags) { function () -- @note we need not uses vstool.runv to enable unicode output for ml.exe - os.runv(_compargv1(self, sourcefile, objectfile, flags)) + local program, argv = compargv(self, sourcefile, objectfile, flags) + os.runv(program, argv, {envs = self:runenvs()}) end, catch { @@ -125,23 +126,3 @@ function _compile1(self, sourcefile, objectfile, dependinfo, flags) } end --- make the compile arguments list -function compargv(self, sourcefiles, objectfile, flags) - - -- only support single source file now - assert(type(sourcefiles) ~= "table", "'object:sources' not support!") - - -- for only single source file - return _compargv1(self, sourcefiles, objectfile, flags) -end - --- compile the source file -function compile(self, sourcefiles, objectfile, dependinfo, flags) - - -- only support single source file now - assert(type(sourcefiles) ~= "table", "'object:sources' not support!") - - -- for only single source file - _compile1(self, sourcefiles, objectfile, dependinfo, flags) -end - diff --git a/xmake/modules/core/tools/rc.lua b/xmake/modules/core/tools/rc.lua index cdaaa6b49..a0379ca57 100644 --- a/xmake/modules/core/tools/rc.lua +++ b/xmake/modules/core/tools/rc.lua @@ -59,7 +59,8 @@ function compile(self, sourcefile, objectfile, dependinfo, flags) { function () -- @note we need not uses vstool.iorunv to enable unicode output for rc.exe - local outdata, errdata = os.iorunv(compargv(self, sourcefile, objectfile, flags)) + local program, argv = compargv(self, sourcefile, objectfile, flags) + local outdata, errdata = os.iorunv(program, argv, {envs = self:runenvs()}) return (outdata or "") .. (errdata or "") end, catch diff --git a/xmake/modules/detect/sdks/find_xcode.lua b/xmake/modules/detect/sdks/find_xcode.lua index d7eb2ddd7..a1ab709df 100644 --- a/xmake/modules/detect/sdks/find_xcode.lua +++ b/xmake/modules/detect/sdks/find_xcode.lua @@ -147,13 +147,19 @@ function main(sdkdir, opt) local plat = opt.plat or config.get("plat") or "macosx" local arch = opt.arch or config.get("arch") or "x86_64" + -- get xcode sdk version + local xcode_sdkver = (plat == config.plat()) and config.get("xcode_sdkver") + if not xcode_sdkver then + xcode_sdkver = config.get("xcode_sdkver_" .. plat) + end + -- find xcode - local xcode = _find_xcode(sdkdir or config.get("xcode") or global.get("xcode") or config.get("sdk"), opt.sdkver or config.get("xcode_sdkver"), plat, arch) + local xcode = _find_xcode(sdkdir or config.get("xcode") or global.get("xcode"), opt.sdkver or xcode_sdkver, plat, arch) if xcode and xcode.sdkdir then -- save to config config.set("xcode", xcode.sdkdir, {force = true, readonly = true}) - config.set("xcode_sdkver", xcode.sdkver, {force = true, readonly = true}) + config.set("xcode_sdkver_" .. plat, xcode.sdkver, {force = true, readonly = true}) config.set("xcode_codesign_identity", xcode.codesign_identity, {force = true, readonly = true}) config.set("xcode_mobile_provision", xcode.mobile_provision, {force = true, readonly = true}) @@ -166,7 +172,7 @@ function main(sdkdir, opt) else cprint("checking for the Codesign Identity of Xcode ... ${color.nothing}${text.nothing}") end - if is_plat("iphoneos") then + if plat == "iphoneos" then if xcode.mobile_provision then cprint("checking for the Mobile Provision of Xcode ... ${color.success}%s", xcode.mobile_provision) else diff --git a/xmake/modules/detect/tools/cl/features.lua b/xmake/modules/detect/tools/cl/features.lua index 976085659..fb4c98cca 100644 --- a/xmake/modules/detect/tools/cl/features.lua +++ b/xmake/modules/detect/tools/cl/features.lua @@ -36,8 +36,8 @@ function _get_macro_defines(snippets, extension, opt) local defines = try { function () - os.runv(opt.program, table.join(opt.flags or {}, {"-nologo", "-Fo" .. objectfile, sourcefile, "-link", "-out:" .. binaryfile})) - return os.iorunv(binaryfile) + os.runv(opt.program, table.join(opt.flags or {}, {"-nologo", "-Fo" .. objectfile, sourcefile, "-link", "-out:" .. binaryfile}), {envs = opt.envs}) + return os.iorunv(binaryfile, {}, {envs = opt.envs}) end } if defines then @@ -50,8 +50,6 @@ function _get_macro_defines(snippets, extension, opt) os.tryrm(sourcefile) os.tryrm(objectfile) os.tryrm(binaryfile) - - -- ok? return results end @@ -97,6 +95,7 @@ end function check_features(opt) -- check features with all extensions + opt = opt or {} local results = {} for extension, features in pairs(_g.features) do diff --git a/xmake/modules/detect/tools/cl/has_flags.lua b/xmake/modules/detect/tools/cl/has_flags.lua index 1d9deff3f..b5dabc737 100644 --- a/xmake/modules/detect/tools/cl/has_flags.lua +++ b/xmake/modules/detect/tools/cl/has_flags.lua @@ -44,7 +44,7 @@ function _check_from_arglist(flags, opt) -- get argument list allflags = {} - local arglist = os.iorunv(opt.program, {"-?"}) + local arglist = os.iorunv(opt.program, {"-?"}, {envs = opt.envs}) if arglist then for arg in arglist:gmatch("(/[%-%a%d]+)%s+") do allflags[arg:gsub("/", "-")] = true @@ -72,7 +72,7 @@ function _check_try_running(flags, opt) -- check it local errors = nil return try { function () - local _, errs = os.iorunv(opt.program, table.join("-c", "-nologo", flags, "-Fo" .. os.nuldev(), sourcefile)) + local _, errs = os.iorunv(opt.program, table.join("-c", "-nologo", flags, "-Fo" .. os.nuldev(), sourcefile), {envs = opt.envs}) if errs and #errs:trim() > 0 then return false, errs end diff --git a/xmake/modules/detect/tools/find_cl.lua b/xmake/modules/detect/tools/find_cl.lua index 48289cfbc..a6f5d2fa6 100644 --- a/xmake/modules/detect/tools/find_cl.lua +++ b/xmake/modules/detect/tools/find_cl.lua @@ -38,7 +38,7 @@ function main(opt) -- init options opt = opt or {} - opt.check = opt.check or function (program) os.run(program) end + opt.check = opt.check or function (program) os.runv(program, {}, {envs = opt.envs}) end -- find program local program = find_program(opt.program or "cl.exe", opt) diff --git a/xmake/modules/detect/tools/find_lib.lua b/xmake/modules/detect/tools/find_lib.lua index 9c5b4be74..653dca5bb 100644 --- a/xmake/modules/detect/tools/find_lib.lua +++ b/xmake/modules/detect/tools/find_lib.lua @@ -21,6 +21,7 @@ -- imports import("lib.detect.find_program") import("lib.detect.find_programver") +import("lib.detect.find_tool") -- find lib -- @@ -50,9 +51,11 @@ function main(opt) io.writefile(sourcefile, "int test(void)\n{return 0;}") -- check it - os.run("cl -c -Fo%s %s", objectfile, sourcefile) - os.run("link -lib -out:%s %s", libraryfile, objectfile) - verinfo = os.iorun("%s -list %s", program, libraryfile) + local cl = assert(find_tool("cl")) + local link = assert(find_tool("link")) + os.runv(cl.program, {"-c", "-Fo" .. objectfile, sourcefile}, {envs = opt.envs}) + os.runv(link.program, {"-lib", "-out:" .. libraryfile, objectfile}, {envs = opt.envs}) + verinfo = os.iorunv(program, {"-list", libraryfile}, {envs = opt.envs}) -- remove files os.rm(objectfile) diff --git a/xmake/modules/detect/tools/find_link.lua b/xmake/modules/detect/tools/find_link.lua index 71fba5323..5814cba09 100644 --- a/xmake/modules/detect/tools/find_link.lua +++ b/xmake/modules/detect/tools/find_link.lua @@ -21,6 +21,7 @@ -- imports import("lib.detect.find_program") import("lib.detect.find_programver") +import("lib.detect.find_tool") -- find link -- @@ -43,17 +44,20 @@ function main(opt) opt = opt or {} opt.check = opt.check or function (program) + -- find cl + local cl = assert(find_tool("cl", {envs = opt.envs})) + -- make an stub source file local binaryfile = os.tmpfile() .. ".exe" local objectfile = os.tmpfile() .. ".obj" local sourcefile = os.tmpfile() .. ".c" - -- main entry + -- compile sourcefile first io.writefile(sourcefile, "int main(int argc, char** argv)\n{return 0;}") + os.runv(cl.program, {"-c", "-Fo" .. objectfile, sourcefile}, {envs = opt.envs}) - -- check it - os.run("cl -c -Fo%s %s", objectfile, sourcefile) - verinfo = os.iorun("%s -out:%s %s", program, binaryfile, objectfile) + -- do link + verinfo = os.iorunv(program, {"-lib", "-out:" .. binaryfile, objectfile}, {envs = opt.envs}) -- remove files os.rm(objectfile) diff --git a/xmake/modules/detect/tools/find_ml.lua b/xmake/modules/detect/tools/find_ml.lua index dda0da3e1..c5da1eaee 100644 --- a/xmake/modules/detect/tools/find_ml.lua +++ b/xmake/modules/detect/tools/find_ml.lua @@ -38,7 +38,7 @@ function main(opt) -- init options opt = opt or {} - opt.check = opt.check or function (program) os.run(program) end + opt.check = opt.check or function (program) os.runv(program, {}, {envs = opt.envs}) end -- find program local program = find_program(opt.program or "ml.exe", opt) @@ -46,7 +46,7 @@ function main(opt) -- find program version local version = nil if program and opt and opt.version then - opt.command = opt.command or function () local _, info = os.iorun(program); return info end + opt.command = opt.command or function () local _, info = os.iorunv(program, {}, {envs = opt.envs}); return info end opt.parse = opt.parse or function (output) return output:match("Version (%d+%.?%d*%.?%d*.-)%s") end version = find_programver(program, opt) end diff --git a/xmake/modules/detect/tools/find_ml64.lua b/xmake/modules/detect/tools/find_ml64.lua index bb2083ae7..f446fbeeb 100644 --- a/xmake/modules/detect/tools/find_ml64.lua +++ b/xmake/modules/detect/tools/find_ml64.lua @@ -38,7 +38,7 @@ function main(opt) -- init options opt = opt or {} - opt.check = opt.check or function (program) os.run(program) end + opt.check = opt.check or function (program) os.runv(program, {}, {envs = opt.envs}) end -- find program local program = find_program(opt.program or "ml64.exe", opt) @@ -46,7 +46,7 @@ function main(opt) -- find program version local version = nil if program and opt and opt.version then - opt.command = opt.command or function () local _, info = os.iorun(program); return info end + opt.command = opt.command or function () local _, info = os.iorunv(program, {}, {envs = opt.envs}); return info end opt.parse = opt.parse or function (output) return output:match("Version (%d+%.?%d*%.?%d*.-)%s") end version = find_programver(program, opt) end diff --git a/xmake/modules/detect/tools/find_msbuild.lua b/xmake/modules/detect/tools/find_msbuild.lua new file mode 100644 index 000000000..38d83c5ab --- /dev/null +++ b/xmake/modules/detect/tools/find_msbuild.lua @@ -0,0 +1,55 @@ +--!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 find_msbuild.lua +-- + +-- imports +import("lib.detect.find_program") +import("lib.detect.find_programver") + +-- find msbuild +-- +-- @param opt the argument options, e.g. {version = true} +-- +-- @return program, version +-- +-- @code +-- +-- local msbuild = find_msbuild() +-- +-- @endcode +-- +function main(opt) + + -- init options + opt = opt or {} + opt.check = "/version" + + -- find program + local program = find_program(opt.program or "msbuild.exe", opt) + + -- find program version + local version = nil + if program and opt and opt.version then + version = find_programver(program, opt) + end + + -- ok? + return program, version +end + diff --git a/xmake/modules/detect/tools/find_nmake.lua b/xmake/modules/detect/tools/find_nmake.lua new file mode 100644 index 000000000..dcb65f63c --- /dev/null +++ b/xmake/modules/detect/tools/find_nmake.lua @@ -0,0 +1,55 @@ +--!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 find_nmake.lua +-- + +-- imports +import("lib.detect.find_program") +import("lib.detect.find_programver") + +-- find nmake +-- +-- @param opt the argument options, e.g. {version = true} +-- +-- @return program, version +-- +-- @code +-- +-- local nmake = find_nmake() +-- +-- @endcode +-- +function main(opt) + + -- init options + opt = opt or {} + opt.check = "/?" + + -- find program + local program = find_program(opt.program or "nmake.exe", opt) + + -- find program version + local version = nil + if program and opt and opt.version then + version = find_programver(program, opt) + end + + -- ok? + return program, version +end + diff --git a/xmake/modules/detect/tools/gcc/features.lua b/xmake/modules/detect/tools/gcc/features.lua index 6f339f664..ad4cb3214 100644 --- a/xmake/modules/detect/tools/gcc/features.lua +++ b/xmake/modules/detect/tools/gcc/features.lua @@ -32,7 +32,7 @@ function _get_macro_defines(snippets, extension, opt) -- get defines local results = {} - local defines = try { function () return os.iorunv(opt.program, table.join(opt.flags or {}, {"-dM", "-E", sourcefile})) end } + local defines = try { function () return os.iorunv(opt.program, table.join(opt.flags or {}, {"-dM", "-E", sourcefile}), {envs = opt.envs}) end } if defines then for _, define in ipairs(defines:split("\n")) do local name = define:match("#define%s+(.-)%s+") diff --git a/xmake/modules/detect/tools/gcc/has_flags.lua b/xmake/modules/detect/tools/gcc/has_flags.lua index 28b4cd254..04956998b 100644 --- a/xmake/modules/detect/tools/gcc/has_flags.lua +++ b/xmake/modules/detect/tools/gcc/has_flags.lua @@ -37,11 +37,9 @@ function _islinker(flags, opt) end -- try running -function _try_running(...) - - local argv = {...} +function _try_running(program, argv, opt) local errors = nil - return try { function () os.runv(unpack(argv)); return true end, catch { function (errs) errors = (errs or ""):trim() end }}, errors + return try { function () os.runv(program, argv, opt); return true end, catch { function (errs) errors = (errs or ""):trim() end }}, errors end -- attempt to check it from the argument list @@ -67,7 +65,7 @@ function _check_from_arglist(flags, opt, islinker) -- get argument list allflags = {} - local arglist = os.iorunv(opt.program, {"--help"}) + local arglist = os.iorunv(opt.program, {"--help"}, {envs = opt.envs}) if arglist then for arg in arglist:gmatch("%s+(%-[%-%a%d]+)%s+") do allflags[arg] = true @@ -98,12 +96,12 @@ function _check_try_running(flags, opt, islinker) -- check flags for linker if islinker then - return _try_running(opt.program, table.join(flags, "-o", os.tmpfile(), sourcefile)) + return _try_running(opt.program, table.join(flags, "-o", os.tmpfile(), sourcefile), opt) end -- check flags for compiler -- @note we cannot use os.nuldev() as the output file, maybe run failed for some flags, e.g. --coverage - return _try_running(opt.program, table.join(flags, "-S", "-o", os.tmpfile(), sourcefile)) + return _try_running(opt.program, table.join(flags, "-S", "-o", os.tmpfile(), sourcefile), opt) end -- has_flags(flags)? diff --git a/xmake/modules/detect/tools/link/has_flags.lua b/xmake/modules/detect/tools/link/has_flags.lua index db93ba195..188d22976 100644 --- a/xmake/modules/detect/tools/link/has_flags.lua +++ b/xmake/modules/detect/tools/link/has_flags.lua @@ -20,13 +20,12 @@ -- imports import("lib.detect.cache") +import("lib.detect.find_tool") -- try running -function _try_running(...) - - local argv = {...} +function _try_running(program, argv, opt) local errors = nil - return try { function () os.runv(unpack(argv)); return true end, catch { function (errs) errors = (errs or ""):trim() end }}, errors + return try { function () os.runv(program, argv, opt); return true end, catch { function (errs) errors = (errs or ""):trim() end }}, errors end -- attempt to check it from the argument list @@ -55,7 +54,7 @@ function _check_from_arglist(flags, opt) local arglist = nil try { - function () os.runv(opt.program, {"-?"}) end, + function () os.runv(opt.program, {"-?"}, {envs = opt.envs}) end, catch { function (errors) arglist = errors end @@ -71,8 +70,6 @@ function _check_from_arglist(flags, opt) cacheinfo[flagskey] = allflags cache.save(key, cacheinfo) end - - -- ok? return allflags[flags[1]:gsub("/", "-"):lower()] end @@ -94,16 +91,15 @@ function _check_try_running(flags, opt) -- compile the source file local objectfile = os.tmpfile() .. ".obj" local binaryfile = os.tmpfile() .. ".exe" - os.runv("cl", {"-c", "-nologo", "-Fo" .. objectfile, sourcefile}) + local cl = find_tool("cl") + if cl then + os.runv(cl.program, {"-c", "-nologo", "-Fo" .. objectfile, sourcefile}, {envs = envs}) + end -- try link it - local ok, errors = _try_running(opt.program, table.join(flags, "-nologo", "-out:" .. binaryfile, objectfile)) - - -- remove files + local ok, errors = _try_running(opt.program, table.join(flags, "-nologo", "-out:" .. binaryfile, objectfile), {envs = opt.envs}) os.tryrm(objectfile) os.tryrm(binaryfile) - - -- ok? return ok, errors end diff --git a/xmake/modules/detect/tools/ml/has_flags.lua b/xmake/modules/detect/tools/ml/has_flags.lua index 98bbb2775..21641d91d 100644 --- a/xmake/modules/detect/tools/ml/has_flags.lua +++ b/xmake/modules/detect/tools/ml/has_flags.lua @@ -44,7 +44,7 @@ function _check_from_arglist(flags, opt) -- get argument list allflags = {} - local arglist = os.iorunv(opt.program, {"-?"}) + local arglist = os.iorunv(opt.program, {"-?"}, {envs = opt.envs}) if arglist then for arg in arglist:gmatch("(/[%-%a%d]+)%s+") do allflags[arg:gsub("/", "-")] = true @@ -72,7 +72,7 @@ function _check_try_running(flags, opt) -- check it local errors = nil return try { function () - local _, errs = os.iorunv(opt.program, table.join("-c", "-nologo", flags, "-Fo" .. os.nuldev(), sourcefile)) + local _, errs = os.iorunv(opt.program, table.join("-c", "-nologo", flags, "-Fo" .. os.nuldev(), sourcefile), {envs = opt.envs}) if errs and #errs:trim() > 0 then return false, errs end diff --git a/xmake/modules/devel/git/clone.lua b/xmake/modules/devel/git/clone.lua index 4285b392d..ef3aa769b 100644 --- a/xmake/modules/devel/git/clone.lua +++ b/xmake/modules/devel/git/clone.lua @@ -21,6 +21,7 @@ -- imports import("core.base.option") import("lib.detect.find_tool") +import("net.proxy") -- clone url -- @@ -75,6 +76,13 @@ function main(url, opt) table.insert(argv, path.translate(opt.outputdir)) end + -- use proxy? + local envs + local proxy_conf = proxy.get(url) + if proxy_conf then + envs = {ALL_PROXY = proxy_conf} + end + -- clone it - os.vrunv(git.program, argv) + os.vrunv(git.program, argv, {envs = envs}) end diff --git a/xmake/modules/devel/git/ls_remote.lua b/xmake/modules/devel/git/ls_remote.lua index a52e0d68d..1775567db 100644 --- a/xmake/modules/devel/git/ls_remote.lua +++ b/xmake/modules/devel/git/ls_remote.lua @@ -21,6 +21,7 @@ -- imports import("core.base.option") import("lib.detect.find_tool") +import("net.proxy") -- ls_remote to given branch, tag or commit -- @@ -55,8 +56,15 @@ function main(reftype, url) print("%s %s", git.program, os.args(argv)) end + -- use proxy? + local envs + local proxy_conf = proxy.get(url) + if proxy_conf then + envs = {ALL_PROXY = proxy_conf} + end + -- get refs - local data = os.iorunv(git.program, argv) + local data = os.iorunv(git.program, argv, {envs = envs}) -- get commmits and tags local refs = {} diff --git a/xmake/modules/devel/git/pull.lua b/xmake/modules/devel/git/pull.lua index 7eba74114..2320c51bd 100644 --- a/xmake/modules/devel/git/pull.lua +++ b/xmake/modules/devel/git/pull.lua @@ -21,6 +21,7 @@ -- imports import("core.base.option") import("lib.detect.find_tool") +import("net.proxy") -- pull remote commits -- @@ -63,8 +64,29 @@ function main(opt) oldir = os.cd(opt.repodir) end + -- use proxy? + local envs + local proxy_conf = proxy.get() + if proxy_conf then + -- get proxy configuration from the current remote url + local remoteinfo = try { function() return os.iorunv(git.program, {"remote", "-v"}) end } + if remoteinfo then + for _, line in ipairs(remoteinfo:split('\n', {plain = true})) do + local splitinfo = line:split("%s+") + if #splitinfo > 1 and splitinfo[1] == (opt.remote or "origin") then + local url = splitinfo[2] + if url then + proxy_conf = proxy.get(url) + end + break + end + end + end + envs = {ALL_PROXY = proxy_conf} + end + -- pull it - os.vrunv(git.program, argv) + os.vrunv(git.program, argv, {envs = envs}) -- leave repository directory if oldir then diff --git a/xmake/modules/lib/detect/features.lua b/xmake/modules/lib/detect/features.lua index 048ee85a6..9146e5da6 100644 --- a/xmake/modules/lib/detect/features.lua +++ b/xmake/modules/lib/detect/features.lua @@ -32,7 +32,7 @@ import("core.base.scheduler") -- @code -- local features = features("clang") -- local features = features("clang", {flags = "-O0", program = "xcrun -sdk macosx clang"}) --- local features = features("clang", {flags = {"-g", "-O0"}}) +-- local features = features("clang", {flags = {"-g", "-O0"}, envs = {PATH = ""}}) -- @endcode -- function main(name, opt) diff --git a/xmake/modules/lib/detect/find_tool.lua b/xmake/modules/lib/detect/find_tool.lua index 7e40c0b0e..83f543ebf 100644 --- a/xmake/modules/lib/detect/find_tool.lua +++ b/xmake/modules/lib/detect/find_tool.lua @@ -41,7 +41,7 @@ end -- @param name the tool name -- @param opt the options, e.g. {program = "xcrun -sdk macosx clang", pathes = {"/usr/bin"}, -- check = function (tool) os.run("%s -h", tool) end, version = true --- force = true, cachekey = "xxx"} +-- force = true, cachekey = "xxx", envs = {PATH = "xxx"}} -- -- @return {name = "", program = "", version = ""} or nil -- diff --git a/xmake/modules/lib/detect/has_flags.lua b/xmake/modules/lib/detect/has_flags.lua index 833bbcf65..4e4f3535a 100644 --- a/xmake/modules/lib/detect/has_flags.lua +++ b/xmake/modules/lib/detect/has_flags.lua @@ -62,14 +62,14 @@ function main(name, flags, opt) opt.programver = tool.version -- get tool platform - local plat = config.get("plat") or os.host() + local plat = opt.plat or config.get("plat") or os.host() -- get tool architecture -- -- some tools select arch by path environment, not be flags, e.g. cl.exe of msvc) -- so, it will affect the cache result -- - local arch = config.get("arch") or os.arch() + local arch = opt.arch or config.get("arch") or os.arch() -- init cache key local key = plat .. "_" .. arch .. "_" .. tool.program .. "_" .. (tool.version or "") .. "_" .. (opt.toolkind or "") .. "_" .. (opt.flagkind or "") .. "_" .. table.concat(opt.sysflags, " ") .. "_" .. opt.flagskey @@ -113,7 +113,7 @@ function main(name, flags, opt) if hasflags then result, errors = hasflags(checkflags, opt) else - result = try { function () os.runv(tool.program, checkflags); return true end, catch { function (errs) errors = errs end }} + result = try { function () os.runv(tool.program, checkflags, {envs = opt.envs}); return true end, catch { function (errs) errors = errs end }} end _g._checking = nil result = result or false diff --git a/xmake/modules/net/http/download.lua b/xmake/modules/net/http/download.lua index 6a292c20e..1267e24b8 100644 --- a/xmake/modules/net/http/download.lua +++ b/xmake/modules/net/http/download.lua @@ -21,6 +21,7 @@ -- imports import("core.base.option") import("lib.detect.find_tool") +import("net.proxy") -- get user agent function _get_user_agent() @@ -62,6 +63,13 @@ function _curl_download(tool, url, outputfile) table.insert(argv, "-fsSL") end + -- use proxy? + local proxy_conf = proxy.get(url) + if proxy_conf then + table.insert(argv, "-x") + table.insert(argv, proxy_conf) + end + -- set user-agent local user_agent = _get_user_agent() if user_agent then @@ -99,6 +107,23 @@ function _wget_download(tool, url, outputfile) os.mkdir(outputdir) end + -- use proxy? + local proxy_conf = proxy.get(url) + if proxy_conf then + table.insert(argv, "-e") + table.insert(argv, "use_proxy=yes") + table.insert(argv, "-e") + if url:startswith("http://") then + table.insert(argv, "http_proxy=" .. proxy_conf) + elseif url:startswith("https://") then + table.insert(argv, "https_proxy=" .. proxy_conf) + elseif url:startswith("ftp://") then + table.insert(argv, "ftp_proxy=" .. proxy_conf) + else + table.insert(argv, "http_proxy=" .. proxy_conf) + end + end + -- set user-agent local user_agent = _get_user_agent() if user_agent then diff --git a/xmake/modules/net/proxy.lua b/xmake/modules/net/proxy.lua new file mode 100644 index 000000000..0c7d308cb --- /dev/null +++ b/xmake/modules/net/proxy.lua @@ -0,0 +1,62 @@ +--!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 proxy.lua +-- + +-- imports +import("core.base.global") + +-- get proxy hosts +function _proxy_hosts() + local proxy_hosts = _g._PROXY_HOSTS + if proxy_hosts == nil then + proxy_hosts = global.get("proxy_hosts") + if proxy_hosts then + proxy_hosts = proxy_hosts:split(',', {plain = true}) + end + _g._PROXY_HOSTS = proxy_hosts or false + end + return proxy_hosts or nil +end + +-- convert host pattern to a lua pattern +function _host_pattern(pattern) + pattern = pattern:gsub("([%+%.%-%^%$%(%)%%])", "%%%1") + pattern = pattern:gsub("%*", "\001") + pattern = pattern:gsub("\001", ".*") + return pattern +end + +-- get proxy configuration from the given url, [protocol://]host[:port] +function get(url) + if url then + local host = url:match("://(.-)/") or url:match("@(.-):") + local proxy_hosts = _proxy_hosts() + if host and proxy_hosts then + host = host:lower() + for _, proxy_host in ipairs(proxy_hosts) do + proxy_host = proxy_host:lower() + if host == proxy_hosts or host:match(_host_pattern(proxy_host)) then + return global.get("proxy") + end + end + end + return + end + return global.get("proxy") +end diff --git a/xmake/modules/package/manager/conan/install_package.lua b/xmake/modules/package/manager/conan/install_package.lua index 201c50841..e1ad06df4 100644 --- a/xmake/modules/package/manager/conan/install_package.lua +++ b/xmake/modules/package/manager/conan/install_package.lua @@ -219,7 +219,7 @@ function main(name, opt) table.insert(argv, "compiler.runtime=" .. opt.vs_runtime) end elseif opt.plat == "iphoneos" then - local target_minver = config.get("target_minver") + local target_minver = config.get("target_minver_iphoneos") if target_minver and tonumber(target_minver) > 10 and (arch == "armv7" or arch == "armv7s" or arch == "x86") then target_minver = "10" -- iOS 10 is the maximum deployment target for 32-bit targets end diff --git a/xmake/modules/package/tools/cmake.lua b/xmake/modules/package/tools/cmake.lua index 7299f20b4..f35b489b4 100644 --- a/xmake/modules/package/tools/cmake.lua +++ b/xmake/modules/package/tools/cmake.lua @@ -20,7 +20,9 @@ -- imports import("core.base.option") +import("core.tool.toolchain") import("lib.detect.find_file") +import("lib.detect.find_tool") -- get configs function _get_configs(package, configs) @@ -118,10 +120,12 @@ function install(package, configs, opt) -- do build and install if package:is_plat("windows") then local slnfile = assert(find_file("*.sln", os.curdir()), "*.sln file not found!") - os.vrun("msbuild \"%s\" -nologo -t:Rebuild -p:Configuration=%s -p:Platform=%s", slnfile, package:debug() and "Debug" or "Release", package:is_arch("x64") and "x64" or "Win32") + local runenvs = toolchain.load("msvc", {plat = package:plat(), arch = package:arch()}):runenvs() + local msbuild = find_tool("msbuild", {envs = runenvs}) + os.vrunv(msbuild.program, {slnfile, "-nologo", "-t:Rebuild", "-p:Configuration=" .. (package:debug() and "Debug" or "Release"), "-p:Platform=" .. (package:is_arch("x64") and "x64" or "Win32")}, {envs = runenvs}) local projfile = os.isfile("INSTALL.vcxproj") and "INSTALL.vcxproj" or "INSTALL.vcproj" if os.isfile(projfile) then - os.vrun("msbuild \"%s\" /property:configuration=%s", projfile, package:debug() and "Debug" or "Release") + os.vrunv(msbuild.program, {projfile, "/property:configuration=" .. (package:debug() and "Debug" or "Release")}, {envs = runenvs}) os.trycp("install/lib", package:installdir()) -- perhaps only headers library os.cp("install/include", package:installdir()) else diff --git a/xmake/modules/package/tools/msbuild.lua b/xmake/modules/package/tools/msbuild.lua new file mode 100644 index 000000000..98263d5bf --- /dev/null +++ b/xmake/modules/package/tools/msbuild.lua @@ -0,0 +1,49 @@ +--!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 msbuild.lua +-- + +-- imports +import("core.base.option") +import("core.tool.toolchain") +import("lib.detect.find_tool") + +-- build package +function build(package, configs, opt) + + -- init options + opt = opt or {} + + -- pass configurations + local argv = {} + for name, value in pairs(configs) do + value = tostring(value):trim() + if value ~= "" then + if type(name) == "number" then + table.insert(argv, value) + else + table.insert(argv, name .. "=" .. value) + end + end + end + + -- do build + local runenvs = toolchain.load("msvc"):runenvs() + local msbuild = find_tool("msbuild", {envs = runenvs}) + os.vrunv(msbuild.program, argv, {envs = runenvs}) +end diff --git a/xmake/modules/package/tools/nmake.lua b/xmake/modules/package/tools/nmake.lua new file mode 100644 index 000000000..d948df039 --- /dev/null +++ b/xmake/modules/package/tools/nmake.lua @@ -0,0 +1,78 @@ +--!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 nmake.lua +-- + +-- imports +import("core.base.option") +import("core.project.config") +import("core.tool.toolchain") +import("lib.detect.find_tool") + +-- build package +function build(package, configs, opt) + + -- init options + opt = opt or {} + + -- pass configurations + local argv = {} + if option.get("verbose") then + table.insert(argv, "VERBOSE=1") + end + for name, value in pairs(configs) do + value = tostring(value):trim() + if value ~= "" then + if type(name) == "number" then + table.insert(argv, value) + else + table.insert(argv, name .. "=" .. value) + end + end + end + + -- do build + local runenvs = toolchain.load("msvc"):runenvs() + local nmake = find_tool("nmake", {envs = runenvs}) + os.vrunv(nmake.program, argv, {envs = runenvs}) +end + +-- install package +function install(package, configs) + + -- pass configurations + local argv = {"install"} + if option.get("verbose") then + table.insert(argv, "VERBOSE=1") + end + for name, value in pairs(configs) do + value = tostring(value):trim() + if value ~= "" then + if type(name) == "number" then + table.insert(argv, value) + else + table.insert(argv, name .. "=" .. value) + end + end + end + + -- do install + local runenvs = toolchain.load("msvc"):runenvs() + local nmake = find_tool("nmake", {envs = runenvs}) + os.vrunv(nmake.program, argv, {envs = runenvs}) +end diff --git a/xmake/modules/private/action/trybuild/cmake.lua b/xmake/modules/private/action/trybuild/cmake.lua index d5e0cbce2..684941c39 100644 --- a/xmake/modules/private/action/trybuild/cmake.lua +++ b/xmake/modules/private/action/trybuild/cmake.lua @@ -22,6 +22,7 @@ import("core.base.cli") import("core.base.option") import("core.project.config") +import("core.tool.toolchain") import("lib.detect.find_file") import("lib.detect.find_tool") @@ -76,7 +77,9 @@ function clean() if configfile then local oldir = os.cd(buildir) if is_plat("windows") then - os.vexec("msbuild \"%s\" -nologo -t:Clean -p:Configuration=%s -p:Platform=%s", configfile, is_mode("debug") and "Debug" or "Release", is_arch("x64") and "x64" or "Win32") + local runenvs = toolchain.load("msvc"):runenvs() + local msbuild = find_tool("msbuild", {envs = runenvs}) + os.vexecv(msbuild.program, {configfile, "-nologo", "-t:Clean", "-p:Configuration=" .. (is_mode("debug") and "Debug" or "Release"), "-p:Platform=" .. (is_arch("x64") and "x64" or "Win32")}, {envs = runenvs}) else os.vexec("make clean") end @@ -107,11 +110,13 @@ function build() -- do build if is_plat("windows") then + local runenvs = toolchain.load("msvc"):runenvs() + local msbuild = find_tool("msbuild", {envs = runenvs}) local slnfile = assert(find_file("*.sln", os.curdir()), "*.sln file not found!") - os.vexec("msbuild \"%s\" -nologo -t:Build -p:Configuration=%s -p:Platform=%s", slnfile, is_mode("debug") and "Debug" or "Release", is_arch("x64") and "x64" or "Win32") + os.vexecv(msbuild.program, {slnfile, "-nologo", "-t:Build", "-p:Configuration=" .. (is_mode("debug") and "Debug" or "Release"), "-p:Platform=" .. (is_arch("x64") and "x64" or "Win32")}, {envs = runenvs}) local projfile = os.isfile("INSTALL.vcxproj") and "INSTALL.vcxproj" or "INSTALL.vcproj" if os.isfile(projfile) then - os.vexec("msbuild \"%s\" /property:configuration=%s", projfile, is_mode("debug") and "Debug" or "Release") + os.vexecv(msbuild.program, {projfile, "/property:configuration=" .. (is_mode("debug") and "Debug" or "Release")}, {envs = runenvs}) end else local argv = {"-j" .. option.get("jobs")} diff --git a/xmake/modules/private/action/trybuild/msbuild.lua b/xmake/modules/private/action/trybuild/msbuild.lua index 0cd00fef9..e86830900 100644 --- a/xmake/modules/private/action/trybuild/msbuild.lua +++ b/xmake/modules/private/action/trybuild/msbuild.lua @@ -21,7 +21,9 @@ -- imports import("core.base.option") import("core.project.config") +import("core.tool.toolchain") import("lib.detect.find_file") +import("lib.detect.find_tool") -- detect build-system and configuration file function detect() @@ -32,7 +34,9 @@ end -- do clean function clean() - os.vexec("msbuild \"%s\" -nologo -t:Clean -p:Configuration=Release -p:Platform=%s", configfile, is_arch("x64") and "x64" or "Win32") + local runenvs = toolchain.load("msvc"):runenvs() + local msbuild = find_tool("msbuild", {envs = runenvs}) + os.vexecv(msbuild.program, {configfile, "-nologo", "-t:Clean", "-p:Configuration=Release", "-p:Platform=" .. (is_arch("x64") and "x64" or "Win32")}, {envs = runenvs}) end -- do build @@ -42,6 +46,9 @@ function build() assert(is_subhost(config.plat()), "msbuild: %s not supported!", config.plat()) -- do build - os.vexec("msbuild \"%s\" -nologo -t:Build -p:Configuration=Release -p:Platform=%s", configfile, is_arch("x64") and "x64" or "Win32") + local configfile = find_file("*.sln", os.curdir()) + local runenvs = toolchain.load("msvc"):runenvs() + local msbuild = find_tool("msbuild", {envs = runenvs}) + os.vexecv(msbuild.program, {configfile, "-nologo", "-t:Build", "-p:Configuration=Release", "-p:Platform=" .. (is_arch("x64") and "x64" or "Win32")}, {envs = runenvs}) cprint("${color.success}build ok!") end diff --git a/xmake/modules/private/tools/vstool.lua b/xmake/modules/private/tools/vstool.lua index e632ed00f..b53758838 100644 --- a/xmake/modules/private/tools/vstool.lua +++ b/xmake/modules/private/tools/vstool.lua @@ -31,10 +31,10 @@ 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 = table.join(opt.envs or {}, {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 +93,10 @@ 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 = table.join(opt.envs or {}, {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 +132,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 |
