diff options
| author | ruki <[email protected]> | 2020-10-07 22:53:15 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2020-10-07 22:53:15 +0800 |
| commit | d99942591281a478ae97e90163eb2bc83a7f5010 (patch) | |
| tree | cf0a3ee328238525de19e3d0c5e71b7daf5bf648 | |
| parent | 272052e6545c85c5fcc90cd7fd81177cbb431de1 (diff) | |
add ifort compiler
| -rw-r--r-- | xmake/modules/core/tools/ifort.lua | 115 | ||||
| -rw-r--r-- | xmake/modules/detect/sdks/find_iccenv.lua (renamed from xmake/modules/detect/sdks/find_intel.lua) | 10 | ||||
| -rw-r--r-- | xmake/modules/detect/sdks/find_ifortenv.lua | 135 | ||||
| -rw-r--r-- | xmake/modules/detect/tools/find_ifort.lua | 65 | ||||
| -rw-r--r-- | xmake/modules/detect/tools/ifort/has_flags.lua | 27 | ||||
| -rw-r--r-- | xmake/toolchains/icc/check.lua | 10 | ||||
| -rw-r--r-- | xmake/toolchains/icc/load.lua | 1 | ||||
| -rw-r--r-- | xmake/toolchains/ifort/check.lua | 73 | ||||
| -rw-r--r-- | xmake/toolchains/ifort/load.lua | 104 | ||||
| -rw-r--r-- | xmake/toolchains/ifort/xmake.lua | 35 |
10 files changed, 564 insertions, 11 deletions
diff --git a/xmake/modules/core/tools/ifort.lua b/xmake/modules/core/tools/ifort.lua new file mode 100644 index 000000000..5e94a8a25 --- /dev/null +++ b/xmake/modules/core/tools/ifort.lua @@ -0,0 +1,115 @@ +--!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 ifort.lua +-- + +if is_host("windows") then + + -- imports + import("core.project.config") + import("private.tools.vstool") + inherit("cl") + + -- get the property + function get(self, name) + local values = self._INFO[name] + if name == "fcldflags" or name == "fcarflags" or name == "fcshflags" then + -- switch architecture, @note does cache it in init() for generating vs201x project + values = table.join(values, "-machine:" .. (self:arch() or "x86")) + end + return values + end + + -- make the strip flag + function nf_strip(self, level) + -- @note we explicitly strip some useless code, because `/debug` may keep them + -- @see https://github.com/xmake-io/xmake/issues/907 + -- + local maps = + { + debug = "/opt:ref /opt:icf" + , all = "/opt:ref /opt:icf /ltcg" -- we enable /ltcg for optimize/smallest:/Gl + } + return maps[level] + end + + -- make the link flag + function nf_link(self, lib) + return lib .. ".lib" + end + + -- make the syslink flag + function nf_syslink(self, lib) + return nf_link(self, lib) + end + + -- make the linkdir flag + function nf_linkdir(self, dir) + return "-libpath:" .. os.args(path.translate(dir)) + end + + -- make the link arguments list + function linkargv(self, objectfiles, targetkind, targetfile, flags, opt) + opt = opt or {} + local argv = table.join(flags, "-out:" .. targetfile, objectfiles) + 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 + function link(self, objectfiles, targetkind, targetfile, flags, opt) + + -- ensure the target directory + os.mkdir(path.directory(targetfile)) + + try + { + function () + + -- use vstool to link and enable vs_unicode_output @see https://github.com/xmake-io/xmake/issues/528 + local program, argv = linkargv(self, objectfiles, targetkind, targetfile, flags, opt) + vstool.runv(program, argv, {envs = self:runenvs()}) + end, + catch + { + function (errors) + + -- use link/stdout as errors first from vstool.iorunv() + if type(errors) == "table" then + local errs = errors.stdout or "" + if #errs:trim() == 0 then + errs = errors.stderr or "" + end + errors = errs + end + os.raise(tostring(errors)) + end + } + } + end +else + inherit("gfortran") +end diff --git a/xmake/modules/detect/sdks/find_intel.lua b/xmake/modules/detect/sdks/find_iccenv.lua index f6edfaafd..9e5e3d3ae 100644 --- a/xmake/modules/detect/sdks/find_intel.lua +++ b/xmake/modules/detect/sdks/find_iccenv.lua @@ -15,14 +15,14 @@ -- Copyright (C) 2015-2020, TBOOX Open Source Group. -- -- @author ruki --- @file find_intel.lua +-- @file find_iccenv.lua -- -- imports import("lib.detect.find_file") import("lib.detect.find_tool") --- init vc variables +-- init icl variables local iclvars = {"path", "lib", "libpath", @@ -93,7 +93,7 @@ function _load_iclvars(iclvars_bat, arch, opt) return variables end --- find intel envirnoment on windows +-- find intel c/c++ envirnoment on windows function _find_intel_on_windows(opt) -- init options @@ -113,7 +113,7 @@ function _find_intel_on_windows(opt) end end --- find intel envirnoment on linux +-- find intel c/c++ envirnoment on linux function _find_intel_on_linux(opt) -- attempt to find the sdk directory @@ -125,7 +125,7 @@ function _find_intel_on_linux(opt) end end --- find intel environment +-- find intel c/c++ environment function main(opt) if is_host("windows") then return _find_intel_on_windows(opt) diff --git a/xmake/modules/detect/sdks/find_ifortenv.lua b/xmake/modules/detect/sdks/find_ifortenv.lua new file mode 100644 index 000000000..e3c60200f --- /dev/null +++ b/xmake/modules/detect/sdks/find_ifortenv.lua @@ -0,0 +1,135 @@ +--!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_ifortenv.lua +-- + +-- imports +import("lib.detect.find_file") +import("lib.detect.find_tool") + +-- init ifort variables +local ifortvars = {"path", + "lib", + "libpath", + "include", + "DevEnvdir", + "VSInstallDir", + "VCInstallDir", + "WindowsSdkDir", + "WindowsLibPath", + "WindowsSDKVersion", + "WindowsSdkBinPath", + "UniversalCRTSdkDir", + "UCRTVersion"} + +-- load ifortvars_bat environment variables +function _load_ifortvars(ifortvars_bat, arch, opt) + + -- make the genifortvars.bat + opt = opt or {} + local genifortvars_bat = os.tmpfile() .. "_genifortvars.bat" + local genifortvars_dat = os.tmpfile() .. "_genifortvars.txt" + local file = io.open(genifortvars_bat, "w") + file:print("@echo off") + file:print("call \"%s\" -arch %s > nul", ifortvars_bat, arch) + for idx, var in ipairs(ifortvars) do + file:print("echo " .. var .. " = %%" .. var .. "%% %s %s", idx == 1 and ">" or ">>", genifortvars_dat) + end + file:close() + + -- run genifortvars.bat + os.run(genifortvars_bat) + + -- load all envirnoment variables + local variables = {} + for _, line in ipairs((io.readfile(genifortvars_dat) or ""):split("\n")) do + local p = line:find('=', 1, true) + if p then + local name = line:sub(1, p - 1):trim() + local value = line:sub(p + 1):trim() + variables[name] = value + end + end + if not variables.path then + return + end + + -- remove some empty entries + for _, name in ipairs(ifortvars) do + if variables[name] and #variables[name]:trim() == 0 then + variables[name] = nil + end + end + + -- fix bin path for ia32 + if variables.path and arch == "ia32" then + variables.path = variables.path:gsub("windows\\bin\\intel64;", "windows\\bin\\intel64_ia32;") + end + + -- convert path/lib/include to PATH/LIB/INCLUDE + variables.PATH = variables.path + variables.LIB = variables.lib + variables.LIBPATH = variables.libpath + variables.INCLUDE = variables.include + variables.path = nil + variables.lib = nil + variables.include = nil + variables.libpath = nil + return variables +end + +-- find intel fortran envirnoment on windows +function _find_intel_on_windows(opt) + + -- init options + opt = opt or {} + + -- find ifortvars_bat.bat + local paths = {"$(env IFORT_COMPILER20)"} + local ifortvars_bat = find_file("bin/ifortvars.bat", paths) + if ifortvars_bat then + + -- load ifortvars_bat + local ifortvars_x86 = _load_ifortvars(ifortvars_bat, "ia32", opt) + local ifortvars_x64 = _load_ifortvars(ifortvars_bat, "intel64", opt) + + -- save results + return {ifortvars_bat = ifortvars_bat, ifortvars = {x86 = ifortvars_x86, x64 = ifortvars_x64}} + end +end + +-- find intel fortran envirnoment on linux +function _find_intel_on_linux(opt) + + -- attempt to find the sdk directory + local paths = {"/opt/intel/bin", "/usr/local/bin", "/usr/bin"} + local ifort = find_file("ifort", paths) + if ifort then + local sdkdir = path.directory(path.directory(ifort)) + return {sdkdir = sdkdir, bindir = path.directory(ifort), path.join(sdkdir, "include"), libdir = path.join(sdkdir, "lib")} + end +end + +-- find intel fortran environment +function main(opt) + if is_host("windows") then + return _find_intel_on_windows(opt) + else + return _find_intel_on_linux(opt) + end +end diff --git a/xmake/modules/detect/tools/find_ifort.lua b/xmake/modules/detect/tools/find_ifort.lua new file mode 100644 index 000000000..6f2d45a2d --- /dev/null +++ b/xmake/modules/detect/tools/find_ifort.lua @@ -0,0 +1,65 @@ +--!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_ifort.lua +-- + +-- imports +import("lib.detect.find_program") +import("lib.detect.find_programver") + +-- find ifort +-- +-- @param opt the argument options, e.g. {version = true} +-- +-- @return program, version +-- +-- @code +-- +-- local ifort = find_ifort() +-- local ifort, version, hintname = find_ifort({program = "ifort", version = true}) +-- +-- @endcode +-- +function main(opt) + + opt = opt or {} + if is_host("windows") then + -- find program + opt.check = opt.check or function (program) os.runv(program, {"/help"}, {envs = opt.envs}) end + local program = find_program(opt.program or "ifort.exe", opt) + + -- find program version + local version = nil + if program and opt and opt.version then + opt.command = opt.command or function () local _, info = os.iorunv(program, {"/help"}, {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 + return program, version + else + -- find program + local program = find_program(opt.program or "ifort", opt) + + -- find program version + local version = nil + if program and opt.version then + version = find_programver(program, opt) + end + return program, version + end +end diff --git a/xmake/modules/detect/tools/ifort/has_flags.lua b/xmake/modules/detect/tools/ifort/has_flags.lua new file mode 100644 index 000000000..38adcd260 --- /dev/null +++ b/xmake/modules/detect/tools/ifort/has_flags.lua @@ -0,0 +1,27 @@ +--!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 has_flags.lua +-- + +-- imports +if is_host("windows") then + inherit("detect.tools.cl.has_flags") +else + inherit("detect.tools.gfortran.has_flags") +end + diff --git a/xmake/toolchains/icc/check.lua b/xmake/toolchains/icc/check.lua index 4cbc9f5d2..7f8b04deb 100644 --- a/xmake/toolchains/icc/check.lua +++ b/xmake/toolchains/icc/check.lua @@ -21,7 +21,7 @@ -- imports import("core.base.option") import("core.project.config") -import("detect.sdks.find_intel") +import("detect.sdks.find_iccenv") import("lib.detect.find_tool") -- check intel on windows @@ -32,10 +32,10 @@ function _check_intel_on_windows(toolchain) return true end - -- find intel - local intel = find_intel() - if intel and intel.iclvars then - local iclvarsall = intel.iclvars + -- find intel c/c++ compiler environment + local iccenv = find_iccenv() + if iccenv and iccenv.iclvars then + local iclvarsall = iccenv.iclvars local iclenv = iclvarsall[toolchain:arch()] if iclenv and iclenv.PATH and iclenv.INCLUDE and iclenv.LIB then diff --git a/xmake/toolchains/icc/load.lua b/xmake/toolchains/icc/load.lua index c854b7b91..b3dbf589f 100644 --- a/xmake/toolchains/icc/load.lua +++ b/xmake/toolchains/icc/load.lua @@ -99,7 +99,6 @@ function _load_intel_on_linux(toolchain) end if march then toolchain:add("cxflags", march) - toolchain:add("mxflags", march) toolchain:add("asflags", march) toolchain:add("ldflags", march) toolchain:add("shflags", march) diff --git a/xmake/toolchains/ifort/check.lua b/xmake/toolchains/ifort/check.lua new file mode 100644 index 000000000..f87ea3d9e --- /dev/null +++ b/xmake/toolchains/ifort/check.lua @@ -0,0 +1,73 @@ +--!A cross-toolchain 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 check.lua +-- + +-- imports +import("core.base.option") +import("core.project.config") +import("detect.sdks.find_ifortenv") +import("lib.detect.find_tool") + +-- check intel on windows +function _check_intel_on_windows(toolchain) + + -- have been checked? + if config.get("__ifortvarsall") then + return true + end + + -- find intel fortran compiler environment + local ifortenv = find_ifortenv() + if ifortenv and ifortenv.ifortvars then + local ifortvarsall = ifortenv.ifortvars + local ifortenv = ifortvarsall[toolchain:arch()] + if ifortenv and ifortenv.PATH and ifortenv.INCLUDE and ifortenv.LIB then + + -- save ifortvars + config.set("__ifortvarsall", ifortvarsall) + + -- check compiler + local program = nil + local tool = find_tool("ifort.exe", {force = true, envs = ifortenv, version = true}) + if tool then + program = tool.program + end + if program then + cprint("checking for Intel Fortran Compiler (%s) ... ${color.success}${text.success}", toolchain:arch()) + return true + end + end + end +end + +-- check intel on linux +function _check_intel_on_linux(toolchain) + return find_tool("ifort") +end + +-- main entry +function main(toolchain) + if is_host("windows") then + return _check_intel_on_windows(toolchain) + else + return _check_intel_on_linux(toolchain) + end +end + + diff --git a/xmake/toolchains/ifort/load.lua b/xmake/toolchains/ifort/load.lua new file mode 100644 index 000000000..7144b62c4 --- /dev/null +++ b/xmake/toolchains/ifort/load.lua @@ -0,0 +1,104 @@ +--!A cross-toolchain 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 load.lua +-- + +-- imports +import("core.base.option") +import("core.project.config") + +-- add the given ifort environment +function _add_ifortenv(toolchain, name) + + -- get ifortvarsall + local ifortvarsall = config.get("__ifortvarsall") + if not ifortvarsall then + return + end + + -- get ifort environment for the current arch + local arch = toolchain:arch() + local ifortenv = ifortvarsall[arch] or {} + + -- get the paths for the ifort environment + local env = ifortenv[name] + if env then + toolchain:add("runenvs", name:upper(), path.splitenv(env)) + end +end + +-- load intel on windows +function _load_intel_on_windows(toolchain) + + -- set toolset + if toolchain:is_plat("windows") then + toolchain:set("toolset", "fc", "ifort.exe") + toolchain:set("toolset", "mrc", "rc.exe") + if toolchain:is_arch("x64") then + toolchain:set("toolset", "as", "ml64.exe") + else + toolchain:set("toolset", "as", "ml.exe") + end + toolchain:set("toolset", "fcld", "ifort.exe") + toolchain:set("toolset", "fcsh", "ifort.exe") + toolchain:set("toolset", "ar", "link.exe") + toolchain:set("toolset", "ex", "lib.exe") + else + toolchain:set("toolset", "fc", "ifort") + toolchain:set("toolset", "fcld", "ifort") + toolchain:set("toolset", "fcsh", "ifort") + end + + -- add ifort environments + _add_ifortenv(toolchain, "PATH") + _add_ifortenv(toolchain, "LIB") + _add_ifortenv(toolchain, "INCLUDE") + _add_ifortenv(toolchain, "LIBPATH") +end + +-- load intel on linux +function _load_intel_on_linux(toolchain) + + -- set toolset + toolchain:set("toolset", "fc", "ifort") + toolchain:set("toolset", "fcld", "ifort") + toolchain:set("toolset", "fcsh", "ifort") + + -- add march flags + local march + if toolchain:is_arch("x86_64", "x64") then + march = "-m64" + elseif toolchain:is_arch("i386", "x86") then + march = "-m32" + end + if march then + toolchain:add("fcflags", march) + toolchain:add("fcldflags", march) + toolchain:add("fcshflags", march) + end +end + +-- main entry +function main(toolchain) + if is_host("windows") then + return _load_intel_on_windows(toolchain) + else + return _load_intel_on_linux(toolchain) + end +end + diff --git a/xmake/toolchains/ifort/xmake.lua b/xmake/toolchains/ifort/xmake.lua new file mode 100644 index 000000000..4dc531baa --- /dev/null +++ b/xmake/toolchains/ifort/xmake.lua @@ -0,0 +1,35 @@ +--!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 xmake.lua +-- + +-- define toolchain +toolchain("ifort") + + -- set homepage + set_homepage("https://software.intel.com/content/www/us/en/develop/tools/compilers/fortran-compilers.html") + set_description("Intel Fortran Compiler") + + -- mark as standalone toolchain + set_kind("standalone") + + -- check toolchain + on_check("check") + + -- on load + on_load("load") |
