diff options
Diffstat (limited to 'lua/cmake/variants.lua')
-rw-r--r-- | lua/cmake/variants.lua | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/lua/cmake/variants.lua b/lua/cmake/variants.lua new file mode 100644 index 0000000..50254c8 --- /dev/null +++ b/lua/cmake/variants.lua @@ -0,0 +1,157 @@ +local config = require("cmake.config") +local utils = require("cmake.utils") + +local VariantConfig = {} + +VariantConfig.__index = VariantConfig + +local global_variant_subs = { + ["${workspaceFolder}"] = vim.loop.cwd(), + ["${userHome}"] = vim.loop.os_homedir(), +} + +local _configure_args = function(obj, build_directory) + local args = {} + if obj.generator then + table.insert(args, "-G " .. '"' .. obj.generator .. '"') + end + table.insert(args, "-B" .. build_directory) + if obj.buildType then + table.insert(args, "-DCMAKE_BUILD_TYPE=" .. obj.buildType) + end + if obj.linkage and string.lower(obj.linkage) == "static" then + table.insert(args, "-DCMAKE_BUILD_SHARED_LIBS=OFF") + elseif obj.linkage and string.lower(obj.linkage) == "shared" then + table.insert(args, "-DCMAKE_BUILD_SHARED_LIBS=ON") + end + for k, v in pairs(obj.settings or {}) do + table.insert(args, "-D" .. k .. "=" .. v) + end + table.insert(args, "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON") + return args +end + +local _configure_command = function(obj, configure_args) + local ret = {} + ret.cmd = config.cmake.cmake_path + ret.args = table.concat(configure_args, " ") + ret.env = vim.tbl_deep_extend("keep", obj.env, config.cmake.configure_environment, config.cmake.environment) + return ret +end + +local _build_args = function(obj, build_directory) + local args = { "--build" } + table.insert(args, build_directory) + if #obj.buildArgs ~= 0 then + for _, v in ipairs(obj.buildArgs) do + table.insert(args, v) + end + elseif #config.cmake.build_args ~= 0 then + for _, v in ipairs(config.cmake.build_args) do + table.insert(args, v) + end + end + if #obj.buildToolArgs ~= 0 or #config.cmake.build_tool_args ~= 0 then + table.insert(args, "--") + if #obj.buildToolArgs ~= 0 then + for _, v in ipairs(obj.buildToolArgs) do + table.insert(args, v) + end + elseif #config.cmake.build_tool_args ~= 0 then + for _, v in ipairs(config.cmake.build_tool_args) do + table.insert(args, v) + end + end + end + return args +end + +local _build_command = function(obj, build_args) + local ret = {} + ret.cmd = config.cmake.cmake_path + ret.args = table.concat(build_args, " ") + ret.env = vim.tbl_deep_extend("keep", obj.env, config.cmake.configure_environment, config.cmake.environment) + return ret +end + +function VariantConfig:new(source) + local obj = {} + local subs = vim.tbl_deep_extend("keep", global_variant_subs, { ["${buildType}"] = source.buildType }) + + obj.name = source.short + obj.long_name = source.long + obj.directory = utils.substitude(config.cmake.build_directory, subs) + local configure_args = _configure_args(source, obj.directory) + obj.generate_command = _configure_command(source, configure_args) + local build_args = _build_args(source, obj.directory) + obj.build_options = { + { + name = source.short, + long_name = source.long, + command = _build_command(source, build_args), + }, + } + + setmetatable(obj, VariantConfig) + return obj +end + +function VariantConfig.cartesian_product(sets) + -- vim.notify("cartesian_product", vim.log.levels.INFO) + local function collapse_result(res) + -- vim.notify("collapse_result", vim.log.levels.INFO) + local ret = { + short = {}, + long = {}, + buildType = nil, + linkage = nil, + generator = nil, + buildArgs = {}, + buildToolArgs = {}, + settings = {}, + env = {}, + } + local is_default = true + for _, v in ipairs(res) do + if not v.default then + is_default = false + end + ret.short[#ret.short + 1] = v.short + ret.long[#ret.long + 1] = v.long + ret.buildType = v.buildType or ret.buildType + ret.linkage = v.linkage or ret.linkage + ret.generator = v.generator or ret.generator + ret.buildArgs = v.buildArgs or ret.buildArgs + ret.buildToolArgs = v.buildToolArgs or ret.buildToolArgs + for sname, sval in pairs(v.settings or {}) do + ret.settings[sname] = sval + end + for ename, eres in pairs(v.env or {}) do + ret.env[ename] = eres + end + end + -- vim.notify(vim.inspect(ret), vim.log.levels.INFO) + return VariantConfig:new(ret), is_default + end + local result = {} + local set_count = #sets + local function descend(depth) + for k, v in pairs(sets[depth].choices) do + if sets[depth].default ~= k then + result.default = false + end + result[depth] = v + result[depth].default = (k == sets[depth].default) + if depth == set_count then + coroutine.yield(collapse_result(result)) + else + descend(depth + 1) + end + end + end + return coroutine.wrap(function() + descend(1) + end) +end + +return VariantConfig |