summaryrefslogtreecommitdiff
path: root/xmake/modules/core/tools/cl
diff options
context:
space:
mode:
authorruki <[email protected]>2025-01-25 00:59:17 +0800
committerruki <[email protected]>2025-01-25 00:59:17 +0800
commit35677f50e4eb8ecb5aabe70e6ce900e28fd0adc2 (patch)
treef88df0f22e606bc8bf4361f13059bd3cb00ab0ed /xmake/modules/core/tools/cl
parentd1b1492b07d370f9cf06414490fc489c1dda6ed8 (diff)
move has_flags.lua
Diffstat (limited to 'xmake/modules/core/tools/cl')
-rw-r--r--xmake/modules/core/tools/cl/cfeatures.lua49
-rw-r--r--xmake/modules/core/tools/cl/cxxfeatures.lua151
-rw-r--r--xmake/modules/core/tools/cl/features.lua140
-rw-r--r--xmake/modules/core/tools/cl/has_flags.lua119
4 files changed, 459 insertions, 0 deletions
diff --git a/xmake/modules/core/tools/cl/cfeatures.lua b/xmake/modules/core/tools/cl/cfeatures.lua
new file mode 100644
index 000000000..9b043f7e1
--- /dev/null
+++ b/xmake/modules/core/tools/cl/cfeatures.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-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file cfeatures.lua
+--
+
+-- set features
+function _set(feature, condition)
+ _g.features = _g.features or {}
+ _g.features[feature] = condition
+end
+
+-- get features
+function main()
+
+ -- init conditions
+ local msvc_minver = "_MSC_VER >= 1200"
+ local msvc_2005 = "_MSC_VER >= 1400"
+ local msvc_2010 = "_MSC_VER >= 1600"
+ local msvc_2019 = "_MSC_VER >= 1920"
+
+ -- set language standard supports
+ _set("c_std_89", msvc_2005)
+ _set("c_std_99", msvc_2019)
+
+ -- set features
+ _set("c_static_assert", msvc_2010)
+ _set("c_restrict", msvc_2005)
+ _set("c_variadic_macros", msvc_2005)
+ _set("c_function_prototypes", msvc_minver)
+
+ -- get features
+ return _g.features
+end
+
diff --git a/xmake/modules/core/tools/cl/cxxfeatures.lua b/xmake/modules/core/tools/cl/cxxfeatures.lua
new file mode 100644
index 000000000..c8b683e6f
--- /dev/null
+++ b/xmake/modules/core/tools/cl/cxxfeatures.lua
@@ -0,0 +1,151 @@
+--!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-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file cxxfeatures.lua
+--
+
+-- set features
+function _set(feature, condition)
+ _g.features = _g.features or {}
+ _g.features[feature] = condition
+end
+
+-- get features
+--
+-- Reference: http://msdn.microsoft.com/en-us/library/vstudio/hh567368.aspx
+-- http://blogs.msdn.com/b/vcblog/archive/2013/06/28/c-11-14-stl-features-fixes-and-breaking-changes-in-vs-2013.aspx
+-- http://blogs.msdn.com/b/vcblog/archive/2014/11/17/c-11-14-17-features-in-vs-2015-preview.aspx
+-- http://www.visualstudio.com/en-us/news/vs2015-preview-vs.aspx
+-- http://blogs.msdn.com/b/vcblog/archive/2015/04/29/c-11-14-17-features-in-vs-2015-rc.aspx
+-- http://blogs.msdn.com/b/vcblog/archive/2015/06/19/c-11-14-17-features-in-vs-2015-rtm.aspx
+-- https://docs.microsoft.com/en-us/cpp/overview/visual-cpp-language-conformance?view=msvc-160
+--
+-- porting from Modules/Compiler/MSVC-CXX-FeatureTests.cmake
+--
+function main()
+
+ -- init conditions
+ local msvc_minver = "_MSC_VER >= 1200"
+ local msvc_60 = "_MSC_VER >= 1200"
+ local msvc_70 = "_MSC_VER >= 1300"
+ local msvc_71 = "_MSC_VER >= 1310"
+ local msvc_2005 = "_MSC_VER >= 1400"
+ local msvc_2008 = "_MSC_VER >= 1500"
+ local msvc_2010 = "_MSC_VER >= 1600"
+ local msvc_2012 = "_MSC_VER >= 1700"
+ local msvc_2013 = "_MSC_VER >= 1800"
+ local msvc_2015 = "_MSC_VER >= 1900"
+ local msvc_2017 = "_MSC_VER >= 1910"
+ local msvc_2019 = "_MSC_VER >= 1920"
+ local msvc_2022 = "_MSC_VER >= 1930"
+
+ -- set language standard supports
+ _set("cxx_std_98", msvc_2005)
+ _set("cxx_std_11", msvc_2015)
+ _set("cxx_std_14", msvc_2017)
+ _set("cxx_std_17", msvc_2019)
+ _set("cxx_std_20", msvc_2022)
+
+ -- VS version 15 (not 2015) introduces support for aggregate initializers.
+ _set("cxx_aggregate_default_initializers", "_MSC_FULL_VER >= 190024406")
+
+ -- VS 2015 Update 2 introduces support for variable templates.
+ -- https://www.visualstudio.com/en-us/news/vs2015-update2-vs.aspx
+ _set("cxx_variable_templates", "_MSC_FULL_VER >= 190023918")
+
+ _set("cxx_alignas", msvc_2015)
+ _set("cxx_alignof", msvc_2015)
+ _set("cxx_attributes", msvc_2015)
+ _set("cxx_attribute_deprecated", msvc_2015)
+ _set("cxx_binary_literals", msvc_2015)
+ _set("cxx_constexpr", msvc_2015)
+ _set("cxx_decltype_auto", msvc_2015)
+ _set("cxx_digit_separators", msvc_2015)
+ _set("cxx_func_identifier", msvc_2015)
+ _set("cxx_nonstatic_member_init", msvc_2015)
+ _set("cxx_defaulted_move_initializers", msvc_2015)
+ _set("cxx_generic_lambdas", msvc_2015)
+ _set("cxx_inheriting_constructors", msvc_2015)
+ _set("cxx_inline_namespaces", msvc_2015)
+ _set("cxx_lambda_init_captures", msvc_2015)
+ _set("cxx_noexcept", msvc_2015)
+ _set("cxx_return_type_deduction", msvc_2015)
+ _set("cxx_sizeof_member", msvc_2015)
+ _set("cxx_thread_local", msvc_2015)
+ _set("cxx_unicode_literals", msvc_2015)
+ _set("cxx_unrestricted_unions", msvc_2015)
+ _set("cxx_user_literals", msvc_2015)
+ _set("cxx_reference_qualified_functions", msvc_2015)
+
+ -- "The copies and moves don't interact precisely like the Standard says they
+ -- should. For example, deletion of moves is specified to also suppress
+ -- copies, but Visual C++ in Visual Studio 2013 does not."
+ -- http://blogs.msdn.com/b/vcblog/archive/2014/11/17/c-11-14-17-features-in-vs-2015-preview.aspx
+ -- lists this as 'partial' in 2013
+ _set("cxx_deleted_functions", msvc_2015)
+
+ -- http://blogs.msdn.com/b/vcblog/archive/2014/11/17/c-11-14-17-features-in-vs-2015-preview.aspx
+ -- Note 1. While previous version of VisualStudio said they supported these
+ -- they silently produced bad code, and are now marked as having partial
+ -- support in previous versions. The footnote says the support will be complete
+ -- in msvc 2015, so support the feature for that version, assuming that is true.
+ -- The blog post also says that VS 2013 Update 3 generates an error in cases
+ -- that previously produced bad code.
+ _set("cxx_generalized_initializers", "_MSC_FULL_VER >= 180030723")
+
+ -- Microsoft now states they support contextual conversions in 2013 and above.
+ -- See footnote 6 at:
+ -- http://blogs.msdn.com/b/vcblog/archive/2014/11/17/c-11-14-17-features-in-vs-2015-preview.aspx
+ _set("cxx_contextual_conversions", msvc_2013)
+ _set("cxx_default_function_template_args", msvc_2013)
+ _set("cxx_defaulted_functions", msvc_2013)
+ _set("cxx_delegating_constructors", msvc_2013)
+ _set("cxx_explicit_conversions", msvc_2013)
+ _set("cxx_raw_string_literals", msvc_2013)
+ _set("cxx_uniform_initialization", msvc_2013)
+ _set("cxx_alias_templates", msvc_2013)
+
+ -- Support is documented, but possibly partly broken:
+ -- https://msdn.microsoft.com/en-us/library/hh567368.aspx
+ -- http://thread.gmane.org/gmane.comp.lib.boost.devel/244986/focus=245333
+ _set("cxx_variadic_templates", msvc_2013)
+
+ _set("cxx_enum_forward_declarations", msvc_2012)
+ _set("cxx_final", msvc_2012)
+ _set("cxx_range_for", msvc_2012)
+ _set("cxx_strong_enums", msvc_2012)
+
+ _set("cxx_auto_type", msvc_2010)
+ _set("cxx_decltype", msvc_2010)
+ _set("cxx_extended_friend_declarations", msvc_2010)
+ _set("cxx_extern_templates", msvc_2010)
+ _set("cxx_lambdas", msvc_2010)
+ _set("cxx_local_type_template_args", msvc_2010)
+ _set("cxx_long_long_type", msvc_2010)
+ _set("cxx_nullptr", msvc_2010)
+ _set("cxx_override", msvc_2010)
+ _set("cxx_right_angle_brackets", msvc_2010)
+ _set("cxx_rvalue_references", msvc_2010)
+ _set("cxx_static_assert", msvc_2010)
+ _set("cxx_template_template_parameters", msvc_2010)
+ _set("cxx_trailing_return_types", msvc_2010)
+ _set("cxx_variadic_macros", msvc_2010)
+
+ -- get features
+ return _g.features
+end
+
diff --git a/xmake/modules/core/tools/cl/features.lua b/xmake/modules/core/tools/cl/features.lua
new file mode 100644
index 000000000..0957fd7ed
--- /dev/null
+++ b/xmake/modules/core/tools/cl/features.lua
@@ -0,0 +1,140 @@
+--!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-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file features.lua
+--
+
+-- imports
+import("cfeatures")
+import("cxxfeatures")
+
+-- get macro defines
+function _get_macro_defines(snippets, extension, opt)
+
+ -- make an stub source file
+ local sourcefile = os.tmpfile() .. extension
+ local objectfile = sourcefile .. ".obj"
+ local binaryfile = sourcefile .. ".exe"
+ io.writefile(sourcefile, "#include <stdio.h>\n\nint main(int argc, char** argv)\n{\n" .. table.concat(table.wrap(snippets), "\n") .. "\nreturn 0;\n}\n")
+
+ -- get defines
+ local results = {}
+ local defines = try
+ {
+ function ()
+ 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
+ for _, define in ipairs(defines:split("\n")) do
+ results[define] = true
+ end
+ end
+
+ -- remove files
+ os.tryrm(sourcefile)
+ os.tryrm(objectfile)
+ os.tryrm(binaryfile)
+ return results
+end
+
+-- set feature with condition
+function _set_feature(feature, condition)
+
+ -- init features
+ _g.features = _g.features or {}
+
+ -- get feature kind
+ local kind = feature:match("^(%w-)_")
+ assert(kind, "unknown kind for the feature: %s", feature)
+
+ -- init language extensions
+ _g.extensions = _g.extensions or {c = ".c", cxx = ".cpp", objc = ".m", objcxx = ".mm"}
+
+ -- get extension
+ local extension = _g.extensions[kind]
+ assert(extension, "not supported kind for the feature: %s", feature)
+
+ -- make snippet
+ local snippet = format([[
+#if (%s)
+ printf("%s\n");
+#endif]], condition, feature)
+
+ -- init features with the given extension
+ local features = _g.features[extension] or {}
+ _g.features[extension] = features
+
+ -- set feature and snippet
+ features[feature] = snippet
+end
+
+-- set features
+function set_features(features)
+ for feature, condition in pairs(features) do
+ _set_feature(feature, condition)
+ end
+end
+
+-- check features
+function check_features(opt)
+
+ -- check features with all extensions
+ opt = opt or {}
+ local results = {}
+ for extension, features in pairs(_g.features) do
+
+ -- make snippets
+ local snippets = {}
+ for _, snippet in pairs(features) do
+ table.insert(snippets, snippet)
+ end
+
+ -- get defines
+ local defines = _get_macro_defines(snippets, extension, opt)
+
+ -- check features
+ for feature, _ in pairs(features) do
+ if defines[feature] then
+ results[feature] = true
+ end
+ end
+ end
+
+ -- ok?
+ return results
+end
+
+-- get features
+--
+-- @param opt the argument options, e.g. {toolname = "", program = "", programver = "", flags = {}}
+--
+-- @return the features
+--
+function main(opt)
+
+ -- set features for c
+ set_features(cfeatures())
+
+ -- set features for c++
+ set_features(cxxfeatures())
+
+ -- check features
+ return check_features(opt)
+end
+
diff --git a/xmake/modules/core/tools/cl/has_flags.lua b/xmake/modules/core/tools/cl/has_flags.lua
new file mode 100644
index 000000000..d174d84e2
--- /dev/null
+++ b/xmake/modules/core/tools/cl/has_flags.lua
@@ -0,0 +1,119 @@
+--!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-present, TBOOX Open Source Group.
+--
+-- @author ruki
+-- @file has_flags.lua
+--
+
+-- imports
+import("core.language.language")
+import("core.cache.global_detectcache")
+
+-- attempt to check it from known flags
+function _check_from_knownargs(flags, opt)
+ local flag = flags[1]:gsub("/", "-")
+ if flag:startswith("-D") or
+ flag:startswith("-U") or
+ flag:startswith("-I") then
+ return true
+ end
+end
+
+-- attempt to check it from the argument list
+function _check_from_arglist(flags, opt)
+ local key = "core.tools.cl.has_flags"
+ local flagskey = opt.program .. "_" .. (opt.programver or "")
+ local allflags = global_detectcache:get2(key, flagskey)
+ if not allflags then
+ allflags = {}
+ 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
+ end
+ end
+ global_detectcache:set2(key, flagskey, allflags)
+ global_detectcache:save()
+ end
+ local flag = flags[1]:gsub("/", "-")
+ if flag:startswith("-D") or flag:startswith("-I") then
+ return true
+ end
+ return allflags[flag]
+end
+
+-- get extension
+function _get_extension(opt)
+ return opt.flagkind == "cxxflags" and ".cpp" or (table.wrap(language.sourcekinds()[opt.toolkind or "cc"])[1] or ".c")
+end
+
+-- try running to check flags
+function _check_try_running(flags, opt)
+
+ -- make an stub source file
+ local snippet = opt.snippet or "int main(int argc, char** argv)\n{return 0;}\n"
+ local sourcefile = os.tmpfile("cl_has_flags:" .. snippet) .. _get_extension(opt)
+ if not os.isfile(sourcefile) then
+ io.writefile(sourcefile, snippet)
+ end
+
+ -- check it
+ local errors = nil
+ return try { function ()
+ local tmpdir = os.tmpdir()
+ local nuldev = os.nuldev()
+ local tmpfile
+ if not is_host("windows") then
+ tmpfile = os.tmpfile()
+ nuldev = tmpfile
+ end
+ local _, errs = os.iorunv(opt.program, table.join("-c", "-nologo", flags, "-Fo" .. nuldev, sourcefile),
+ {envs = opt.envs, curdir = tmpdir}) -- we need to switch to tmpdir to avoid generating some tmp files, e.g. /Zi -> vc140.pdb
+ if tmpfile then
+ os.tryrm(tmpfile)
+ end
+ if errs and #errs:trim() > 0 then
+ return false, errs
+ end
+ return true
+ end,
+ catch { function (errs) errors = errs end }
+ }, errors
+end
+
+-- has_flags(flags)?
+--
+-- @param opt the argument options, e.g. {toolname = "", program = "", programver = "", toolkind = "[cc|cxx|ld|ar|sh|gc|rc|dc|mm|mxx]"}
+--
+-- @return true or false
+--
+function main(flags, opt)
+
+ -- attempt to check it from the argument list
+ opt = opt or {}
+ if not opt.tryrun then
+ if _check_from_arglist(flags, opt) then
+ return true
+ end
+ if _check_from_knownargs(flags, opt) then
+ return true
+ end
+ end
+
+ -- try running to check it
+ return _check_try_running(flags, opt)
+end
+