summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2020-10-07 22:53:15 +0800
committerruki <[email protected]>2020-10-07 22:53:15 +0800
commitd99942591281a478ae97e90163eb2bc83a7f5010 (patch)
treecf0a3ee328238525de19e3d0c5e71b7daf5bf648
parent272052e6545c85c5fcc90cd7fd81177cbb431de1 (diff)
add ifort compiler
-rw-r--r--xmake/modules/core/tools/ifort.lua115
-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.lua135
-rw-r--r--xmake/modules/detect/tools/find_ifort.lua65
-rw-r--r--xmake/modules/detect/tools/ifort/has_flags.lua27
-rw-r--r--xmake/toolchains/icc/check.lua10
-rw-r--r--xmake/toolchains/icc/load.lua1
-rw-r--r--xmake/toolchains/ifort/check.lua73
-rw-r--r--xmake/toolchains/ifort/load.lua104
-rw-r--r--xmake/toolchains/ifort/xmake.lua35
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")