neri 0.9.0 → 0.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/README.ja.md +1 -1
- data/Rakefile +3 -1
- data/lib/neri/ayame.rb +3 -6
- data/lib/neri/build.rb +235 -239
- data/lib/neri/dxruby.rb +18 -28
- data/lib/neri/dxruby_tiled.rb +1 -1
- data/lib/neri/runtime.rb +77 -74
- data/lib/neri/version.rb +1 -1
- data/neri.gemspec +23 -24
- metadata +12 -40
- data/.gitignore +0 -9
data/lib/neri/build.rb
CHANGED
@@ -1,39 +1,38 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
# encoding: UTF-8
|
3
2
|
|
4
3
|
require "neri"
|
5
4
|
|
6
5
|
module Neri
|
7
6
|
@data_files = []
|
8
|
-
|
7
|
+
|
9
8
|
@options = {
|
10
9
|
quiet: false,
|
11
10
|
verbose: false,
|
12
|
-
|
11
|
+
|
13
12
|
external_encoding: nil,
|
14
|
-
|
13
|
+
|
15
14
|
dlls: [],
|
16
15
|
libs: [],
|
17
16
|
gems: [],
|
18
17
|
encoding: "*",
|
19
|
-
|
18
|
+
|
20
19
|
enable_gems: false,
|
21
20
|
enable_did_you_mean: false,
|
22
21
|
chdir_first: false,
|
23
22
|
pause_last: nil,
|
24
23
|
pause_text: nil,
|
25
|
-
|
24
|
+
|
26
25
|
output_dir: "./",
|
27
26
|
system_dir: "system",
|
28
|
-
|
27
|
+
|
29
28
|
datafile: nil,
|
30
29
|
encryption_key: nil,
|
31
|
-
|
30
|
+
|
32
31
|
no_exe: false,
|
33
32
|
use_b2ec: false,
|
34
33
|
b2ec_path: "Bat_To_Exe_Converter",
|
35
34
|
b2ec: {
|
36
|
-
icon:
|
35
|
+
icon: File.expand_path("#{File.dirname(__FILE__)}/../../share/default.ico"),
|
37
36
|
invisible: nil,
|
38
37
|
x64: nil,
|
39
38
|
uac_admin: nil,
|
@@ -50,50 +49,49 @@ module Neri
|
|
50
49
|
specialbuild: nil,
|
51
50
|
comments: nil
|
52
51
|
},
|
53
|
-
|
52
|
+
|
54
53
|
use_upx: false,
|
55
54
|
upx_path: "upx",
|
56
55
|
upx_targets: ["bin/**/*.dll"],
|
57
56
|
upx_options: "",
|
58
|
-
|
57
|
+
|
59
58
|
zipfile: nil,
|
60
59
|
sevenzip_path: "7z",
|
61
|
-
|
60
|
+
|
62
61
|
inno_script: nil,
|
63
|
-
iscc_path: "iscc"
|
62
|
+
iscc_path: "iscc"
|
64
63
|
}
|
65
64
|
@rubyopt = ENV["RUBYOPT"].to_s
|
66
65
|
@args = ""
|
67
66
|
@encryption_key = nil
|
68
|
-
|
67
|
+
|
69
68
|
@use_dxruby = false
|
70
69
|
@use_dxruby_tiled = false
|
71
70
|
@use_ayame = false
|
72
|
-
|
71
|
+
|
73
72
|
class << self
|
74
|
-
|
75
73
|
attr_reader :options
|
76
|
-
|
77
|
-
def relative_path(path, basedir=rubydir, prepath = "")
|
74
|
+
|
75
|
+
def relative_path(path, basedir = rubydir, prepath = "")
|
78
76
|
basedir.concat(File::SEPARATOR) unless basedir.end_with?(File::SEPARATOR)
|
79
|
-
|
77
|
+
path.start_with?(basedir) ? path.sub(basedir, prepath) : path
|
80
78
|
end
|
81
|
-
|
79
|
+
|
82
80
|
def to_winpath(path)
|
83
|
-
|
81
|
+
File::ALT_SEPARATOR ? path.tr(File::SEPARATOR, File::ALT_SEPARATOR) : path
|
84
82
|
end
|
85
|
-
|
86
|
-
def bindir
|
87
|
-
def rubydir
|
88
|
-
def rubyexe
|
89
|
-
def scriptfile
|
90
|
-
def basename
|
91
|
-
def basepath
|
92
|
-
def datafile
|
93
|
-
|
83
|
+
|
84
|
+
def bindir ; RbConfig::CONFIG["bindir"] || File.join(rubydir, "bin"); end
|
85
|
+
def rubydir ; File.join(RbConfig::TOPDIR, ""); end
|
86
|
+
def rubyexe ; RbConfig.ruby; end
|
87
|
+
def scriptfile; @data_files.first; end
|
88
|
+
def basename ; File.basename(scriptfile, ".*"); end
|
89
|
+
def basepath ; File.join(options[:output_dir], basename); end
|
90
|
+
def datafile ; File.join(options[:output_dir], options[:system_dir], options[:datafile]); end
|
91
|
+
|
94
92
|
# --help
|
95
93
|
def output_help
|
96
|
-
puts <<-
|
94
|
+
puts <<-HELP_MESSAGE
|
97
95
|
usage: neri [options] script.rb (other_files...) -- script_arguments
|
98
96
|
|
99
97
|
options:
|
@@ -101,28 +99,28 @@ options:
|
|
101
99
|
--version or -v
|
102
100
|
--quiet
|
103
101
|
--verbose
|
104
|
-
|
102
|
+
|
105
103
|
--external-encoding <encoding>
|
106
|
-
|
104
|
+
|
107
105
|
--dll <dll1>,<dll2>,...
|
108
106
|
--lib <lib1>,<lib2>,...
|
109
107
|
--gem <gem1>,<gem2>,...
|
110
|
-
|
108
|
+
|
111
109
|
--no-enc
|
112
110
|
--encoding <enc1>,<enc2>,...
|
113
|
-
|
111
|
+
|
114
112
|
--enable-gems
|
115
113
|
--enable-did-you-mean
|
116
114
|
--chdir-first
|
117
115
|
--pause-last
|
118
116
|
--no-pause-last
|
119
117
|
--pause-text <text>
|
120
|
-
|
118
|
+
|
121
119
|
--output-dir <dirname>
|
122
120
|
--system-dir <dirname>
|
123
121
|
--datafile <filename>
|
124
122
|
--encryption-key <key>
|
125
|
-
|
123
|
+
|
126
124
|
--no-exe
|
127
125
|
--use-b2ec
|
128
126
|
--b2ec-path <bat_to_exe_converter_path>
|
@@ -143,28 +141,28 @@ options:
|
|
143
141
|
--privatebuild <string>
|
144
142
|
--specialbuild <string>
|
145
143
|
--comments <string>
|
146
|
-
|
144
|
+
|
147
145
|
--use-upx
|
148
146
|
--upx-path <upx path>
|
149
147
|
--upx_targets '<glob>' # ex) 'bin/**/*.dll'
|
150
148
|
--upx-options <options>
|
151
|
-
|
149
|
+
|
152
150
|
--zipfile <filename>
|
153
151
|
--7zip-path <7-zip path>
|
154
|
-
|
152
|
+
|
155
153
|
--innosetup <inno_script>
|
156
154
|
--iscc-path <iscc path>
|
157
|
-
|
155
|
+
|
158
156
|
--create-recipe <recipefile>
|
159
157
|
--recipe <recipefile>
|
160
|
-
|
158
|
+
HELP_MESSAGE
|
161
159
|
end
|
162
|
-
|
160
|
+
|
163
161
|
# --version
|
164
162
|
def output_version
|
165
163
|
puts "Neri #{Neri::VERSION}"
|
166
164
|
end
|
167
|
-
|
165
|
+
|
168
166
|
# --create-recipe
|
169
167
|
def create_recipe(file, hash = options, pre = "Neri.options")
|
170
168
|
hash.each_pair do |key, value|
|
@@ -180,8 +178,7 @@ options:
|
|
180
178
|
end
|
181
179
|
end
|
182
180
|
end
|
183
|
-
|
184
|
-
|
181
|
+
|
185
182
|
def check_options
|
186
183
|
nputs_v "Checking Neri options."
|
187
184
|
while arg = ARGV.shift
|
@@ -194,7 +191,7 @@ options:
|
|
194
191
|
exit
|
195
192
|
when "--quiet", "-q"
|
196
193
|
options[:quiet] = true
|
197
|
-
when "--verbose"
|
194
|
+
when "--verbose"
|
198
195
|
options[:verbose] = true
|
199
196
|
when "--external_encoding"
|
200
197
|
options[:external_encoding] = ARGV.shift
|
@@ -278,7 +275,7 @@ options:
|
|
278
275
|
when "--upx-options"
|
279
276
|
options[:upx_options] = ARGV.shift
|
280
277
|
when "--zipfile"
|
281
|
-
options[:zipfile] = ARGV.shift.encode(
|
278
|
+
options[:zipfile] = "#{ARGV.shift.encode('utf-8').sub(/\.zip$/, '')}.zip"
|
282
279
|
when "--7zip-path"
|
283
280
|
options[:sevenzip_path] = ARGV.shift.encode("utf-8")
|
284
281
|
when "--innosetup"
|
@@ -289,7 +286,7 @@ options:
|
|
289
286
|
require "json"
|
290
287
|
filename = ARGV.shift.encode("utf-8")
|
291
288
|
nputs "Creating recipe_file '#{filename}'."
|
292
|
-
open(filename, "w:utf-8"){ |file| create_recipe(file) }
|
289
|
+
File.open(filename, "w:utf-8") { |file| create_recipe(file) }
|
293
290
|
exit
|
294
291
|
when "--recipe"
|
295
292
|
filename = ARGV.shift.encode("utf-8")
|
@@ -305,113 +302,115 @@ options:
|
|
305
302
|
@data_files.push(arg.encode("utf-8"))
|
306
303
|
end
|
307
304
|
end
|
308
|
-
|
305
|
+
|
309
306
|
if @data_files.empty?
|
310
307
|
error "No Script File!"
|
311
308
|
output_help
|
312
309
|
exit
|
313
310
|
end
|
314
|
-
|
315
|
-
@args = ARGV.map{ |
|
316
|
-
@options[:external_encoding] ||= Encoding
|
317
|
-
unless options[:enable_gems]
|
318
|
-
@rubyopt += " --disable-gems"
|
311
|
+
|
312
|
+
@args = ARGV.map { |a| %( "#{a}") }.join("")
|
313
|
+
@options[:external_encoding] ||= Encoding.default_external.name
|
314
|
+
unless options[:enable_gems] || @rubyopt.index("--disable-gems")
|
315
|
+
@rubyopt += " --disable-gems"
|
319
316
|
end
|
320
|
-
unless options[:enable_did_you_mean]
|
321
|
-
@rubyopt += " --disable-did_you_mean"
|
317
|
+
unless options[:enable_did_you_mean] || @rubyopt.index("--disable-did_you_mean")
|
318
|
+
@rubyopt += " --disable-did_you_mean"
|
319
|
+
end
|
320
|
+
if @data_files.size > 1 || options[:encryption_key]
|
321
|
+
options[:datafile] ||= "#{basename}.dat"
|
322
322
|
end
|
323
323
|
end
|
324
|
-
|
325
|
-
|
324
|
+
|
326
325
|
# check dependencies
|
327
|
-
def rb_dependencies
|
328
|
-
|
326
|
+
def rb_dependencies
|
327
|
+
$LOADED_FEATURES.uniq
|
329
328
|
end
|
330
|
-
|
331
|
-
def dll_dependencies
|
329
|
+
|
330
|
+
def dll_dependencies
|
332
331
|
require "Win32API"
|
333
|
-
|
332
|
+
|
334
333
|
enumprocessmodules = Win32API.new("psapi" , "EnumProcessModules", ["L","P","L","P"], "L")
|
335
334
|
getmodulefilename = Win32API.new("kernel32", "GetModuleFileNameW", ["L","P","L"], "L")
|
336
335
|
getcurrentprocess = Win32API.new("kernel32", "GetCurrentProcess" , [], "L")
|
337
|
-
|
336
|
+
|
338
337
|
bytes_needed = 4 * 32
|
339
338
|
module_handle_buffer = nil
|
340
|
-
process_handle = getcurrentprocess.call
|
339
|
+
process_handle = getcurrentprocess.call
|
341
340
|
loop do
|
342
341
|
module_handle_buffer = "\x00" * bytes_needed
|
343
342
|
bytes_needed_buffer = [0].pack("I")
|
344
|
-
|
345
|
-
bytes_needed = bytes_needed_buffer.
|
343
|
+
enumprocessmodules.call(process_handle, module_handle_buffer, module_handle_buffer.size, bytes_needed_buffer)
|
344
|
+
bytes_needed = bytes_needed_buffer.unpack1("I")
|
346
345
|
break if bytes_needed <= module_handle_buffer.size
|
347
346
|
end
|
348
|
-
|
347
|
+
|
349
348
|
handles = module_handle_buffer.unpack("I*")
|
350
349
|
dependencies = handles.select { |handle| handle > 0 }.map do |handle|
|
351
350
|
str = "\x00\x00" * 256
|
352
351
|
modulefilename_length = getmodulefilename.call(handle, str, str.size)
|
353
|
-
|
354
|
-
end
|
355
|
-
|
356
|
-
dependencies.map!{|dep| dep.sub(/^\\\\\?\\/, "")}
|
357
|
-
if File::ALT_SEPARATOR
|
358
|
-
dependencies.map!{|dep| dep.tr(File::ALT_SEPARATOR, File::SEPARATOR)}
|
352
|
+
str[0, modulefilename_length * 2].force_encoding("UTF-16LE").encode("UTF-8")
|
359
353
|
end
|
354
|
+
|
355
|
+
dependencies.map! { |dep| dep.sub(/^\\\\\?\\/, "") }
|
356
|
+
dependencies.map! { |dep| dep.tr(File::ALT_SEPARATOR, File::SEPARATOR) } if File::ALT_SEPARATOR
|
360
357
|
dependencies.delete(rubyexe)
|
361
|
-
|
362
|
-
|
358
|
+
|
359
|
+
dependencies.uniq
|
363
360
|
end
|
364
|
-
|
365
|
-
def ruby_dependencies
|
361
|
+
|
362
|
+
def ruby_dependencies
|
366
363
|
dependencies = Dir.glob(File.join(bindir, "**", "*.manifest"))
|
367
364
|
dependencies.push(rubyexe)
|
368
|
-
|
365
|
+
dependencies.uniq
|
369
366
|
end
|
370
|
-
|
371
|
-
def additional_dlls_dependencies
|
367
|
+
|
368
|
+
def additional_dlls_dependencies
|
372
369
|
dependencies = []
|
373
370
|
options[:dlls].each do |dll|
|
374
371
|
dependencies += Dir.glob(File.join(bindir, "**", dll))
|
375
|
-
dependencies += Dir.glob(File.join(bindir, "**", dll
|
372
|
+
dependencies += Dir.glob(File.join(bindir, "**", "#{dll}.*"))
|
376
373
|
end
|
377
|
-
|
374
|
+
dependencies.uniq
|
378
375
|
end
|
379
|
-
|
380
|
-
def additional_libs_dependencies
|
376
|
+
|
377
|
+
def additional_libs_dependencies
|
381
378
|
dependencies = []
|
382
379
|
options[:libs].each do |lib|
|
383
380
|
$LOAD_PATH.each do |path|
|
384
381
|
dependencies += Dir.glob(File.join(path, lib))
|
385
|
-
dependencies += Dir.glob(File.join(path, lib
|
382
|
+
dependencies += Dir.glob(File.join(path, "#{lib}.*"))
|
386
383
|
dependencies += Dir.glob(File.join(path, lib, "**", "*"))
|
387
384
|
end
|
388
385
|
end
|
389
|
-
|
386
|
+
dependencies.uniq
|
390
387
|
end
|
391
|
-
|
392
|
-
def additional_gems_dependencies
|
388
|
+
|
389
|
+
def additional_gems_dependencies
|
393
390
|
require "rubygems"
|
394
391
|
dependencies = []
|
395
392
|
rubygems_dir = File.join(Gem.dir, "gems")
|
396
393
|
options[:gems].each do |gem|
|
397
|
-
gem.sub!(
|
398
|
-
targets =
|
394
|
+
gem.sub!(/:(.+)/, "")
|
395
|
+
targets = Regexp.last_match(1).to_s.split("|")
|
399
396
|
targets.push("lib/**/*")
|
400
397
|
gem += "-*" unless gem.match("-")
|
401
|
-
gemdir = Dir.glob(File.join(rubygems_dir, gem)).
|
398
|
+
gemdir = Dir.glob(File.join(rubygems_dir, gem)).max
|
402
399
|
next unless gemdir
|
400
|
+
|
403
401
|
targets.each do |target|
|
404
402
|
dependencies += Dir.glob(File.join(gemdir, target))
|
405
403
|
end
|
406
404
|
end
|
407
|
-
|
405
|
+
dependencies.uniq
|
408
406
|
end
|
409
|
-
|
410
|
-
def encoding_dependencies
|
407
|
+
|
408
|
+
def encoding_dependencies
|
411
409
|
return [] unless options[:encoding]
|
410
|
+
|
412
411
|
dependencies = []
|
413
412
|
enc_dir = Dir.glob(File.join(RbConfig::CONFIG["archdir"] || RbConfig::TOPDIR, "**", "enc")).first
|
414
|
-
|
413
|
+
|
415
414
|
options[:encoding].split(",").map(&:strip).each do |enc|
|
416
415
|
case enc
|
417
416
|
when "ja"
|
@@ -420,21 +419,21 @@ options:
|
|
420
419
|
end
|
421
420
|
else
|
422
421
|
dependencies += Dir.glob(File.join(enc_dir, "**", enc))
|
423
|
-
dependencies += Dir.glob(File.join(enc_dir, "**", enc
|
422
|
+
dependencies += Dir.glob(File.join(enc_dir, "**", "#{enc}.*"))
|
424
423
|
end
|
425
424
|
end
|
426
|
-
|
427
|
-
|
425
|
+
|
426
|
+
dependencies.uniq
|
428
427
|
end
|
429
|
-
|
430
|
-
def check_dependencies
|
428
|
+
|
429
|
+
def check_dependencies
|
431
430
|
nputs "Running script '#{scriptfile}' to check dependencies."
|
432
431
|
begin
|
433
432
|
load File.expand_path(scriptfile)
|
434
433
|
rescue SystemExit, Interrupt
|
435
434
|
end
|
436
435
|
nputs "Script '#{scriptfile}' end."
|
437
|
-
|
436
|
+
|
438
437
|
if defined? DXRuby
|
439
438
|
require "neri/dxruby"
|
440
439
|
@use_dxruby = true
|
@@ -447,15 +446,15 @@ options:
|
|
447
446
|
require "neri/ayame"
|
448
447
|
@use_ayame = true
|
449
448
|
end
|
450
|
-
|
451
|
-
if options[:b2ec][:invisible]
|
449
|
+
|
450
|
+
if options[:b2ec][:invisible].nil? &&
|
452
451
|
(File.extname(scriptfile) == ".rbw" || @use_dxruby)
|
453
452
|
options[:b2ec][:invisible] = true
|
454
453
|
end
|
455
|
-
if options[:pause_last]
|
456
|
-
options[:pause_last] = true
|
454
|
+
if options[:pause_last].nil? && !options[:b2ec][:invisible]
|
455
|
+
options[:pause_last] = true
|
457
456
|
end
|
458
|
-
|
457
|
+
|
459
458
|
require "rbconfig"
|
460
459
|
dependencies = []
|
461
460
|
dependencies += rb_dependencies
|
@@ -466,59 +465,58 @@ options:
|
|
466
465
|
dependencies += additional_gems_dependencies
|
467
466
|
dependencies += encoding_dependencies
|
468
467
|
dependencies = select_dependencies(dependencies)
|
469
|
-
|
470
|
-
size = dependencies.map{|d| File.size(d)}.inject(&:+)
|
468
|
+
|
469
|
+
size = dependencies.map { |d| File.size(d) }.inject(&:+)
|
471
470
|
nputs "#{dependencies.size} files, #{size} bytes dependencies."
|
472
471
|
if options[:verbose]
|
473
472
|
dependencies.each do |dependency|
|
474
473
|
nputs_v " - #{dependency}"
|
475
474
|
end
|
476
475
|
end
|
477
|
-
|
478
|
-
|
476
|
+
|
477
|
+
dependencies
|
479
478
|
end
|
480
|
-
|
479
|
+
|
481
480
|
def select_dependencies(dependencies)
|
482
481
|
dependencies.select! do |dependency|
|
483
482
|
dependency.start_with?(rubydir)
|
484
483
|
end
|
485
|
-
|
484
|
+
|
486
485
|
@data_files.each do |file|
|
487
486
|
dependencies.delete(File.expand_path(file))
|
488
487
|
end
|
489
|
-
|
488
|
+
|
490
489
|
unless options[:enable_gems]
|
491
490
|
dependencies.delete_if do |dependency|
|
492
491
|
File.basename(dependency) == "rubygems.rb" ||
|
493
|
-
|
492
|
+
dependency.split(File::SEPARATOR).index("rubygems")
|
494
493
|
end
|
495
494
|
end
|
496
495
|
unless options[:enable_did_you_mean]
|
497
496
|
dependencies.delete_if do |dependency|
|
498
497
|
File.basename(dependency) == "did_you_mean.rb" ||
|
499
|
-
|
498
|
+
dependency.split(File::SEPARATOR).index("did_you_mean")
|
500
499
|
end
|
501
500
|
end
|
502
|
-
|
503
|
-
|
501
|
+
|
502
|
+
dependencies.uniq
|
504
503
|
end
|
505
|
-
|
506
|
-
|
504
|
+
|
507
505
|
def copy_files(dependencies)
|
508
506
|
nputs "Copying dependencies."
|
509
507
|
require "fileutils"
|
510
508
|
src_dir = rubydir
|
511
509
|
desc_dir = File.join(options[:output_dir], options[:system_dir], "")
|
512
|
-
|
510
|
+
|
513
511
|
system_files = dependencies.map do |file|
|
514
512
|
[file, file.sub(src_dir, desc_dir)]
|
515
513
|
end
|
516
514
|
unless options[:enable_gems]
|
517
|
-
system_files.each do |
|
518
|
-
desc.sub!(
|
515
|
+
system_files.each do |_src, desc|
|
516
|
+
desc.sub!(%r{/gems(/\d+\.\d+\.\d+/)gems/(.+?)-[^/]+/lib/}, "/vendor_ruby\\1")
|
519
517
|
end
|
520
518
|
end
|
521
|
-
|
519
|
+
|
522
520
|
system_files.each do |src, desc|
|
523
521
|
FileUtils.makedirs(File.dirname(desc))
|
524
522
|
if File.file?(src)
|
@@ -528,49 +526,52 @@ options:
|
|
528
526
|
end
|
529
527
|
FileUtils.copy(scriptfile, desc_dir) unless options[:datafile]
|
530
528
|
end
|
531
|
-
|
532
|
-
|
533
|
-
def create_datafile()
|
534
|
-
if @data_files.size > 1 || options[:encryption_key]
|
535
|
-
options[:datafile] ||= basename + ".dat"
|
536
|
-
end
|
529
|
+
|
530
|
+
def create_datafile
|
537
531
|
return unless options[:datafile]
|
538
|
-
|
532
|
+
|
539
533
|
nputs "Creating datafile '#{datafile}'."
|
540
534
|
data_files = @data_files.select { |file| File.file? file }
|
541
535
|
@data_files.select { |file| File.directory? file }.each do |dir|
|
542
|
-
data_files += Dir.glob(dir
|
536
|
+
data_files += Dir.glob("#{dir}/**/*").select { |file| File.file? file }
|
543
537
|
end
|
538
|
+
data_files = data_files.reverse.uniq { |file| File.expand_path(file) }
|
544
539
|
if options[:encryption_key]
|
545
540
|
require "digest/sha2"
|
546
541
|
@encryption_key = Digest::SHA2.hexdigest(options[:encryption_key])
|
547
542
|
end
|
548
543
|
Neri.key = @encryption_key || "0" * 64
|
549
|
-
open(datafile, "wb") do |f|
|
544
|
+
File.open(datafile, "wb") do |f|
|
550
545
|
pos = 0
|
551
|
-
files_str = data_files.map{|file|
|
552
|
-
|
553
|
-
filename =
|
554
|
-
|
555
|
-
|
546
|
+
files_str = data_files.map { |file|
|
547
|
+
fullpath = File.expand_path(file)
|
548
|
+
filename = if fullpath.start_with?(rubydir)
|
549
|
+
relative_path(fullpath, rubydir, "*neri*#{File::SEPARATOR}")
|
550
|
+
else
|
551
|
+
file
|
552
|
+
end
|
553
|
+
filedata = [filename, File.size(file), pos].join("\t")
|
554
|
+
nputs_v " - #{filename}:#{File.size(file)} bytes"
|
555
|
+
if File.expand_path(filename).start_with?(Dir.pwd) && filename.include?("..")
|
556
|
+
cd_path = ".#{File.expand_path(filename).delete_prefix(Dir.pwd)}"
|
557
|
+
filedata += "\n" + [cd_path, File.size(file), pos].join("\t")
|
558
|
+
end
|
556
559
|
pos += File.size(file)
|
557
560
|
pos += BLOCK_LENGTH - pos % BLOCK_LENGTH unless pos % BLOCK_LENGTH == 0
|
558
|
-
|
559
|
-
filedata.join("\t")
|
561
|
+
filedata
|
560
562
|
}.join("\n").encode(Encoding::UTF_8)
|
561
|
-
|
562
|
-
f.write(
|
563
|
+
|
564
|
+
f.write(format("%#{BLOCK_LENGTH}d", files_str.bytesize))
|
563
565
|
f.write(xor(files_str))
|
564
566
|
data_files.each do |file|
|
565
567
|
f.write(xor(File.binread(file)))
|
566
568
|
end
|
567
569
|
end
|
568
570
|
end
|
569
|
-
|
570
|
-
|
571
|
-
def create_batfile()
|
571
|
+
|
572
|
+
def create_batfile
|
572
573
|
nputs "Creating batch_file '#{basepath}.bat'."
|
573
|
-
|
574
|
+
|
574
575
|
pause_command = ""
|
575
576
|
if options[:pause_last]
|
576
577
|
pause_command += "echo.\n"
|
@@ -582,64 +583,67 @@ options:
|
|
582
583
|
end
|
583
584
|
end
|
584
585
|
chdir = options[:chdir_first] ? 'cd /d "%~dp0"' : ""
|
585
|
-
|
586
|
-
open(basepath
|
587
|
-
f.puts <<-
|
586
|
+
|
587
|
+
File.open("#{basepath}.bat", "w:#{options[:external_encoding]}") do |f|
|
588
|
+
f.puts <<-BATCH
|
588
589
|
@echo off
|
589
590
|
setlocal
|
590
591
|
set PATH=%~dp0#{options[:system_dir]}\\#{relative_path(bindir)};%PATH%
|
592
|
+
set NERI_EXECUTABLE=%~0
|
591
593
|
#{chdir}
|
592
594
|
if %~x0 == .exe ( shift )
|
593
|
-
#{ruby_command(
|
595
|
+
#{ruby_command(options[:chdir_first] ? '' : '%~dp0')} %1 %2 %3 %4 %5 %6 %7 %8 %9
|
594
596
|
#{pause_command}
|
595
597
|
endlocal
|
596
|
-
|
598
|
+
BATCH
|
597
599
|
end
|
598
600
|
end
|
599
|
-
|
600
|
-
def create_exefile
|
601
|
+
|
602
|
+
def create_exefile
|
601
603
|
unless system("gcc --version >nul 2>&1 && windres --version >nul 2>&1")
|
602
604
|
error "gcc or windres not found !"
|
603
605
|
create_batfile
|
604
606
|
return
|
605
607
|
end
|
606
|
-
|
607
|
-
exe_file = to_winpath(basepath
|
608
|
-
c_file = to_winpath(basepath
|
609
|
-
o_file = to_winpath(basepath
|
610
|
-
rc_file = to_winpath(basepath
|
608
|
+
|
609
|
+
exe_file = to_winpath("#{basepath}.exe" )
|
610
|
+
c_file = to_winpath("#{basepath}_tmp.c" )
|
611
|
+
o_file = to_winpath("#{basepath}_tmp.o" )
|
612
|
+
rc_file = to_winpath("#{basepath}_tmp.rc")
|
611
613
|
system_dir = escape_cstr(to_winpath(File.join(options[:system_dir], "")))
|
612
614
|
nputs "Creating exe_file '#{exe_file}'."
|
613
|
-
open(c_file, "w:#{options[:external_encoding]}") do |f|
|
614
|
-
f.puts <<-
|
615
|
+
File.open(c_file, "w:#{options[:external_encoding]}") do |f|
|
616
|
+
f.puts <<-CFILE
|
615
617
|
#include <stdio.h>
|
618
|
+
#include <stdlib.h>
|
616
619
|
#include <windows.h>
|
617
620
|
#include <unistd.h>
|
618
621
|
|
619
622
|
int main(int argc, char *argv[])
|
620
623
|
{
|
621
|
-
char exepath[_MAX_PATH * 2 + 1],
|
624
|
+
char exepath[_MAX_PATH * 2 + 1],
|
622
625
|
drive [_MAX_DRIVE + 1],
|
623
626
|
dir [_MAX_DIR * 2 + 1],
|
624
627
|
fname [_MAX_FNAME * 2 + 1],
|
625
628
|
ext [_MAX_EXT * 2 + 1],
|
626
629
|
paths [_MAX_PATH * 32 + 1],
|
627
630
|
runruby[_MAX_PATH * 32 + 1];
|
628
|
-
PROCESS_INFORMATION pi;
|
631
|
+
PROCESS_INFORMATION pi;
|
629
632
|
STARTUPINFO si;
|
630
633
|
ZeroMemory(&si, sizeof(STARTUPINFO));
|
631
|
-
|
634
|
+
|
632
635
|
if(GetModuleFileName(NULL, exepath, MAX_PATH * 2) != 0){
|
633
636
|
_splitpath_s(exepath, drive, _MAX_DRIVE, dir, _MAX_DIR * 2, fname, _MAX_FNAME * 2, ext, _MAX_EXT * 2);
|
634
637
|
} else {
|
635
638
|
exit(EXIT_FAILURE);
|
636
639
|
}
|
637
|
-
|
640
|
+
snprintf(paths, sizeof(paths), "NERI_EXECUTABLE=%s", exepath);
|
638
641
|
putenv(paths);
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
642
|
+
snprintf(paths, sizeof(paths), "PATH=%s%s#{system_dir}bin;%s", drive, dir, getenv("PATH"));
|
643
|
+
putenv(paths);
|
644
|
+
#{options[:chdir_first] ? 'snprintf(paths, sizeof(paths), "%s%s", drive, dir);chdir(paths);' : ''}
|
645
|
+
snprintf(runruby, sizeof(runruby), "#{escape_cstr(ruby_command(options[:chdir_first] ? '' : '%s%s'))} %s %s %s %s %s %s %s %s %s",
|
646
|
+
#{options[:chdir_first] ? '' : 'drive, dir,'}
|
643
647
|
argc > 1 ? argv[1] : "",
|
644
648
|
argc > 2 ? argv[2] : "",
|
645
649
|
argc > 3 ? argv[3] : "",
|
@@ -650,7 +654,7 @@ int main(int argc, char *argv[])
|
|
650
654
|
argc > 8 ? argv[8] : "",
|
651
655
|
argc > 9 ? argv[9] : ""
|
652
656
|
);
|
653
|
-
|
657
|
+
CFILE
|
654
658
|
if options[:b2ec][:invisible]
|
655
659
|
f.puts %[ CreateProcess(NULL, runruby, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, NULL, NULL, &si, &pi);]
|
656
660
|
else
|
@@ -667,14 +671,14 @@ int main(int argc, char *argv[])
|
|
667
671
|
end
|
668
672
|
f.puts " return 0;\n}"
|
669
673
|
end
|
670
|
-
|
671
|
-
open(rc_file, "w:#{options[:external_encoding]}") do |f|
|
672
|
-
f.puts <<-
|
674
|
+
|
675
|
+
File.open(rc_file, "w:#{options[:external_encoding]}") do |f|
|
676
|
+
f.puts <<-RCFILE
|
673
677
|
#include <winver.h>
|
674
678
|
|
675
679
|
1 VERSIONINFO
|
676
|
-
#{options[:b2ec][:fileversion ] ? "FILEVERSION
|
677
|
-
#{options[:b2ec][:productversion] ? "PRODUCTVERSION
|
680
|
+
#{options[:b2ec][:fileversion ] ? "FILEVERSION #{escape_cstr(options[:b2ec][:fileversion ])}" : ""}
|
681
|
+
#{options[:b2ec][:productversion] ? "PRODUCTVERSION #{escape_cstr(options[:b2ec][:productversion])}" : ""}
|
678
682
|
FILETYPE VFT_APP
|
679
683
|
BEGIN
|
680
684
|
BLOCK "StringFileInfo"
|
@@ -703,36 +707,35 @@ BEGIN
|
|
703
707
|
END
|
704
708
|
|
705
709
|
2 ICON "#{escape_cstr(options[:b2ec][:icon])}"
|
706
|
-
|
710
|
+
RCFILE
|
707
711
|
end
|
708
|
-
nsystem(%
|
709
|
-
nsystem(%
|
710
|
-
nsystem(%
|
712
|
+
nsystem(%(windres -o "#{o_file}" "#{rc_file}"))
|
713
|
+
nsystem(%(gcc#{options[:b2ec][:invisible] ? ' -mwindows' : ''} -o "#{exe_file}" "#{c_file}" "#{o_file}"))
|
714
|
+
nsystem(%(strip "#{exe_file}"))
|
711
715
|
File.delete(c_file, rc_file, o_file)
|
712
716
|
end
|
713
|
-
|
717
|
+
|
714
718
|
def ruby_command(path)
|
715
|
-
system_dir = "#{path}#{File.join(options[:system_dir],
|
719
|
+
system_dir = "#{path}#{File.join(options[:system_dir], '')}"
|
716
720
|
ruby_code = ""
|
717
721
|
ruby_code = "Neri.key='#{@encryption_key}';" if @encryption_key
|
718
722
|
if options[:datafile]
|
719
723
|
ruby_code += "Neri.datafile='#{system_dir}' + #{unpack_filename(options[:datafile])};"
|
720
|
-
ruby_code += "load
|
724
|
+
ruby_code += "load #{unpack_filename(File.basename(scriptfile))}"
|
721
725
|
else
|
722
726
|
ruby_code += "load File.expand_path('#{system_dir}' + #{unpack_filename(scriptfile)})"
|
723
727
|
end
|
724
|
-
|
728
|
+
|
725
729
|
r = " -rneri"
|
726
730
|
r += " -rneri/dxruby" if @use_dxruby
|
727
731
|
r += " -rneri/dxruby_tiled" if @use_dxruby_tiled
|
728
732
|
r += " -rneri/ayame" if @use_ayame
|
729
|
-
|
733
|
+
|
730
734
|
ruby = to_winpath(relative_path(rubyexe, bindir))
|
731
|
-
|
735
|
+
%(#{ruby}#{r} #{@rubyopt} -e "# coding:utf-8" -e "#{ruby_code}" #{@args})
|
732
736
|
end
|
733
|
-
|
734
|
-
|
735
|
-
def bat_to_exe_converter()
|
737
|
+
|
738
|
+
def bat_to_exe_converter
|
736
739
|
create_batfile
|
737
740
|
begin
|
738
741
|
`#{options[:b2ec_path]} /help`
|
@@ -740,36 +743,32 @@ END
|
|
740
743
|
error "Bat To Exe Converter not found !"
|
741
744
|
return
|
742
745
|
end
|
743
|
-
|
744
|
-
batch_file = basepath
|
745
|
-
exe_file = basepath
|
746
|
+
|
747
|
+
batch_file = "#{basepath}.bat"
|
748
|
+
exe_file = "#{basepath}.exe"
|
746
749
|
nputs "Creating exe_file '#{exe_file}' with Bat To Exe Converter."
|
747
750
|
File.delete(exe_file) if File.exist?(exe_file)
|
748
|
-
if options[:b2ec][:x64]
|
749
|
-
options[:b2ec][:x64] = true
|
751
|
+
if options[:b2ec][:x64].nil? && RbConfig::CONFIG["target"].to_s.index("64")
|
752
|
+
options[:b2ec][:x64] = true
|
750
753
|
end
|
751
|
-
args = %
|
752
|
-
args += options[:b2ec].map{|key, value|
|
754
|
+
args = %( /bat "#{batch_file}" /exe "#{exe_file}")
|
755
|
+
args += options[:b2ec].map { |key, value|
|
753
756
|
case value
|
754
|
-
when String
|
755
|
-
when true
|
756
|
-
else;
|
757
|
+
when String then %( /#{key.to_s.tr('_', '-')} "#{value}")
|
758
|
+
when true then %( /#{key.to_s.tr('_', '-')})
|
759
|
+
else; %()
|
757
760
|
end
|
758
761
|
}.join("")
|
759
|
-
|
760
|
-
|
761
|
-
unless nsystem "#{options[:b2ec_path]}#{args}"
|
762
|
-
error "Failed to create exe_file !"
|
763
|
-
end
|
762
|
+
|
763
|
+
error "Failed to create exe_file !" unless nsystem "#{options[:b2ec_path]}#{args}"
|
764
764
|
end
|
765
|
-
|
766
|
-
|
767
|
-
def upx()
|
765
|
+
|
766
|
+
def upx
|
768
767
|
unless system("#{options[:upx_path]} --version >nul 2>&1")
|
769
768
|
error "UPX not found !"
|
770
769
|
return
|
771
770
|
end
|
772
|
-
|
771
|
+
|
773
772
|
nputs "Compressing with UPX."
|
774
773
|
options[:upx_targets].each do |target|
|
775
774
|
Dir.glob(File.join(options[:output_dir], options[:system_dir], target)).each do |target_path|
|
@@ -778,78 +777,76 @@ END
|
|
778
777
|
end
|
779
778
|
end
|
780
779
|
end
|
781
|
-
|
782
|
-
|
783
|
-
def create_zipfile()
|
780
|
+
|
781
|
+
def create_zipfile
|
784
782
|
unless system("#{options[:sevenzip_path]} >nul 2>&1")
|
785
783
|
error "7-Zip not found !"
|
786
784
|
return
|
787
785
|
end
|
788
|
-
|
786
|
+
|
789
787
|
nputs "Creating zip_file '#{options[:zipfile]}'."
|
790
788
|
File.delete(options[:zipfile]) if File.exist?(options[:zipfile])
|
791
789
|
files = []
|
792
790
|
if options[:output_dir] == "./"
|
793
791
|
files.push(options[:system_dir])
|
794
|
-
files.push(File.exist?(basepath
|
792
|
+
files.push(File.exist?("#{basepath}.exe") ? "#{basepath}.exe" : "#{basepath}.bat")
|
795
793
|
else
|
796
794
|
files.push(options[:output_dir])
|
797
795
|
end
|
798
796
|
command = %("#{options[:sevenzip_path]}" a "#{options[:zipfile]}" "#{files.join('" "')}")
|
799
797
|
nsystem command
|
800
798
|
end
|
801
|
-
|
802
|
-
|
803
|
-
def inno_setup()
|
799
|
+
|
800
|
+
def inno_setup
|
804
801
|
unless system("#{options[:iscc_path]} /? >nul 2>&1")
|
805
802
|
error("Inno Setup not found !")
|
806
803
|
return
|
807
804
|
end
|
808
|
-
|
805
|
+
|
809
806
|
filename = options[:inno_script]
|
810
807
|
nputs "Creating Installer '#{filename}'."
|
811
808
|
script = "[Setup]\n"
|
812
809
|
if File.exist?(filename)
|
813
810
|
script = File.read(filename, encoding: Encoding::UTF_8)
|
814
|
-
filename = File.basename(filename,
|
811
|
+
filename = "#{File.basename(filename, '.*')}_tmp#{File.extname(filename)}"
|
815
812
|
end
|
816
|
-
|
813
|
+
|
817
814
|
version = options[:b2ec][:productversion] || options[:b2ec][:fileversion]
|
818
815
|
if !script.match(/^AppName=/) && options[:b2ec][:productname]
|
819
|
-
script.sub!(/^(\[Setup\])(\s+)/i){ "#{$1}\nAppName=#{options[:b2ec][:productname]}#{$2}" }
|
816
|
+
script.sub!(/^(\[Setup\])(\s+)/i) { "#{$1}\nAppName=#{options[:b2ec][:productname]}#{$2}" }
|
820
817
|
end
|
821
818
|
if !script.match(/^AppVersion=/) && version
|
822
|
-
script.sub!(/^(\[Setup\])(\s+)/i){ "#{$1}\nAppVersion=#{version}#{$2}" }
|
819
|
+
script.sub!(/^(\[Setup\])(\s+)/i) { "#{$1}\nAppVersion=#{version}#{$2}" }
|
823
820
|
end
|
824
821
|
if !script.match(/^AppVerName=/) && options[:b2ec][:productname] && version
|
825
|
-
script.sub!(/^(\[Setup\])(\s+)/i){ "#{$1}\nAppVerName=#{options[:b2ec][:productname]} #{version}#{$2}" }
|
822
|
+
script.sub!(/^(\[Setup\])(\s+)/i) { "#{$1}\nAppVerName=#{options[:b2ec][:productname]} #{version}#{$2}" }
|
826
823
|
end
|
827
824
|
if !script.match(/^AppPublisher=/) && options[:b2ec][:company]
|
828
|
-
script.sub!(/^(\[Setup\])(\s+)/i){ "#{$1}\nAppPublisher=#{options[:b2ec][:company]}#{$2}" }
|
825
|
+
script.sub!(/^(\[Setup\])(\s+)/i) { "#{$1}\nAppPublisher=#{options[:b2ec][:company]}#{$2}" }
|
829
826
|
end
|
830
827
|
if !script.match(/^AppCopyright=/) && options[:b2ec][:copyright]
|
831
|
-
script.sub!(/^(\[Setup\])(\s+)/i){ "#{$1}\nAppCopyright=#{options[:b2ec][:copyright]}#{$2}" }
|
828
|
+
script.sub!(/^(\[Setup\])(\s+)/i) { "#{$1}\nAppCopyright=#{options[:b2ec][:copyright]}#{$2}" }
|
832
829
|
end
|
833
|
-
|
830
|
+
|
834
831
|
script += "\n[Files]\n" unless script.match(/^\[Files\]/)
|
835
832
|
dir = File.expand_path(options[:output_dir])
|
836
833
|
files_str = ""
|
837
834
|
Dir.glob(File.join(dir, "**", "*")).each do |file|
|
838
835
|
next unless File.file? file
|
836
|
+
|
839
837
|
dist_dir = to_winpath(File::SEPARATOR + File.dirname(relative_path(file, dir)))
|
840
838
|
dist_dir = "" if dist_dir == "\\."
|
841
839
|
files_str += "\nSource: \"#{to_winpath(file)}\"; DistDir: \"{app}#{dist_dir}"
|
842
840
|
files_str += "; Flags: isreadme" if File.basename(file).match(/^readme/i)
|
843
841
|
end
|
844
|
-
script.sub!(/^(\[Files\])(\s*)/i){ "#{$1}#{files_str}#{$2}" }
|
845
|
-
|
842
|
+
script.sub!(/^(\[Files\])(\s*)/i) { "#{$1}#{files_str}#{$2}" }
|
843
|
+
|
846
844
|
File.write(filename, script)
|
847
845
|
command = %(#{options[:iscc_path]} "#{filename}")
|
848
846
|
nsystem command
|
849
847
|
end
|
850
|
-
|
851
|
-
|
852
|
-
def run()
|
848
|
+
|
849
|
+
def run
|
853
850
|
check_options
|
854
851
|
dependencies = check_dependencies
|
855
852
|
copy_files(dependencies)
|
@@ -864,34 +861,33 @@ END
|
|
864
861
|
inno_setup if options[:inno_script]
|
865
862
|
nputs "Neri Finished."
|
866
863
|
end
|
867
|
-
|
868
864
|
|
869
865
|
private
|
870
|
-
|
866
|
+
|
871
867
|
def nputs(str)
|
872
868
|
puts "=== #{str}" unless options[:quiet]
|
873
869
|
end
|
874
|
-
|
870
|
+
|
875
871
|
def nputs_v(str)
|
876
872
|
puts str if options[:verbose]
|
877
873
|
end
|
878
|
-
|
874
|
+
|
879
875
|
def error(str)
|
880
876
|
puts "\e[31m#{str}\e[0m"
|
881
877
|
end
|
882
|
-
|
878
|
+
|
883
879
|
def unpack_filename(filename)
|
884
|
-
"[
|
880
|
+
"[#{filename.unpack('U*').map(&:to_s).join(',')}].pack('U*')"
|
885
881
|
end
|
886
|
-
|
882
|
+
|
887
883
|
def escape_cstr(str)
|
888
|
-
str.gsub("\\"){ "\\\\" }.gsub('"'){ '\\"' }.gsub("'"){ "\\'" }
|
884
|
+
str.gsub("\\") { "\\\\" }.gsub('"') { '\\"' }.gsub("'") { "\\'" }
|
889
885
|
end
|
890
|
-
|
886
|
+
|
891
887
|
def nsystem(str)
|
892
888
|
nputs_v(str)
|
893
889
|
command = str.encode(options[:external_encoding])
|
894
|
-
|
890
|
+
system(command + (options[:quiet] ? " >nul 2>&1" : ""))
|
895
891
|
end
|
896
892
|
end
|
897
893
|
end
|