aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimone Livieri <simone.livieri@gmail.com>2020-09-14 05:55:21 +0900
committerHisham Muhammad <hisham@gobolinux.org>2020-09-16 10:51:18 -0300
commit04513372d7d5859ea865252095c3b5ce0762228f (patch)
treea54477ede059c1b75283328992201bc12507dffe
parent7b712fc9d2188e5f3743720239a465f8089bdebf (diff)
downloadluarocks-04513372d7d5859ea865252095c3b5ce0762228f.tar.gz
luarocks-04513372d7d5859ea865252095c3b5ce0762228f.tar.bz2
luarocks-04513372d7d5859ea865252095c3b5ce0762228f.zip
silence the MSVC env setup script
-rw-r--r--install.bat2460
1 files changed, 1230 insertions, 1230 deletions
diff --git a/install.bat b/install.bat
index 06d8348c..e5d9cce0 100644
--- a/install.bat
+++ b/install.bat
@@ -1,1230 +1,1230 @@
1rem=rem --[[--lua 1rem=rem --[[--lua
2@setlocal& set luafile="%~f0" & if exist "%~f0.bat" set luafile="%~f0.bat" 2@setlocal& set luafile="%~f0" & if exist "%~f0.bat" set luafile="%~f0.bat"
3@win32\lua5.1\bin\lua5.1.exe %luafile% %*& exit /b ]] 3@win32\lua5.1\bin\lua5.1.exe %luafile% %*& exit /b ]]
4 4
5local vars = {} 5local vars = {}
6 6
7 7
8vars.PREFIX = nil 8vars.PREFIX = nil
9vars.VERSION = "3.0" 9vars.VERSION = "3.0"
10vars.SYSCONFDIR = nil 10vars.SYSCONFDIR = nil
11vars.CONFBACKUPDIR = nil 11vars.CONFBACKUPDIR = nil
12vars.SYSCONFFILENAME = nil 12vars.SYSCONFFILENAME = nil
13vars.CONFIG_FILE = nil 13vars.CONFIG_FILE = nil
14vars.TREE_ROOT = nil 14vars.TREE_ROOT = nil
15vars.TREE_BIN = nil 15vars.TREE_BIN = nil
16vars.TREE_LMODULE = nil 16vars.TREE_LMODULE = nil
17vars.TREE_CMODULE = nil 17vars.TREE_CMODULE = nil
18vars.LUA_INTERPRETER = nil 18vars.LUA_INTERPRETER = nil
19vars.LUA_PREFIX = nil 19vars.LUA_PREFIX = nil
20vars.LUA_BINDIR = nil 20vars.LUA_BINDIR = nil
21vars.LUA_INCDIR = nil 21vars.LUA_INCDIR = nil
22vars.LUA_LIBDIR = nil 22vars.LUA_LIBDIR = nil
23vars.LUA_LIBNAME = nil 23vars.LUA_LIBNAME = nil
24vars.LUA_VERSION = "5.1" 24vars.LUA_VERSION = "5.1"
25vars.LUA_SHORTV = nil -- "51" 25vars.LUA_SHORTV = nil -- "51"
26vars.LUA_RUNTIME = nil 26vars.LUA_RUNTIME = nil
27vars.UNAME_M = nil 27vars.UNAME_M = nil
28vars.COMPILER_ENV_CMD = nil 28vars.COMPILER_ENV_CMD = nil
29vars.MINGW_BIN_PATH = nil 29vars.MINGW_BIN_PATH = nil
30vars.MINGW_CC = nil 30vars.MINGW_CC = nil
31vars.MINGW_MAKE = nil 31vars.MINGW_MAKE = nil
32vars.MINGW_RC = nil 32vars.MINGW_RC = nil
33vars.MINGW_LD = nil 33vars.MINGW_LD = nil
34vars.MINGW_AR = nil 34vars.MINGW_AR = nil
35vars.MINGW_RANLIB = nil 35vars.MINGW_RANLIB = nil
36 36
37local FORCE = false 37local FORCE = false
38local FORCE_CONFIG = false 38local FORCE_CONFIG = false
39local INSTALL_LUA = false 39local INSTALL_LUA = false
40local USE_MINGW = false 40local USE_MINGW = false
41local USE_MSVC_MANUAL = false 41local USE_MSVC_MANUAL = false
42local REGISTRY = true 42local REGISTRY = true
43local NOADMIN = false 43local NOADMIN = false
44local PROMPT = true 44local PROMPT = true
45local SELFCONTAINED = false 45local SELFCONTAINED = false
46 46
47local lua_version_set = false 47local lua_version_set = false
48 48
49--- 49---
50-- Some helpers 50-- Some helpers
51-- 51--
52 52
53local pe = assert(loadfile(".\\win32\\pe-parser.lua"))() 53local pe = assert(loadfile(".\\win32\\pe-parser.lua"))()
54 54
55local function die(message) 55local function die(message)
56 if message then print(message) end 56 if message then print(message) end
57 print() 57 print()
58 print("Failed installing LuaRocks. Run with /? for help.") 58 print("Failed installing LuaRocks. Run with /? for help.")
59 os.exit(1) 59 os.exit(1)
60end 60end
61 61
62local function exec(cmd) 62local function exec(cmd)
63 --print(cmd) 63 --print(cmd)
64 local status = os.execute("type NUL && "..cmd) 64 local status = os.execute("type NUL && "..cmd)
65 return (status == 0 or status == true) -- compat 5.1/5.2 65 return (status == 0 or status == true) -- compat 5.1/5.2
66end 66end
67 67
68local function exists(filename) 68local function exists(filename)
69 local fd, _, code = io.open(filename, "r") 69 local fd, _, code = io.open(filename, "r")
70 if code == 13 then 70 if code == 13 then
71 -- code 13 means "Permission denied" on both Unix and Windows 71 -- code 13 means "Permission denied" on both Unix and Windows
72 -- io.open on folders always fails with code 13 on Windows 72 -- io.open on folders always fails with code 13 on Windows
73 return true 73 return true
74 end 74 end
75 if fd then 75 if fd then
76 fd:close() 76 fd:close()
77 return true 77 return true
78 end 78 end
79 return false 79 return false
80end 80end
81 81
82local function mkdir (dir) 82local function mkdir (dir)
83 return exec([[.\win32\tools\mkdir -p "]]..dir..[[" >NUL]]) 83 return exec([[.\win32\tools\mkdir -p "]]..dir..[[" >NUL]])
84end 84end
85 85
86-- does the current user have admin privileges ( = elevated) 86-- does the current user have admin privileges ( = elevated)
87local function permission() 87local function permission()
88 return exec("net session >NUL 2>&1") -- fails if not admin 88 return exec("net session >NUL 2>&1") -- fails if not admin
89end 89end
90 90
91-- rename filename (full path) to backupname (name only), appending number if required 91-- rename filename (full path) to backupname (name only), appending number if required
92-- returns the new name (name only) 92-- returns the new name (name only)
93local function backup(filename, backupname) 93local function backup(filename, backupname)
94 local path = filename:match("(.+)%\\.-$").."\\" 94 local path = filename:match("(.+)%\\.-$").."\\"
95 local nname = backupname 95 local nname = backupname
96 local i = 0 96 local i = 0
97 while exists(path..nname) do 97 while exists(path..nname) do
98 i = i + 1 98 i = i + 1
99 nname = backupname..tostring(i) 99 nname = backupname..tostring(i)
100 end 100 end
101 exec([[REN "]]..filename..[[" "]]..nname..[[" > NUL]]) 101 exec([[REN "]]..filename..[[" "]]..nname..[[" > NUL]])
102 return nname 102 return nname
103end 103end
104 104
105-- interpolate string with values from 'vars' table 105-- interpolate string with values from 'vars' table
106local function S (tmpl) 106local function S (tmpl)
107 return (tmpl:gsub('%$([%a_][%w_]*)', vars)) 107 return (tmpl:gsub('%$([%a_][%w_]*)', vars))
108end 108end
109 109
110local function print_help() 110local function print_help()
111 print(S[[ 111 print(S[[
112Installs LuaRocks. 112Installs LuaRocks.
113 113
114/P [dir] Where to install LuaRocks. 114/P [dir] Where to install LuaRocks.
115 Default is %PROGRAMFILES%\LuaRocks 115 Default is %PROGRAMFILES%\LuaRocks
116 116
117Configuring the destinations: 117Configuring the destinations:
118/TREE [dir] Root of the local system tree of installed rocks. 118/TREE [dir] Root of the local system tree of installed rocks.
119 Default is {BIN}\..\ if {BIN} ends with '\bin' 119 Default is {BIN}\..\ if {BIN} ends with '\bin'
120 otherwise it is {BIN}\systree. 120 otherwise it is {BIN}\systree.
121/SCRIPTS [dir] Where to install commandline scripts installed by 121/SCRIPTS [dir] Where to install commandline scripts installed by
122 rocks. Default is {TREE}\bin. 122 rocks. Default is {TREE}\bin.
123/LUAMOD [dir] Where to install Lua modules installed by rocks. 123/LUAMOD [dir] Where to install Lua modules installed by rocks.
124 Default is {TREE}\share\lua\{LV}. 124 Default is {TREE}\share\lua\{LV}.
125/CMOD [dir] Where to install c modules installed by rocks. 125/CMOD [dir] Where to install c modules installed by rocks.
126 Default is {TREE}\lib\lua\{LV}. 126 Default is {TREE}\lib\lua\{LV}.
127/CONFIG [dir] Location where the config file should be installed. 127/CONFIG [dir] Location where the config file should be installed.
128 Default is to follow /P option 128 Default is to follow /P option
129/SELFCONTAINED Creates a self contained installation in a single 129/SELFCONTAINED Creates a self contained installation in a single
130 directory given by /P. 130 directory given by /P.
131 Sets the /TREE and /CONFIG options to the same 131 Sets the /TREE and /CONFIG options to the same
132 location as /P. And does not load registry info 132 location as /P. And does not load registry info
133 with option /NOREG. The only option NOT self 133 with option /NOREG. The only option NOT self
134 contained is the user rock tree, so don't use that 134 contained is the user rock tree, so don't use that
135 if you create a self contained installation. 135 if you create a self contained installation.
136 136
137Configuring the Lua interpreter: 137Configuring the Lua interpreter:
138/LV [version] Lua version to use; either 5.1, 5.2, 5.3, or 5.4. 138/LV [version] Lua version to use; either 5.1, 5.2, 5.3, or 5.4.
139 Default is auto-detected. 139 Default is auto-detected.
140/LUA [dir] Location where Lua is installed - e.g. c:\lua\5.1\ 140/LUA [dir] Location where Lua is installed - e.g. c:\lua\5.1\
141 If not provided, the installer will search the system 141 If not provided, the installer will search the system
142 path and some default locations for a valid Lua 142 path and some default locations for a valid Lua
143 installation. 143 installation.
144 This is the base directory, the installer will look 144 This is the base directory, the installer will look
145 for subdirectories bin, lib, include. Alternatively 145 for subdirectories bin, lib, include. Alternatively
146 these can be specified explicitly using the /INC, 146 these can be specified explicitly using the /INC,
147 /LIB, and /BIN options. 147 /LIB, and /BIN options.
148/INC [dir] Location of Lua includes - e.g. c:\lua\5.1\include 148/INC [dir] Location of Lua includes - e.g. c:\lua\5.1\include
149 If provided overrides sub directory found using /LUA. 149 If provided overrides sub directory found using /LUA.
150/LIB [dir] Location of Lua libraries (.dll/.lib) - e.g. c:\lua\5.1\lib 150/LIB [dir] Location of Lua libraries (.dll/.lib) - e.g. c:\lua\5.1\lib
151 If provided overrides sub directory found using /LUA. 151 If provided overrides sub directory found using /LUA.
152/BIN [dir] Location of Lua executables - e.g. c:\lua\5.1\bin 152/BIN [dir] Location of Lua executables - e.g. c:\lua\5.1\bin
153 If provided overrides sub directory found using /LUA. 153 If provided overrides sub directory found using /LUA.
154/L Install LuaRocks' own copy of Lua even if detected, 154/L Install LuaRocks' own copy of Lua even if detected,
155 this will always be a 5.1 installation. 155 this will always be a 5.1 installation.
156 (/LUA, /INC, /LIB, /BIN cannot be used with /L) 156 (/LUA, /INC, /LIB, /BIN cannot be used with /L)
157 157
158Compiler configuration: 158Compiler configuration:
159 By default the installer will try to determine the 159 By default the installer will try to determine the
160 Microsoft toolchain to use. And will automatically use 160 Microsoft toolchain to use. And will automatically use
161 a setup command to initialize that toolchain when 161 a setup command to initialize that toolchain when
162 LuaRocks is run. If it cannot find it, it will default 162 LuaRocks is run. If it cannot find it, it will default
163 to the /MSVC switch. 163 to the /MSVC switch.
164/MSVC Use MS toolchain, without a setup command (tools must 164/MSVC Use MS toolchain, without a setup command (tools must
165 be in your path) 165 be in your path)
166/MW Use mingw as build system (tools must be in your path) 166/MW Use mingw as build system (tools must be in your path)
167 167
168Other options: 168Other options:
169/FORCECONFIG Use a single config location. Do not use the 169/FORCECONFIG Use a single config location. Do not use the
170 LUAROCKS_CONFIG variable or the user's home directory. 170 LUAROCKS_CONFIG variable or the user's home directory.
171 Useful to avoid conflicts when LuaRocks 171 Useful to avoid conflicts when LuaRocks
172 is embedded within an application. 172 is embedded within an application.
173/F Remove installation directory if it already exists. 173/F Remove installation directory if it already exists.
174/NOREG Do not load registry info to register '.rockspec' 174/NOREG Do not load registry info to register '.rockspec'
175 extension with LuaRocks commands (right-click). 175 extension with LuaRocks commands (right-click).
176/NOADMIN The installer requires admin privileges. If not 176/NOADMIN The installer requires admin privileges. If not
177 available it will elevate a new process. Use this 177 available it will elevate a new process. Use this
178 switch to prevent elevation, but make sure the 178 switch to prevent elevation, but make sure the
179 destination paths are all accessible for the current 179 destination paths are all accessible for the current
180 user. 180 user.
181/Q Do not prompt for confirmation of settings 181/Q Do not prompt for confirmation of settings
182 182
183]]) 183]])
184end 184end
185 185
186-- *********************************************************** 186-- ***********************************************************
187-- Option parser 187-- Option parser
188-- *********************************************************** 188-- ***********************************************************
189local function parse_options(args) 189local function parse_options(args)
190 for _, option in ipairs(args) do 190 for _, option in ipairs(args) do
191 local name = option.name:upper() 191 local name = option.name:upper()
192 if name == "/?" then 192 if name == "/?" then
193 print_help() 193 print_help()
194 os.exit(0) 194 os.exit(0)
195 elseif name == "/P" then 195 elseif name == "/P" then
196 vars.PREFIX = option.value 196 vars.PREFIX = option.value
197 elseif name == "/CONFIG" then 197 elseif name == "/CONFIG" then
198 vars.SYSCONFDIR = option.value 198 vars.SYSCONFDIR = option.value
199 elseif name == "/TREE" then 199 elseif name == "/TREE" then
200 vars.TREE_ROOT = option.value 200 vars.TREE_ROOT = option.value
201 elseif name == "/SCRIPTS" then 201 elseif name == "/SCRIPTS" then
202 vars.TREE_BIN = option.value 202 vars.TREE_BIN = option.value
203 elseif name == "/LUAMOD" then 203 elseif name == "/LUAMOD" then
204 vars.TREE_LMODULE = option.value 204 vars.TREE_LMODULE = option.value
205 elseif name == "/CMOD" then 205 elseif name == "/CMOD" then
206 vars.TREE_CMODULE = option.value 206 vars.TREE_CMODULE = option.value
207 elseif name == "/LV" then 207 elseif name == "/LV" then
208 vars.LUA_VERSION = option.value 208 vars.LUA_VERSION = option.value
209 lua_version_set = true 209 lua_version_set = true
210 elseif name == "/L" then 210 elseif name == "/L" then
211 INSTALL_LUA = true 211 INSTALL_LUA = true
212 elseif name == "/MW" then 212 elseif name == "/MW" then
213 USE_MINGW = true 213 USE_MINGW = true
214 elseif name == "/MSVC" then 214 elseif name == "/MSVC" then
215 USE_MSVC_MANUAL = true 215 USE_MSVC_MANUAL = true
216 elseif name == "/LUA" then 216 elseif name == "/LUA" then
217 vars.LUA_PREFIX = option.value 217 vars.LUA_PREFIX = option.value
218 elseif name == "/LIB" then 218 elseif name == "/LIB" then
219 vars.LUA_LIBDIR = option.value 219 vars.LUA_LIBDIR = option.value
220 elseif name == "/INC" then 220 elseif name == "/INC" then
221 vars.LUA_INCDIR = option.value 221 vars.LUA_INCDIR = option.value
222 elseif name == "/BIN" then 222 elseif name == "/BIN" then
223 vars.LUA_BINDIR = option.value 223 vars.LUA_BINDIR = option.value
224 elseif name == "/FORCECONFIG" then 224 elseif name == "/FORCECONFIG" then
225 FORCE_CONFIG = true 225 FORCE_CONFIG = true
226 elseif name == "/F" then 226 elseif name == "/F" then
227 FORCE = true 227 FORCE = true
228 elseif name == "/SELFCONTAINED" then 228 elseif name == "/SELFCONTAINED" then
229 SELFCONTAINED = true 229 SELFCONTAINED = true
230 elseif name == "/NOREG" then 230 elseif name == "/NOREG" then
231 REGISTRY = false 231 REGISTRY = false
232 elseif name == "/NOADMIN" then 232 elseif name == "/NOADMIN" then
233 NOADMIN = true 233 NOADMIN = true
234 elseif name == "/Q" then 234 elseif name == "/Q" then
235 PROMPT = false 235 PROMPT = false
236 else 236 else
237 die("Unrecognized option: " .. name) 237 die("Unrecognized option: " .. name)
238 end 238 end
239 end 239 end
240end 240end
241 241
242-- check for combination/required flags 242-- check for combination/required flags
243local function check_flags() 243local function check_flags()
244 if SELFCONTAINED then 244 if SELFCONTAINED then
245 if not vars.PREFIX then 245 if not vars.PREFIX then
246 die("Option /P is required when using /SELFCONTAINED") 246 die("Option /P is required when using /SELFCONTAINED")
247 end 247 end
248 if vars.SYSCONFDIR or vars.TREE_ROOT or vars.TREE_BIN or vars.TREE_LMODULE or vars.TREE_CMODULE then 248 if vars.SYSCONFDIR or vars.TREE_ROOT or vars.TREE_BIN or vars.TREE_LMODULE or vars.TREE_CMODULE then
249 die("Cannot combine /TREE, /SCRIPTS, /LUAMOD, /CMOD, or /CONFIG with /SELFCONTAINED") 249 die("Cannot combine /TREE, /SCRIPTS, /LUAMOD, /CMOD, or /CONFIG with /SELFCONTAINED")
250 end 250 end
251 end 251 end
252 if INSTALL_LUA then 252 if INSTALL_LUA then
253 if vars.LUA_INCDIR or vars.LUA_BINDIR or vars.LUA_LIBDIR or vars.LUA_PREFIX then 253 if vars.LUA_INCDIR or vars.LUA_BINDIR or vars.LUA_LIBDIR or vars.LUA_PREFIX then
254 die("Cannot combine option /L with any of /LUA /BIN /LIB /INC") 254 die("Cannot combine option /L with any of /LUA /BIN /LIB /INC")
255 end 255 end
256 if vars.LUA_VERSION ~= "5.1" then 256 if vars.LUA_VERSION ~= "5.1" then
257 die("Bundled Lua version is 5.1, cannot install "..vars.LUA_VERSION) 257 die("Bundled Lua version is 5.1, cannot install "..vars.LUA_VERSION)
258 end 258 end
259 end 259 end
260 if not vars.LUA_VERSION:match("^5%.[1234]$") then 260 if not vars.LUA_VERSION:match("^5%.[1234]$") then
261 die("Bad argument: /LV must either be 5.1, 5.2, 5.3, or 5.4") 261 die("Bad argument: /LV must either be 5.1, 5.2, 5.3, or 5.4")
262 end 262 end
263 if USE_MSVC_MANUAL and USE_MINGW then 263 if USE_MSVC_MANUAL and USE_MINGW then
264 die("Cannot combine option /MSVC and /MW") 264 die("Cannot combine option /MSVC and /MW")
265 end 265 end
266end 266end
267 267
268-- *********************************************************** 268-- ***********************************************************
269-- Detect Lua 269-- Detect Lua
270-- *********************************************************** 270-- ***********************************************************
271local function detect_lua_version(interpreter_path) 271local function detect_lua_version(interpreter_path)
272 local handler = io.popen(('type NUL && "%s" -e "io.stdout:write(_VERSION)" 2>NUL'):format(interpreter_path), "r") 272 local handler = io.popen(('type NUL && "%s" -e "io.stdout:write(_VERSION)" 2>NUL'):format(interpreter_path), "r")
273 if not handler then 273 if not handler then
274 return nil, "interpreter does not work" 274 return nil, "interpreter does not work"
275 end 275 end
276 local full_version = handler:read("*a") 276 local full_version = handler:read("*a")
277 handler:close() 277 handler:close()
278 278
279 local version = full_version:match(" (5%.[1234])$") 279 local version = full_version:match(" (5%.[1234])$")
280 if not version then 280 if not version then
281 return nil, "unknown interpreter version '" .. full_version .. "'" 281 return nil, "unknown interpreter version '" .. full_version .. "'"
282 end 282 end
283 return version 283 return version
284end 284end
285 285
286local function look_for_interpreter(directory) 286local function look_for_interpreter(directory)
287 local names 287 local names
288 if lua_version_set then 288 if lua_version_set then
289 names = {S"lua$LUA_VERSION.exe", S"lua$LUA_SHORTV.exe"} 289 names = {S"lua$LUA_VERSION.exe", S"lua$LUA_SHORTV.exe"}
290 else 290 else
291 names = {"lua5.4.exe", "lua54.exe", "lua5.3.exe", "lua53.exe", "lua5.2.exe", "lua52.exe", "lua5.1.exe", "lua51.exe"} 291 names = {"lua5.4.exe", "lua54.exe", "lua5.3.exe", "lua53.exe", "lua5.2.exe", "lua52.exe", "lua5.1.exe", "lua51.exe"}
292 end 292 end
293 table.insert(names, "lua.exe") 293 table.insert(names, "lua.exe")
294 table.insert(names, "luajit.exe") 294 table.insert(names, "luajit.exe")
295 295
296 local directories 296 local directories
297 if vars.LUA_BINDIR then 297 if vars.LUA_BINDIR then
298 -- If LUA_BINDIR is specified, look only in that directory. 298 -- If LUA_BINDIR is specified, look only in that directory.
299 directories = {vars.LUA_BINDIR} 299 directories = {vars.LUA_BINDIR}
300 else 300 else
301 -- Try candidate directory and its `bin` subdirectory. 301 -- Try candidate directory and its `bin` subdirectory.
302 directories = {directory, directory .. "\\bin"} 302 directories = {directory, directory .. "\\bin"}
303 end 303 end
304 304
305 for _, dir in ipairs(directories) do 305 for _, dir in ipairs(directories) do
306 for _, name in ipairs(names) do 306 for _, name in ipairs(names) do
307 local full_name = dir .. "\\" .. name 307 local full_name = dir .. "\\" .. name
308 if exists(full_name) then 308 if exists(full_name) then
309 print(" Found " .. name .. ", testing it...") 309 print(" Found " .. name .. ", testing it...")
310 local version, err = detect_lua_version(full_name) 310 local version, err = detect_lua_version(full_name)
311 if not version then 311 if not version then
312 print(" Error: " .. err) 312 print(" Error: " .. err)
313 else 313 else
314 if version ~= vars.LUA_VERSION then 314 if version ~= vars.LUA_VERSION then
315 if lua_version_set then 315 if lua_version_set then
316 die("Version of interpreter clashes with the value of /LV. Please check your configuration.") 316 die("Version of interpreter clashes with the value of /LV. Please check your configuration.")
317 else 317 else
318 vars.LUA_VERSION = version 318 vars.LUA_VERSION = version
319 vars.LUA_SHORTV = version:gsub("%.", "") 319 vars.LUA_SHORTV = version:gsub("%.", "")
320 end 320 end
321 end 321 end
322 322
323 vars.LUA_INTERPRETER = name 323 vars.LUA_INTERPRETER = name
324 vars.LUA_BINDIR = dir 324 vars.LUA_BINDIR = dir
325 return true 325 return true
326 end 326 end
327 end 327 end
328 end 328 end
329 end 329 end
330 330
331 if vars.LUA_BINDIR then 331 if vars.LUA_BINDIR then
332 die(("Working Lua executable (one of %s) not found in %s"):format(table.concat(names, ", "), vars.LUA_BINDIR)) 332 die(("Working Lua executable (one of %s) not found in %s"):format(table.concat(names, ", "), vars.LUA_BINDIR))
333 end 333 end
334 return false 334 return false
335end 335end
336 336
337local function look_for_link_libraries(directory) 337local function look_for_link_libraries(directory)
338 -- MinGW does not generate .lib, nor needs it to link, but MSVC does, 338 -- MinGW does not generate .lib, nor needs it to link, but MSVC does,
339 -- so .lib must be listed first to ensure they are found first if present, 339 -- so .lib must be listed first to ensure they are found first if present,
340 -- to prevent MSVC trying to link to a .dll, which won't work. 340 -- to prevent MSVC trying to link to a .dll, which won't work.
341 local names = {S"lua$LUA_VERSION.lib", S"lua$LUA_SHORTV.lib", S"lua$LUA_VERSION.dll", S"lua$LUA_SHORTV.dll", "liblua.dll.a"} 341 local names = {S"lua$LUA_VERSION.lib", S"lua$LUA_SHORTV.lib", S"lua$LUA_VERSION.dll", S"lua$LUA_SHORTV.dll", "liblua.dll.a"}
342 local directories 342 local directories
343 if vars.LUA_LIBDIR then 343 if vars.LUA_LIBDIR then
344 directories = {vars.LUA_LIBDIR} 344 directories = {vars.LUA_LIBDIR}
345 else 345 else
346 directories = {directory, directory .. "\\lib", directory .. "\\bin"} 346 directories = {directory, directory .. "\\lib", directory .. "\\bin"}
347 end 347 end
348 348
349 for _, dir in ipairs(directories) do 349 for _, dir in ipairs(directories) do
350 for _, name in ipairs(names) do 350 for _, name in ipairs(names) do
351 local full_name = dir .. "\\" .. name 351 local full_name = dir .. "\\" .. name
352 print(" checking for " .. full_name) 352 print(" checking for " .. full_name)
353 if exists(full_name) then 353 if exists(full_name) then
354 vars.LUA_LIBDIR = dir 354 vars.LUA_LIBDIR = dir
355 vars.LUA_LIBNAME = name 355 vars.LUA_LIBNAME = name
356 print(" Found " .. name) 356 print(" Found " .. name)
357 return true 357 return true
358 end 358 end
359 end 359 end
360 end 360 end
361 361
362 if vars.LUA_LIBDIR then 362 if vars.LUA_LIBDIR then
363 die(("Link library (one of %s) not found in %s"):format(table.concat(names, ", "), vars.LUA_LIBDIR)) 363 die(("Link library (one of %s) not found in %s"):format(table.concat(names, ", "), vars.LUA_LIBDIR))
364 end 364 end
365 return false 365 return false
366end 366end
367 367
368local function look_for_headers(directory) 368local function look_for_headers(directory)
369 local directories 369 local directories
370 if vars.LUA_INCDIR then 370 if vars.LUA_INCDIR then
371 directories = {vars.LUA_INCDIR} 371 directories = {vars.LUA_INCDIR}
372 else 372 else
373 directories = { 373 directories = {
374 directory .. S"\\include\\lua\\$LUA_VERSION", 374 directory .. S"\\include\\lua\\$LUA_VERSION",
375 directory .. S"\\include\\lua$LUA_SHORTV", 375 directory .. S"\\include\\lua$LUA_SHORTV",
376 directory .. S"\\include\\lua$LUA_VERSION", 376 directory .. S"\\include\\lua$LUA_VERSION",
377 directory .. "\\include", 377 directory .. "\\include",
378 directory 378 directory
379 } 379 }
380 end 380 end
381 381
382 for _, dir in ipairs(directories) do 382 for _, dir in ipairs(directories) do
383 local full_name = dir .. "\\lua.h" 383 local full_name = dir .. "\\lua.h"
384 print(" checking for " .. full_name) 384 print(" checking for " .. full_name)
385 if exists(full_name) then 385 if exists(full_name) then
386 vars.LUA_INCDIR = dir 386 vars.LUA_INCDIR = dir
387 print(" Found lua.h") 387 print(" Found lua.h")
388 return true 388 return true
389 end 389 end
390 end 390 end
391 391
392 if vars.LUA_INCDIR then 392 if vars.LUA_INCDIR then
393 die(S"lua.h not found in $LUA_INCDIR") 393 die(S"lua.h not found in $LUA_INCDIR")
394 end 394 end
395 return false 395 return false
396end 396end
397 397
398 398
399local function get_runtime() 399local function get_runtime()
400 local f 400 local f
401 vars.LUA_RUNTIME, f = pe.msvcrt(vars.LUA_BINDIR.."\\"..vars.LUA_INTERPRETER) 401 vars.LUA_RUNTIME, f = pe.msvcrt(vars.LUA_BINDIR.."\\"..vars.LUA_INTERPRETER)
402 if type(vars.LUA_RUNTIME) ~= "string" then 402 if type(vars.LUA_RUNTIME) ~= "string" then
403 -- analysis failed, issue a warning 403 -- analysis failed, issue a warning
404 vars.LUA_RUNTIME = "MSVCR80" 404 vars.LUA_RUNTIME = "MSVCR80"
405 print("*** WARNING ***: could not analyse the runtime used, defaulting to "..vars.LUA_RUNTIME) 405 print("*** WARNING ***: could not analyse the runtime used, defaulting to "..vars.LUA_RUNTIME)
406 else 406 else
407 print(" "..f.." uses "..vars.LUA_RUNTIME..".DLL as runtime") 407 print(" "..f.." uses "..vars.LUA_RUNTIME..".DLL as runtime")
408 end 408 end
409 return true 409 return true
410end 410end
411 411
412local function get_architecture() 412local function get_architecture()
413 -- detect processor arch interpreter was compiled for 413 -- detect processor arch interpreter was compiled for
414 local proc = (pe.parse(vars.LUA_BINDIR.."\\"..vars.LUA_INTERPRETER) or {}).Machine 414 local proc = (pe.parse(vars.LUA_BINDIR.."\\"..vars.LUA_INTERPRETER) or {}).Machine
415 if not proc then 415 if not proc then
416 die("Could not detect processor architecture used in "..vars.LUA_INTERPRETER) 416 die("Could not detect processor architecture used in "..vars.LUA_INTERPRETER)
417 end 417 end
418 print("arch: " .. proc .. " -> " .. pe.const.Machine[proc]) 418 print("arch: " .. proc .. " -> " .. pe.const.Machine[proc])
419 proc = pe.const.Machine[proc] -- collect name from constant value 419 proc = pe.const.Machine[proc] -- collect name from constant value
420 if proc == "IMAGE_FILE_MACHINE_I386" then 420 if proc == "IMAGE_FILE_MACHINE_I386" then
421 proc = "x86" 421 proc = "x86"
422 elseif proc == "IMAGE_FILE_MACHINE_ARM64" then 422 elseif proc == "IMAGE_FILE_MACHINE_ARM64" then
423 proc = "arm64" 423 proc = "arm64"
424 else 424 else
425 proc = "x86_64" 425 proc = "x86_64"
426 end 426 end
427 return proc 427 return proc
428end 428end
429 429
430-- get a string value from windows registry. 430-- get a string value from windows registry.
431local function get_registry(key, value) 431local function get_registry(key, value)
432 local keys = {key} 432 local keys = {key}
433 local key64, replaced = key:gsub("(%u+\\Software\\)", "%1Wow6432Node\\", 1) 433 local key64, replaced = key:gsub("(%u+\\Software\\)", "%1Wow6432Node\\", 1)
434 434
435 if replaced == 1 then 435 if replaced == 1 then
436 keys = {key64, key} 436 keys = {key64, key}
437 end 437 end
438 438
439 for _, k in ipairs(keys) do 439 for _, k in ipairs(keys) do
440 local h = io.popen('reg query "'..k..'" /v '..value..' 2>NUL') 440 local h = io.popen('reg query "'..k..'" /v '..value..' 2>NUL')
441 local output = h:read("*a") 441 local output = h:read("*a")
442 h:close() 442 h:close()
443 443
444 local v = output:match("REG_SZ%s+([^\n]+)") 444 local v = output:match("REG_SZ%s+([^\n]+)")
445 if v then 445 if v then
446 return v 446 return v
447 end 447 end
448 end 448 end
449 return nil 449 return nil
450end 450end
451 451
452local function get_visual_studio_directory_from_registry() 452local function get_visual_studio_directory_from_registry()
453 assert(type(vars.LUA_RUNTIME)=="string", "requires vars.LUA_RUNTIME to be set before calling this function.") 453 assert(type(vars.LUA_RUNTIME)=="string", "requires vars.LUA_RUNTIME to be set before calling this function.")
454 local major, minor = vars.LUA_RUNTIME:match('VCR%u*(%d+)(%d)$') -- MSVCR<x><y> or VCRUNTIME<x><y> 454 local major, minor = vars.LUA_RUNTIME:match('VCR%u*(%d+)(%d)$') -- MSVCR<x><y> or VCRUNTIME<x><y>
455 if not major then 455 if not major then
456 print(S[[ Cannot auto-detect Visual Studio version from $LUA_RUNTIME]]) 456 print(S[[ Cannot auto-detect Visual Studio version from $LUA_RUNTIME]])
457 return nil 457 return nil
458 end 458 end
459 local keys = { 459 local keys = {
460 "HKLM\\Software\\Microsoft\\VisualStudio\\%d.%d\\Setup\\VC", 460 "HKLM\\Software\\Microsoft\\VisualStudio\\%d.%d\\Setup\\VC",
461 "HKLM\\Software\\Microsoft\\VCExpress\\%d.%d\\Setup\\VS" 461 "HKLM\\Software\\Microsoft\\VCExpress\\%d.%d\\Setup\\VS"
462 } 462 }
463 for _, key in ipairs(keys) do 463 for _, key in ipairs(keys) do
464 local versionedkey = key:format(major, minor) 464 local versionedkey = key:format(major, minor)
465 local vcdir = get_registry(versionedkey, "ProductDir") 465 local vcdir = get_registry(versionedkey, "ProductDir")
466 print(" checking: "..versionedkey) 466 print(" checking: "..versionedkey)
467 if vcdir then 467 if vcdir then
468 print(" Found: "..vcdir) 468 print(" Found: "..vcdir)
469 return vcdir 469 return vcdir
470 end 470 end
471 end 471 end
472 return nil 472 return nil
473end 473end
474 474
475local function get_visual_studio_directory_from_vswhere() 475local function get_visual_studio_directory_from_vswhere()
476 assert(type(vars.LUA_RUNTIME)=="string", "requires vars.LUA_RUNTIME to be set before calling this function.") 476 assert(type(vars.LUA_RUNTIME)=="string", "requires vars.LUA_RUNTIME to be set before calling this function.")
477 local major, minor = vars.LUA_RUNTIME:match('VCR%u*(%d+)(%d)$') 477 local major, minor = vars.LUA_RUNTIME:match('VCR%u*(%d+)(%d)$')
478 if not major then 478 if not major then
479 print(S[[ Cannot auto-detect Visual Studio version from $LUA_RUNTIME]]) 479 print(S[[ Cannot auto-detect Visual Studio version from $LUA_RUNTIME]])
480 return nil 480 return nil
481 end 481 end
482 if tonumber(major) < 14 then 482 if tonumber(major) < 14 then
483 return nil 483 return nil
484 end 484 end
485 local program_dir = os.getenv('PROGRAMFILES(X86)') 485 local program_dir = os.getenv('PROGRAMFILES(X86)')
486 if not program_dir then 486 if not program_dir then
487 return nil 487 return nil
488 end 488 end
489 local vswhere = program_dir.."\\Microsoft Visual Studio\\Installer\\vswhere.exe" 489 local vswhere = program_dir.."\\Microsoft Visual Studio\\Installer\\vswhere.exe"
490 if not exists(vswhere) then 490 if not exists(vswhere) then
491 return nil 491 return nil
492 end 492 end
493 local f, msg = io.popen('"'..vswhere..'" -products * -property installationPath') 493 local f, msg = io.popen('"'..vswhere..'" -products * -property installationPath')
494 if not f then return nil, "failed to run vswhere: "..msg end 494 if not f then return nil, "failed to run vswhere: "..msg end
495 local vsdir = nil 495 local vsdir = nil
496 while true do 496 while true do
497 local l, err = f:read() 497 local l, err = f:read()
498 if not l then 498 if not l then
499 if err then 499 if err then
500 f:close() 500 f:close()
501 return nil, err 501 return nil, err
502 else 502 else
503 break 503 break
504 end 504 end
505 end 505 end
506 vsdir = l 506 vsdir = l
507 end 507 end
508 f:close() 508 f:close()
509 if not vsdir then 509 if not vsdir then
510 return nil 510 return nil
511 end 511 end
512 print(" Visual Studio 2017 or higher found in: "..vsdir) 512 print(" Visual Studio 2017 or higher found in: "..vsdir)
513 return vsdir 513 return vsdir
514end 514end
515 515
516local function get_windows_sdk_directory() 516local function get_windows_sdk_directory()
517 assert(type(vars.LUA_RUNTIME) == "string", "requires vars.LUA_RUNTIME to be set before calling this function.") 517 assert(type(vars.LUA_RUNTIME) == "string", "requires vars.LUA_RUNTIME to be set before calling this function.")
518 -- Only v7.1 and v6.1 shipped with compilers 518 -- Only v7.1 and v6.1 shipped with compilers
519 -- Other versions requires a separate installation of Visual Studio. 519 -- Other versions requires a separate installation of Visual Studio.
520 -- see https://github.com/luarocks/luarocks/pull/443#issuecomment-152792516 520 -- see https://github.com/luarocks/luarocks/pull/443#issuecomment-152792516
521 local wsdks = { 521 local wsdks = {
522 ["MSVCR100"] = "v7.1", -- shipped with Visual Studio 2010 compilers. 522 ["MSVCR100"] = "v7.1", -- shipped with Visual Studio 2010 compilers.
523 ["MSVCR100D"] = "v7.1", -- shipped with Visual Studio 2010 compilers. 523 ["MSVCR100D"] = "v7.1", -- shipped with Visual Studio 2010 compilers.
524 ["MSVCR90"] = "v6.1", -- shipped with Visual Studio 2008 compilers. 524 ["MSVCR90"] = "v6.1", -- shipped with Visual Studio 2008 compilers.
525 ["MSVCR90D"] = "v6.1", -- shipped with Visual Studio 2008 compilers. 525 ["MSVCR90D"] = "v6.1", -- shipped with Visual Studio 2008 compilers.
526 } 526 }
527 local wsdkver = wsdks[vars.LUA_RUNTIME] 527 local wsdkver = wsdks[vars.LUA_RUNTIME]
528 if not wsdkver then 528 if not wsdkver then
529 print(S[[ Cannot auto-detect Windows SDK version from $LUA_RUNTIME]]) 529 print(S[[ Cannot auto-detect Windows SDK version from $LUA_RUNTIME]])
530 return nil 530 return nil
531 end 531 end
532 532
533 local key = "HKLM\\Software\\Microsoft\\Microsoft SDKs\\Windows\\"..wsdkver 533 local key = "HKLM\\Software\\Microsoft\\Microsoft SDKs\\Windows\\"..wsdkver
534 print(" checking: "..key) 534 print(" checking: "..key)
535 local dir = get_registry(key, "InstallationFolder") 535 local dir = get_registry(key, "InstallationFolder")
536 if dir then 536 if dir then
537 print(" Found: "..dir) 537 print(" Found: "..dir)
538 return dir 538 return dir
539 end 539 end
540 print(" No SDK found") 540 print(" No SDK found")
541 return nil 541 return nil
542end 542end
543 543
544-- returns the batch command to setup msvc compiler path. 544-- returns the batch command to setup msvc compiler path.
545-- or an empty string (eg. "") if not found 545-- or an empty string (eg. "") if not found
546local function get_msvc_env_setup_cmd() 546local function get_msvc_env_setup_cmd()
547 print(S[[Looking for Microsoft toolchain matching runtime $LUA_RUNTIME and architecture $UNAME_M]]) 547 print(S[[Looking for Microsoft toolchain matching runtime $LUA_RUNTIME and architecture $UNAME_M]])
548 548
549 assert(type(vars.UNAME_M) == "string", "requires vars.UNAME_M to be set before calling this function.") 549 assert(type(vars.UNAME_M) == "string", "requires vars.UNAME_M to be set before calling this function.")
550 local x64 = vars.UNAME_M=="x86_64" 550 local x64 = vars.UNAME_M=="x86_64"
551 551
552 -- 1. try visual studio command line tools of VS 2017 or higher 552 -- 1. try visual studio command line tools of VS 2017 or higher
553 local vsdir, err = get_visual_studio_directory_from_vswhere() 553 local vsdir, err = get_visual_studio_directory_from_vswhere()
554 if err then 554 if err then
555 print(" Error when finding Visual Studio directory from vswhere: "..err) 555 print(" Error when finding Visual Studio directory from vswhere: "..err)
556 end 556 end
557 if vsdir then 557 if vsdir then
558 local vcvarsall = vsdir .. '\\VC\\Auxiliary\\Build\\vcvarsall.bat' 558 local vcvarsall = vsdir .. '\\VC\\Auxiliary\\Build\\vcvarsall.bat'
559 if exists(vcvarsall) then 559 if exists(vcvarsall) then
560 local vcvarsall_args = { x86 = "", x86_64 = " x64", arm64 = " x86_arm64" } 560 local vcvarsall_args = { x86 = "", x86_64 = " x64", arm64 = " x86_arm64" }
561 assert(vcvarsall_args[vars.UNAME_M], "vars.UNAME_M: only x86, x86_64 and arm64 are supported") 561 assert(vcvarsall_args[vars.UNAME_M], "vars.UNAME_M: only x86, x86_64 and arm64 are supported")
562 return ('call "%s"%s'):format(vcvarsall, vcvarsall_args[vars.UNAME_M]) 562 return ('call "%s"%s'):format(vcvarsall, vcvarsall_args[vars.UNAME_M])
563 end 563 end
564 end 564 end
565 565
566 -- 2. try visual studio command line tools 566 -- 2. try visual studio command line tools
567 local vcdir = get_visual_studio_directory_from_registry() 567 local vcdir = get_visual_studio_directory_from_registry()
568 if vcdir then 568 if vcdir then
569 local vcvars_bats = { 569 local vcvars_bats = {
570 x86 = { 570 x86 = {
571 "bin\\vcvars32.bat", -- prefers native compiler 571 "bin\\vcvars32.bat", -- prefers native compiler
572 "bin\\amd64_x86\\vcvarsamd64_x86.bat"-- then cross compiler 572 "bin\\amd64_x86\\vcvarsamd64_x86.bat"-- then cross compiler
573 }, 573 },
574 x86_64 = { 574 x86_64 = {
575 "bin\\amd64\\vcvars64.bat", -- prefers native compiler 575 "bin\\amd64\\vcvars64.bat", -- prefers native compiler
576 "bin\\x86_amd64\\vcvarsx86_amd64.bat" -- then cross compiler 576 "bin\\x86_amd64\\vcvarsx86_amd64.bat" -- then cross compiler
577 }, 577 },
578 arm64 = { 578 arm64 = {
579 "bin\\x86_arm64\\vcvarsx86_arm64.bat" -- need to use cross compiler" 579 "bin\\x86_arm64\\vcvarsx86_arm64.bat" -- need to use cross compiler"
580 } 580 }
581 } 581 }
582 assert(vcvars_bats[vars.UNAME_M], "vars.UNAME_M: only x86, arm64 and x86_64 are supported") 582 assert(vcvars_bats[vars.UNAME_M], "vars.UNAME_M: only x86, arm64 and x86_64 are supported")
583 for _, bat in ipairs(vcvars_bats[vars.UNAME_M]) do 583 for _, bat in ipairs(vcvars_bats[vars.UNAME_M]) do
584 local full_path = vcdir .. bat 584 local full_path = vcdir .. bat
585 if exists(full_path) then 585 if exists(full_path) then
586 return ('call "%s"'):format(full_path) 586 return ('call "%s"'):format(full_path)
587 end 587 end
588 end 588 end
589 589
590 -- try vcvarsall.bat in case MS changes the undocumented bat files above. 590 -- try vcvarsall.bat in case MS changes the undocumented bat files above.
591 -- but this way we don't know if specified compiler is installed... 591 -- but this way we don't know if specified compiler is installed...
592 local vcvarsall = vcdir .. 'vcvarsall.bat' 592 local vcvarsall = vcdir .. 'vcvarsall.bat'
593 if exists(vcvarsall) then 593 if exists(vcvarsall) then
594 local vcvarsall_args = { x86 = "", x86_64 = " amd64", arm64 = " x86_arm64" } 594 local vcvarsall_args = { x86 = "", x86_64 = " amd64", arm64 = " x86_arm64" }
595 return ('call "%s"%s'):format(vcvarsall, vcvarsall_args[vars.UNAME_M]) 595 return ('call "%s"%s'):format(vcvarsall, vcvarsall_args[vars.UNAME_M])
596 end 596 end
597 end 597 end
598 598
599 -- 3. try for Windows SDKs command line tools. 599 -- 3. try for Windows SDKs command line tools.
600 local wsdkdir = get_windows_sdk_directory() 600 local wsdkdir = get_windows_sdk_directory()
601 if wsdkdir then 601 if wsdkdir then
602 local setenv = wsdkdir.."Bin\\SetEnv.cmd" 602 local setenv = wsdkdir.."Bin\\SetEnv.cmd"
603 if exists(setenv) then 603 if exists(setenv) then
604 return ('call "%s" /%s'):format(setenv, x64 and "x64" or "x86") 604 return ('call "%s" /%s'):format(setenv, x64 and "x64" or "x86")
605 end 605 end
606 end 606 end
607 607
608 -- finally, we can't detect more, just don't setup the msvc compiler in luarocks.bat. 608 -- finally, we can't detect more, just don't setup the msvc compiler in luarocks.bat.
609 return "" 609 return ""
610end 610end
611 611
612local function get_possible_lua_directories() 612local function get_possible_lua_directories()
613 if vars.LUA_PREFIX then 613 if vars.LUA_PREFIX then
614 return {vars.LUA_PREFIX} 614 return {vars.LUA_PREFIX}
615 end 615 end
616 616
617 -- No prefix given, so use PATH. 617 -- No prefix given, so use PATH.
618 local path = os.getenv("PATH") or "" 618 local path = os.getenv("PATH") or ""
619 local directories = {} 619 local directories = {}
620 for dir in path:gmatch("[^;]+") do 620 for dir in path:gmatch("[^;]+") do
621 -- Remove trailing backslashes, but not from a drive letter like `C:\`. 621 -- Remove trailing backslashes, but not from a drive letter like `C:\`.
622 dir = dir:gsub("([^:])\\+$", "%1") 622 dir = dir:gsub("([^:])\\+$", "%1")
623 -- Remove trailing `bin` subdirectory, the searcher will check there anyway. 623 -- Remove trailing `bin` subdirectory, the searcher will check there anyway.
624 if dir:upper():match("[:\\]BIN$") then 624 if dir:upper():match("[:\\]BIN$") then
625 dir = dir:sub(1, -5) 625 dir = dir:sub(1, -5)
626 end 626 end
627 table.insert(directories, dir) 627 table.insert(directories, dir)
628 end 628 end
629 -- Finally add some other default paths. 629 -- Finally add some other default paths.
630 table.insert(directories, [[c:\lua5.1.2]]) 630 table.insert(directories, [[c:\lua5.1.2]])
631 table.insert(directories, [[c:\lua]]) 631 table.insert(directories, [[c:\lua]])
632 table.insert(directories, [[c:\kepler\1.1]]) 632 table.insert(directories, [[c:\kepler\1.1]])
633 return directories 633 return directories
634end 634end
635 635
636local function look_for_lua_install () 636local function look_for_lua_install ()
637 print("Looking for Lua interpreter") 637 print("Looking for Lua interpreter")
638 if vars.LUA_BINDIR and vars.LUA_LIBDIR and vars.LUA_INCDIR then 638 if vars.LUA_BINDIR and vars.LUA_LIBDIR and vars.LUA_INCDIR then
639 if look_for_interpreter(vars.LUA_BINDIR) and 639 if look_for_interpreter(vars.LUA_BINDIR) and
640 look_for_link_libraries(vars.LUA_LIBDIR) and 640 look_for_link_libraries(vars.LUA_LIBDIR) and
641 look_for_headers(vars.LUA_INCDIR) 641 look_for_headers(vars.LUA_INCDIR)
642 then 642 then
643 if get_runtime() then 643 if get_runtime() then
644 print("Runtime check completed.") 644 print("Runtime check completed.")
645 return true 645 return true
646 end 646 end
647 end 647 end
648 return false 648 return false
649 end 649 end
650 650
651 for _, directory in ipairs(get_possible_lua_directories()) do 651 for _, directory in ipairs(get_possible_lua_directories()) do
652 print(" checking " .. directory) 652 print(" checking " .. directory)
653 if exists(directory) then 653 if exists(directory) then
654 if look_for_interpreter(directory) then 654 if look_for_interpreter(directory) then
655 print("Interpreter found, now looking for link libraries...") 655 print("Interpreter found, now looking for link libraries...")
656 if look_for_link_libraries(directory) then 656 if look_for_link_libraries(directory) then
657 print("Link library found, now looking for headers...") 657 print("Link library found, now looking for headers...")
658 if look_for_headers(directory) then 658 if look_for_headers(directory) then
659 print("Headers found, checking runtime to use...") 659 print("Headers found, checking runtime to use...")
660 if get_runtime() then 660 if get_runtime() then
661 print("Runtime check completed.") 661 print("Runtime check completed.")
662 return true 662 return true
663 end 663 end
664 end 664 end
665 end 665 end
666 end 666 end
667 end 667 end
668 end 668 end
669 return false 669 return false
670end 670end
671 671
672-- backup config[x.x].lua[.bak] 672-- backup config[x.x].lua[.bak]
673local function backup_config_files() 673local function backup_config_files()
674 local temppath 674 local temppath
675 while not temppath do 675 while not temppath do
676 temppath = os.getenv("temp").."\\LR-config-backup-"..tostring(math.random(10000)) 676 temppath = os.getenv("temp").."\\LR-config-backup-"..tostring(math.random(10000))
677 if exists(temppath) then temppath = nil end 677 if exists(temppath) then temppath = nil end
678 end 678 end
679 vars.CONFBACKUPDIR = temppath 679 vars.CONFBACKUPDIR = temppath
680 mkdir(vars.CONFBACKUPDIR) 680 mkdir(vars.CONFBACKUPDIR)
681 exec(S[[COPY "$PREFIX\config*.*" "$CONFBACKUPDIR" >NUL]]) 681 exec(S[[COPY "$PREFIX\config*.*" "$CONFBACKUPDIR" >NUL]])
682end 682end
683 683
684-- restore previously backed up config files 684-- restore previously backed up config files
685local function restore_config_files() 685local function restore_config_files()
686 if not vars.CONFBACKUPDIR then return end -- there is no backup to restore 686 if not vars.CONFBACKUPDIR then return end -- there is no backup to restore
687 exec(S[[COPY "$CONFBACKUPDIR\config*.*" "$PREFIX" >NUL]]) 687 exec(S[[COPY "$CONFBACKUPDIR\config*.*" "$PREFIX" >NUL]])
688 -- cleanup 688 -- cleanup
689 exec(S[[RD /S /Q "$CONFBACKUPDIR"]]) 689 exec(S[[RD /S /Q "$CONFBACKUPDIR"]])
690 vars.CONFBACKUPDIR = nil 690 vars.CONFBACKUPDIR = nil
691end 691end
692 692
693-- Find GCC based toolchain 693-- Find GCC based toolchain
694local find_gcc_suite = function() 694local find_gcc_suite = function()
695 695
696 -- read output os-command 696 -- read output os-command
697 local read_output = function(cmd) 697 local read_output = function(cmd)
698 local f = io.popen("type NUL && " .. cmd .. ' 2>NUL') 698 local f = io.popen("type NUL && " .. cmd .. ' 2>NUL')
699 if not f then return nil, "failed to open command: " .. tostring(cmd) end 699 if not f then return nil, "failed to open command: " .. tostring(cmd) end
700 local lines = {} 700 local lines = {}
701 while true do 701 while true do
702 local l = f:read() 702 local l = f:read()
703 if not l then 703 if not l then
704 f:close() 704 f:close()
705 return lines 705 return lines
706 end 706 end
707 table.insert(lines, l) 707 table.insert(lines, l)
708 end 708 end
709 end 709 end
710 710
711 -- returns: full filename, path, filename 711 -- returns: full filename, path, filename
712 local find_file = function(mask, path) 712 local find_file = function(mask, path)
713 local cmd 713 local cmd
714 if path then 714 if path then
715 cmd = 'where.exe /R "' .. path .. '" ' .. mask 715 cmd = 'where.exe /R "' .. path .. '" ' .. mask
716 else 716 else
717 cmd = 'where.exe ' .. mask 717 cmd = 'where.exe ' .. mask
718 end 718 end
719 local files, err = read_output(cmd) 719 local files, err = read_output(cmd)
720 if not files or not files[1] then 720 if not files or not files[1] then
721 return nil, "couldn't find '".. mask .. "', " .. (err or "not found") 721 return nil, "couldn't find '".. mask .. "', " .. (err or "not found")
722 end 722 end
723 local path, file = string.match(files[1], "^(.+)%\\([^%\\]+)$") 723 local path, file = string.match(files[1], "^(.+)%\\([^%\\]+)$")
724 return files[1], path, file 724 return files[1], path, file
725 end 725 end
726 726
727 local first_one = "*gcc.exe" -- first file we're assuming to point to the compiler suite 727 local first_one = "*gcc.exe" -- first file we're assuming to point to the compiler suite
728 local full, path, filename = find_file(first_one, nil) 728 local full, path, filename = find_file(first_one, nil)
729 if not full then 729 if not full then
730 return nil, path 730 return nil, path
731 end 731 end
732 vars.MINGW_BIN_PATH = path 732 vars.MINGW_BIN_PATH = path
733 733
734 local result = { 734 local result = {
735 gcc = full 735 gcc = full
736 } 736 }
737 for i, name in ipairs({"make", "ar", "windres", "ranlib"}) do 737 for i, name in ipairs({"make", "ar", "windres", "ranlib"}) do
738 result[name] = find_file(name..".exe", path) 738 result[name] = find_file(name..".exe", path)
739 if not result[name] then 739 if not result[name] then
740 result[name] = find_file("*"..name.."*.exe", path) 740 result[name] = find_file("*"..name.."*.exe", path)
741 end 741 end
742 end 742 end
743 743
744 vars.MINGW_MAKE = (result.make and '[['..result.make..']]') or "nil, -- not found by installer" 744 vars.MINGW_MAKE = (result.make and '[['..result.make..']]') or "nil, -- not found by installer"
745 vars.MINGW_CC = (result.gcc and '[['..result.gcc..']]') or "nil, -- not found by installer" 745 vars.MINGW_CC = (result.gcc and '[['..result.gcc..']]') or "nil, -- not found by installer"
746 vars.MINGW_RC = (result.windres and '[['..result.windres..']]') or "nil, -- not found by installer" 746 vars.MINGW_RC = (result.windres and '[['..result.windres..']]') or "nil, -- not found by installer"
747 vars.MINGW_LD = (result.gcc and '[['..result.gcc..']]') or "nil, -- not found by installer" 747 vars.MINGW_LD = (result.gcc and '[['..result.gcc..']]') or "nil, -- not found by installer"
748 vars.MINGW_AR = (result.ar and '[['..result.ar..']]') or "nil, -- not found by installer" 748 vars.MINGW_AR = (result.ar and '[['..result.ar..']]') or "nil, -- not found by installer"
749 vars.MINGW_RANLIB = (result.ranlib and '[['..result.ranlib..']]') or "nil, -- not found by installer" 749 vars.MINGW_RANLIB = (result.ranlib and '[['..result.ranlib..']]') or "nil, -- not found by installer"
750 return true 750 return true
751end 751end
752 752
753-- *********************************************************** 753-- ***********************************************************
754-- Installer script start 754-- Installer script start
755-- *********************************************************** 755-- ***********************************************************
756 756
757-- Poor man's command-line parsing 757-- Poor man's command-line parsing
758local config = {} 758local config = {}
759local with_arg = { -- options followed by an argument, others are flags 759local with_arg = { -- options followed by an argument, others are flags
760 ["/P"] = true, 760 ["/P"] = true,
761 ["/CONFIG"] = true, 761 ["/CONFIG"] = true,
762 ["/TREE"] = true, 762 ["/TREE"] = true,
763 ["/SCRIPTS"] = true, 763 ["/SCRIPTS"] = true,
764 ["/LUAMOD"] = true, 764 ["/LUAMOD"] = true,
765 ["/CMOD"] = true, 765 ["/CMOD"] = true,
766 ["/LV"] = true, 766 ["/LV"] = true,
767 ["/LUA"] = true, 767 ["/LUA"] = true,
768 ["/INC"] = true, 768 ["/INC"] = true,
769 ["/BIN"] = true, 769 ["/BIN"] = true,
770 ["/LIB"] = true, 770 ["/LIB"] = true,
771} 771}
772-- reconstruct argument values with spaces and double quotes 772-- reconstruct argument values with spaces and double quotes
773-- this will be damaged by the batch construction at the start of this file 773-- this will be damaged by the batch construction at the start of this file
774local oarg = arg -- retain old table 774local oarg = arg -- retain old table
775if #arg > 0 then 775if #arg > 0 then
776 local farg = table.concat(arg, " ") .. " " 776 local farg = table.concat(arg, " ") .. " "
777 arg = {} 777 arg = {}
778 farg = farg:gsub('%"', "") 778 farg = farg:gsub('%"', "")
779 local i = 0 779 local i = 0
780 while #farg>0 do 780 while #farg>0 do
781 i = i + 1 781 i = i + 1
782 if (farg:sub(1,1) ~= "/") and ((arg[i-1] or ""):sub(1,1) ~= "/") then 782 if (farg:sub(1,1) ~= "/") and ((arg[i-1] or ""):sub(1,1) ~= "/") then
783 i = i - 1 -- continued previous arg 783 i = i - 1 -- continued previous arg
784 if i == 0 then i = 1 end 784 if i == 0 then i = 1 end
785 end 785 end
786 if arg[i] then 786 if arg[i] then
787 arg[i] = arg[i] .. " " 787 arg[i] = arg[i] .. " "
788 else 788 else
789 arg[i] = "" 789 arg[i] = ""
790 end 790 end
791 local v,r = farg:match("^(.-)%s(.*)$") 791 local v,r = farg:match("^(.-)%s(.*)$")
792 arg[i], farg = arg[i]..v, r 792 arg[i], farg = arg[i]..v, r
793 while farg:sub(1,1) == " " do farg = farg:sub(2,-1) end -- remove prefix spaces 793 while farg:sub(1,1) == " " do farg = farg:sub(2,-1) end -- remove prefix spaces
794 end 794 end
795end 795end
796for k,v in pairs(oarg) do if k < 1 then arg[k] = v end end -- copy 0 and negative indexes 796for k,v in pairs(oarg) do if k < 1 then arg[k] = v end end -- copy 0 and negative indexes
797 797
798-- build config option table with name and value elements 798-- build config option table with name and value elements
799local i = 1 799local i = 1
800while i <= #arg do 800while i <= #arg do
801 local opt = arg[i] 801 local opt = arg[i]
802 if with_arg[opt:upper()] then 802 if with_arg[opt:upper()] then
803 local value = arg[i + 1] 803 local value = arg[i + 1]
804 if not value then 804 if not value then
805 die("Missing value for option "..opt) 805 die("Missing value for option "..opt)
806 end 806 end
807 config[#config + 1] = { name = opt, value = value } 807 config[#config + 1] = { name = opt, value = value }
808 i = i + 1 808 i = i + 1
809 else 809 else
810 config[#config + 1] = { name = opt } 810 config[#config + 1] = { name = opt }
811 end 811 end
812 i = i + 1 812 i = i + 1
813end 813end
814 814
815print(S"LuaRocks $VERSION.x installer.\n") 815print(S"LuaRocks $VERSION.x installer.\n")
816 816
817parse_options(config) 817parse_options(config)
818 818
819print([[ 819print([[
820 820
821======================== 821========================
822== Checking system... == 822== Checking system... ==
823======================== 823========================
824 824
825]]) 825]])
826 826
827check_flags() 827check_flags()
828 828
829if not permission() then 829if not permission() then
830 if not NOADMIN then 830 if not NOADMIN then
831 -- must elevate the process with admin privileges 831 -- must elevate the process with admin privileges
832 if not exec("PowerShell /? >NUL 2>&1") then 832 if not exec("PowerShell /? >NUL 2>&1") then
833 -- powershell is not available, so error out 833 -- powershell is not available, so error out
834 die("No administrative privileges detected and cannot auto-elevate. Please run with admin privileges or use the /NOADMIN switch") 834 die("No administrative privileges detected and cannot auto-elevate. Please run with admin privileges or use the /NOADMIN switch")
835 end 835 end
836 print("Need admin privileges, now elevating a new process to continue installing...") 836 print("Need admin privileges, now elevating a new process to continue installing...")
837 local runner = os.getenv("TEMP").."\\".."LuaRocks_Installer.bat" 837 local runner = os.getenv("TEMP").."\\".."LuaRocks_Installer.bat"
838 local f = io.open(runner, "w") 838 local f = io.open(runner, "w")
839 f:write("@echo off\n") 839 f:write("@echo off\n")
840 f:write("CHDIR /D "..arg[0]:match("(.+)%\\.-$").."\n") -- return to current dir, elevation changes current path 840 f:write("CHDIR /D "..arg[0]:match("(.+)%\\.-$").."\n") -- return to current dir, elevation changes current path
841 f:write('"'..arg[-1]..'" "'..table.concat(arg, '" "', 0)..'"\n') 841 f:write('"'..arg[-1]..'" "'..table.concat(arg, '" "', 0)..'"\n')
842 f:write("ECHO Press any key to close this window...\n") 842 f:write("ECHO Press any key to close this window...\n")
843 f:write("PAUSE > NUL\n") 843 f:write("PAUSE > NUL\n")
844 f:write('DEL "'..runner..'"') -- temp batch file deletes itself 844 f:write('DEL "'..runner..'"') -- temp batch file deletes itself
845 f:close() 845 f:close()
846 -- run the created temp batch file in elevated mode 846 -- run the created temp batch file in elevated mode
847 exec("PowerShell -Command (New-Object -com 'Shell.Application').ShellExecute('"..runner.."', '', '', 'runas')\n") 847 exec("PowerShell -Command (New-Object -com 'Shell.Application').ShellExecute('"..runner.."', '', '', 'runas')\n")
848 print("Now exiting unprivileged installer") 848 print("Now exiting unprivileged installer")
849 os.exit() -- exit here, the newly created elevated process will do the installing 849 os.exit() -- exit here, the newly created elevated process will do the installing
850 else 850 else
851 print("Attempting to install without admin privileges...") 851 print("Attempting to install without admin privileges...")
852 end 852 end
853else 853else
854 print("Admin privileges available for installing") 854 print("Admin privileges available for installing")
855end 855end
856 856
857vars.PREFIX = vars.PREFIX or os.getenv("PROGRAMFILES")..[[\LuaRocks]] 857vars.PREFIX = vars.PREFIX or os.getenv("PROGRAMFILES")..[[\LuaRocks]]
858vars.BINDIR = vars.PREFIX 858vars.BINDIR = vars.PREFIX
859vars.LIBDIR = vars.PREFIX 859vars.LIBDIR = vars.PREFIX
860vars.LUADIR = S"$PREFIX\\lua" 860vars.LUADIR = S"$PREFIX\\lua"
861vars.INCDIR = S"$PREFIX\\include" 861vars.INCDIR = S"$PREFIX\\include"
862vars.LUA_SHORTV = vars.LUA_VERSION:gsub("%.", "") 862vars.LUA_SHORTV = vars.LUA_VERSION:gsub("%.", "")
863 863
864if INSTALL_LUA then 864if INSTALL_LUA then
865 vars.LUA_INTERPRETER = "lua5.1" 865 vars.LUA_INTERPRETER = "lua5.1"
866 vars.LUA_BINDIR = vars.BINDIR 866 vars.LUA_BINDIR = vars.BINDIR
867 vars.LUA_LIBDIR = vars.LIBDIR 867 vars.LUA_LIBDIR = vars.LIBDIR
868 vars.LUA_INCDIR = vars.INCDIR 868 vars.LUA_INCDIR = vars.INCDIR
869 vars.LUA_LIBNAME = "lua5.1.lib" 869 vars.LUA_LIBNAME = "lua5.1.lib"
870 vars.LUA_RUNTIME = "MSVCR80" 870 vars.LUA_RUNTIME = "MSVCR80"
871 vars.UNAME_M = "x86" 871 vars.UNAME_M = "x86"
872else 872else
873 if not look_for_lua_install() then 873 if not look_for_lua_install() then
874 die("Could not find Lua. See /? for options for specifying the location of Lua, or installing a bundled copy of Lua 5.1.") 874 die("Could not find Lua. See /? for options for specifying the location of Lua, or installing a bundled copy of Lua 5.1.")
875 end 875 end
876 vars.UNAME_M = get_architecture() -- can only do when installation was found 876 vars.UNAME_M = get_architecture() -- can only do when installation was found
877end 877end
878 878
879-- check location of system tree 879-- check location of system tree
880if not vars.TREE_ROOT then 880if not vars.TREE_ROOT then
881 -- no system tree location given, so we need to construct a default value 881 -- no system tree location given, so we need to construct a default value
882 if vars.LUA_BINDIR:lower():match([[([\/]+bin[\/]*)$]]) then 882 if vars.LUA_BINDIR:lower():match([[([\/]+bin[\/]*)$]]) then
883 -- lua binary is located in a 'bin' subdirectory, so assume 883 -- lua binary is located in a 'bin' subdirectory, so assume
884 -- default Lua layout and match rocktree on top 884 -- default Lua layout and match rocktree on top
885 vars.TREE_ROOT = vars.LUA_BINDIR:lower():gsub([[[\/]+bin[\/]*$]], [[\]]) 885 vars.TREE_ROOT = vars.LUA_BINDIR:lower():gsub([[[\/]+bin[\/]*$]], [[\]])
886 else 886 else
887 -- no 'bin', so use a named tree next to the Lua executable 887 -- no 'bin', so use a named tree next to the Lua executable
888 vars.TREE_ROOT = vars.LUA_BINDIR .. [[\systree]] 888 vars.TREE_ROOT = vars.LUA_BINDIR .. [[\systree]]
889 end 889 end
890end 890end
891 891
892vars.SYSCONFDIR = vars.SYSCONFDIR or vars.PREFIX 892vars.SYSCONFDIR = vars.SYSCONFDIR or vars.PREFIX
893vars.SYSCONFFILENAME = S"config-$LUA_VERSION.lua" 893vars.SYSCONFFILENAME = S"config-$LUA_VERSION.lua"
894vars.CONFIG_FILE = vars.SYSCONFDIR.."\\"..vars.SYSCONFFILENAME 894vars.CONFIG_FILE = vars.SYSCONFDIR.."\\"..vars.SYSCONFFILENAME
895if SELFCONTAINED then 895if SELFCONTAINED then
896 vars.SYSCONFDIR = vars.PREFIX 896 vars.SYSCONFDIR = vars.PREFIX
897 vars.TREE_ROOT = vars.PREFIX..[[\systree]] 897 vars.TREE_ROOT = vars.PREFIX..[[\systree]]
898 REGISTRY = false 898 REGISTRY = false
899end 899end
900if USE_MINGW then 900if USE_MINGW then
901 vars.COMPILER_ENV_CMD = "" 901 vars.COMPILER_ENV_CMD = ""
902 local found, err = find_gcc_suite() 902 local found, err = find_gcc_suite()
903 if not found then 903 if not found then
904 die("Failed to find MinGW/gcc based toolchain, make sure it is in your path: " .. tostring(err)) 904 die("Failed to find MinGW/gcc based toolchain, make sure it is in your path: " .. tostring(err))
905 end 905 end
906else 906else
907 vars.COMPILER_ENV_CMD = (USE_MSVC_MANUAL and "") or get_msvc_env_setup_cmd() 907 vars.COMPILER_ENV_CMD = (USE_MSVC_MANUAL and "") or get_msvc_env_setup_cmd()
908end 908end
909 909
910print(S[[ 910print(S[[
911 911
912========================== 912==========================
913== System check results == 913== System check results ==
914========================== 914==========================
915 915
916Will configure LuaRocks with the following paths: 916Will configure LuaRocks with the following paths:
917LuaRocks : $PREFIX 917LuaRocks : $PREFIX
918Config file : $CONFIG_FILE 918Config file : $CONFIG_FILE
919Rocktree : $TREE_ROOT 919Rocktree : $TREE_ROOT
920 920
921Lua interpreter : $LUA_BINDIR\$LUA_INTERPRETER 921Lua interpreter : $LUA_BINDIR\$LUA_INTERPRETER
922 binaries : $LUA_BINDIR 922 binaries : $LUA_BINDIR
923 libraries : $LUA_LIBDIR 923 libraries : $LUA_LIBDIR
924 includes : $LUA_INCDIR 924 includes : $LUA_INCDIR
925 architecture: $UNAME_M 925 architecture: $UNAME_M
926 binary link : $LUA_LIBNAME with runtime $LUA_RUNTIME.dll 926 binary link : $LUA_LIBNAME with runtime $LUA_RUNTIME.dll
927]]) 927]])
928 928
929if USE_MINGW then 929if USE_MINGW then
930 print(S[[Compiler : MinGW/gcc (make sure it is in your path before using LuaRocks)]]) 930 print(S[[Compiler : MinGW/gcc (make sure it is in your path before using LuaRocks)]])
931 print(S[[ in: $MINGW_BIN_PATH]]) 931 print(S[[ in: $MINGW_BIN_PATH]])
932else 932else
933 if vars.COMPILER_ENV_CMD == "" then 933 if vars.COMPILER_ENV_CMD == "" then
934 print("Compiler : Microsoft (make sure it is in your path before using LuaRocks)") 934 print("Compiler : Microsoft (make sure it is in your path before using LuaRocks)")
935 else 935 else
936 print(S[[Compiler : Microsoft, using; $COMPILER_ENV_CMD]]) 936 print(S[[Compiler : Microsoft, using; $COMPILER_ENV_CMD]])
937 end 937 end
938end 938end
939 939
940if PROMPT then 940if PROMPT then
941 print("\nPress <ENTER> to start installing, or press <CTRL>+<C> to abort. Use install /? for installation options.") 941 print("\nPress <ENTER> to start installing, or press <CTRL>+<C> to abort. Use install /? for installation options.")
942 io.read() 942 io.read()
943end 943end
944 944
945print([[ 945print([[
946 946
947============================ 947============================
948== Installing LuaRocks... == 948== Installing LuaRocks... ==
949============================ 949============================
950 950
951]]) 951]])
952 952
953-- *********************************************************** 953-- ***********************************************************
954-- Install LuaRocks files 954-- Install LuaRocks files
955-- *********************************************************** 955-- ***********************************************************
956 956
957if exists(vars.PREFIX) then 957if exists(vars.PREFIX) then
958 if not FORCE then 958 if not FORCE then
959 die(S"$PREFIX exists. Use /F to force removal and reinstallation.") 959 die(S"$PREFIX exists. Use /F to force removal and reinstallation.")
960 else 960 else
961 backup_config_files() 961 backup_config_files()
962 print(S"Removing $PREFIX...") 962 print(S"Removing $PREFIX...")
963 exec(S[[RD /S /Q "$PREFIX"]]) 963 exec(S[[RD /S /Q "$PREFIX"]])
964 print() 964 print()
965 end 965 end
966end 966end
967 967
968print(S"Installing LuaRocks in $PREFIX...") 968print(S"Installing LuaRocks in $PREFIX...")
969if not exists(vars.BINDIR) then 969if not exists(vars.BINDIR) then
970 if not mkdir(vars.BINDIR) then 970 if not mkdir(vars.BINDIR) then
971 die() 971 die()
972 end 972 end
973end 973end
974 974
975if INSTALL_LUA then 975if INSTALL_LUA then
976 -- Copy the included Lua interpreter binaries 976 -- Copy the included Lua interpreter binaries
977 if not exists(vars.LUA_BINDIR) then 977 if not exists(vars.LUA_BINDIR) then
978 mkdir(vars.LUA_BINDIR) 978 mkdir(vars.LUA_BINDIR)
979 end 979 end
980 if not exists(vars.LUA_INCDIR) then 980 if not exists(vars.LUA_INCDIR) then
981 mkdir(vars.LUA_INCDIR) 981 mkdir(vars.LUA_INCDIR)
982 end 982 end
983 exec(S[[COPY win32\lua5.1\bin\*.* "$LUA_BINDIR" >NUL]]) 983 exec(S[[COPY win32\lua5.1\bin\*.* "$LUA_BINDIR" >NUL]])
984 exec(S[[COPY win32\lua5.1\include\*.* "$LUA_INCDIR" >NUL]]) 984 exec(S[[COPY win32\lua5.1\include\*.* "$LUA_INCDIR" >NUL]])
985 print(S"Installed the LuaRocks bundled Lua interpreter in $LUA_BINDIR") 985 print(S"Installed the LuaRocks bundled Lua interpreter in $LUA_BINDIR")
986end 986end
987 987
988-- Copy the LuaRocks binaries 988-- Copy the LuaRocks binaries
989if not exists(S[[$BINDIR\tools]]) then 989if not exists(S[[$BINDIR\tools]]) then
990 if not mkdir(S[[$BINDIR\tools]]) then 990 if not mkdir(S[[$BINDIR\tools]]) then
991 die() 991 die()
992 end 992 end
993end 993end
994if not exec(S[[COPY win32\tools\*.* "$BINDIR\tools" >NUL]]) then 994if not exec(S[[COPY win32\tools\*.* "$BINDIR\tools" >NUL]]) then
995 die() 995 die()
996end 996end
997-- Copy LR bin helper files 997-- Copy LR bin helper files
998if not exec(S[[COPY win32\*.* "$BINDIR" >NUL]]) then 998if not exec(S[[COPY win32\*.* "$BINDIR" >NUL]]) then
999 die() 999 die()
1000end 1000end
1001-- Copy the LuaRocks lua source files 1001-- Copy the LuaRocks lua source files
1002if not exists(S[[$LUADIR\luarocks]]) then 1002if not exists(S[[$LUADIR\luarocks]]) then
1003 if not mkdir(S[[$LUADIR\luarocks]]) then 1003 if not mkdir(S[[$LUADIR\luarocks]]) then
1004 die() 1004 die()
1005 end 1005 end
1006end 1006end
1007if not exec(S[[XCOPY /S src\luarocks\*.* "$LUADIR\luarocks" >NUL]]) then 1007if not exec(S[[XCOPY /S src\luarocks\*.* "$LUADIR\luarocks" >NUL]]) then
1008 die() 1008 die()
1009end 1009end
1010-- Create start scripts 1010-- Create start scripts
1011if not exec(S[[COPY src\bin\*.* "$BINDIR" >NUL]]) then 1011if not exec(S[[COPY src\bin\*.* "$BINDIR" >NUL]]) then
1012 die() 1012 die()
1013end 1013end
1014for _, c in ipairs{"luarocks", "luarocks-admin"} do 1014for _, c in ipairs{"luarocks", "luarocks-admin"} do
1015 -- rename unix-lua scripts to .lua files 1015 -- rename unix-lua scripts to .lua files
1016 if not exec( (S[[RENAME "$BINDIR\%s" %s.lua]]):format(c, c) ) then 1016 if not exec( (S[[RENAME "$BINDIR\%s" %s.lua]]):format(c, c) ) then
1017 die() 1017 die()
1018 end 1018 end
1019 -- create a bootstrap batch file for the lua file, to start them 1019 -- create a bootstrap batch file for the lua file, to start them
1020 exec(S[[DEL /F /Q "$BINDIR\]]..c..[[.bat" 2>NUL]]) 1020 exec(S[[DEL /F /Q "$BINDIR\]]..c..[[.bat" 2>NUL]])
1021 local f = io.open(vars.BINDIR.."\\"..c..".bat", "w") 1021 local f = io.open(vars.BINDIR.."\\"..c..".bat", "w")
1022 f:write(S[[ 1022 f:write(S[[
1023@ECHO OFF 1023@ECHO OFF
1024SETLOCAL ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS 1024SETLOCAL ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS
1025$COMPILER_ENV_CMD 1025$COMPILER_ENV_CMD >NUL
1026SET "LUA_PATH=$LUADIR\?.lua;$LUADIR\?\init.lua;%LUA_PATH%" 1026SET "LUA_PATH=$LUADIR\?.lua;$LUADIR\?\init.lua;%LUA_PATH%"
1027IF NOT "%LUA_PATH_5_2%"=="" ( 1027IF NOT "%LUA_PATH_5_2%"=="" (
1028 SET "LUA_PATH_5_2=$LUADIR\?.lua;$LUADIR\?\init.lua;%LUA_PATH_5_2%" 1028 SET "LUA_PATH_5_2=$LUADIR\?.lua;$LUADIR\?\init.lua;%LUA_PATH_5_2%"
1029) 1029)
1030IF NOT "%LUA_PATH_5_3%"=="" ( 1030IF NOT "%LUA_PATH_5_3%"=="" (
1031 SET "LUA_PATH_5_3=$LUADIR\?.lua;$LUADIR\?\init.lua;%LUA_PATH_5_3%" 1031 SET "LUA_PATH_5_3=$LUADIR\?.lua;$LUADIR\?\init.lua;%LUA_PATH_5_3%"
1032) 1032)
1033SET "PATH=$BINDIR;%PATH%" 1033SET "PATH=$BINDIR;%PATH%"
1034"$LUA_BINDIR\$LUA_INTERPRETER" "$BINDIR\]]..c..[[.lua" %* 1034"$LUA_BINDIR\$LUA_INTERPRETER" "$BINDIR\]]..c..[[.lua" %*
1035SET EXITCODE=%ERRORLEVEL% 1035SET EXITCODE=%ERRORLEVEL%
1036IF NOT "%EXITCODE%"=="2" GOTO EXITLR 1036IF NOT "%EXITCODE%"=="2" GOTO EXITLR
1037 1037
1038REM Permission denied error, try and auto elevate... 1038REM Permission denied error, try and auto elevate...
1039REM already an admin? (checking to prevent loops) 1039REM already an admin? (checking to prevent loops)
1040NET SESSION >NUL 2>&1 1040NET SESSION >NUL 2>&1
1041IF "%ERRORLEVEL%"=="0" GOTO EXITLR 1041IF "%ERRORLEVEL%"=="0" GOTO EXITLR
1042 1042
1043REM Do we have PowerShell available? 1043REM Do we have PowerShell available?
1044PowerShell /? >NUL 2>&1 1044PowerShell /? >NUL 2>&1
1045IF NOT "%ERRORLEVEL%"=="0" GOTO EXITLR 1045IF NOT "%ERRORLEVEL%"=="0" GOTO EXITLR
1046 1046
1047:GETTEMPNAME 1047:GETTEMPNAME
1048SET TMPFILE=%TEMP%\LuaRocks-Elevator-%RANDOM%.bat 1048SET TMPFILE=%TEMP%\LuaRocks-Elevator-%RANDOM%.bat
1049IF EXIST "%TMPFILE%" GOTO :GETTEMPNAME 1049IF EXIST "%TMPFILE%" GOTO :GETTEMPNAME
1050 1050
1051ECHO @ECHO OFF > "%TMPFILE%" 1051ECHO @ECHO OFF > "%TMPFILE%"
1052ECHO CHDIR /D %CD% >> "%TMPFILE%" 1052ECHO CHDIR /D %CD% >> "%TMPFILE%"
1053ECHO ECHO %0 %* >> "%TMPFILE%" 1053ECHO ECHO %0 %* >> "%TMPFILE%"
1054ECHO ECHO. >> "%TMPFILE%" 1054ECHO ECHO. >> "%TMPFILE%"
1055ECHO CALL %0 %* >> "%TMPFILE%" 1055ECHO CALL %0 %* >> "%TMPFILE%"
1056ECHO ECHO. >> "%TMPFILE%" 1056ECHO ECHO. >> "%TMPFILE%"
1057ECHO ECHO Press any key to close this window... >> "%TMPFILE%" 1057ECHO ECHO Press any key to close this window... >> "%TMPFILE%"
1058ECHO PAUSE ^> NUL >> "%TMPFILE%" 1058ECHO PAUSE ^> NUL >> "%TMPFILE%"
1059ECHO DEL "%TMPFILE%" >> "%TMPFILE%" 1059ECHO DEL "%TMPFILE%" >> "%TMPFILE%"
1060 1060
1061ECHO Now retrying as a privileged user... 1061ECHO Now retrying as a privileged user...
1062PowerShell -Command (New-Object -com 'Shell.Application').ShellExecute('%TMPFILE%', '', '', 'runas') 1062PowerShell -Command (New-Object -com 'Shell.Application').ShellExecute('%TMPFILE%', '', '', 'runas')
1063 1063
1064:EXITLR 1064:EXITLR
1065exit /b %EXITCODE% 1065exit /b %EXITCODE%
1066]]) 1066]])
1067 f:close() 1067 f:close()
1068 print(S"Created LuaRocks command: $BINDIR\\"..c..".bat") 1068 print(S"Created LuaRocks command: $BINDIR\\"..c..".bat")
1069end 1069end
1070 1070
1071-- *********************************************************** 1071-- ***********************************************************
1072-- Configure LuaRocks 1072-- Configure LuaRocks
1073-- *********************************************************** 1073-- ***********************************************************
1074 1074
1075restore_config_files() 1075restore_config_files()
1076print() 1076print()
1077print("Configuring LuaRocks...") 1077print("Configuring LuaRocks...")
1078 1078
1079-- Create hardcoded.lua 1079-- Create hardcoded.lua
1080 1080
1081local hardcoded_lua = S[[$LUADIR\luarocks\core\hardcoded.lua]] 1081local hardcoded_lua = S[[$LUADIR\luarocks\core\hardcoded.lua]]
1082 1082
1083os.remove(hardcoded_lua) 1083os.remove(hardcoded_lua)
1084 1084
1085vars.SYSTEM = USE_MINGW and "mingw" or "windows" 1085vars.SYSTEM = USE_MINGW and "mingw" or "windows"
1086 1086
1087local f = io.open(hardcoded_lua, "w") 1087local f = io.open(hardcoded_lua, "w")
1088f:write(S[=[ 1088f:write(S[=[
1089return { 1089return {
1090 LUA_INCDIR=[[$LUA_INCDIR]], 1090 LUA_INCDIR=[[$LUA_INCDIR]],
1091 LUA_LIBDIR=[[$LUA_LIBDIR]], 1091 LUA_LIBDIR=[[$LUA_LIBDIR]],
1092 LUA_BINDIR=[[$LUA_BINDIR]], 1092 LUA_BINDIR=[[$LUA_BINDIR]],
1093 LUA_INTERPRETER=[[$LUA_INTERPRETER]], 1093 LUA_INTERPRETER=[[$LUA_INTERPRETER]],
1094 SYSTEM = [[$SYSTEM]], 1094 SYSTEM = [[$SYSTEM]],
1095 PROCESSOR = [[$UNAME_M]], 1095 PROCESSOR = [[$UNAME_M]],
1096 PREFIX = [[$PREFIX]], 1096 PREFIX = [[$PREFIX]],
1097 SYSCONFDIR = [[$SYSCONFDIR]], 1097 SYSCONFDIR = [[$SYSCONFDIR]],
1098 WIN_TOOLS = [[$PREFIX/tools]], 1098 WIN_TOOLS = [[$PREFIX/tools]],
1099]=]) 1099]=])
1100if FORCE_CONFIG then 1100if FORCE_CONFIG then
1101 f:write(" FORCE_CONFIG = true,\n") 1101 f:write(" FORCE_CONFIG = true,\n")
1102end 1102end
1103f:write("}\n") 1103f:write("}\n")
1104f:close() 1104f:close()
1105print(S([[Created LuaRocks hardcoded settings file: $LUADIR\luarocks\core\hardcoded.lua]])) 1105print(S([[Created LuaRocks hardcoded settings file: $LUADIR\luarocks\core\hardcoded.lua]]))
1106 1106
1107-- create config file 1107-- create config file
1108if not exists(vars.SYSCONFDIR) then 1108if not exists(vars.SYSCONFDIR) then
1109 mkdir(vars.SYSCONFDIR) 1109 mkdir(vars.SYSCONFDIR)
1110end 1110end
1111if exists(vars.CONFIG_FILE) then 1111if exists(vars.CONFIG_FILE) then
1112 local nname = backup(vars.CONFIG_FILE, vars.SYSCONFFILENAME..".bak") 1112 local nname = backup(vars.CONFIG_FILE, vars.SYSCONFFILENAME..".bak")
1113 print("***************") 1113 print("***************")
1114 print(S"*** WARNING *** LuaRocks config file already exists: '$CONFIG_FILE'. The old file has been renamed to '"..nname.."'") 1114 print(S"*** WARNING *** LuaRocks config file already exists: '$CONFIG_FILE'. The old file has been renamed to '"..nname.."'")
1115 print("***************") 1115 print("***************")
1116end 1116end
1117local f = io.open(vars.CONFIG_FILE, "w") 1117local f = io.open(vars.CONFIG_FILE, "w")
1118f:write([=[ 1118f:write([=[
1119rocks_trees = { 1119rocks_trees = {
1120]=]) 1120]=])
1121if FORCE_CONFIG then 1121if FORCE_CONFIG then
1122 f:write(" home..[[/luarocks]],\n") 1122 f:write(" home..[[/luarocks]],\n")
1123end 1123end
1124f:write(S" { name = [[user]],\n") 1124f:write(S" { name = [[user]],\n")
1125f:write(S" root = home..[[/luarocks]],\n") 1125f:write(S" root = home..[[/luarocks]],\n")
1126f:write(S" },\n") 1126f:write(S" },\n")
1127f:write(S" { name = [[system]],\n") 1127f:write(S" { name = [[system]],\n")
1128f:write(S" root = [[$TREE_ROOT]],\n") 1128f:write(S" root = [[$TREE_ROOT]],\n")
1129if vars.TREE_BIN then 1129if vars.TREE_BIN then
1130 f:write(S" bin_dir = [[$TREE_BIN]],\n") 1130 f:write(S" bin_dir = [[$TREE_BIN]],\n")
1131end 1131end
1132if vars.TREE_CMODULE then 1132if vars.TREE_CMODULE then
1133 f:write(S" lib_dir = [[$TREE_CMODULE]],\n") 1133 f:write(S" lib_dir = [[$TREE_CMODULE]],\n")
1134end 1134end
1135if vars.TREE_LMODULE then 1135if vars.TREE_LMODULE then
1136 f:write(S" lua_dir = [[$TREE_LMODULE]],\n") 1136 f:write(S" lua_dir = [[$TREE_LMODULE]],\n")
1137end 1137end
1138f:write(S" },\n") 1138f:write(S" },\n")
1139f:write("}\n") 1139f:write("}\n")
1140f:write("variables = {\n") 1140f:write("variables = {\n")
1141if USE_MINGW and vars.LUA_RUNTIME == "MSVCRT" then 1141if USE_MINGW and vars.LUA_RUNTIME == "MSVCRT" then
1142 f:write(" MSVCRT = 'm', -- make MinGW use MSVCRT.DLL as runtime\n") 1142 f:write(" MSVCRT = 'm', -- make MinGW use MSVCRT.DLL as runtime\n")
1143else 1143else
1144 f:write(" MSVCRT = '"..vars.LUA_RUNTIME.."',\n") 1144 f:write(" MSVCRT = '"..vars.LUA_RUNTIME.."',\n")
1145end 1145end
1146f:write(S" LUALIB = '$LUA_LIBNAME',\n") 1146f:write(S" LUALIB = '$LUA_LIBNAME',\n")
1147if USE_MINGW then 1147if USE_MINGW then
1148 f:write(S[[ 1148 f:write(S[[
1149 CC = $MINGW_CC, 1149 CC = $MINGW_CC,
1150 MAKE = $MINGW_MAKE, 1150 MAKE = $MINGW_MAKE,
1151 RC = $MINGW_RC, 1151 RC = $MINGW_RC,
1152 LD = $MINGW_LD, 1152 LD = $MINGW_LD,
1153 AR = $MINGW_AR, 1153 AR = $MINGW_AR,
1154 RANLIB = $MINGW_RANLIB, 1154 RANLIB = $MINGW_RANLIB,
1155]]) 1155]])
1156end 1156end
1157f:write("}\n") 1157f:write("}\n")
1158f:write("verbose = false -- set to 'true' to enable verbose output\n") 1158f:write("verbose = false -- set to 'true' to enable verbose output\n")
1159f:close() 1159f:close()
1160 1160
1161print(S"Created LuaRocks config file: $CONFIG_FILE") 1161print(S"Created LuaRocks config file: $CONFIG_FILE")
1162 1162
1163 1163
1164print() 1164print()
1165print("Creating rocktrees...") 1165print("Creating rocktrees...")
1166if not exists(vars.TREE_ROOT) then 1166if not exists(vars.TREE_ROOT) then
1167 mkdir(vars.TREE_ROOT) 1167 mkdir(vars.TREE_ROOT)
1168 print(S[[Created system rocktree : "$TREE_ROOT"]]) 1168 print(S[[Created system rocktree : "$TREE_ROOT"]])
1169else 1169else
1170 print(S[[System rocktree exists : "$TREE_ROOT"]]) 1170 print(S[[System rocktree exists : "$TREE_ROOT"]])
1171end 1171end
1172 1172
1173vars.APPDATA = os.getenv("APPDATA") 1173vars.APPDATA = os.getenv("APPDATA")
1174vars.LOCAL_TREE = vars.APPDATA..[[\LuaRocks]] 1174vars.LOCAL_TREE = vars.APPDATA..[[\LuaRocks]]
1175if not exists(vars.LOCAL_TREE) then 1175if not exists(vars.LOCAL_TREE) then
1176 mkdir(vars.LOCAL_TREE) 1176 mkdir(vars.LOCAL_TREE)
1177 print(S[[Created local user rocktree: "$LOCAL_TREE"]]) 1177 print(S[[Created local user rocktree: "$LOCAL_TREE"]])
1178else 1178else
1179 print(S[[Local user rocktree exists : "$LOCAL_TREE"]]) 1179 print(S[[Local user rocktree exists : "$LOCAL_TREE"]])
1180end 1180end
1181 1181
1182-- Load registry information 1182-- Load registry information
1183if REGISTRY then 1183if REGISTRY then
1184 -- expand template with correct path information 1184 -- expand template with correct path information
1185 print() 1185 print()
1186 print([[Loading registry information for ".rockspec" files]]) 1186 print([[Loading registry information for ".rockspec" files]])
1187 exec( S[[win32\lua5.1\bin\lua5.1.exe "$PREFIX\LuaRocks.reg.lua" "$PREFIX\LuaRocks.reg.template"]] ) 1187 exec( S[[win32\lua5.1\bin\lua5.1.exe "$PREFIX\LuaRocks.reg.lua" "$PREFIX\LuaRocks.reg.template"]] )
1188 exec( S[[regedit /S "$PREFIX\\LuaRocks.reg"]] ) 1188 exec( S[[regedit /S "$PREFIX\\LuaRocks.reg"]] )
1189end 1189end
1190 1190
1191-- *********************************************************** 1191-- ***********************************************************
1192-- Cleanup 1192-- Cleanup
1193-- *********************************************************** 1193-- ***********************************************************
1194-- remove registry related files, no longer needed 1194-- remove registry related files, no longer needed
1195exec( S[[del "$PREFIX\LuaRocks.reg.*" >NUL]] ) 1195exec( S[[del "$PREFIX\LuaRocks.reg.*" >NUL]] )
1196 1196
1197-- *********************************************************** 1197-- ***********************************************************
1198-- Exit handlers 1198-- Exit handlers
1199-- *********************************************************** 1199-- ***********************************************************
1200vars.TREE_BIN = vars.TREE_BIN or vars.TREE_ROOT..[[\bin]] 1200vars.TREE_BIN = vars.TREE_BIN or vars.TREE_ROOT..[[\bin]]
1201vars.TREE_LMODULE = vars.TREE_LMODULE or vars.TREE_ROOT..[[\share\lua\]]..vars.LUA_VERSION 1201vars.TREE_LMODULE = vars.TREE_LMODULE or vars.TREE_ROOT..[[\share\lua\]]..vars.LUA_VERSION
1202vars.TREE_CMODULE = vars.TREE_CMODULE or vars.TREE_ROOT..[[\lib\lua\]]..vars.LUA_VERSION 1202vars.TREE_CMODULE = vars.TREE_CMODULE or vars.TREE_ROOT..[[\lib\lua\]]..vars.LUA_VERSION
1203print(S[[ 1203print(S[[
1204 1204
1205============================ 1205============================
1206== LuaRocks is installed! == 1206== LuaRocks is installed! ==
1207============================ 1207============================
1208 1208
1209 1209
1210You may want to add the following elements to your paths; 1210You may want to add the following elements to your paths;
1211Lua interpreter; 1211Lua interpreter;
1212 PATH : $LUA_BINDIR 1212 PATH : $LUA_BINDIR
1213 PATHEXT : .LUA 1213 PATHEXT : .LUA
1214LuaRocks; 1214LuaRocks;
1215 PATH : $PREFIX 1215 PATH : $PREFIX
1216 LUA_PATH : $PREFIX\lua\?.lua;$PREFIX\lua\?\init.lua 1216 LUA_PATH : $PREFIX\lua\?.lua;$PREFIX\lua\?\init.lua
1217Local user rocktree (Note: %APPDATA% is user dependent); 1217Local user rocktree (Note: %APPDATA% is user dependent);
1218 PATH : %APPDATA%\LuaRocks\bin 1218 PATH : %APPDATA%\LuaRocks\bin
1219 LUA_PATH : %APPDATA%\LuaRocks\share\lua\$LUA_VERSION\?.lua;%APPDATA%\LuaRocks\share\lua\$LUA_VERSION\?\init.lua 1219 LUA_PATH : %APPDATA%\LuaRocks\share\lua\$LUA_VERSION\?.lua;%APPDATA%\LuaRocks\share\lua\$LUA_VERSION\?\init.lua
1220 LUA_CPATH: %APPDATA%\LuaRocks\lib\lua\$LUA_VERSION\?.dll 1220 LUA_CPATH: %APPDATA%\LuaRocks\lib\lua\$LUA_VERSION\?.dll
1221System rocktree 1221System rocktree
1222 PATH : $TREE_BIN 1222 PATH : $TREE_BIN
1223 LUA_PATH : $TREE_LMODULE\?.lua;$TREE_LMODULE\?\init.lua 1223 LUA_PATH : $TREE_LMODULE\?.lua;$TREE_LMODULE\?\init.lua
1224 LUA_CPATH: $TREE_CMODULE\?.dll 1224 LUA_CPATH: $TREE_CMODULE\?.dll
1225 1225
1226Note that the %APPDATA% element in the paths above is user specific and it MUST be replaced by its actual value. 1226Note that the %APPDATA% element in the paths above is user specific and it MUST be replaced by its actual value.
1227For the current user that value is: $APPDATA. 1227For the current user that value is: $APPDATA.
1228 1228
1229]]) 1229]])
1230os.exit(0) 1230os.exit(0)