diff options
author | Fabio Mascarenhas <mascarenhas@lambda-2.local> | 2010-01-15 15:29:44 -0200 |
---|---|---|
committer | Fabio Mascarenhas <mascarenhas@lambda-2.local> | 2010-01-15 15:29:44 -0200 |
commit | 0ee1494093763b872de3c4e74575ff8e1aa122bd (patch) | |
tree | 1b5135b8ddbeacb738d65fc0b4fef207df46358e /src | |
parent | 598292ee8bc732527a09fdbaee9ede8599179b4d (diff) | |
download | luarocks-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.lua | 64 | ||||
-rw-r--r-- | src/luarocks/cfg.lua | 4 | ||||
-rw-r--r-- | src/luarocks/fs/lua.lua | 21 | ||||
-rw-r--r-- | src/luarocks/fs/win32.lua | 11 | ||||
-rw-r--r-- | src/luarocks/fs/win32/tools.lua | 122 |
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(...) |
30 | end | 30 | end |
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 | ||
34 | local 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() | ||
52 | end | ||
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 = {} |
23 | end | 23 | end |
24 | 24 | ||
25 | program_version = "2.0.1" | 25 | program_version = "2.0.2" |
26 | user_agent = "LuaRocks/"..program_version | 26 | user_agent = "LuaRocks/"..program_version |
27 | 27 | ||
28 | local persist = require("luarocks.persist") | 28 | local 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 | |||
64 | function make_temp_dir(name) | 64 | function 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. |
171 | function make_dir(directory) | 172 | function 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. |
304 | function delete(arg) | 310 | function 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 |
308 | end | 313 | end |
309 | 314 | ||
@@ -467,7 +472,7 @@ if md5_ok then | |||
467 | -- @return string: The MD5 checksum | 472 | -- @return string: The MD5 checksum |
468 | function get_md5(file) | 473 | function 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('"', '\\"') .. '"' |
23 | end | 23 | end |
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. | ||
30 | local function strip_extension(filename) | ||
31 | assert(type(filename) == "string") | ||
32 | |||
33 | return (filename:gsub("%.[^.]+$", "")) or filename | ||
34 | end | ||
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 @@ | |||
5 | module("luarocks.fs.win32.tools", package.seeall) | 5 | module("luarocks.fs.win32.tools", package.seeall) |
6 | 6 | ||
7 | local fs = require("luarocks.fs") | 7 | local fs = require("luarocks.fs") |
8 | local cfg = require("luarocks.cfg") | ||
9 | |||
10 | local 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. | ||
17 | local function strip_extension(filename) | ||
18 | assert(type(filename) == "string") | ||
19 | |||
20 | return (filename:gsub("%.[^.]+$", "")) or filename | ||
21 | end | ||
8 | 22 | ||
9 | local function command_at(directory, cmd) | 23 | local 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") |
25 | end | 39 | end |
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. | ||
44 | function 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 | ||
55 | end | ||
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. |
30 | function is_dir(file) | 60 | function 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) |
63 | end | ||
64 | |||
65 | --- Get the MD5 checksum for a file. | ||
66 | -- @param file string: The file to be computed. | ||
67 | -- @return string: The MD5 checksum | ||
68 | function 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 | ||
94 | end | ||
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. | ||
101 | function change_dir(d) | ||
102 | assert(type(d) == "string") | ||
103 | table.insert(dir_stack, d) | ||
104 | end | ||
105 | |||
106 | --- Change directory to root. | ||
107 | -- Allows leaving a directory (e.g. for deleting it) in | ||
108 | -- a crossplatform way. | ||
109 | function change_dir_to_root() | ||
110 | table.insert(dir_stack, "/") | ||
111 | end | ||
112 | |||
113 | --- Change working directory to the previous in the dir stack. | ||
114 | function pop_dir() | ||
115 | local d = table.remove(dir_stack) | ||
116 | return d ~= nil | ||
33 | end | 117 | end |
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. |
51 | function is_dir(file) | 135 | function 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") |
54 | end | 138 | end |
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") |
74 | end | 158 | end |
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. | ||
164 | function remove_dir_tree_if_empty(d) | ||
165 | assert(d) | ||
166 | fs.execute_string("rmdir "..fs.Q(d).." 1> NUL 2> NUL") | ||
167 | end | ||
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 | |||
171 | function download(url, filename) | 264 | function 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 |
181 | end | 274 | end |
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. | ||
281 | function zip(zipfile, ...) | ||
282 | return fs.execute("zip -r", zipfile, ...) | ||
283 | end | ||
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. | ||
288 | function unzip(zipfile) | ||
289 | assert(zipfile) | ||
290 | return fs.execute("unzip", zipfile) | ||
291 | end | ||
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 |