diff --git a/modules/codelite/codelite_project.lua b/modules/codelite/codelite_project.lua index b856ec45b6..7dd3d03a98 100755 --- a/modules/codelite/codelite_project.lua +++ b/modules/codelite/codelite_project.lua @@ -33,35 +33,33 @@ m.elements = {} m.ctools = { - gcc = "gnu gcc", - clang = "clang", - msc = "Visual C++", + [p.tools.gcc] = "gnu gcc", + [p.tools.clang] = "clang", + [p.tools.msc] = "Visual C++", } m.cxxtools = { - gcc = "gnu g++", - clang = "clang++", - msc = "Visual C++", + [p.tools.gcc] = "gnu g++", + [p.tools.clang] = "clang++", + [p.tools.msc] = "Visual C++", } function m.getcompilername(cfg) - local tool = _OPTIONS.cc or cfg.toolset or p.CLANG - - local toolset = p.tools[tool] + local toolset, version = p.tools.canonical(cfg.toolset) if not toolset then - error("Invalid toolset '" + (_OPTIONS.cc or cfg.toolset) + "'") + error("Invalid toolset '" + cfg.toolset + "'") end if p.languages.isc(cfg.language) then - return m.ctools[tool] + return m.ctools[toolset] elseif p.languages.iscpp(cfg.language) then - return m.cxxtools[tool] + return m.cxxtools[toolset] end end function m.getcompiler(cfg) - local toolset = p.tools[_OPTIONS.cc or cfg.toolset or p.CLANG] + local toolset, version = p.tools.canonical(cfg.toolset) if not toolset then - error("Invalid toolset '" + (_OPTIONS.cc or cfg.toolset) + "'") + error("Invalid toolset '" + cfg.toolset + "'") end return toolset end diff --git a/modules/gmake/_preload.lua b/modules/gmake/_preload.lua index 87920ac337..ea764ed645 100644 --- a/modules/gmake/_preload.lua +++ b/modules/gmake/_preload.lua @@ -15,7 +15,7 @@ trigger = "gmake", shortname = "GNU Make", description = "Generate GNU makefiles for POSIX, MinGW, and Cygwin", - toolset = "gcc", + toolset = iif(os.target() == p.MACOSX, "clang", "gcc"), valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib", "Utility", "Makefile", "None" }, valid_languages = { "C", "C++", "C#" }, diff --git a/modules/gmake/gmake_cpp.lua b/modules/gmake/gmake_cpp.lua index a31587ea80..a59662a5d7 100644 --- a/modules/gmake/gmake_cpp.lua +++ b/modules/gmake/gmake_cpp.lua @@ -138,7 +138,7 @@ -- identify the toolset used by this configurations (would be nicer if -- this were computed and stored with the configuration up front) - local toolset = p.tools[_OPTIONS.cc or cfg.toolset or "gcc"] + local toolset, version = p.tools.canonical(cfg.toolset or p.GCC) if not toolset then error("Invalid toolset '" .. cfg.toolset .. "'") end diff --git a/modules/gmake/gmake_makefile.lua b/modules/gmake/gmake_makefile.lua index e5c67bcd14..2e7112e1ef 100644 --- a/modules/gmake/gmake_makefile.lua +++ b/modules/gmake/gmake_makefile.lua @@ -46,7 +46,7 @@ -- identify the toolset used by this configurations (would be nicer if -- this were computed and stored with the configuration up front) - local toolset = p.tools[cfg.toolset or "gcc"] + local toolset, version = p.tools.canonical(cfg.toolset or p.GCC) if not toolset then error("Invalid toolset '" .. cfg.toolset .. "'") end diff --git a/modules/gmake/gmake_utility.lua b/modules/gmake/gmake_utility.lua index bb10205fc7..d68870af68 100644 --- a/modules/gmake/gmake_utility.lua +++ b/modules/gmake/gmake_utility.lua @@ -46,7 +46,7 @@ -- identify the toolset used by this configurations (would be nicer if -- this were computed and stored with the configuration up front) - local toolset = p.tools[cfg.toolset or "gcc"] + local toolset, version = p.tools.canonical(cfg.toolset or p.GCC) if not toolset then error("Invalid toolset '" .. cfg.toolset .. "'") end diff --git a/modules/gmake2/_preload.lua b/modules/gmake2/_preload.lua index b92151f66e..e1bb0b7a38 100644 --- a/modules/gmake2/_preload.lua +++ b/modules/gmake2/_preload.lua @@ -15,7 +15,7 @@ trigger = "gmake2", shortname = "Alternative GNU Make", description = "Generate GNU makefiles for POSIX, MinGW, and Cygwin", - toolset = "gcc", + toolset = iif(os.target() == p.MACOSX, "clang", "gcc"), valid_kinds = { "ConsoleApp", "WindowedApp", "StaticLib", "SharedLib", "Utility", "Makefile", "None" }, diff --git a/modules/gmake2/gmake2.lua b/modules/gmake2/gmake2.lua index 902c082f0f..e735497836 100644 --- a/modules/gmake2/gmake2.lua +++ b/modules/gmake2/gmake2.lua @@ -173,7 +173,7 @@ function gmake2.getToolSet(cfg) local default = iif(cfg.system == p.MACOSX, "clang", "gcc") - local toolset = p.tools[_OPTIONS.cc or cfg.toolset or default] + local toolset, version = p.tools.canonical(cfg.toolset or default) if not toolset then error("Invalid toolset '" .. cfg.toolset .. "'") end diff --git a/modules/gmake2/gmake2_makefile.lua b/modules/gmake2/gmake2_makefile.lua index 577e083e80..672a0c1202 100644 --- a/modules/gmake2/gmake2_makefile.lua +++ b/modules/gmake2/gmake2_makefile.lua @@ -52,7 +52,7 @@ -- identify the toolset used by this configurations (would be nicer if -- this were computed and stored with the configuration up front) - local toolset = p.tools[cfg.toolset or "gcc"] + local toolset, version = p.tools.canonical(cfg.toolset or p.GCC) if not toolset then error("Invalid toolset '" .. cfg.toolset .. "'") end diff --git a/modules/xcode/_preload.lua b/modules/xcode/_preload.lua index cefea8b6f8..49e07bc87b 100644 --- a/modules/xcode/_preload.lua +++ b/modules/xcode/_preload.lua @@ -69,7 +69,7 @@ -- Xcode always uses Mac OS X path and naming conventions - toolset = "clang", + toolset = "clang", -- TODO: os.target() == p.MACOSX and p.checkVersion(minOSVersion, "<10.7") -> gcc -- The capabilities of this action diff --git a/modules/xcode/xcode_common.lua b/modules/xcode/xcode_common.lua index b08122aeba..34cb331f93 100644 --- a/modules/xcode/xcode_common.lua +++ b/modules/xcode/xcode_common.lua @@ -278,16 +278,8 @@ -- function xcode.getToolSet(cfg) - local default = "clang" - local minOSVersion = project.systemversion(cfg) - if minOSVersion ~= nil - and cfg.system == p.MACOSX - and p.checkVersion(minOSVersion, "<10.7") - then - default = "gcc" - end - local toolset = p.tools[_OPTIONS.cc or cfg.toolset or default] + local toolset, version = p.tools.canonical(cfg.toolset) if not toolset then error("Invalid toolset '" .. cfg.toolset .. "'") end diff --git a/src/_premake_init.lua b/src/_premake_init.lua index 43afa56030..02532b7304 100644 --- a/src/_premake_init.lua +++ b/src/_premake_init.lua @@ -1799,6 +1799,10 @@ { "msc-v141", "Microsoft compiler (Visual Studio 2017)" }, { "msc-v142", "Microsoft compiler (Visual Studio 2019)" }, { "msc-v143", "Microsoft compiler (Visual Studio 2022)" }, + function (name) + local toolset, version = p.tools.canonical(name) + return toolset + end } } diff --git a/src/base/action.lua b/src/base/action.lua index 39dfcb4717..b6de9bfc11 100644 --- a/src/base/action.lua +++ b/src/base/action.lua @@ -293,6 +293,8 @@ if not valid_tools then return true end + toolset = p.tools.normalize(toolset) + toolset = toolset:explode("-", true, 1)[1] -- get rid of version return table.contains(valid_tools, toolset) end diff --git a/src/base/help.lua b/src/base/help.lua index eb5142c055..9a693582bb 100644 --- a/src/base/help.lua +++ b/src/base/help.lua @@ -51,12 +51,16 @@ printf(" --%-" .. length .. "s %s", trigger, description) if (option.allowed) then local function compareValue(a, b) + if type(a) == "function" then return false end + if type(b) == "function" then return true end return a[1] < b[1] end table.sort(option.allowed, compareValue) for _, value in ipairs(option.allowed) do - printf(" %-" .. length-1 .. "s %s", value[1], value[2]) + if type(value) ~= "function" then + printf(" %-" .. length-1 .. "s %s", value[1], value[2]) + end end printf("") end diff --git a/src/base/option.lua b/src/base/option.lua index 2d0f1ead22..6bc6da82bb 100644 --- a/src/base/option.lua +++ b/src/base/option.lua @@ -160,7 +160,12 @@ if opt.allowed then local found = false for _, match in ipairs(opt.allowed) do - if match[1] == value then + if type(match) == "function" then + if match(value) then + found = true + break + end + elseif match[1] == value then found = true break end diff --git a/src/tools/clang.lua b/src/tools/clang.lua index 9dcc61809f..e9ccf0946e 100644 --- a/src/tools/clang.lua +++ b/src/tools/clang.lua @@ -340,13 +340,18 @@ clang.tools = { cc = "clang", cxx = "clang++", - ar = function(cfg) return iif(cfg.flags.LinkTimeOptimization, "llvm-ar", "ar") end + ar = function(cfg) return iif(cfg.flags.LinkTimeOptimization, "llvm-ar", "ar") end, + rc = "windres" } function clang.gettoolname(cfg, tool) + local toolset, version = p.tools.canonical(cfg.toolset or p.CLANG) local value = clang.tools[tool] if type(value) == "function" then value = value(cfg) end + if toolset == p.tools.clang and version ~= nil then + value = value .. "-" .. version + end return value end diff --git a/src/tools/gcc.lua b/src/tools/gcc.lua index 26f66828ff..e4aa12c2bb 100644 --- a/src/tools/gcc.lua +++ b/src/tools/gcc.lua @@ -675,8 +675,14 @@ } function gcc.gettoolname(cfg, tool) - if (cfg.gccprefix and gcc.tools[tool]) or tool == "rc" then - return (cfg.gccprefix or "") .. gcc.tools[tool] + local toolset, version = p.tools.canonical(cfg.toolset or p.GCC) + if toolset == p.tools.gcc and version ~= nil then + version = "-" .. version + else + version = "" + end + if ((cfg.gccprefix or version ~= "") and gcc.tools[tool]) or tool == "rc" then + return (cfg.gccprefix or "") .. gcc.tools[tool] .. version end return nil end diff --git a/tests/base/test_option.lua b/tests/base/test_option.lua index c3181839c2..1ece48e873 100644 --- a/tests/base/test_option.lua +++ b/tests/base/test_option.lua @@ -43,3 +43,27 @@ test.isnotnil(p.option.get("testopt2")) end + + -- Test allowed validators + + function suite.OptionValidationText() + newoption { + trigger = "TestOptValidation", + description = "Testing", + allowed = {{"value1", "desc1"}} + } + + test.istrue(p.option.validate( {testoptvalidation = "value1"})) + test.isfalse(p.option.validate( {testoptvalidation = "other"})) + end + + function suite.OptionValidationFunc() + newoption { + trigger = "TestOptValidation", + description = "Testing", + allowed = {function(text) return text == "OK" end} + } + + test.istrue(p.option.validate( {testoptvalidation = "OK"})) + test.isfalse(p.option.validate( {testoptvalidation = "KO"})) + end diff --git a/tests/tools/test_clang.lua b/tests/tools/test_clang.lua index 875733fa61..9b628eba5b 100644 --- a/tests/tools/test_clang.lua +++ b/tests/tools/test_clang.lua @@ -27,6 +27,27 @@ end +-- +-- Check the selection of tools based on the target system. +-- + + function suite.tools_onDefaults() + prepare() + test.isequal("clang", clang.gettoolname(cfg, "cc")) + test.isequal("clang++", clang.gettoolname(cfg, "cxx")) + test.isequal("ar", clang.gettoolname(cfg, "ar")) + test.isequal("windres", clang.gettoolname(cfg, "rc")) + end + + function suite.tools_forVersion() + toolset "clang-16" + prepare() + test.isequal("clang-16", clang.gettoolname(cfg, "cc")) + test.isequal("clang++-16", clang.gettoolname(cfg, "cxx")) + test.isequal("ar-16", clang.gettoolname(cfg, "ar")) + test.isequal("windres-16", clang.gettoolname(cfg, "rc")) + end + -- -- Check Mac OS X deployment target flags -- diff --git a/tests/tools/test_gcc.lua b/tests/tools/test_gcc.lua index 26a0fb9c2e..fcc085511d 100644 --- a/tests/tools/test_gcc.lua +++ b/tests/tools/test_gcc.lua @@ -48,6 +48,14 @@ test.isequal("test-prefix-windres", gcc.gettoolname(cfg, "rc")) end + function suite.tools_forVersion() + toolset "gcc-16" + prepare() + test.isequal("gcc-16", gcc.gettoolname(cfg, "cc")) + test.isequal("g++-16", gcc.gettoolname(cfg, "cxx")) + test.isequal("ar-16", gcc.gettoolname(cfg, "ar")) + test.isequal("windres-16", gcc.gettoolname(cfg, "rc")) + end -- -- By default, the -MMD -MP are used to generate dependencies.