ocra 1.0.3 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +12 -1
- data/Manifest.txt +1 -0
- data/README.txt +93 -16
- data/Rakefile +18 -4
- data/bin/ocra.rb +138 -8
- data/lib/ocra.rb +1 -1
- data/share/ocra/edicon.exe +0 -0
- data/share/ocra/stub.exe +0 -0
- data/share/ocra/stubw.exe +0 -0
- data/test/test_ocra.rb +199 -123
- metadata +3 -2
data/History.txt
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
=== 1.1.0
|
2
|
+
|
3
|
+
* Added an icon to the executable. Can be replaced from a .ico file
|
4
|
+
using the --icon <ico> option.
|
5
|
+
|
6
|
+
* Improved handling of load paths added either from the command line
|
7
|
+
(ruby -I), RUBYLIB environment variable or during the script (by
|
8
|
+
modifying $: or $LOAD_PATH).
|
9
|
+
|
10
|
+
* Now automatically detects loaded DLLs through Win32::API. Disable
|
11
|
+
with --no-autodll.
|
12
|
+
|
1
13
|
=== 1.0.3 / 2009-05-25
|
2
14
|
|
3
15
|
* Fixed invokation of executables with spaces in path names (#25966).
|
@@ -21,4 +33,3 @@
|
|
21
33
|
* 1 major enhancement
|
22
34
|
|
23
35
|
* Birthday!
|
24
|
-
|
data/Manifest.txt
CHANGED
data/README.txt
CHANGED
@@ -18,6 +18,11 @@ any additionally needed ruby libraries or DLL.
|
|
18
18
|
* Both console programs and desktop programs supported (no console will
|
19
19
|
pop up with .rbw files).
|
20
20
|
|
21
|
+
If you experience problems with Ocra or have found a bug, please use
|
22
|
+
the tracker on the RubyForge project page
|
23
|
+
http://rubyforge.org/projects/ocra/. You are welcome to ask questions
|
24
|
+
in the forums there aswell.
|
25
|
+
|
21
26
|
== TODO:
|
22
27
|
|
23
28
|
* Clean up using manual recursive deletion (not SHop).
|
@@ -32,16 +37,18 @@ ocra.rb [option] your/script.rb
|
|
32
37
|
* Your program should 'require' all necessary files when invoked without
|
33
38
|
arguments, so ocra can detect all dependencies.
|
34
39
|
|
35
|
-
*
|
36
|
-
|
40
|
+
* Ocra executables clear the RUBYLIB environment variable but set
|
41
|
+
RUBYOPT to whatever value it had when you invoked Ocra.
|
37
42
|
|
38
43
|
* Ocra does not set up the include path. Use "$:.unshift
|
39
44
|
File.dirname(__FILE__)" at the start of your script if you need to
|
40
45
|
'require' additional source files in the same directory no matter
|
41
46
|
what the user's current working directory is.
|
42
47
|
|
43
|
-
* DLLs
|
44
|
-
|
48
|
+
* Loaded DLLs are detected automatically but only those located in
|
49
|
+
your Ruby installation are included. Automatic detection can be
|
50
|
+
disabled using --no-autodll. DLLs can be manually added using the
|
51
|
+
--dll option.
|
45
52
|
|
46
53
|
== REQUIREMENTS:
|
47
54
|
|
@@ -57,29 +64,96 @@ ocra.rb [option] your/script.rb
|
|
57
64
|
|
58
65
|
Can also be downloaded from http://rubyforge.org/frs/?group_id=8185
|
59
66
|
|
60
|
-
|
67
|
+
=== Stand-alone
|
61
68
|
|
62
69
|
Get ocrasa.rb from http://rubyforge.org/frs/?group_id=8185. Requires
|
63
70
|
nothing but a working Ruby installation on Windows.
|
64
71
|
|
65
72
|
== TECHNICAL DETAILS
|
66
73
|
|
67
|
-
The Ocra stub extracts the
|
68
|
-
|
69
|
-
|
70
|
-
|
74
|
+
The Ocra stub extracts the Ruby interpreter and your scripts into a
|
75
|
+
temporary directory. The directory will contains the same directory
|
76
|
+
layout as your Ruby installlation. The source files for your
|
77
|
+
application will be put in the 'src' subdirectory.
|
78
|
+
|
79
|
+
=== Libraries
|
80
|
+
|
81
|
+
Rubygems will be automatically included in the Ocra executable.
|
71
82
|
|
72
83
|
Libraries found in non-standard path (for example, if you invoke Ocra
|
73
84
|
with "ruby -I some/path") will be placed into the site dir
|
74
|
-
(lib/ruby/site_ruby).
|
85
|
+
(lib/ruby/site_ruby). Avoid changing $LOAD_PATH / $: from your script
|
86
|
+
to include paths outside your source tree.
|
75
87
|
|
76
|
-
|
77
|
-
launched by the executable in order not to interfere with any Ruby
|
78
|
-
installation on the end user's installation.
|
79
|
-
|
80
|
-
Autoloaded constants will be attempted loaded when building the
|
88
|
+
Autoloaded libraries will be attempted loaded when building the
|
81
89
|
executable. Modules that doesn't exist will be ignore (but a warning
|
82
|
-
will be logged.
|
90
|
+
will be logged).
|
91
|
+
|
92
|
+
=== Environment variables
|
93
|
+
|
94
|
+
Ocra executables clear the RUBYLIB environment variable before your
|
95
|
+
script is launched. This is done to ensure that your script does not
|
96
|
+
use load paths from the end user's Ruby installation.
|
97
|
+
|
98
|
+
Ocra executables set the RUBYOPT environment variable to the value it
|
99
|
+
had when you invoked Ocra. For example, if you had "RUBYOPT=rubygems"
|
100
|
+
on your build PC, Ocra ensures that it is also set on PC's running the
|
101
|
+
executables.
|
102
|
+
|
103
|
+
=== Working directory
|
104
|
+
|
105
|
+
You should not assume that the current working directory when invoking
|
106
|
+
an executable built with .exe is the location of the source script. It
|
107
|
+
can be the directory where the executable is placed (when invoked
|
108
|
+
through the Windows Explorer), the users' current working directory
|
109
|
+
(when invoking from the Command Prompt), or even C:\WINDOWS\SYSTEM32
|
110
|
+
when the executable is invoked through a file association. You can
|
111
|
+
optionally change the directory yourself:
|
112
|
+
|
113
|
+
Dir.chdir File.dirname(__FILE__)
|
114
|
+
|
115
|
+
If you wish to maintain the user's working directory, but need to
|
116
|
+
'require' additional Ruby scripts from the source directory, you can
|
117
|
+
add the following line to your script:
|
118
|
+
|
119
|
+
$LOAD_PATH.unshift File.dirname(__FILE__)
|
120
|
+
|
121
|
+
=== $LOAD_PATH/$: mangling
|
122
|
+
|
123
|
+
Adding paths to $LOAD_PATH or $: at runtime is not recommended. Adding
|
124
|
+
relative load paths depends on the working directory being the same as
|
125
|
+
where the script is located (See above). If you have additional
|
126
|
+
library files in directories below the directory containing your
|
127
|
+
source script you can use this idiom:
|
128
|
+
|
129
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), 'path/to/script')
|
130
|
+
|
131
|
+
=== Detecting OCRA
|
132
|
+
|
133
|
+
You can detect whether Ocra is currently building your script by
|
134
|
+
looking for the 'Ocra' constant. If it is defined, Ocra is currenly
|
135
|
+
building the executable from your script. For example, you can use
|
136
|
+
this to avoid opening a GUI window when compiling executables:
|
137
|
+
|
138
|
+
app = MyApp.new
|
139
|
+
if not defined?(Ocra)
|
140
|
+
app.main_loop
|
141
|
+
end
|
142
|
+
|
143
|
+
=== Additional files and resources
|
144
|
+
|
145
|
+
You can add additional files to the Ocra executable (for example
|
146
|
+
images) by appending them to the command line. They should be placed
|
147
|
+
in the source directory with your main script (or a subdirectory).
|
148
|
+
|
149
|
+
ocra.rb mainscript.rb someimage.jpeg docs/document.txt
|
150
|
+
|
151
|
+
This will create the following layout in the temporary directory when
|
152
|
+
your program is executed:
|
153
|
+
|
154
|
+
src/mainscript.rb
|
155
|
+
src/someimage.jpeg
|
156
|
+
src/docs/document.txt
|
83
157
|
|
84
158
|
== CREDITS:
|
85
159
|
|
@@ -88,6 +162,9 @@ source code used was place into Public Domain by Igor Pavlov.
|
|
88
162
|
|
89
163
|
Erik Veenstra for rubyscript2exe which provided inspiration.
|
90
164
|
|
165
|
+
Dice for the default .exe icon (vit-ruby.ico,
|
166
|
+
http://ruby.morphball.net/vit-ruby-ico_en.html)
|
167
|
+
|
91
168
|
== LICENSE:
|
92
169
|
|
93
170
|
(The MIT License)
|
data/Rakefile
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'hoe'
|
5
|
-
require '
|
5
|
+
require 'bin/ocra'
|
6
6
|
|
7
7
|
Hoe.new('ocra', Ocra::VERSION) do |p|
|
8
8
|
p.developer('Lars Christensen', 'larsch@belunktum.dk')
|
@@ -12,17 +12,26 @@ task :stub do
|
|
12
12
|
sh "mingw32-make -C src"
|
13
13
|
cp 'src/stub.exe', 'share/ocra/stub.exe'
|
14
14
|
cp 'src/stubw.exe', 'share/ocra/stubw.exe'
|
15
|
+
cp 'src/edicon.exe', 'share/ocra/edicon.exe'
|
15
16
|
end
|
16
17
|
|
17
18
|
task :test => :stub
|
18
19
|
|
19
20
|
task :standalone => [ 'bin/ocrasa.rb' ]
|
20
21
|
|
21
|
-
|
22
|
-
|
22
|
+
standalone_zip = "bin/ocrasa-#{ENV['VERSION']}.zip"
|
23
|
+
|
24
|
+
file standalone_zip => 'bin/ocrasa.rb' do
|
25
|
+
chdir('bin') do
|
26
|
+
system("zip ocrasa-#{ENV['VERSION']}.zip ocrasa.rb")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
task :release_standalone => standalone_zip do
|
31
|
+
sh "rubyforge add_release ocra ocra-standalone #{Ocra::VERSION} #{standalone_zip}"
|
23
32
|
end
|
24
33
|
|
25
|
-
file 'bin/ocrasa.rb' => [ 'bin/ocra.rb', 'share/ocra/stub.exe', 'share/ocra/stubw.exe', 'share/ocra/lzma.exe' ] do
|
34
|
+
file 'bin/ocrasa.rb' => [ 'bin/ocra.rb', 'share/ocra/stub.exe', 'share/ocra/stubw.exe', 'share/ocra/lzma.exe', 'share/ocra/edicon.exe' ] do
|
26
35
|
cp 'bin/ocra.rb', 'bin/ocrasa.rb'
|
27
36
|
File.open("bin/ocrasa.rb", "a") do |f|
|
28
37
|
f.puts "__END__"
|
@@ -41,6 +50,11 @@ file 'bin/ocrasa.rb' => [ 'bin/ocra.rb', 'share/ocra/stub.exe', 'share/ocra/stub
|
|
41
50
|
lzma64 = [lzma].pack("m")
|
42
51
|
f.puts lzma64.size
|
43
52
|
f.puts lzma64
|
53
|
+
|
54
|
+
lzma = File.open("share/ocra/edicon.exe", "rb") {|g| g.read}
|
55
|
+
lzma64 = [lzma].pack("m")
|
56
|
+
f.puts lzma64.size
|
57
|
+
f.puts lzma64
|
44
58
|
end
|
45
59
|
end
|
46
60
|
|
data/bin/ocra.rb
CHANGED
@@ -10,6 +10,10 @@ module Ocra
|
|
10
10
|
OP_DECOMPRESS_LZMA = 4
|
11
11
|
OP_SETENV = 5
|
12
12
|
|
13
|
+
VERSION = "1.1.0"
|
14
|
+
|
15
|
+
IGNORE_MODULES = /^enumerator.so$/
|
16
|
+
|
13
17
|
class << self
|
14
18
|
attr_accessor :lzma_mode
|
15
19
|
attr_accessor :extra_dlls
|
@@ -17,8 +21,11 @@ module Ocra
|
|
17
21
|
attr_accessor :load_autoload
|
18
22
|
attr_accessor :force_windows
|
19
23
|
attr_accessor :force_console
|
24
|
+
attr_accessor :icon_filename
|
20
25
|
attr_accessor :quiet
|
26
|
+
attr_accessor :autodll
|
21
27
|
attr_reader :lzmapath
|
28
|
+
attr_reader :ediconpath
|
22
29
|
attr_reader :stubimage
|
23
30
|
attr_reader :stubwimage
|
24
31
|
|
@@ -28,18 +35,23 @@ module Ocra
|
|
28
35
|
end
|
29
36
|
|
30
37
|
def Ocra.initialize_ocra
|
38
|
+
@load_path_before = $LOAD_PATH.dup
|
39
|
+
|
31
40
|
if defined?(DATA)
|
32
41
|
@stubimage = get_next_embedded_image
|
33
42
|
@stubwimage = get_next_embedded_image
|
34
43
|
lzmaimage = get_next_embedded_image
|
35
44
|
@lzmapath = File.join(ENV['TEMP'], 'lzma.exe').tr('/','\\')
|
36
45
|
File.open(@lzmapath, "wb") { |file| file << lzmaimage }
|
46
|
+
ediconimage = get_next_embedded_image
|
47
|
+
@ediconpath = File.join(ENV['TEMP'], 'edicon.exe').tr('/','\\')
|
48
|
+
File.open(@ediconpath, "wb") { |file| file << ediconimage }
|
37
49
|
else
|
38
50
|
ocrapath = File.dirname(__FILE__)
|
39
51
|
@stubimage = File.open(File.join(ocrapath, '../share/ocra/stub.exe'), "rb") { |file| file.read }
|
40
52
|
@stubwimage = File.open(File.join(ocrapath, '../share/ocra/stubw.exe'), "rb") { |file| file.read }
|
41
53
|
@lzmapath = File.expand_path('../share/ocra/lzma.exe', ocrapath).tr('/','\\')
|
42
|
-
|
54
|
+
@ediconpath = File.expand_path('../share/ocra/edicon.exe', ocrapath).tr('/','\\')
|
43
55
|
end
|
44
56
|
end
|
45
57
|
|
@@ -50,7 +62,9 @@ module Ocra
|
|
50
62
|
load_autoload = true
|
51
63
|
force_windows = false
|
52
64
|
force_console = false
|
65
|
+
icon_filename = nil
|
53
66
|
quiet = false
|
67
|
+
autodll = true
|
54
68
|
|
55
69
|
usage = <<EOF
|
56
70
|
ocra [options] script.rb
|
@@ -62,6 +76,8 @@ ocra [options] script.rb
|
|
62
76
|
--windows Force Windows application (rubyw.exe)
|
63
77
|
--console Force console application (ruby.exe)
|
64
78
|
--no-autoload Don't load/include script.rb's autoloads
|
79
|
+
--icon <ico> Replace icon with a custom one
|
80
|
+
--version Display version number
|
65
81
|
EOF
|
66
82
|
|
67
83
|
while arg = argv.shift
|
@@ -78,6 +94,14 @@ EOF
|
|
78
94
|
force_console = true
|
79
95
|
when /\A--no-autoload\z/
|
80
96
|
load_autoload = false
|
97
|
+
when /\A--icon\z/
|
98
|
+
icon_filename = argv.shift
|
99
|
+
raise "Icon file #{icon_filename} not found.\n" unless File.exist?(icon_filename)
|
100
|
+
when /\A--no-autodll\z/
|
101
|
+
autodll = false
|
102
|
+
when /\A--version\z/
|
103
|
+
puts "Ocra #{VERSION}"
|
104
|
+
exit
|
81
105
|
when /\A--help\z/, /\A--/
|
82
106
|
puts usage
|
83
107
|
exit
|
@@ -97,6 +121,8 @@ EOF
|
|
97
121
|
@force_windows = force_windows
|
98
122
|
@force_console = force_console
|
99
123
|
@load_autoload = load_autoload
|
124
|
+
@icon_filename = icon_filename
|
125
|
+
@autodll = autodll
|
100
126
|
@files = files
|
101
127
|
end
|
102
128
|
|
@@ -130,8 +156,32 @@ EOF
|
|
130
156
|
end
|
131
157
|
end
|
132
158
|
end
|
159
|
+
|
160
|
+
def Ocra.relative_path(src, tgt)
|
161
|
+
a = src.split('/')
|
162
|
+
b = tgt.split('/')
|
163
|
+
while a.first && a.first.downcase == b.first.downcase
|
164
|
+
a.shift
|
165
|
+
b.shift
|
166
|
+
end
|
167
|
+
return tgt if b.first =~ /^[a-z]:/i
|
168
|
+
a.size.times { b.unshift '..' }
|
169
|
+
return b.join('/')
|
170
|
+
end
|
171
|
+
|
172
|
+
def Ocra.find_load_path(paths, path)
|
173
|
+
if path[1,1] == ":"
|
174
|
+
rps = paths.map {|p| relative_path(p, path) }
|
175
|
+
rps.zip(paths).sort_by {|x| x[0].size }.first[1]
|
176
|
+
else
|
177
|
+
candidates = paths.select { |p| File.exist?(File.expand_path(path, p)) }
|
178
|
+
candidates.sort_by {|p| p.size}.last
|
179
|
+
end
|
180
|
+
end
|
133
181
|
|
134
182
|
def Ocra.build_exe
|
183
|
+
@added_load_paths = $LOAD_PATH - @load_path_before
|
184
|
+
|
135
185
|
# Attempt to autoload libraries before doing anything else.
|
136
186
|
attempt_load_autoload if Ocra.load_autoload
|
137
187
|
|
@@ -154,25 +204,40 @@ EOF
|
|
154
204
|
libruby_so = RbConfig::CONFIG['LIBRUBY_SO']
|
155
205
|
|
156
206
|
instsitelibdir = sitelibdir[exec_prefix.size+1..-1]
|
207
|
+
|
208
|
+
load_path = []
|
157
209
|
|
158
210
|
# Find loaded files
|
159
211
|
libs = []
|
160
212
|
features.each do |filename|
|
161
|
-
path =
|
213
|
+
path = find_load_path($:, filename)
|
162
214
|
if path
|
215
|
+
if filename[1,1] == ":"
|
216
|
+
filename = relative_path(File.expand_path(path), filename)
|
217
|
+
end
|
218
|
+
if filename =~ /^\.\.\//
|
219
|
+
puts "=== WARNING: Detected a relative require (#{filename}). This is not recommended."
|
220
|
+
end
|
163
221
|
fullpath = File.expand_path(filename, path)
|
164
222
|
if fullpath.index(exec_prefix) == 0
|
165
223
|
libs << [ fullpath, fullpath[exec_prefix.size+1..-1] ]
|
166
224
|
elsif fullpath.index(src_prefix) == 0
|
167
|
-
|
225
|
+
targetpath = "src/" + fullpath[src_prefix.size+1..-1]
|
226
|
+
libs << [ fullpath, targetpath ]
|
227
|
+
if not @added_load_paths.include?(path) and not load_path.include?(path)
|
228
|
+
load_path << File.join("\xFF", File.dirname(targetpath))
|
229
|
+
end
|
168
230
|
else
|
169
231
|
libs << [ fullpath, File.join(instsitelibdir, filename) ]
|
170
232
|
end
|
171
233
|
else
|
172
|
-
puts "=== WARNING: Couldn't find #{filename}"
|
234
|
+
puts "=== WARNING: Couldn't find #{filename}" unless filename =~ IGNORE_MODULES
|
173
235
|
end
|
174
236
|
end
|
175
237
|
|
238
|
+
# Detect additional DLLs
|
239
|
+
dlls = Ocra.autodll ? LibraryDetector.detect_dlls : []
|
240
|
+
|
176
241
|
executable = Ocra.files[0].sub(/(\.rbw?)?$/, '.exe')
|
177
242
|
|
178
243
|
windowed = (Ocra.files[0] =~ /\.rbw$/ || Ocra.force_windows) && !Ocra.force_console
|
@@ -196,6 +261,16 @@ EOF
|
|
196
261
|
sb.createfile(File.join(bindir, libruby_so), "bin\\#{libruby_so}")
|
197
262
|
end
|
198
263
|
|
264
|
+
# Add detected DLLs
|
265
|
+
dlls.each do |dll|
|
266
|
+
if dll.tr('\\','/').index(exec_prefix) == 0
|
267
|
+
target = dll[exec_prefix.size+1..-1]
|
268
|
+
else
|
269
|
+
target = File.join('bin', File.basename(dll))
|
270
|
+
end
|
271
|
+
sb.createfile(dll, target)
|
272
|
+
end
|
273
|
+
|
199
274
|
# Add extra DLLs
|
200
275
|
Ocra.extra_dlls.each do |dll|
|
201
276
|
sb.createfile(File.join(bindir, dll), File.join("bin", dll).tr('/','\\'))
|
@@ -218,7 +293,7 @@ EOF
|
|
218
293
|
|
219
294
|
# Set environment variable
|
220
295
|
sb.setenv('RUBYOPT', '')
|
221
|
-
sb.setenv('RUBYLIB', '')
|
296
|
+
sb.setenv('RUBYLIB', load_path.join(';'))
|
222
297
|
|
223
298
|
# Launch the script
|
224
299
|
sb.createprocess("bin\\" + rubyexe, "#{rubyexe} \xff\\src\\" + Ocra.files[0])
|
@@ -227,6 +302,52 @@ EOF
|
|
227
302
|
end
|
228
303
|
puts "=== Finished (Final size was #{File.size(executable)})" unless Ocra.quiet
|
229
304
|
end
|
305
|
+
|
306
|
+
module LibraryDetector
|
307
|
+
def LibraryDetector.loaded_dlls
|
308
|
+
begin
|
309
|
+
require 'rubygems'
|
310
|
+
gem 'win32-api', '>=1.4.0'
|
311
|
+
require 'win32/api'
|
312
|
+
rescue Exception => e
|
313
|
+
puts "=== ERROR: Failed to load the win32-api gem. Install win32-api or use --no-autodll."
|
314
|
+
puts "=== CAUSE: #{e.class.name}: #{e.message.chomp}"
|
315
|
+
exit
|
316
|
+
end
|
317
|
+
|
318
|
+
enumprocessmodules = Win32::API.new('EnumProcessModules', 'LPLP', 'B', 'psapi')
|
319
|
+
getmodulefilename = Win32::API.new('GetModuleFileName', 'LPL', 'L')
|
320
|
+
getcurrentprocess = Win32::API.new('GetCurrentProcess', 'V', 'L')
|
321
|
+
|
322
|
+
bytes_needed = 4 * 32
|
323
|
+
module_handle_buffer = nil
|
324
|
+
process_handle = getcurrentprocess.call()
|
325
|
+
loop do
|
326
|
+
module_handle_buffer = "\x00" * bytes_needed
|
327
|
+
bytes_needed_buffer = [0].pack("I")
|
328
|
+
r = enumprocessmodules.call(process_handle, module_handle_buffer, module_handle_buffer.size, bytes_needed_buffer)
|
329
|
+
bytes_needed = bytes_needed_buffer.unpack("I")[0]
|
330
|
+
break if bytes_needed <= module_handle_buffer.size
|
331
|
+
end
|
332
|
+
|
333
|
+
handles = module_handle_buffer.unpack("I*")
|
334
|
+
handles.select{|x|x>0}.map do |h|
|
335
|
+
str = "\x00" * 256
|
336
|
+
r = getmodulefilename.call(h, str, str.size)
|
337
|
+
str[0,r]
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
def LibraryDetector.detect_dlls
|
342
|
+
loaded = loaded_dlls
|
343
|
+
exec_prefix = RbConfig::CONFIG['exec_prefix']
|
344
|
+
loaded.select do |path|
|
345
|
+
path.tr('\\','/').index(exec_prefix) == 0 and
|
346
|
+
File.basename(path) =~ /\.dll$/ and
|
347
|
+
File.basename(path).downcase != RbConfig::CONFIG['LIBRUBY_SO'].downcase
|
348
|
+
end
|
349
|
+
end
|
350
|
+
end
|
230
351
|
|
231
352
|
class OcraBuilder
|
232
353
|
def initialize(path, windowed)
|
@@ -238,7 +359,16 @@ EOF
|
|
238
359
|
else
|
239
360
|
ocrafile.write(Ocra.stubimage)
|
240
361
|
end
|
241
|
-
|
362
|
+
end
|
363
|
+
|
364
|
+
if Ocra.icon_filename
|
365
|
+
system("#{Ocra.ediconpath} #{path} #{Ocra.icon_filename}")
|
366
|
+
end
|
367
|
+
|
368
|
+
opcode_offset = File.size(path)
|
369
|
+
|
370
|
+
File.open(path, "ab") do |ocrafile|
|
371
|
+
|
242
372
|
if Ocra.lzma_mode
|
243
373
|
@of = ""
|
244
374
|
else
|
@@ -263,7 +393,7 @@ EOF
|
|
263
393
|
end
|
264
394
|
|
265
395
|
ocrafile.write([OP_END].pack("V"))
|
266
|
-
ocrafile.write([
|
396
|
+
ocrafile.write([opcode_offset].pack("V")) # Pointer to start of opcodes
|
267
397
|
ocrafile.write(Signature.pack("C*"))
|
268
398
|
end
|
269
399
|
end
|
@@ -308,7 +438,7 @@ if File.basename(__FILE__) == File.basename($0)
|
|
308
438
|
Ocra.build_exe
|
309
439
|
exit(0)
|
310
440
|
end
|
311
|
-
|
441
|
+
|
312
442
|
puts "=== Loading script to check dependencies" unless Ocra.quiet
|
313
443
|
$0 = Ocra.files[0]
|
314
444
|
load Ocra.files[0]
|
data/lib/ocra.rb
CHANGED
Binary file
|
data/share/ocra/stub.exe
CHANGED
Binary file
|
data/share/ocra/stubw.exe
CHANGED
Binary file
|
data/test/test_ocra.rb
CHANGED
@@ -3,9 +3,12 @@ require "ocra"
|
|
3
3
|
require "tmpdir"
|
4
4
|
require "fileutils"
|
5
5
|
require "rbconfig"
|
6
|
+
include FileUtils
|
6
7
|
|
7
8
|
class TestOcra < Test::Unit::TestCase
|
8
9
|
|
10
|
+
DefaultArgs = [ '--quiet', '--no-lzma' ]
|
11
|
+
|
9
12
|
TESTED_OCRA = ENV['TESTED_OCRA'] || 'ocra.rb'
|
10
13
|
|
11
14
|
def initialize(*args)
|
@@ -18,6 +21,41 @@ class TestOcra < Test::Unit::TestCase
|
|
18
21
|
def ocra
|
19
22
|
@ocra
|
20
23
|
end
|
24
|
+
|
25
|
+
OcraRoot = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
26
|
+
|
27
|
+
FixturePath = File.expand_path(File.join(File.dirname(__FILE__), 'fixtures'))
|
28
|
+
|
29
|
+
# Sets up an directory with a copy of a fixture and yields to the
|
30
|
+
# block, then cleans up everything. A fixture here is a hierachy of
|
31
|
+
# files located in test/fixtures.
|
32
|
+
def with_fixture(name)
|
33
|
+
path = File.join(FixturePath, name)
|
34
|
+
FileUtils.cp_r path, '.'
|
35
|
+
begin
|
36
|
+
cd name do
|
37
|
+
yield
|
38
|
+
end
|
39
|
+
ensure
|
40
|
+
rm_rf 'name'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Sets up temporary environment variable and yields to the block.
|
45
|
+
def with_env(hash)
|
46
|
+
old = {}
|
47
|
+
hash.each do |k,v|
|
48
|
+
old[k] = ENV[k]
|
49
|
+
ENV[k] = v
|
50
|
+
end
|
51
|
+
begin
|
52
|
+
yield
|
53
|
+
ensure
|
54
|
+
hash.each do |k,v|
|
55
|
+
ENV[k] = old[k]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
21
59
|
|
22
60
|
def setup
|
23
61
|
@testnum += 1
|
@@ -32,168 +70,206 @@ class TestOcra < Test::Unit::TestCase
|
|
32
70
|
end
|
33
71
|
|
34
72
|
def test_helloworld
|
35
|
-
|
36
|
-
|
73
|
+
with_fixture 'helloworld' do
|
74
|
+
assert system("ruby", ocra, "helloworld.rb", *DefaultArgs)
|
75
|
+
assert File.exist?("helloworld.exe")
|
76
|
+
assert system("helloworld.exe")
|
37
77
|
end
|
38
|
-
assert system("ruby", ocra, "--quiet", "helloworld.rb")
|
39
|
-
assert File.exist?("helloworld.exe")
|
40
|
-
assert system("helloworld.exe")
|
41
78
|
end
|
42
79
|
|
43
80
|
def test_writefile
|
44
|
-
|
45
|
-
|
81
|
+
with_fixture 'writefile' do
|
82
|
+
assert system("ruby", ocra, "writefile.rb", *DefaultArgs)
|
83
|
+
assert File.exist?("writefile.exe")
|
84
|
+
assert system("writefile.exe")
|
85
|
+
assert File.exist?("output.txt")
|
86
|
+
assert "output", File.read("output.txt")
|
46
87
|
end
|
47
|
-
assert system("ruby", ocra, "--quiet", "writefile.rb")
|
48
|
-
assert File.exist?("writefile.exe")
|
49
|
-
assert system("writefile.exe")
|
50
|
-
assert File.exist?("output.txt")
|
51
|
-
assert "output", File.read("output.txt")
|
52
88
|
end
|
53
89
|
|
54
90
|
def test_exitstatus
|
55
|
-
|
56
|
-
|
91
|
+
with_fixture 'exitstatus' do
|
92
|
+
assert system("ruby", ocra, "exitstatus.rb", *DefaultArgs)
|
93
|
+
system("exitstatus.exe")
|
94
|
+
assert_equal 167, $?.exitstatus
|
57
95
|
end
|
58
|
-
assert system("ruby", ocra, "--quiet", "exitstatus.rb")
|
59
|
-
system("exitstatus.exe")
|
60
|
-
assert_equal 167, $?.exitstatus
|
61
96
|
end
|
62
97
|
|
63
98
|
def test_arguments
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
f << "exit(5)\n"
|
71
|
-
f << "end"
|
72
|
-
end
|
73
|
-
assert system("ruby", ocra, "--quiet", "arguments.rb")
|
74
|
-
assert File.exist?("arguments.exe")
|
75
|
-
# system(File.expand_path("arguments.exe"), "foo", "bar baz", "\"smile\"")
|
76
|
-
system("arguments.exe foo \"bar baz\"")
|
77
|
-
assert_equal 5, $?.exitstatus
|
99
|
+
with_fixture 'arguments' do
|
100
|
+
assert system("ruby", ocra, "arguments.rb", *DefaultArgs)
|
101
|
+
assert File.exist?("arguments.exe")
|
102
|
+
system("arguments.exe foo \"bar baz\"")
|
103
|
+
assert_equal 5, $?.exitstatus
|
104
|
+
end
|
78
105
|
end
|
79
106
|
|
80
107
|
def test_stdout_redir
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
108
|
+
with_fixture 'stdoutredir' do
|
109
|
+
assert system("ruby", ocra, "stdoutredir.rb", *DefaultArgs)
|
110
|
+
assert File.exist?("stdoutredir.exe")
|
111
|
+
system("stdoutredir.exe > output.txt")
|
112
|
+
assert File.exist?("output.txt")
|
113
|
+
assert_equal "Hello, World!\n", File.read("output.txt")
|
85
114
|
end
|
86
|
-
assert system("ruby", ocra, "--quiet", "stdoutredir.rb")
|
87
|
-
assert File.exist?("stdoutredir.exe")
|
88
|
-
system("stdoutredir.exe > output.txt")
|
89
|
-
assert File.exist?("output.txt")
|
90
|
-
assert_equal "Hello, World!\n", File.read("output.txt")
|
91
115
|
end
|
92
116
|
|
93
117
|
def test_stdin_redir
|
94
|
-
|
95
|
-
|
118
|
+
with_fixture 'stdinredir' do
|
119
|
+
assert system("ruby", ocra, "stdinredir.rb", *DefaultArgs)
|
120
|
+
assert File.exist?("stdinredir.exe")
|
121
|
+
system("stdinredir.exe < input.txt")
|
122
|
+
assert 104, $?.exitstatus
|
96
123
|
end
|
97
|
-
File.open("stdinredir.rb", "w") do |f|
|
98
|
-
f << "if $0 == __FILE__\n"
|
99
|
-
f << " exit 104 if gets == \"Hello, World!\\n\""
|
100
|
-
f << "end\n"
|
101
|
-
end
|
102
|
-
assert system("ruby", ocra, "--quiet", "stdinredir.rb")
|
103
|
-
assert File.exist?("stdinredir.exe")
|
104
|
-
system("stdinredir.exe < input.txt")
|
105
|
-
assert 104, $?.exitstatus
|
106
124
|
end
|
107
125
|
|
108
126
|
def test_gdbmdll
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
gdbmdllpath = Dir[File.join(bindir, 'gdbm*.dll')][0]
|
116
|
-
raise "gdbm dll was not found" unless gdbmdllpath
|
117
|
-
gdbmdll = File.basename(gdbmdllpath)
|
118
|
-
assert system("ruby", ocra, "--quiet", "--dll", gdbmdll, "gdbmdll.rb")
|
119
|
-
path = ENV['PATH']
|
120
|
-
ENV['PATH'] = "."
|
121
|
-
begin
|
122
|
-
system("gdbmdll.exe")
|
123
|
-
ensure
|
124
|
-
ENV['PATH'] = path
|
127
|
+
with_fixture 'gdbmdll' do
|
128
|
+
assert system("ruby", ocra, "gdbmdll.rb", *DefaultArgs)
|
129
|
+
with_env 'PATH' => '.' do
|
130
|
+
system("gdbmdll.exe")
|
131
|
+
assert_equal 104, $?.exitstatus
|
132
|
+
end
|
125
133
|
end
|
126
|
-
assert_equal 104, $?.exitstatus
|
127
134
|
end
|
128
135
|
|
129
136
|
def test_relative_require
|
130
|
-
|
131
|
-
|
132
|
-
|
137
|
+
with_fixture 'relativerequire' do
|
138
|
+
assert system("ruby", ocra, "relativerequire.rb", *DefaultArgs)
|
139
|
+
assert File.exist?("relativerequire.exe")
|
140
|
+
system("relativerequire.exe")
|
141
|
+
assert_equal 160, $?.exitstatus
|
133
142
|
end
|
134
|
-
|
135
|
-
|
136
|
-
|
143
|
+
end
|
144
|
+
|
145
|
+
# Test that autoloaded files which are not actually loaded while
|
146
|
+
# running the script through Ocra are included in the resulting
|
147
|
+
# executable.
|
148
|
+
def test_autoload
|
149
|
+
with_fixture 'autoload' do
|
150
|
+
assert system("ruby", ocra, "autoload.rb", *DefaultArgs)
|
151
|
+
assert File.exist?("autoload.exe")
|
152
|
+
File.unlink('foo.rb')
|
153
|
+
assert system("autoload.exe")
|
137
154
|
end
|
138
|
-
assert system("ruby", ocra, "--quiet", "relativerequire.rb")
|
139
|
-
assert File.exist?("relativerequire.exe")
|
140
|
-
system("relativerequire.exe")
|
141
|
-
assert_equal 160, $?.exitstatus
|
142
155
|
end
|
143
156
|
|
144
|
-
|
145
|
-
|
146
|
-
|
157
|
+
# Test that autoload statement which point to non-existing files are
|
158
|
+
# ignored by Ocra (a warning may be logged).
|
159
|
+
def test_autoload_missing
|
160
|
+
with_fixture 'autoloadmissing' do
|
161
|
+
assert system("ruby", ocra, "autoloadmissing.rb", *DefaultArgs)
|
162
|
+
assert File.exist?("autoloadmissing.exe")
|
163
|
+
assert system("autoloadmissing.exe")
|
147
164
|
end
|
148
|
-
assert system("ruby", ocra, "--quiet", "exiting.rb")
|
149
|
-
assert File.exist?("exiting.exe")
|
150
|
-
system("exiting.exe")
|
151
|
-
assert_equal 214, $?.exitstatus
|
152
165
|
end
|
153
166
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
167
|
+
# Test that Ocra picks up autoload statement nested in modules.
|
168
|
+
def test_autoload_nested
|
169
|
+
with_fixture 'autoloadnested' do
|
170
|
+
assert system("ruby", ocra, "autoloadnested.rb", *DefaultArgs)
|
171
|
+
assert File.exist?("autoloadnested.exe")
|
172
|
+
File.unlink('foo.rb')
|
173
|
+
assert system("autoloadnested.exe")
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
# Test that we can use custom include paths when invoking Ocra (ruby
|
178
|
+
# -I somepath). In this case the lib scripts are put in the src/
|
179
|
+
# directory.
|
180
|
+
def test_relative_loadpath1_ilib
|
181
|
+
with_fixture 'relloadpath1' do
|
182
|
+
assert system('ruby', '-I', 'lib', ocra, 'relloadpath1.rb', *DefaultArgs)
|
183
|
+
assert File.exist?('relloadpath1.exe')
|
184
|
+
assert system('relloadpath1.exe')
|
159
185
|
end
|
160
|
-
|
161
|
-
|
186
|
+
end
|
187
|
+
|
188
|
+
# Same as above with './lib'
|
189
|
+
def test_relative_loadpath_idotlib
|
190
|
+
with_fixture 'relloadpath1' do
|
191
|
+
assert system('ruby', '-I', './lib', ocra, 'relloadpath1.rb', *DefaultArgs)
|
192
|
+
assert File.exist?('relloadpath1.exe')
|
193
|
+
assert system('relloadpath1.exe')
|
162
194
|
end
|
163
|
-
assert system("ruby", ocra, "--quiet", "autoload.rb")
|
164
|
-
assert File.exist?("autoload.exe")
|
165
|
-
File.unlink('foo.rb')
|
166
|
-
assert system("autoload.exe")
|
167
|
-
# assert_equal 214, $?.exitstatus
|
168
195
|
end
|
169
196
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
197
|
+
# Test that we can use custom include paths when invoking Ocra (env
|
198
|
+
# RUBYLIB=lib). In this case the lib scripts are put in the src/
|
199
|
+
# directory.
|
200
|
+
def test_relative_loadpath_rubyliblib
|
201
|
+
with_fixture 'relloadpath1' do
|
202
|
+
with_env 'RUBYLIB' => 'lib' do
|
203
|
+
assert system('ruby', ocra, 'relloadpath1.rb', *DefaultArgs)
|
204
|
+
assert File.exist?('relloadpath1.exe')
|
205
|
+
assert system('relloadpath1.exe')
|
206
|
+
end
|
174
207
|
end
|
175
|
-
assert system("ruby", ocra, "--quiet", "autoloadmissing.rb")
|
176
|
-
assert File.exist?("autoloadmissing.exe")
|
177
|
-
assert system("autoloadmissing.exe")
|
178
208
|
end
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
209
|
+
|
210
|
+
# Same as above with './lib'
|
211
|
+
def test_relative_loadpath_rubylibdotlib
|
212
|
+
with_fixture 'relloadpath1' do
|
213
|
+
with_env 'RUBYLIB' => './lib' do
|
214
|
+
assert system('ruby', ocra, 'relloadpath1.rb', *DefaultArgs)
|
215
|
+
assert File.exist?('relloadpath1.exe')
|
216
|
+
assert system('relloadpath1.exe')
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
# Relative path with .. prefix (../lib).
|
222
|
+
def test_relative_loadpath2_idotdotlib
|
223
|
+
with_fixture 'relloadpath2' do
|
224
|
+
cd 'src' do
|
225
|
+
assert system('ruby', '-I', '../lib', ocra, 'relloadpath2.rb', *DefaultArgs)
|
226
|
+
assert File.exist?('relloadpath2.exe')
|
227
|
+
assert system('relloadpath2.exe')
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
# Test that scripts which modify $LOAD_PATH with a relative path
|
233
|
+
# (./lib) work correctly.
|
234
|
+
def test_relloadpath3
|
235
|
+
with_fixture 'relloadpath3' do
|
236
|
+
assert system('ruby', ocra, 'relloadpath3.rb', *DefaultArgs)
|
237
|
+
assert File.exist?('relloadpath3.exe')
|
238
|
+
assert system('relloadpath3.exe')
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
# Test that scripts which modify $LOAD_PATH with a relative path
|
243
|
+
# (../lib) work correctly.
|
244
|
+
def test_relloadpath4
|
245
|
+
with_fixture 'relloadpath4' do
|
246
|
+
cd 'src' do
|
247
|
+
assert system('ruby', ocra, 'relloadpath4.rb', *DefaultArgs)
|
248
|
+
assert File.exist?('relloadpath4.exe')
|
249
|
+
assert system('relloadpath4.exe')
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
def test_version
|
255
|
+
assert_match(/^Ocra \d+(\.\d)+$/, `ruby #{ocra} --version`)
|
256
|
+
end
|
257
|
+
|
258
|
+
def test_icon
|
259
|
+
with_fixture 'helloworld' do
|
260
|
+
icofile = File.join(OcraRoot, 'src', 'vit-ruby.ico')
|
261
|
+
assert system("ruby", ocra, '--icon', icofile, "helloworld.rb", *DefaultArgs)
|
262
|
+
assert File.exist?("helloworld.exe")
|
263
|
+
assert system("helloworld.exe")
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
def test_resource
|
268
|
+
with_fixture 'resource' do
|
269
|
+
assert system("ruby", ocra, "resource.rb", "resource.txt", "res/resource.txt", *DefaultArgs)
|
270
|
+
assert File.exist?("resource.exe")
|
271
|
+
assert system("resource.exe")
|
272
|
+
end
|
198
273
|
end
|
199
274
|
end
|
275
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ocra
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lars Christensen
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-05-
|
12
|
+
date: 2009-05-27 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -46,6 +46,7 @@ files:
|
|
46
46
|
- share/ocra/lzma.exe
|
47
47
|
- share/ocra/stub.exe
|
48
48
|
- share/ocra/stubw.exe
|
49
|
+
- share/ocra/edicon.exe
|
49
50
|
- test/test_ocra.rb
|
50
51
|
- lib/ocra.rb
|
51
52
|
has_rdoc: true
|