irpack 0.2.5 → 0.2.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +57 -0
- data/lib/irpack.rb +16 -38
- data/lib/irpack/application.rb +71 -115
- data/lib/irpack/packager.rb +1 -1
- data/lib/irpack/rake/generateexetask.rb +86 -0
- data/lib/irpack/specification.rb +182 -0
- data/test/fixtures/foo.rb +3 -0
- data/test/test_application.rb +90 -72
- data/test/test_generateexetask.rb +152 -0
- data/test/test_irpack.rb +17 -13
- data/test/test_packager.rb +4 -4
- data/test/test_specification.rb +237 -0
- data/test/utils.rb +1 -0
- metadata +10 -2
data/README.rdoc
CHANGED
@@ -13,6 +13,8 @@ IronRuby 1.1.3 or later.
|
|
13
13
|
You need to use igem (gem command for IronRuby) instead of gem.
|
14
14
|
|
15
15
|
==Usage
|
16
|
+
|
17
|
+
===Command
|
16
18
|
$ irpack [options] ENTRYFILE [EMBEDFILES...]
|
17
19
|
-b BASEDIR Specify base directory. [base of ENTRYFILE]
|
18
20
|
-o OUTPUTFILE Specify output file name.
|
@@ -70,6 +72,33 @@ files. To load compressed file costs extra time.
|
|
70
72
|
Runtime options are passed to script engine when generated executable started
|
71
73
|
as well as ir.exe.
|
72
74
|
|
75
|
+
===Rake task
|
76
|
+
|
77
|
+
In Rakefile:
|
78
|
+
|
79
|
+
require 'irpack/rake/generateexetask'
|
80
|
+
|
81
|
+
exe_spec = IRPack::Specification.new do |s|
|
82
|
+
s.output_file = 'example.exe'
|
83
|
+
s.entry_file = 'bin/main.rb'
|
84
|
+
s.files = Rake::Filelist['lib/**/*.rb']
|
85
|
+
s.target = :exe
|
86
|
+
s.embed_stdlibs = true
|
87
|
+
s.embed_assemblies = true
|
88
|
+
s.compress = true
|
89
|
+
end
|
90
|
+
|
91
|
+
IRPack::Rake::GenerateExeTask.new(exe_spec) do |t|
|
92
|
+
end
|
93
|
+
|
94
|
+
Invoke 'exe' task to generate 'example.exe'.
|
95
|
+
|
96
|
+
rake exe
|
97
|
+
|
98
|
+
If rake command is not exists, use ir.exe;
|
99
|
+
|
100
|
+
ir -rrake -e "Rake.application.run" exe
|
101
|
+
|
73
102
|
==Limitations
|
74
103
|
Embedded native dlls and mixed (C++/CLI) assemblies are not loadable.
|
75
104
|
|
@@ -91,6 +120,7 @@ IronRubyでしか動かないのでigem (IronRubyのgemコマンド)を使って
|
|
91
120
|
|
92
121
|
==使い方
|
93
122
|
|
123
|
+
===コマンド
|
94
124
|
$ irpack [options] ENTRYFILE [EMBEDFILES...]
|
95
125
|
-b BASEDIR 埋め込み基準のディレクトリを指定します。[ENTRYFILEのあるディレクトリ]
|
96
126
|
-o OUTPUTFILE 出力ファイル名を指定します。[ENTRYFILEの拡張子を.exeにしたもの]
|
@@ -159,6 +189,33 @@ EMBEDFILESにアイコン(.ico)ファイルを指定するとexeのアイコン
|
|
159
189
|
実行時オプションは生成した実行ファイルの起動時にスクリプトエンジンに渡されます。
|
160
190
|
ir.exeに指定するのと同じものです。
|
161
191
|
|
192
|
+
===Rakeタスク
|
193
|
+
|
194
|
+
Rakefileにて:
|
195
|
+
|
196
|
+
require 'irpack/rake/generateexetask'
|
197
|
+
|
198
|
+
exe_spec = IRPack::Specification.new do |s|
|
199
|
+
s.output_file = 'example.exe'
|
200
|
+
s.entry_file = 'bin/main.rb'
|
201
|
+
s.files = Rake::Filelist['lib/**/*.rb']
|
202
|
+
s.target = :exe
|
203
|
+
s.embed_stdlibs = true
|
204
|
+
s.embed_assemblies = true
|
205
|
+
s.compress = true
|
206
|
+
end
|
207
|
+
|
208
|
+
IRPack::Rake::GenerateExeTask.new(exe_spec) do |t|
|
209
|
+
end
|
210
|
+
|
211
|
+
'exe'タスクを起動すると'example.exe'を生成することができます。
|
212
|
+
|
213
|
+
rake exe
|
214
|
+
|
215
|
+
rakeコマンドが無い場合はir.exeから起動できます。
|
216
|
+
|
217
|
+
ir -rrake -e "Rake.application.run" exe
|
218
|
+
|
162
219
|
==制限
|
163
220
|
C++/CLIの混合アセンブリやネイティブdllは埋め込めません。
|
164
221
|
|
data/lib/irpack.rb
CHANGED
@@ -26,6 +26,7 @@ require 'irpack/bootloader'
|
|
26
26
|
require 'irpack/entrypoint'
|
27
27
|
require 'irpack/packager'
|
28
28
|
require 'irpack/missing'
|
29
|
+
require 'irpack/specification'
|
29
30
|
require 'tmpdir'
|
30
31
|
|
31
32
|
module IRPack
|
@@ -73,57 +74,34 @@ module IRPack
|
|
73
74
|
def ironruby_libraries(dstpath='stdlib', srcpath=ironruby_library_path)
|
74
75
|
res = {}
|
75
76
|
Dir.glob(File.join(srcpath, "{ironruby,ruby/#{ironruby_standard_library_version}}", '**', '*')) do |fn|
|
76
|
-
res[fn
|
77
|
+
res[fn.sub(/^#{srcpath}/, dstpath)] = fn if File.file?(fn)
|
77
78
|
end
|
78
79
|
res
|
79
80
|
end
|
80
81
|
|
81
|
-
def pack(
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
}.update(opts)
|
90
|
-
runtime_options = {
|
91
|
-
DebugMode: false,
|
92
|
-
PrivateBinding: false,
|
93
|
-
NoAdaptiveCompilation: false,
|
94
|
-
CompilationThreshold: -1,
|
95
|
-
ExceptionDetail: false,
|
96
|
-
ShowClrExceptions: false,
|
97
|
-
Profile: false,
|
98
|
-
Verbosity: 1,
|
99
|
-
DebugVariable: false,
|
100
|
-
EnableTracing: false,
|
101
|
-
RequiredPaths: [],
|
102
|
-
SearchPaths: [],
|
103
|
-
}.update(runtime_options)
|
104
|
-
output_file = File.expand_path(output_file)
|
105
|
-
basename = File.basename(output_file, '.*')
|
106
|
-
module_name = opts[:module_name]
|
107
|
-
target = opts[:target]
|
108
|
-
references = opts[:references] || ironruby_assemblies
|
109
|
-
compress = opts[:compress]
|
110
|
-
pack_files = {}.merge(files)
|
111
|
-
pack_files = ironruby_libraries.merge(pack_files) if opts[:complete]
|
112
|
-
if opts[:embed_references] then
|
82
|
+
def pack(spec)
|
83
|
+
output_file = File.expand_path(spec.output_file)
|
84
|
+
entry_file = spec.map_entry
|
85
|
+
basename = File.basename(spec.output_file, '.*')
|
86
|
+
references = ironruby_assemblies
|
87
|
+
pack_files = spec.map_files
|
88
|
+
pack_files = ironruby_libraries.merge(pack_files) if spec.embed_stdlibs
|
89
|
+
if spec.embed_assemblies then
|
113
90
|
references.each do |asm|
|
114
|
-
pack_files[asm] =
|
91
|
+
pack_files[File.basename(asm)] = asm
|
115
92
|
end
|
116
93
|
end
|
117
94
|
|
95
|
+
module_name = spec.module_name || path_to_module_name(output_file)
|
118
96
|
Dir.mktmpdir(File.basename($0,'.*')) do |tmp_path|
|
119
97
|
entry_dll = File.join(tmp_path, module_name+'.EntryPoint.dll')
|
120
|
-
EntryPoint.compile(entry_dll, module_name, entry_file, references, runtime_options)
|
121
|
-
pack_files[entry_dll] =
|
98
|
+
EntryPoint.compile(entry_dll, module_name, entry_file, references, spec.runtime_options.to_hash)
|
99
|
+
pack_files[File.basename(entry_dll)] = entry_dll
|
122
100
|
|
123
101
|
package_file = File.join(tmp_path, basename+'.pkg')
|
124
|
-
Packager.pack(pack_files, package_file, compress)
|
102
|
+
Packager.pack(pack_files, package_file, spec.compress)
|
125
103
|
|
126
|
-
BootLoader.compile(target, output_file, module_name, references, package_file)
|
104
|
+
BootLoader.compile(spec.target, output_file, module_name, references, package_file)
|
127
105
|
end
|
128
106
|
output_file
|
129
107
|
end
|
data/lib/irpack/application.rb
CHANGED
@@ -22,131 +22,87 @@ freely, subject to the following restrictions:
|
|
22
22
|
=end
|
23
23
|
|
24
24
|
require 'irpack'
|
25
|
+
require 'irpack/specification'
|
25
26
|
require 'optparse'
|
26
27
|
require 'pathname'
|
27
28
|
|
28
29
|
module IRPack
|
29
30
|
module Application
|
30
|
-
|
31
|
-
|
32
|
-
:
|
33
|
-
|
34
|
-
|
35
|
-
:
|
36
|
-
:
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
}
|
90
|
-
opt.on('-W[level]', 'set warning level; 0=silence, 1=medium (default), 2=verbose', Integer) {|v|
|
91
|
-
args.runtime_options[:Verbosity] = (v || 2).to_i
|
92
|
-
}
|
93
|
-
opt.on('--trace', 'enable support for set_trace_func') {|v|
|
94
|
-
args.runtime_options[:EnableTracing] = v
|
95
|
-
}
|
96
|
-
opt.on('--profile', "enable support for 'pi = IronRuby::Clr.profile { block_to_profile }'") {|v|
|
97
|
-
args.runtime_options[:Profile] = v
|
98
|
-
}
|
99
|
-
opt.on('--exception-detail', 'enable ExceptionDetail mode') {|v|
|
100
|
-
args.runtime_options[:ExceptionDetail] = v
|
101
|
-
}
|
102
|
-
opt.on('--no-adaptive-compilation', 'disable adaptive compilation - all code will be compiled') {|v|
|
103
|
-
args.runtime_options[:NoAdaptiveCompilation] = true
|
104
|
-
}
|
105
|
-
opt.on('--compilation-threshold THRESHOLD', 'the number of iterations before the interpreter starts compiling', Integer) {|v|
|
106
|
-
args.runtime_options[:CompilationThreshold] = v.to_i
|
107
|
-
}
|
108
|
-
opt.on('--pass-exceptions', 'do not catch exceptions that are unhandled by script code') {|v|
|
109
|
-
args.runtime_options[:PassExceptions] = v
|
110
|
-
}
|
111
|
-
opt.on('--private-binding', 'enable binding to private members') {|v|
|
112
|
-
args.runtime_options[:PrivateBinding] = v
|
113
|
-
}
|
114
|
-
opt.on('--show-clr-exceptions', 'display CLS Exception information') {|v|
|
115
|
-
args.runtime_options[:ShowClrExceptions] = v
|
116
|
-
}
|
117
|
-
opt.parse!(argv)
|
31
|
+
def self.parse!(argv)
|
32
|
+
spec = ::IRPack::Specification.new
|
33
|
+
opt = OptionParser.new("Usage: #{$0} [options] ENTRYFILE [EMBEDFILES...]", 24, ' ')
|
34
|
+
opt.on('-b BASEDIR', 'Specify base directory.') {|v| spec.base_paths << v }
|
35
|
+
opt.on('-o OUTPUTFILE', 'Specify output file name.') {|v| spec.output_file = v }
|
36
|
+
opt.on('--window', 'Generate window app.') { spec.target = :winexe }
|
37
|
+
opt.on('--console', 'Generate console app.[default]') { spec.target = :exe }
|
38
|
+
opt.on('--compress', 'Compress package.') { spec.compress = true }
|
39
|
+
opt.on('--complete', 'Embed all standard libraries.') { spec.complete = true }
|
40
|
+
opt.on('--no-embed', 'Do not embed IronRuby assemblies.') {|v| spec.embed_assemblies = v }
|
41
|
+
opt.on('--[no-]embed-assemblies', 'Embed IronRuby assemblies.') {|v| spec.embed_assemblies = v }
|
42
|
+
opt.on('--[no-]embed-stdlibs', 'Embed all standard libraris.') {|v| spec.embed_stdlibs = v }
|
43
|
+
opt.separator('Runtime options:')
|
44
|
+
opt.on('-Idirectory', 'specify $LOAD_PATH directory (may be used more than once)') {|v|
|
45
|
+
spec.runtime_options.search_paths << v
|
46
|
+
}
|
47
|
+
opt.on('-rlibrary', 'require the library, before executing your script') {|v|
|
48
|
+
spec.runtime_options.required_paths << v
|
49
|
+
}
|
50
|
+
opt.on('-d', 'set debugging flags (set $DEBUG to true)') {|v|
|
51
|
+
spec.runtime_options.debug_variable = v
|
52
|
+
}
|
53
|
+
opt.on('-D', 'emit debugging information (PDBs) for Visual Studio debugger') {|v|
|
54
|
+
spec.runtime_options.debug_mode = v
|
55
|
+
}
|
56
|
+
opt.on('-v', 'print version number, then turn on verbose mode') {|v|
|
57
|
+
spec.runtime_options.warning_level = 2
|
58
|
+
}
|
59
|
+
opt.on('-w', 'turn warnings on for your script') {|v|
|
60
|
+
spec.runtime_options.warning_level = 2
|
61
|
+
}
|
62
|
+
opt.on('-W[level]', 'set warning level; 0=silence, 1=medium (default), 2=verbose', Integer) {|v|
|
63
|
+
spec.runtime_options.warning_level = (v || 2).to_i
|
64
|
+
}
|
65
|
+
opt.on('--trace', 'enable support for set_trace_func') {|v|
|
66
|
+
spec.runtime_options.trace = v
|
67
|
+
}
|
68
|
+
opt.on('--profile', "enable support for 'pi = IronRuby::Clr.profile { block_to_profile }'") {|v|
|
69
|
+
spec.runtime_options.profile = v
|
70
|
+
}
|
71
|
+
opt.on('--exception-detail', 'enable ExceptionDetail mode') {|v|
|
72
|
+
spec.runtime_options.exception_detail = v
|
73
|
+
}
|
74
|
+
opt.on('--no-adaptive-compilation', 'disable adaptive compilation - all code will be compiled') {|v|
|
75
|
+
spec.runtime_options.no_adaptive_compilation = true
|
76
|
+
}
|
77
|
+
opt.on('--compilation-threshold THRESHOLD', 'the number of iterations before the interpreter starts compiling', Integer) {|v|
|
78
|
+
spec.runtime_options.compilation_threshold = v.to_i
|
79
|
+
}
|
80
|
+
opt.on('--pass-exceptions', 'do not catch exceptions that are unhandled by script code') {|v|
|
81
|
+
spec.runtime_options.pass_exceptions = v
|
82
|
+
}
|
83
|
+
opt.on('--private-binding', 'enable binding to private members') {|v|
|
84
|
+
spec.runtime_options.private_binding = v
|
85
|
+
}
|
86
|
+
opt.on('--show-clr-exceptions', 'display CLS Exception information') {|v|
|
87
|
+
spec.runtime_options.show_clr_exceptions = v
|
88
|
+
}
|
89
|
+
opt.parse!(argv)
|
118
90
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
argv.each_with_index do |file, i|
|
127
|
-
fullpath = Pathname.new(file.gsub(/\\/, '/')).expand_path
|
128
|
-
relpath = fullpath.relative_path_from(basedir)
|
129
|
-
args.files[fullpath.to_s] = relpath.to_s
|
130
|
-
args.entry_file = relpath.to_s if i==0
|
131
|
-
end
|
132
|
-
args
|
91
|
+
if argv.size<1 then
|
92
|
+
$stderr.puts opt.help
|
93
|
+
nil
|
94
|
+
else
|
95
|
+
spec.entry_file = argv.shift
|
96
|
+
argv.each do |file|
|
97
|
+
spec.files << file
|
133
98
|
end
|
99
|
+
spec
|
134
100
|
end
|
135
101
|
end
|
136
102
|
|
137
|
-
def self.run(
|
138
|
-
return 1 unless
|
139
|
-
IRPack.pack(
|
140
|
-
args.output_file,
|
141
|
-
args.files,
|
142
|
-
args.entry_file,
|
143
|
-
{
|
144
|
-
target: args.target,
|
145
|
-
compress: args.compress,
|
146
|
-
complete: args.complete,
|
147
|
-
embed_references: args.embed_references,
|
148
|
-
},
|
149
|
-
args.runtime_options)
|
103
|
+
def self.run(spec)
|
104
|
+
return 1 unless spec
|
105
|
+
IRPack.pack(spec)
|
150
106
|
return 0
|
151
107
|
end
|
152
108
|
end
|
data/lib/irpack/packager.rb
CHANGED
@@ -33,7 +33,7 @@ module IRPack
|
|
33
33
|
def pack(files, package_file, compress=false)
|
34
34
|
compress_option = compress ? CompressionOption.normal : CompressionOption.not_compressed
|
35
35
|
package = Package.open(package_file, System::IO::FileMode.create)
|
36
|
-
files.each do |
|
36
|
+
files.each do |dest, src|
|
37
37
|
uri = PackUriHelper.create_part_uri(Uri.new(dest, UriKind.relative))
|
38
38
|
part = package.create_part(uri, 'application/octet-stream', compress_option)
|
39
39
|
stream = part.get_stream
|
@@ -0,0 +1,86 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (c) 2011 Ryuichi Sakamoto.
|
3
|
+
|
4
|
+
This software is provided 'as-is', without any express or implied
|
5
|
+
warranty. In no event will the authors be held liable for any damages
|
6
|
+
arising from the use of this software.
|
7
|
+
|
8
|
+
Permission is granted to anyone to use this software for any purpose,
|
9
|
+
including commercial applications, and to alter it and redistribute it
|
10
|
+
freely, subject to the following restrictions:
|
11
|
+
|
12
|
+
1. The origin of this software must not be misrepresented; you must not
|
13
|
+
claim that you wrote the original software. If you use this software
|
14
|
+
in a product, an acknowledgment in the product documentation would be
|
15
|
+
appreciated but is not required.
|
16
|
+
|
17
|
+
2. Altered source versions must be plainly marked as such, and must not be
|
18
|
+
misrepresented as being the original software.
|
19
|
+
|
20
|
+
3. This notice may not be removed or altered from any source
|
21
|
+
distribution.
|
22
|
+
=end
|
23
|
+
|
24
|
+
require 'rake'
|
25
|
+
require 'rake/tasklib'
|
26
|
+
require 'pathname'
|
27
|
+
require 'irpack'
|
28
|
+
|
29
|
+
module IRPack
|
30
|
+
module Rake
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Define task to generate executable described by IRPack::Specification.
|
35
|
+
#
|
36
|
+
# Example:
|
37
|
+
#
|
38
|
+
# require 'irpack/rake/generateexetask'
|
39
|
+
#
|
40
|
+
# exe_spec = IRPack::Specification.new do |s|
|
41
|
+
# s.output_file = 'example.exe'
|
42
|
+
# s.entry_file = 'bin/main.rb'
|
43
|
+
# s.files = Rake::Filelist['lib/**/*.rb']
|
44
|
+
# s.target = :exe
|
45
|
+
# s.embed_stdlibs = true
|
46
|
+
# s.embed_assemblies = true
|
47
|
+
# s.compress = true
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# IRPack::Rake::GenerateExeTask.new(exe_spec) do |t|
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
class IRPack::Rake::GenerateExeTask < ::Rake::TaskLib
|
54
|
+
# Task name. default is +exe+.
|
55
|
+
attr_accessor :name
|
56
|
+
# Spec to generate executable.
|
57
|
+
attr_accessor :exe_spec
|
58
|
+
|
59
|
+
# Create tasks that generates exe file.
|
60
|
+
# Automatically define the gem if a block is given.
|
61
|
+
# If no block is supplied, then +define+
|
62
|
+
# needs to be called to define the task.
|
63
|
+
def initialize(exe_spec, name=:exe)
|
64
|
+
@defined = false
|
65
|
+
@name = name
|
66
|
+
@exe_spec = exe_spec
|
67
|
+
if block_given? then
|
68
|
+
yield self
|
69
|
+
define
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Create rake tasks.
|
74
|
+
def define
|
75
|
+
raise ArgumentError, "No output_file is specified" unless @exe_spec.output_file
|
76
|
+
raise ArgumentError, "No entry_file is specified" unless @exe_spec.entry_file
|
77
|
+
output_file = @exe_spec.output_file
|
78
|
+
sources = @exe_spec.map_files.values.to_a
|
79
|
+
desc "Generate #{File.basename(output_file)}"
|
80
|
+
task @name => [output_file]
|
81
|
+
file output_file => sources do
|
82
|
+
IRPack.pack(@exe_spec)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|