1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
local config = require("cmake.config")
local utils = require("cmake.utils")
local uv = vim.uv
local VariantConfig = {}
VariantConfig.__index = VariantConfig
local global_variant_subs = {
["${workspaceFolder}"] = uv.cwd(),
["${userHome}"] = uv.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 config.cmake.parallel_jobs then
table.insert(args, "-j " .. tostring(config.cmake.parallel_jobs))
end
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)
local function collapse_result(res)
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
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
|