aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFabio Mascarenhas <mascarenhas@lambda-2.local>2010-01-15 15:29:44 -0200
committerFabio Mascarenhas <mascarenhas@lambda-2.local>2010-01-15 15:29:44 -0200
commit0ee1494093763b872de3c4e74575ff8e1aa122bd (patch)
tree1b5135b8ddbeacb738d65fc0b4fef207df46358e /src
parent598292ee8bc732527a09fdbaee9ede8599179b4d (diff)
downloadluarocks-0ee1494093763b872de3c4e74575ff8e1aa122bd.tar.gz
luarocks-0ee1494093763b872de3c4e74575ff8e1aa122bd.tar.bz2
luarocks-0ee1494093763b872de3c4e74575ff8e1aa122bd.zip
changes to make LR2 work in windows: filesystem changes, install.bat changes, executable wrappers for scripts in builtin build type
Diffstat (limited to 'src')
-rw-r--r--src/luarocks/build/builtin.lua64
-rw-r--r--src/luarocks/cfg.lua4
-rw-r--r--src/luarocks/fs/lua.lua21
-rw-r--r--src/luarocks/fs/win32.lua11
-rw-r--r--src/luarocks/fs/win32/tools.lua122
5 files changed, 196 insertions, 26 deletions
diff --git a/src/luarocks/build/builtin.lua b/src/luarocks/build/builtin.lua
index 30159352..d04b69d5 100644
--- a/src/luarocks/build/builtin.lua
+++ b/src/luarocks/build/builtin.lua
@@ -29,6 +29,28 @@ local function execute(...)
29 return fs.execute(...) 29 return fs.execute(...)
30end 30end
31 31
32--- Makes an RC file with an embedded Lua script, for building .exes on Windows
33-- @return nil if could open files, error otherwise
34local function make_rc(luafilename, rcfilename)
35 local rcfile = io.open(rcfilename, "w")
36 if not rcfile then
37 error("Could not open "..rcfilename.." for writing.")
38 end
39 rcfile:write("#define IDS_RCLAUNCHER 1\r\n")
40 rcfile:write("STRINGTABLE\r\nBEGIN\r\n")
41 rcfile:write("IDS_RCLAUNCHER \"")
42
43 for line in io.lines(luafilename) do
44 if not line:match("^#!") then
45 line = line:gsub("\\", "\\\\"):gsub('"', '""'):gsub("[\r\n]+", "")
46 rcfile:write(line .. "\\n\\\r\n")
47 end
48 end
49
50 rcfile:write("\"\r\nEND\r\n")
51 rcfile:close()
52end
53
32--- Driver function for the builtin build back-end. 54--- Driver function for the builtin build back-end.
33-- @param rockspec table: the loaded rockspec. 55-- @param rockspec table: the loaded rockspec.
34-- @return boolean or (nil, string): true if no errors ocurred, 56-- @return boolean or (nil, string): true if no errors ocurred,
@@ -76,6 +98,23 @@ function run(rockspec)
76 end 98 end
77 return ok 99 return ok
78 end 100 end
101 compile_wrapper_binary = function(fullname, name)
102 local fullbasename = fullname:gsub("%.lua$", ""):gsub("/", "\\")
103 local basename = name:gsub("%.lua$", ""):gsub("/", "\\")
104 local rcname = basename..".rc"
105 local resname = basename..".res"
106 local wrapname = basename..".exe"
107 make_rc(fullname, fullbasename..".rc")
108 local ok = execute(variables.RC, "-r", "-fo"..resname, rcname)
109 if not ok then return ok end
110 ok = execute(variables.LD, "-out:"..wrapname, resname, variables.WRAPPER,
111 fs.make_path(variables.LUA_LIBDIR, "lua5.1.lib"), "user32.lib")
112 local manifestfile = wrapname..".manifest"
113 if ok and fs.exists(manifestfile) then
114 ok = execute(variables.MT, "-manifest", manifestfile, "-outputresource:"..wrapname..";1")
115 end
116 return ok, wrapname
117 end
79 else 118 else
80 compile_object = function(object, source, defines, incdirs) 119 compile_object = function(object, source, defines, incdirs)
81 local extras = {} 120 local extras = {}
@@ -92,6 +131,7 @@ function run(rockspec)
92 end 131 end
93 return execute(variables.LD.." "..variables.LIBFLAG, "-o", library, "-L"..variables.LUA_LIBDIR, unpack(extras)) 132 return execute(variables.LD.." "..variables.LIBFLAG, "-o", library, "-L"..variables.LUA_LIBDIR, unpack(extras))
94 end 133 end
134 compile_wrapper_binary = function(fullname, name) return true, name end
95 end 135 end
96 136
97 local ok = true 137 local ok = true
@@ -99,6 +139,30 @@ function run(rockspec)
99 local luadir = path.lua_dir(rockspec.name, rockspec.version) 139 local luadir = path.lua_dir(rockspec.name, rockspec.version)
100 local libdir = path.lib_dir(rockspec.name, rockspec.version) 140 local libdir = path.lib_dir(rockspec.name, rockspec.version)
101 local docdir = path.doc_dir(rockspec.name, rockspec.version) 141 local docdir = path.doc_dir(rockspec.name, rockspec.version)
142 -- On Windows, compiles an .exe for each Lua file in build.install.bin, and
143 -- replaces the filename with the .exe name. Strips the .lua extension if it exists,
144 -- otherwise just appends .exe to the name
145 if build.install and build.install.bin then
146 for i, name in ipairs(build.install.bin) do
147 local fullname = fs.make_path(fs.current_dir(), name)
148 local match = name:match("%.lua$")
149 local basename = name:gsub("%.lua$", "")
150 local file
151 if not match then
152 file = io.open(fullname)
153 end
154 if match or (file and file:read():match("#!.*lua.*")) then
155 ok, name = compile_wrapper_binary(fullname, name)
156 if ok then
157 build.install.bin[i] = name
158 else
159 if file then file:close() end
160 return nil, "Build error in wrapper binaries"
161 end
162 end
163 if file then file:close() end
164 end
165 end
102 for name, info in pairs(build.modules) do 166 for name, info in pairs(build.modules) do
103 local moddir = path.module_to_path(name) 167 local moddir = path.module_to_path(name)
104 if type(info) == "string" then 168 if type(info) == "string" then
diff --git a/src/luarocks/cfg.lua b/src/luarocks/cfg.lua
index 0cf58ba3..c39056b4 100644
--- a/src/luarocks/cfg.lua
+++ b/src/luarocks/cfg.lua
@@ -22,7 +22,7 @@ if not ok then
22 config = {} 22 config = {}
23end 23end
24 24
25program_version = "2.0.1" 25program_version = "2.0.2"
26user_agent = "LuaRocks/"..program_version 26user_agent = "LuaRocks/"..program_version
27 27
28local persist = require("luarocks.persist") 28local persist = require("luarocks.persist")
@@ -169,6 +169,8 @@ if detected.windows then
169 defaults.make = "nmake" -- TODO: Split Windows flavors between mingw and msvc 169 defaults.make = "nmake" -- TODO: Split Windows flavors between mingw and msvc
170 defaults.makefile = "Makefile.win" 170 defaults.makefile = "Makefile.win"
171 defaults.variables.CC = "cl" 171 defaults.variables.CC = "cl"
172 defaults.variables.RC = "rc"
173 defaults.variables.WRAPPER = config.LUAROCKS_PREFIX .. "\\2.0\\rclauncher.obj"
172 defaults.variables.LD = "link" 174 defaults.variables.LD = "link"
173 defaults.variables.MT = "mt" 175 defaults.variables.MT = "mt"
174 defaults.variables.CFLAGS = "/MD /O2" 176 defaults.variables.CFLAGS = "/MD /O2"
diff --git a/src/luarocks/fs/lua.lua b/src/luarocks/fs/lua.lua
index c6c16236..3314d394 100644
--- a/src/luarocks/fs/lua.lua
+++ b/src/luarocks/fs/lua.lua
@@ -45,12 +45,12 @@ function is_writable(file)
45 local result 45 local result
46 if fs.is_dir(file) then 46 if fs.is_dir(file) then
47 local file2 = file .. '/.tmpluarockstestwritable' 47 local file2 = file .. '/.tmpluarockstestwritable'
48 local fh = io.open(file2, 'w') 48 local fh = io.open(file2, 'wb')
49 result = fh ~= nil 49 result = fh ~= nil
50 if fh then fh:close() end 50 if fh then fh:close() end
51 os.remove(file2) 51 os.remove(file2)
52 else 52 else
53 local fh = io.open(file, 'r+') 53 local fh = io.open(file, 'rb+')
54 result = fh ~= nil 54 result = fh ~= nil
55 if fh then fh:close() end 55 if fh then fh:close() end
56 end 56 end
@@ -64,6 +64,7 @@ end
64function make_temp_dir(name) 64function make_temp_dir(name)
65 assert(type(name) == "string") 65 assert(type(name) == "string")
66 66
67 name = name:gsub("\\", "/")
67 local temp_dir = (os.getenv("TMP") or "/tmp") .. "/luarocks_" .. name:gsub(dir.separator, "_") .. "-" .. tostring(math.floor(math.random() * 10000)) 68 local temp_dir = (os.getenv("TMP") or "/tmp") .. "/luarocks_" .. name:gsub(dir.separator, "_") .. "-" .. tostring(math.floor(math.random() * 10000))
68 if fs.make_dir(temp_dir) then 69 if fs.make_dir(temp_dir) then
69 return temp_dir 70 return temp_dir
@@ -170,9 +171,14 @@ end
170-- @return boolean: true on success, false on failure. 171-- @return boolean: true on success, false on failure.
171function make_dir(directory) 172function make_dir(directory)
172 assert(type(directory) == "string") 173 assert(type(directory) == "string")
174 directory = directory:gsub("\\", "/")
173 local path = nil 175 local path = nil
174 for d in directory:gmatch("[^"..dir.separator.."]*"..dir.separator.."*") do 176 if directory:sub(2, 2) == ":" then
175 path = path and path..d or d 177 path = directory:sub(1, 2)
178 directory = directory:sub(4)
179 end
180 for d in directory:gmatch("([^"..dir.separator.."]+)"..dir.separator.."*") do
181 path = path and path .. dir.separator .. d or d
176 local mode = lfs.attributes(path, "mode") 182 local mode = lfs.attributes(path, "mode")
177 if not mode then 183 if not mode then
178 if not lfs.mkdir(path) then 184 if not lfs.mkdir(path) then
@@ -217,9 +223,9 @@ function copy(src, dest)
217 if destmode == "directory" then 223 if destmode == "directory" then
218 dest = dir.path(dest, dir.base_name(src)) 224 dest = dir.path(dest, dir.base_name(src))
219 end 225 end
220 local src_h, err = io.open(src, "r") 226 local src_h, err = io.open(src, "rb")
221 if not src_h then return nil, err end 227 if not src_h then return nil, err end
222 local dest_h, err = io.open(dest, "w+") 228 local dest_h, err = io.open(dest, "wb+")
223 if not dest_h then src_h:close() return nil, err end 229 if not dest_h then src_h:close() return nil, err end
224 while true do 230 while true do
225 local block = src_h:read(8192) 231 local block = src_h:read(8192)
@@ -303,7 +309,6 @@ end
303-- @return boolean: true on success, false on failure. 309-- @return boolean: true on success, false on failure.
304function delete(arg) 310function delete(arg)
305 assert(arg) 311 assert(arg)
306 assert(arg:sub(1,1) == "/")
307 return recursive_delete(arg) or false 312 return recursive_delete(arg) or false
308end 313end
309 314
@@ -467,7 +472,7 @@ if md5_ok then
467-- @return string: The MD5 checksum 472-- @return string: The MD5 checksum
468function get_md5(file) 473function get_md5(file)
469 file = fs.absolute_name(file) 474 file = fs.absolute_name(file)
470 local file = io.open(file, "r") 475 local file = io.open(file, "rb")
471 if not file then return false end 476 if not file then return false end
472 local computed = md5.sumhexa(file:read("*a")) 477 local computed = md5.sumhexa(file:read("*a"))
473 file:close() 478 file:close()
diff --git a/src/luarocks/fs/win32.lua b/src/luarocks/fs/win32.lua
index 0fccdf86..87ad26b2 100644
--- a/src/luarocks/fs/win32.lua
+++ b/src/luarocks/fs/win32.lua
@@ -22,17 +22,6 @@ function Q(arg)
22 return '"' .. arg:gsub('"', '\\"') .. '"' 22 return '"' .. arg:gsub('"', '\\"') .. '"'
23end 23end
24 24
25--- Strip the last extension of a filename.
26-- Example: "foo.tar.gz" becomes "foo.tar".
27-- If filename has no dots, returns it unchanged.
28-- @param filename string: The file name to strip.
29-- @return string: The stripped name.
30local function strip_extension(filename)
31 assert(type(filename) == "string")
32
33 return (filename:gsub("%.[^.]+$", "")) or filename
34end
35
36--- Return an absolute pathname from a potentially relative one. 25--- Return an absolute pathname from a potentially relative one.
37-- @param pathname string: pathname to convert. 26-- @param pathname string: pathname to convert.
38-- @param relative_to string or nil: path to prepend when making 27-- @param relative_to string or nil: path to prepend when making
diff --git a/src/luarocks/fs/win32/tools.lua b/src/luarocks/fs/win32/tools.lua
index 60578d8d..2bd2b8c5 100644
--- a/src/luarocks/fs/win32/tools.lua
+++ b/src/luarocks/fs/win32/tools.lua
@@ -5,6 +5,20 @@
5module("luarocks.fs.win32.tools", package.seeall) 5module("luarocks.fs.win32.tools", package.seeall)
6 6
7local fs = require("luarocks.fs") 7local fs = require("luarocks.fs")
8local cfg = require("luarocks.cfg")
9
10local dir_stack = {}
11
12--- Strip the last extension of a filename.
13-- Example: "foo.tar.gz" becomes "foo.tar".
14-- If filename has no dots, returns it unchanged.
15-- @param filename string: The file name to strip.
16-- @return string: The stripped name.
17local function strip_extension(filename)
18 assert(type(filename) == "string")
19
20 return (filename:gsub("%.[^.]+$", "")) or filename
21end
8 22
9local function command_at(directory, cmd) 23local function command_at(directory, cmd)
10 local drive = directory:match("^([A-Za-z]:)") 24 local drive = directory:match("^([A-Za-z]:)")
@@ -24,12 +38,82 @@ function exists(file)
24 " invalidcommandname 2>NUL 1>NUL") 38 " invalidcommandname 2>NUL 1>NUL")
25end 39end
26 40
27--- Test is pathname is a directory. 41--- Obtain current directory.
42-- Uses the module's internal dir stack.
43-- @return string: the absolute pathname of the current directory.
44function current_dir()
45 local current = os.getenv("PWD")
46 if not current then
47 local pipe = io.popen("pwd")
48 current = pipe:read("*l")
49 pipe:close()
50 end
51 for _, d in ipairs(dir_stack) do
52 current = fs.absolute_name(d, current)
53 end
54 return current
55end
56
57--- Test is pathname is a regular file.
28-- @param file string: pathname to test 58-- @param file string: pathname to test
29-- @return boolean: true if it is a directory, false otherwise. 59-- @return boolean: true if it is a regular file, false otherwise.
30function is_dir(file) 60function is_file(file)
31 assert(file) 61 assert(file)
32 return fs.execute("chdir /D " .. fs.Q(file) .. " 2>NUL 1>NUL") 62 return fs.execute("test -f", file)
63end
64
65--- Get the MD5 checksum for a file.
66-- @param file string: The file to be computed.
67-- @return string: The MD5 checksum
68function get_md5(file, md5sum)
69 file = fs.absolute_name(file)
70 local computed
71 if cfg.md5checker == "md5sum" then
72 local pipe = io.popen("md5sum "..file)
73 computed = pipe:read("*l")
74 pipe:close()
75 if computed then
76 computed = computed:gsub("[^%x]+", ""):sub(1,32)
77 end
78 elseif cfg.md5checker == "openssl" then
79 local pipe = io.popen("openssl md5 "..file)
80 computed = pipe:read("*l")
81 pipe:close()
82 if computed then
83 computed = computed:sub(-32)
84 end
85 elseif cfg.md5checker == "md5" then
86 local pipe = io.popen("md5 "..file)
87 computed = pipe:read("*l")
88 pipe:close()
89 if computed then
90 computed = computed:sub(-32)
91 end
92 end
93 return computed
94end
95
96--- Change the current directory.
97-- Uses the module's internal dir stack. This does not have exact
98-- semantics of chdir, as it does not handle errors the same way,
99-- but works well for our purposes for now.
100-- @param d string: The directory to switch to.
101function change_dir(d)
102 assert(type(d) == "string")
103 table.insert(dir_stack, d)
104end
105
106--- Change directory to root.
107-- Allows leaving a directory (e.g. for deleting it) in
108-- a crossplatform way.
109function change_dir_to_root()
110 table.insert(dir_stack, "/")
111end
112
113--- Change working directory to the previous in the dir stack.
114function pop_dir()
115 local d = table.remove(dir_stack)
116 return d ~= nil
33end 117end
34 118
35--- Run the given command. 119--- Run the given command.
@@ -50,7 +134,7 @@ end
50-- @return boolean: true if it is a regular file, false otherwise. 134-- @return boolean: true if it is a regular file, false otherwise.
51function is_dir(file) 135function is_dir(file)
52 assert(file) 136 assert(file)
53 return fs.execute("test -d" .. fs.Q(file) .. " 2>NUL 1>NUL") 137 return fs.execute("test -d " .. fs.Q(file) .. " 2>NUL 1>NUL")
54end 138end
55 139
56--- Create a directory if it does not already exist. 140--- Create a directory if it does not already exist.
@@ -73,6 +157,15 @@ function remove_dir_if_empty(d)
73 fs.execute_string("rmdir "..fs.Q(d).." 1> NUL 2> NUL") 157 fs.execute_string("rmdir "..fs.Q(d).." 1> NUL 2> NUL")
74end 158end
75 159
160--- Remove a directory if it is empty.
161-- Does not return errors (for example, if directory is not empty or
162-- if already does not exist)
163-- @param dir string: pathname of directory to remove.
164function remove_dir_tree_if_empty(d)
165 assert(d)
166 fs.execute_string("rmdir "..fs.Q(d).." 1> NUL 2> NUL")
167end
168
76--- Copy a file. 169--- Copy a file.
77-- @param src string: Pathname of source 170-- @param src string: Pathname of source
78-- @param dest string: Pathname of destination 171-- @param dest string: Pathname of destination
@@ -171,7 +264,7 @@ end
171function download(url, filename) 264function download(url, filename)
172 assert(type(url) == "string") 265 assert(type(url) == "string")
173 assert(type(filename) == "string" or not filename) 266 assert(type(filename) == "string" or not filename)
174 local wget_cmd = "wget --no-cache --user-agent="..cfg.user_agent.." --quiet --continue " 267 local wget_cmd = "wget --cache=off --user-agent="..cfg.user_agent.." --quiet --continue "
175 268
176 if filename then 269 if filename then
177 return fs.execute(wget_cmd.." --output-document ", filename, url) 270 return fs.execute(wget_cmd.." --output-document ", filename, url)
@@ -180,6 +273,23 @@ function download(url, filename)
180 end 273 end
181end 274end
182 275
276--- Compress files in a .zip archive.
277-- @param zipfile string: pathname of .zip archive to be created.
278-- @param ... Filenames to be stored in the archive are given as
279-- additional arguments.
280-- @return boolean: true on success, false on failure.
281function zip(zipfile, ...)
282 return fs.execute("zip -r", zipfile, ...)
283end
284
285--- Uncompress files from a .zip archive.
286-- @param zipfile string: pathname of .zip archive to be extracted.
287-- @return boolean: true on success, false on failure.
288function unzip(zipfile)
289 assert(zipfile)
290 return fs.execute("unzip", zipfile)
291end
292
183--- Uncompress gzip file. 293--- Uncompress gzip file.
184-- @param archive string: Filename of archive. 294-- @param archive string: Filename of archive.
185-- @return boolean : success status 295-- @return boolean : success status