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
160
|
--!A cross-toolchain 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, Xmake Open Source Community.
--
-- @author ruki
-- @file check.lua
--
-- imports
import("core.base.option")
import("core.project.config")
import("detect.sdks.find_vstudio")
import("lib.detect.find_tool")
-- attempt to check vs environment
function _check_vsenv(toolchain)
-- have been checked?
local vs = toolchain:config("vs") or config.get("vs")
if vs then
vs = tostring(vs)
end
local vcvars = toolchain:config("vcvars")
if vs and vcvars then
return vs
end
-- find vstudio
local vs_toolset = toolchain:config("vs_toolset") or config.get("vs_toolset")
local vs_sdkver = toolchain:config("vs_sdkver") or config.get("vs_sdkver")
local vstudio = find_vstudio({toolset = vs_toolset, sdkver = vs_sdkver})
if vstudio then
-- make order vsver
local vsvers = {}
for vsver, _ in pairs(vstudio) do
if not vs or vs ~= vsver then
table.insert(vsvers, vsver)
end
end
table.sort(vsvers, function (a, b) return tonumber(a) > tonumber(b) end)
if vs then
table.insert(vsvers, 1, vs)
end
-- get vcvarsall
for _, vsver in ipairs(vsvers) do
local vcvarsall = (vstudio[vsver] or {}).vcvarsall or {}
local vcvars = vcvarsall[toolchain:arch()]
if vcvars and vcvars.PATH and vcvars.INCLUDE and vcvars.LIB then
-- save vcvars
toolchain:config_set("vcvars", vcvars)
toolchain:config_set("vcarchs", table.orderkeys(vcvarsall))
toolchain:config_set("vs_toolset", vcvars.VCToolsVersion)
toolchain:config_set("vs_sdkver", vcvars.WindowsSDKVersion)
-- check compiler
local program = nil
local tool = find_tool("cl.exe", {force = true, envs = vcvars})
if tool then
program = tool.program
end
if program then
return vsver
end
end
end
end
end
-- check the visual studio
function _check_vstudio(toolchain)
local vs = _check_vsenv(toolchain)
if vs then
if toolchain:is_global() then
config.set("vs", vs, {force = true, readonly = true})
end
toolchain:config_set("vs", vs)
cprint("checking for Microsoft Visual Studio (%s) version ... ${color.success}%s", toolchain:arch(), vs)
else
cprint("checking for Microsoft Visual Studio (%s) version ... ${color.nothing}${text.nothing}", toolchain:arch())
end
return vs
end
function _check_vc_build_tools(toolchain, sdkdir)
local opt = {}
opt.sdkdir = sdkdir
opt.vs_toolset = toolchain:config("vs_toolset") or config.get("vs_toolset")
opt.vs_sdkver = toolchain:config("vs_sdkver") or config.get("vs_sdkver")
local vcvarsall = find_vstudio.find_build_tools(opt)
if not vcvarsall then
return
end
local vcvars = vcvarsall[toolchain:arch()]
if vcvars and vcvars.PATH and vcvars.INCLUDE and vcvars.LIB then
toolchain:config_set("vcvars", vcvars)
toolchain:config_set("vcarchs", table.orderkeys(vcvarsall))
toolchain:config_set("vs_toolset", vcvars.VCToolsVersion)
toolchain:config_set("vs_sdkver", vcvars.WindowsSDKVersion)
-- check compiler
local cl = find_tool("cl.exe", {force = true, envs = vcvars})
if cl then
cprint("checking for Microsoft C/C++ Compiler (%s) ... ${color.success}", toolchain:arch())
end
return vcvars
end
end
function main(toolchain)
-- only for windows or linux (msvc-wine)
if not is_host("windows", "linux") then
return
end
-- @see https://github.com/xmake-io/xmake/pull/679
local cc = path.basename(config.get("cc") or "cl"):lower()
local cxx = path.basename(config.get("cxx") or "cl"):lower()
local mrc = path.basename(config.get("mrc") or "rc"):lower()
if cc == "cl" or cxx == "cl" or mrc == "rc" then
local sdkdir = toolchain:sdkdir()
if sdkdir then
sdkdir = _check_vc_build_tools(toolchain, sdkdir)
end
if not sdkdir then
-- find it from packages
for _, package in ipairs(toolchain:packages()) do
local installdir = package:installdir()
if installdir and os.isdir(installdir) then
local result = _check_vc_build_tools(toolchain, installdir)
if result then
return result
end
end
end
-- find it from system
sdkdir = _check_vstudio(toolchain)
end
return sdkdir
end
end
|