summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2021-07-23 00:08:03 +0800
committerGitHub <[email protected]>2021-07-23 00:08:03 +0800
commit17b4d1f0f73ea69b47cf56be00f94dfa188c5b36 (patch)
tree5d9799ee97c421d966d2391c73eed9f135ab8a3e
parent4061f4d6627358f188bf00778fe296c967b9593e (diff)
parent6fddc9c0d0532e5f66be3e9713498638496ffe7f (diff)
Merge pull request #1527 from xmake-io/allowed
add allowed platforms, archs and modes
-rw-r--r--tests/apis/add_allowedxxx/.gitignore8
-rw-r--r--tests/apis/add_allowedxxx/src/main.cpp9
-rw-r--r--tests/apis/add_allowedxxx/xmake.lua83
-rw-r--r--xmake/actions/config/main.lua53
-rw-r--r--xmake/actions/config/menuconf.lua9
-rw-r--r--xmake/actions/config/xmake.lua337
-rw-r--r--xmake/core/base/option.lua2
-rw-r--r--xmake/core/project/deprecated/project.lua46
-rw-r--r--xmake/core/project/project.lua129
-rw-r--r--xmake/core/sandbox/modules/import/core/project/project.lua4
-rw-r--r--xmake/languages/c++/api.lua10
-rw-r--r--xmake/modules/private/detect/find_platform.lua63
-rw-r--r--xmake/plugins/project/vstudio/impl/vs201x.lua12
-rw-r--r--xmake/plugins/project/vsxmake/getinfo.lua12
14 files changed, 515 insertions, 262 deletions
diff --git a/tests/apis/add_allowedxxx/.gitignore b/tests/apis/add_allowedxxx/.gitignore
new file mode 100644
index 000000000..152105761
--- /dev/null
+++ b/tests/apis/add_allowedxxx/.gitignore
@@ -0,0 +1,8 @@
+# Xmake cache
+.xmake/
+build/
+
+# MacOS Cache
+.DS_Store
+
+
diff --git a/tests/apis/add_allowedxxx/src/main.cpp b/tests/apis/add_allowedxxx/src/main.cpp
new file mode 100644
index 000000000..7c435d251
--- /dev/null
+++ b/tests/apis/add_allowedxxx/src/main.cpp
@@ -0,0 +1,9 @@
+#include <iostream>
+
+using namespace std;
+
+int main(int argc, char** argv)
+{
+ cout << "hello world!" << endl;
+ return 0;
+}
diff --git a/tests/apis/add_allowedxxx/xmake.lua b/tests/apis/add_allowedxxx/xmake.lua
new file mode 100644
index 000000000..e2f1f1ad9
--- /dev/null
+++ b/tests/apis/add_allowedxxx/xmake.lua
@@ -0,0 +1,83 @@
+add_rules("mode.debug", "mode.release")
+
+set_defaultmode("releasedbg")
+set_defaultplat("linux")
+set_defaultarchs("macosx|arm64", "linux|i386", "armv7")
+
+set_allowedmodes("releasedbg", "debug")
+set_allowedplats("windows", "linux", "macosx")
+set_allowedarchs("macosx|arm64", "macosx|x86_64", "linux|i386", "linux|x86_64")
+
+target("test")
+ set_kind("binary")
+ add_files("src/*.cpp")
+
+--
+-- If you want to known more usage about xmake, please see https://xmake.io
+--
+-- ## FAQ
+--
+-- You can enter the project directory firstly before building project.
+--
+-- $ cd projectdir
+--
+-- 1. How to build project?
+--
+-- $ xmake
+--
+-- 2. How to configure project?
+--
+-- $ xmake f -p [macosx|linux|iphoneos ..] -a [x86_64|i386|arm64 ..] -m [debug|release]
+--
+-- 3. Where is the build output directory?
+--
+-- The default output directory is `./build` and you can configure the output directory.
+--
+-- $ xmake f -o outputdir
+-- $ xmake
+--
+-- 4. How to run and debug target after building project?
+--
+-- $ xmake run [targetname]
+-- $ xmake run -d [targetname]
+--
+-- 5. How to install target to the system directory or other output directory?
+--
+-- $ xmake install
+-- $ xmake install -o installdir
+--
+-- 6. Add some frequently-used compilation flags in xmake.lua
+--
+-- @code
+-- -- add debug and release modes
+-- add_rules("mode.debug", "mode.release")
+--
+-- -- add macro defination
+-- add_defines("NDEBUG", "_GNU_SOURCE=1")
+--
+-- -- set warning all as error
+-- set_warnings("all", "error")
+--
+-- -- set language: c99, c++11
+-- set_languages("c99", "c++11")
+--
+-- -- set optimization: none, faster, fastest, smallest
+-- set_optimize("fastest")
+--
+-- -- add include search directories
+-- add_includedirs("/usr/include", "/usr/local/include")
+--
+-- -- add link libraries and search directories
+-- add_links("tbox")
+-- add_linkdirs("/usr/local/lib", "/usr/lib")
+--
+-- -- add system link libraries
+-- add_syslinks("z", "pthread")
+--
+-- -- add compilation and link flags
+-- add_cxflags("-stdnolib", "-fno-strict-aliasing")
+-- add_ldflags("-L/usr/local/lib", "-lpthread", {force = true})
+--
+-- @endcode
+--
+
diff --git a/xmake/actions/config/main.lua b/xmake/actions/config/main.lua
index 68f8ab531..e1095c509 100644
--- a/xmake/actions/config/main.lua
+++ b/xmake/actions/config/main.lua
@@ -191,6 +191,52 @@ function _config_targets(targetname)
end
end
+-- find default mode
+function _find_default_mode()
+ local mode = config.mode()
+ if not mode then
+ mode = project.get("defaultmode")
+ if not mode then
+ mode = "release"
+ end
+ config.set("mode", mode)
+ end
+ return mode
+end
+
+-- check configs
+function _check_configs()
+ -- check allowed modes
+ local mode = config.mode()
+ local allowed_modes = project.allowed_modes()
+ if allowed_modes then
+ if not allowed_modes:has(mode) then
+ local allowed_modes_str = table.concat(allowed_modes:to_array(), ", ")
+ raise("`%s` is not a valid complation mode for this project, please use one of %s", mode, allowed_modes_str)
+ end
+ end
+
+ -- check allowed plats
+ local plat = config.plat()
+ local allowed_plats = project.allowed_plats()
+ if allowed_plats then
+ if not allowed_plats:has(plat) then
+ local allowed_plats_str = table.concat(allowed_plats:to_array(), ", ")
+ raise("`%s` is not a valid platform for this project, please use one of %s", plat, allowed_plats_str)
+ end
+ end
+
+ -- check allowed archs
+ local arch = config.arch()
+ local allowed_archs = project.allowed_archs(config.plat())
+ if allowed_archs then
+ if not allowed_archs:has(arch) then
+ local allowed_archs_str = table.concat(allowed_archs:to_array(), ", ")
+ raise("`%s` is not a valid complation arch for this project, please use one of %s", arch, allowed_archs_str)
+ end
+ end
+end
+
-- export configs
function _export_configs()
local exportfile = option.get("export")
@@ -309,6 +355,10 @@ force to build in current directory via run `xmake -P .`]], os.projectdir())
end
end
+ -- find default mode
+ local mode = _find_default_mode()
+ assert(mode == config.mode())
+
-- find default platform and save to configuration
local plat, arch = find_platform({global = true})
assert(plat == config.plat())
@@ -382,6 +432,9 @@ force to build in current directory via run `xmake -P .`]], os.projectdir())
config.dump()
end
+ -- check configs
+ _check_configs()
+
-- export configs
if option.get("export") then
_export_configs()
diff --git a/xmake/actions/config/menuconf.lua b/xmake/actions/config/menuconf.lua
index 5657b30db..2f8706e4e 100644
--- a/xmake/actions/config/menuconf.lua
+++ b/xmake/actions/config/menuconf.lua
@@ -235,18 +235,23 @@ function app:_basic_configs(cache)
local default = opt[4]
local kind = (opt[3] == "k" or type(default) == "boolean") and "boolean" or "string"
- -- get default platform
+ -- get default values
if name == "plat" then
default = find_platform()
elseif name == "arch" then
_, default = find_platform()
+ elseif name == "mode" then
+ default = project.get("defaultmode")
+ if not default then
+ default = "release"
+ end
end
-- choice option?
local values = opt.values
if values then
if type(values) == "function" then
- values = values()
+ values = values(false, {menuconf = true})
end
for idx, value in ipairs(values) do
if default == value then
diff --git a/xmake/actions/config/xmake.lua b/xmake/actions/config/xmake.lua
index 6b58698d6..67d0af595 100644
--- a/xmake/actions/config/xmake.lua
+++ b/xmake/actions/config/xmake.lua
@@ -18,201 +18,212 @@
-- @file xmake.lua
--
--- define task
-task("config")
-
- -- set category
- set_category("action")
+function _plat_values(complete, opt)
+ import("core.platform.platform")
+ import("core.base.hashset")
+ import("core.project.project")
- -- on run
- on_run("main")
-
- -- set menu
- set_menu {
- -- usage
- usage = "xmake config|f [options] [target]"
+ if not complete or not opt.arch then
+ local plats = try {function () return project.allowed_plats() end}
+ if plats then
+ return plats:to_array()
+ end
+ return platform.plats()
+ end
- -- description
- , description = "Configure the project."
+ -- arch has given, find all supported platforms
+ local plats = {}
+ for _, plat in ipairs(platform.plats()) do
+ local archs = hashset.from(platform.archs(plat))
+ if archs:has(opt.arch) then
+ table.insert(plats, plat)
+ end
+ end
+ return plats
+end
- -- xmake f
- , shortname = 'f'
+function _arch_values(complete, opt)
+ opt = opt or {}
+ if opt.helpmenu then
+ return
+ end
- -- options
- , options =
- {
- {'c', "clean", "k", nil , "Clean the cached configure and configure all again." }
- , {nil, "export", "kv", nil , "Export the current configuration to the given file."
- , " e.g."
- , " - xmake f -m debug -xxx=y --export=build/config.txt" }
- , {nil, "import", "kv", nil , "Import configuration from the given file."
- , " e.g."
- , " - xmake f -import=build/config.txt" }
- , {nil, "menu", "k", nil , "Configure project with a menu-driven user interface." }
- , {category = "."}
- , {'p', "plat", "kv", "auto" , "Compile for the given platform."
- , values = function (complete, opt)
+ -- imports
+ import("core.project.project")
+ import("core.platform.platform")
+ import("core.base.hashset")
- -- imports
- import("core.platform.platform")
- import("core.base.hashset")
+ -- get all platforms
+ local plats = try {function () return project.allowed_plats() end}
+ if plats then
+ plats = plats:to_array()
+ end
+ plats = plats or platform.plats()
- if not complete or not opt.arch then
- return platform.plats()
- end
+ -- get all architectures
+ local archset = hashset.new()
+ for _, plat in ipairs(opt.plat and { opt.plat } or plats) do
+ local archs = try {function () return project.allowed_archs(plat) end}
+ if archs then
+ archs = archs:to_array()
+ end
+ if not archs then
+ archs = platform.archs(plat)
+ end
+ if archs then
+ for _, arch in ipairs(archs) do
+ archset:insert(arch)
+ end
+ end
+ end
+ return archset:to_array()
+end
- -- arch has given, find all supported platforms
- local plats = {}
- for _, plat in ipairs(platform.plats()) do
- local archs = hashset.from(platform.archs(plat))
- if archs:has(opt.arch) then
- table.insert(plats, plat)
- end
- end
- return plats
- end }
- , {'a', "arch", "kv", "auto" , "Compile for the given architecture.",
- -- show the description of all architectures
- function ()
+function _arch_description()
+ import("core.project.project")
+ import("core.platform.platform")
- -- imports
- import("core.platform.platform")
+ -- get all platforms
+ local plats = try {function () return project.allowed_plats() end}
+ if plats then
+ plats = plats:to_array()
+ end
+ plats = plats or platform.plats()
- -- get all architectures
- local description = {}
- for i, plat in ipairs(platform.plats()) do
- local archs = platform.archs(plat)
- if archs then
- description[i] = " - " .. plat .. ":"
- for _, arch in ipairs(archs) do
- description[i] = description[i] .. " " .. arch
- end
- end
- end
- return description
- end
- , values = function (complete, opt)
- if not complete then return end
+ -- get all architectures
+ local description = {}
+ for i, plat in ipairs(plats) do
+ local archs = try {function () return project.allowed_archs(plat) end}
+ if archs then
+ archs = archs:to_array()
+ end
+ if not archs then
+ archs = platform.archs(plat)
+ end
+ if archs and #archs > 0 then
+ local desc = " - " .. plat .. ":"
+ for _, arch in ipairs(archs) do
+ desc = desc .. " " .. arch
+ end
+ table.insert(description, desc)
+ end
+ end
+ return description
+end
- -- imports
- import("core.platform.platform")
- import("core.base.hashset")
+function _mode_values(complete, opt)
+ import("core.project.project")
+ opt = opt or {}
+ local modes = try {function()
+ if opt.menuconf then
+ -- we cannot load target.mode in menuconf
+ local allowed_modes = project.allowed_modes()
+ if allowed_modes then
+ return allowed_modes:to_array()
+ end
+ else
+ return project.modes()
+ end
+ end}
+ if not modes then
+ modes = {"debug", "release"}
+ end
+ return modes
+end
- -- get all architectures
- local archset = hashset.new()
- for _, plat in ipairs(opt.plat and { opt.plat } or platform.plats()) do
- local archs = platform.archs(plat)
- if archs then
- for _, arch in ipairs(archs) do
- archset:insert(arch)
- end
- end
- end
- return archset:to_array()
- end }
- , {'m', "mode", "kv", "release" , "Compile for the given mode."
- , values = function (complete)
- if complete then
- local modes = (try { function()
- return import("core.project.project").modes()
- end }) or {"debug", "release"}
- return modes
- end
- end }
- , {'k', "kind", "kv", "static" , "Compile for the given target kind."
- , values = {"static", "shared", "binary"} }
- , {nil, "host", "kv", "$(host)" , "Set the current host environment." }
+function _target_values(complete, opt)
+ return import("private.utils.complete_helper.targets")(complete, opt)
+end
- -- package configuration
- , {category = "Package Configuration"}
- , {nil, "require", "kv", nil , "Require all dependent packages?"
- , values = function (complete)
- if complete then
- return {"yes", "no"}
- else
- return {"y: force to enable", "n: disable" }
- end
- end }
- , {nil, "pkg_searchdirs", "kv", nil , "The search directories of the remote package."
- , " e.g."
- , " - xmake f --pkg_searchdirs=/dir1" .. path.envsep() .. "/dir2"}
+function _toolchain_values(complete, opt)
+ if complete then
+ import("core.tool.toolchain")
+ return toolchain.list()
+ end
+end
- -- show project menu options
- , function ()
+function _project_menu_options()
+ import("core.project.menu")
+ return menu.options()
+end
- -- import project menu
- import("core.project.menu")
+function _language_menu_options()
+ import("core.language.menu")
+ return menu.options("config")
+end
- -- get project menu options
- return menu.options()
- end
+function _platform_menu_options()
+ import("core.platform.menu")
+ return menu.options("config")
+end
- , {category = "Cross Complation Configuration"}
- , {nil, "cross", "kv", nil, "Set cross toolchains prefix"
+task("config")
+ set_category("action")
+ on_run("main")
+ set_menu {
+ usage = "xmake config|f [options] [target]",
+ description = "Configure the project.",
+ shortname = 'f',
+ options = {
+ {'c', "clean", "k", nil , "Clean the cached configure and configure all again."},
+ {nil, "export", "kv", nil , "Export the current configuration to the given file."
+ , " e.g."
+ , " - xmake f -m debug -xxx=y --export=build/config.txt"},
+ {nil, "import", "kv", nil , "Import configuration from the given file."
+ , " e.g."
+ , " - xmake f -import=build/config.txt"},
+ {nil, "menu", "k", nil , "Configure project with a menu-driven user interface."},
+ {category = "."},
+ {'p', "plat", "kv", "auto" , "Compile for the given platform.", values = _plat_values},
+ {'a', "arch", "kv", "auto" , "Compile for the given architecture.", _arch_description, values = _arch_values},
+ {'m', "mode", "kv", "auto" , "Compile for the given mode.", values = _mode_values},
+ {'k', "kind", "kv", "static" , "Compile for the given target kind.", values = {"static", "shared", "binary"}},
+ {nil, "host", "kv", "$(host)" , "Set the current host environment."},
+ {category = "Package Configuration"},
+ {nil, "require", "kv", nil , "Require all dependent packages?", values = {"yes", "no"}},
+ {nil, "pkg_searchdirs", "kv", nil , "The search directories of the remote package."
+ , " e.g."
+ , " - xmake f --pkg_searchdirs=/dir1" .. path.envsep() .. "/dir2"},
+ _project_menu_options,
+ {category = "Cross Complation Configuration"},
+ {nil, "cross", "kv", nil, "Set cross toolchains prefix"
, "e.g."
, " - i386-mingw32-"
- , " - arm-linux-androideabi-" }
- , {nil, "target_os", "kv", nil, "Set target os only for cross-complation" }
- , {nil, "bin", "kv", nil, "Set cross toolchains bin directory"
+ , " - arm-linux-androideabi-"},
+ {nil, "target_os", "kv", nil, "Set target os only for cross-complation"},
+ {nil, "bin", "kv", nil, "Set cross toolchains bin directory"
, "e.g."
- , " - sdk/bin (/arm-linux-gcc ..)" }
- , {nil, "sdk", "kv", nil, "Set cross SDK directory"
+ , " - sdk/bin (/arm-linux-gcc ..)"},
+ {nil, "sdk", "kv", nil, "Set cross SDK directory"
, "e.g."
, " - sdk/bin"
, " - sdk/lib"
- , " - sdk/include" }
- , {nil, "toolchain", "kv", nil, "Set toolchain name"
+ , " - sdk/include"},
+ {nil, "toolchain", "kv", nil, "Set toolchain name"
, "e.g. "
, " - xmake f --toolchain=clang"
, " - xmake f --toolchain=[cross|llvm|sdcc ..] --sdk=/xxx"
, " - run `xmake show -l toolchains` to get all toolchains"
- , values = function (complete, opt)
- if complete then
- import("core.tool.toolchain")
- return toolchain.list()
- end
- end }
-
- -- show language menu options
- , function ()
-
- -- import language menu
- import("core.language.menu")
-
- -- get config menu options
- return menu.options("config")
- end
-
- -- show platform menu options
- , function ()
-
- -- import platform menu
- import("core.platform.menu")
-
- -- get config menu options
- return menu.options("config")
- end
-
- , {category = "Other Configuration"}
- , {nil, "debugger", "kv", "auto" , "Set debugger" }
- , {nil, "ccache", "kv", true , "Enable or disable the c/c++ compiler cache." }
- , {nil, "trybuild", "kv", nil , "Enable try-build mode and set the third-party buildsystem tool.",
+ , values = _toolchain_values},
+ _language_menu_options,
+ _platform_menu_options,
+ {category = "Other Configuration"},
+ {nil, "debugger", "kv", "auto" , "Set debugger"},
+ {nil, "ccache", "kv", true , "Enable or disable the c/c++ compiler cache."},
+ {nil, "trybuild", "kv", nil , "Enable try-build mode and set the third-party buildsystem tool.",
"e.g.",
" - xmake f --trybuild=auto; xmake",
" - xmake f --trybuild=autotools -p android --ndk=xxx; xmake",
"",
"the third-party buildsystems:"
- , values = {"auto", "make", "autotools", "cmake", "scons", "meson", "bazel", "ninja", "msbuild", "xcodebuild", "ndkbuild"}}
- , {nil, "tryconfigs", "kv", nil , "Set the extra configurations of the third-party buildsystem for the try-build mode.",
+ , values = {"auto", "make", "autotools", "cmake", "scons", "meson", "bazel", "ninja", "msbuild", "xcodebuild", "ndkbuild"}},
+ {nil, "tryconfigs", "kv", nil , "Set the extra configurations of the third-party buildsystem for the try-build mode.",
"e.g.",
- " - xmake f --trybuild=autotools --tryconfigs='--enable-shared=no'"}
- , {'o', "buildir", "kv", "build" , "Set build directory." }
-
- , {}
- , {nil, "target", "v" , nil , "Configure for the given target."
- , values = function (complete, opt) return import("private.utils.complete_helper.targets")(complete, opt) end }
- }
- }
+ " - xmake f --trybuild=autotools --tryconfigs='--enable-shared=no'"},
+ {'o', "buildir", "kv", "build" , "Set build directory."},
+ {},
+ {nil, "target", "v" , nil , "Configure for the given target."
+ , values = _target_values}}}
diff --git a/xmake/core/base/option.lua b/xmake/core/base/option.lua
index 539f3f637..6289cf05e 100644
--- a/xmake/core/base/option.lua
+++ b/xmake/core/base/option.lua
@@ -805,7 +805,7 @@ function option.show_options(options, taskname)
-- append values
local values = opt.values
if type(values) == "function" then
- values = values()
+ values = values(false, {helpmenu = true})
end
if values then
for _, value in ipairs(table.wrap(values)) do
diff --git a/xmake/core/project/deprecated/project.lua b/xmake/core/project/deprecated/project.lua
index 91a38106a..dceeac9ba 100644
--- a/xmake/core/project/deprecated/project.lua
+++ b/xmake/core/project/deprecated/project.lua
@@ -33,24 +33,6 @@ local platform = require("platform/platform")
local deprecated = require("base/deprecated")
local deprecated_interpreter = require("base/deprecated/interpreter")
--- set modes
-function deprecated_project._api_set_modes(interp, ...)
-
- -- get api function
- local apifunc = interp:api_func("set_modes")
- assert(apifunc)
-
- -- register api
- interp:api_register_builtin("set_modes", function (...)
-
- -- deprecated
- deprecated.add("add_rules(\"mode.debug\", \"mode.release\")", "set_modes(\"debug\", \"release\")")
-
- -- dispatch it
- apifunc(...)
- end)
-end
-
-- add_headers for target
function deprecated_project._api_target_add_headers(interp)
@@ -159,37 +141,9 @@ function deprecated_project._api_target_add_tools(interp)
end)
end
--- enable options?
-function deprecated_project._api_is_option(interp, ...)
-
- -- make values
- local values = ""
- for _, v in ipairs(table.join(...)) do
- if v and type(v) == "string" then
- if #values == 0 then
- values = v
- else
- values = values .. ", " .. v
- end
- end
- end
-
- -- deprecated
- deprecated.add("has_config(\"%s\")", "is_option(\"%s\")", values)
-
- -- done
- return config.has(...)
-end
-
-- register api
function deprecated_project.api_register(interp)
- -- register api: is_option() to root
- interp:api_register(nil, "is_option", deprecated_project._api_is_option)
-
- -- register api: set_modes() to root
- deprecated_project._api_set_modes(interp)
-
-- register api: add_headers() to target
deprecated_project._api_target_add_headers(interp)
diff --git a/xmake/core/project/project.lua b/xmake/core/project/project.lua
index 9bdb4ca4d..114b1557d 100644
--- a/xmake/core/project/project.lua
+++ b/xmake/core/project/project.lua
@@ -30,6 +30,7 @@ local utils = require("base/utils")
local table = require("base/table")
local global = require("base/global")
local process = require("base/process")
+local hashset = require("base/hashset")
local deprecated = require("base/deprecated")
local interpreter = require("base/interpreter")
local memcache = require("cache/memcache")
@@ -650,8 +651,13 @@ function project.apis()
{
-- set_xxx
"set_project"
- , "set_modes" -- TODO deprecated
, "set_description"
+ , "set_allowedmodes"
+ , "set_allowedplats"
+ , "set_allowedarchs"
+ , "set_defaultmode"
+ , "set_defaultplat"
+ , "set_defaultarchs"
-- add_xxx
, "add_requires"
, "add_requireconfs"
@@ -1079,20 +1085,6 @@ function project.mtimes()
return project.interpreter():mtimes()
end
--- get the project modes
-function project.modes()
- local modes = project.get("modes") or {}
- for _, target in pairs(table.wrap(project.targets())) do
- for _, rule in ipairs(target:orderules()) do
- local name = rule:name()
- if name:startswith("mode.") then
- table.insert(modes, name:sub(6))
- end
- end
- end
- return table.unique(modes)
-end
-
-- get the project menu
function project.menu()
@@ -1209,5 +1201,112 @@ function project.tmpfile(opt_or_key)
return path.join(project.tmpdir(opt), "_" .. (hash.uuid4(key):gsub("-", "")))
end
+-- get all modes
+function project.modes()
+ local modes
+ local allowed_modes = project.allowed_modes()
+ if allowed_modes then
+ modes = allowed_modes:to_array()
+ else
+ modes = {}
+ for _, target in pairs(table.wrap(project.targets())) do
+ for _, rule in ipairs(target:orderules()) do
+ local name = rule:name()
+ if name:startswith("mode.") then
+ table.insert(modes, name:sub(6))
+ end
+ end
+ end
+ modes = table.unique(modes)
+ end
+ return modes
+end
+
+-- get default architectures from the given platform
+--
+-- set_defaultarchs("linux|x86_64", "iphoneos|arm64")
+--
+function project.default_arch(plat)
+ local default_archs = project._memcache():get("defaultarchs")
+ if not default_archs then
+ default_archs = {}
+ for _, defaultarch in ipairs(table.wrap(project.get("defaultarchs"))) do
+ local splitinfo = defaultarch:split('|')
+ if #splitinfo == 2 then
+ default_archs[splitinfo[1]] = splitinfo[2]
+ elseif #splitinfo == 1 and not default_archs.default then
+ default_archs.default = defaultarch
+ end
+ end
+ project._memcache():set("defaultarchs", default_archs or false)
+ end
+ return default_archs[plat or "default"] or default_archs["default"]
+end
+
+-- get allowed modes
+--
+-- set_allowedmodes("releasedbg", "debug")
+--
+function project.allowed_modes()
+ local allowed_modes_set = project._memcache():get("allowedmodes")
+ if not allowed_modes_set then
+ local allowed_modes = table.wrap(project.get("allowedmodes"))
+ if #allowed_modes > 0 then
+ allowed_modes_set = hashset.from(allowed_modes)
+ end
+ project._memcache():set("allowedmodes", allowed_modes_set or false)
+ end
+ return allowed_modes_set or nil
+end
+
+-- get allowed platforms
+--
+-- set_allowedplats("windows", "mingw", "linux", "macosx")
+--
+function project.allowed_plats()
+ local allowed_plats_set = project._memcache():get("allowedplats")
+ if not allowed_plats_set then
+ local allowed_plats = table.wrap(project.get("allowedplats"))
+ if #allowed_plats > 0 then
+ allowed_plats_set = hashset.from(allowed_plats)
+ end
+ project._memcache():set("allowedplats", allowed_plats_set or false)
+ end
+ return allowed_plats_set or nil
+end
+
+-- get allowed architectures
+--
+-- set_allowedarchs("macosx|arm64", "macosx|x86_64", "linux|i386")
+--
+function project.allowed_archs(plat)
+ plat = plat or ""
+ local allowed_archs_set = project._memcache():get2("allowedarchs", plat)
+ if not allowed_archs_set then
+ local allowed_archs = table.wrap(project.get("allowedarchs"))
+ if #allowed_archs > 0 then
+ for _, allowed_arch in ipairs(allowed_archs) do
+ local splitinfo = allowed_arch:split('|')
+ local splitplat, splitarch
+ if #splitinfo == 2 then
+ splitplat = splitinfo[1]
+ splitarch = splitinfo[2]
+ elseif #splitinfo == 1 then
+ splitplat = ""
+ splitarch = allowed_arch
+ end
+ if plat == splitplat then
+ if not allowed_archs_set then
+ allowed_archs_set = hashset.new()
+ end
+ allowed_archs_set:insert(splitarch)
+ end
+ end
+ end
+ project._memcache():set2("allowedarchs", plat, allowed_archs_set or false)
+ end
+ return allowed_archs_set or nil
+end
+
-- return module: project
return project
diff --git a/xmake/core/sandbox/modules/import/core/project/project.lua b/xmake/core/sandbox/modules/import/core/project/project.lua
index dcd78b205..8e50dfb24 100644
--- a/xmake/core/sandbox/modules/import/core/project/project.lua
+++ b/xmake/core/sandbox/modules/import/core/project/project.lua
@@ -53,6 +53,10 @@ sandbox_core_project.rcfiles = project.rcfiles
sandbox_core_project.directory = project.directory
sandbox_core_project.name = project.name
sandbox_core_project.modes = project.modes
+sandbox_core_project.default_arch = project.default_arch
+sandbox_core_project.allowed_modes = project.allowed_modes
+sandbox_core_project.allowed_plats = project.allowed_plats
+sandbox_core_project.allowed_archs = project.allowed_archs
sandbox_core_project.mtimes = project.mtimes
sandbox_core_project.version = project.version
sandbox_core_project.required_package = project.required_package
diff --git a/xmake/languages/c++/api.lua b/xmake/languages/c++/api.lua
index e3e8e7041..e33580fc4 100644
--- a/xmake/languages/c++/api.lua
+++ b/xmake/languages/c++/api.lua
@@ -26,8 +26,6 @@
-- sigsetjmp{int a = 0; sigsetjmp((void*)a, a);}
--
function _funcinfo(func)
-
- -- parse name and code
local name, code = string.match(func, "(.+){(.+)}")
if code == nil then
local pos = func:find("%(")
@@ -39,8 +37,6 @@ function _funcinfo(func)
code = string.format("volatile void* p%s = (void*)&%s;", name, name)
end
end
-
- -- ok
return name:trim(), code
end
@@ -90,8 +86,7 @@ end
-- TODO add c functions, deprecated
function _api_add_cfuncs(interp, module, links, includes, ...)
-
- -- done
+ wprint("target.add_cfuncs is deprecated, please use option.add_cfuncs()")
for _, func in ipairs({...}) do
_api_add_cfunc(interp, module, nil, links, includes, func)
end
@@ -143,8 +138,7 @@ end
-- TODO add c++ functions, deprecated
function _api_add_cxxfuncs(interp, module, links, includes, ...)
-
- -- done
+ wprint("target.add_cxxfuncs is deprecated, please use option.add_cxxfuncs()")
for _, func in ipairs({...}) do
_api_add_cxxfunc(interp, module, nil, links, includes, func)
end
diff --git a/xmake/modules/private/detect/find_platform.lua b/xmake/modules/private/detect/find_platform.lua
index 590ff9b11..54f8a2182 100644
--- a/xmake/modules/private/detect/find_platform.lua
+++ b/xmake/modules/private/detect/find_platform.lua
@@ -20,13 +20,19 @@
-- imports
import("core.project.config")
+import("core.project.project")
import("detect.sdks.find_cross_toolchain")
-- find platform
function _find_plat(plat)
plat = plat or config.get("plat")
if not plat then
- plat = os.subhost()
+ if not plat then
+ plat = project.get("defaultplat")
+ end
+ if not plat then
+ plat = os.subhost()
+ end
if plat == "msys" then
local msystem = os.getenv("MSYSTEM")
if msystem and msystem:lower():find("mingw", 1, true) then
@@ -81,28 +87,33 @@ end
function _find_arch(plat, arch)
arch = arch or config.get("arch")
if not arch then
- if plat == "android" then
- arch = "armeabi-v7a"
- elseif plat == "iphoneos" or plat == "appletvos" then
- arch = "arm64"
- elseif plat == "watchos" then
- arch = "armv7k"
- elseif plat == "wasm" then
- arch = "wasm32"
- elseif plat == "mingw" then
- local mingw_chost = nil
- if is_subhost("msys") then
- mingw_chost = os.getenv("MINGW_CHOST")
- end
- if mingw_chost == "i686-w64-mingw32" then
- arch = "i386"
+ if not arch then
+ arch = project.default_arch(plat)
+ end
+ if not arch then
+ if plat == "android" then
+ arch = "armeabi-v7a"
+ elseif plat == "iphoneos" or plat == "appletvos" then
+ arch = "arm64"
+ elseif plat == "watchos" then
+ arch = "armv7k"
+ elseif plat == "wasm" then
+ arch = "wasm32"
+ elseif plat == "mingw" then
+ local mingw_chost = nil
+ if is_subhost("msys") then
+ mingw_chost = os.getenv("MINGW_CHOST")
+ end
+ if mingw_chost == "i686-w64-mingw32" then
+ arch = "i386"
+ else
+ arch = "x86_64"
+ end
+ elseif plat == "cross" then
+ arch = _find_arch_from_cross()
else
- arch = "x86_64"
+ arch = os.subarch()
end
- elseif plat == "cross" then
- arch = _find_arch_from_cross()
- else
- arch = os.subarch()
end
end
return arch
@@ -126,17 +137,19 @@ end
--
function main(opt)
- -- find plat and arch
+ -- find platform
opt = opt or {}
local plat = _find_plat(opt.plat)
- local arch = _find_arch(plat, opt.arch)
-
- -- save the local configuration if be global
if opt.global then
if not opt.plat and not config.get("plat") then
config.set("plat", plat)
cprint("checking for platform ... ${color.success}%s", plat)
end
+ end
+
+ -- find architecture
+ local arch = _find_arch(plat, opt.arch)
+ if opt.global then
if not opt.arch and not config.get("arch") then
config.set("arch", arch)
cprint("checking for architecture ... ${color.success}%s", arch)
diff --git a/xmake/plugins/project/vstudio/impl/vs201x.lua b/xmake/plugins/project/vstudio/impl/vs201x.lua
index a66761d4d..da0dd9317 100644
--- a/xmake/plugins/project/vstudio/impl/vs201x.lua
+++ b/xmake/plugins/project/vstudio/impl/vs201x.lua
@@ -212,7 +212,17 @@ function _make_vsinfo_archs()
end
else
-- we use it first if global set_arch("xx") is setted in xmake.lua
- vsinfo_archs = project.get("target.arch") or platform.archs()
+ vsinfo_archs = project.get("target.arch")
+ if not vsinfo_archs then
+ -- for set_allowedarchs()
+ local allowed_archs = project.allowed_archs(config.plat())
+ if allowed_archs then
+ vsinfo_archs = allowed_archs:to_array()
+ end
+ end
+ if not vsinfo_archs then
+ vsinfo_archs = platform.archs()
+ end
end
if not vsinfo_archs or #vsinfo_archs == 0 then
vsinfo_archs = { config.arch() }
diff --git a/xmake/plugins/project/vsxmake/getinfo.lua b/xmake/plugins/project/vsxmake/getinfo.lua
index 407e4cbe4..965e55028 100644
--- a/xmake/plugins/project/vsxmake/getinfo.lua
+++ b/xmake/plugins/project/vsxmake/getinfo.lua
@@ -262,7 +262,17 @@ function _make_vsinfo_archs()
end
else
-- we use it first if global set_arch("xx") is setted in xmake.lua
- vsinfo_archs = project.get("target.arch") or platform.archs()
+ vsinfo_archs = project.get("target.arch")
+ if not vsinfo_archs then
+ -- for set_allowedarchs()
+ local allowed_archs = project.allowed_archs(config.plat())
+ if allowed_archs then
+ vsinfo_archs = allowed_archs:to_array()
+ end
+ end
+ if not vsinfo_archs then
+ vsinfo_archs = platform.archs()
+ end
end
if not vsinfo_archs or #vsinfo_archs == 0 then
vsinfo_archs = { config.arch() }