ocran 1.4.2-x86_64-linux → 1.4.3-x86_64-linux
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 +4 -4
- data/CHANGELOG.txt +7 -0
- data/README.md +16 -10
- data/lib/ocran/direction.rb +9 -8
- data/lib/ocran/ed_icon.rb +157 -0
- data/lib/ocran/stub_builder.rb +2 -2
- data/lib/ocran/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 395439e25a66520b23294233b659afd5cb48a057c37919881652eabc2fc3e00d
|
|
4
|
+
data.tar.gz: 0b5d425c967a32fce5c82ebe1e61e1c73925b59c794ef00df3bc2553d3ac43bf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b5d09a2b2e5bcb3af38e1b9978335722518a1638003d1cd2f361426496650fc40214ca4885be04d35f9d494274baef87316ef9ee56078b4d550341925162eb4c
|
|
7
|
+
data.tar.gz: e68646927cf875767dab3eb4c1ce7a376c07d77a89f8f97fc13f34da3d4fb33400e8faa9e08a1828603a8ca24f673121bac46f070fdc7ec7f938662b2148a0d7
|
data/CHANGELOG.txt
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
=== 1.4.3
|
|
2
|
+
- Migrate edicon from C to Ruby: replace edicon.exe with a pure-Ruby implementation (ed_icon.rb), fixing incorrect BeginUpdateResource error checking and wrong GroupIconSize calculation. Shortens build times and removes the C binary from the build.
|
|
3
|
+
- Include Gem.default_dir in GEM_PATH on all platforms: previously the exec_prefix gem directory was excluded on Windows, causing native-extension gems (e.g. fxruby/fox16) to fail at runtime with a LoadError even though they were bundled correctly.
|
|
4
|
+
- Add FXRuby (fox16) test: verify that native extension DLLs are bundled correctly so the packaged executable does not raise a LoadError at runtime.
|
|
5
|
+
- CI: start a virtual display (xpra + Xorg dummy driver with GLX) on Linux before running tests so FXRuby's X11 requirement is satisfied.
|
|
6
|
+
- CI: install XQuartz on macOS runners and add it to the portability test job so FXRuby can connect to a display on both test and portability jobs.
|
|
7
|
+
|
|
1
8
|
=== 1.4.2
|
|
2
9
|
- Auto-bundle OpenSSL and all its transitive dependencies (openssl.rb, digest.so, etc.) when net/http is loaded but no HTTPS request was made during the dependency scan. OpenSSL is now required inside the OCRAN build process so every file it pulls in appears in the bundled executable.
|
|
3
10
|
- Add companion DLL scan on windows: when a native extension (.so) within the Ruby installation is loaded, all DLLs in the same directory are proactively included. This ensures libssl-3-x64.dll, libcrypto-3-x64.dll, libwinpthread-1.dll, and libyaml-0-2.dll are bundled even when no HTTPS connection is made during the build scan.
|
data/README.md
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# ocran
|
|
2
2
|
|
|
3
3
|
home :: https://github.com/largo/ocran/
|
|
4
|
-
|
|
5
4
|
issues :: http://github.com/largo/ocran/issues
|
|
6
5
|
|
|
7
6
|
## Description
|
|
@@ -23,18 +22,19 @@ Ruby 3.2+ compatibility.
|
|
|
23
22
|
|
|
24
23
|
## Recommended usage
|
|
25
24
|
|
|
26
|
-
The most common use-case is shipping a program to Windows
|
|
27
|
-
who do not have Ruby installed. By default, each time the `.exe` is opened it
|
|
25
|
+
The most common use-case is shipping a program to users running Windows / Linux / macOS
|
|
26
|
+
who do not have Ruby installed. By default, each time the `.exe` / executable is opened it
|
|
28
27
|
extracts the Ruby interpreter and your code to a temporary directory and runs
|
|
29
28
|
them from there.
|
|
30
29
|
|
|
31
|
-
Because extraction takes time on each launch,
|
|
30
|
+
Because extraction takes time on each launch, use `--output-dir` or
|
|
31
|
+
`--output-zip` to produce a portable directory/archive that runs with the
|
|
32
|
+
bundled Ruby on Linux, macOS, or Windows.
|
|
33
|
+
If using Windows you can use the Inno Setup
|
|
32
34
|
option (`--innosetup`) to produce a proper installer that extracts once to a
|
|
33
35
|
permanent directory.
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
`--output-zip` to produce a portable directory/archive that runs with the
|
|
37
|
-
bundled Ruby on Linux, macOS, or Windows.
|
|
37
|
+
You can easily generate binaries for the supported Operating Systems with GitHub Actions.
|
|
38
38
|
|
|
39
39
|
## Features
|
|
40
40
|
|
|
@@ -74,12 +74,12 @@ https://github.com/largo/ocran/releases/.
|
|
|
74
74
|
|
|
75
75
|
## Synopsis
|
|
76
76
|
|
|
77
|
-
### Building
|
|
77
|
+
### Building an executable:
|
|
78
78
|
|
|
79
79
|
ocran script.rb
|
|
80
80
|
|
|
81
81
|
Packages `script.rb`, the Ruby interpreter, and all dependencies (gems and
|
|
82
|
-
DLLs) into `script.exe
|
|
82
|
+
DLLs) into `script.exe` or `script` on Linux or macOS.
|
|
83
83
|
|
|
84
84
|
### Building a portable directory (Linux / macOS / Windows):
|
|
85
85
|
|
|
@@ -243,7 +243,8 @@ a Linux runner for Linux builds).
|
|
|
243
243
|
## Requirements
|
|
244
244
|
|
|
245
245
|
* Ruby 3.2+
|
|
246
|
-
* For building Windows `.exe`: Windows with RubyInstaller DevKit (mingw-w64), or Wine on Linux/macOS
|
|
246
|
+
* For building Windows `.exe`: Windows with [RubyInstaller DevKit](https://rubyinstaller.org/downloads/) (mingw-w64), or Wine on Linux/macOS
|
|
247
|
+
* For building Linux and MacOS binaries: the respective build tools
|
|
247
248
|
* For `--output-dir` / `--output-zip`: any platform with Ruby 3.2+
|
|
248
249
|
* For `--output-zip` on Linux/macOS: the `zip` command must be available
|
|
249
250
|
* For `--output-zip` on Windows: PowerShell (included in Windows 8+)
|
|
@@ -526,6 +527,11 @@ file:
|
|
|
526
527
|
end
|
|
527
528
|
end
|
|
528
529
|
|
|
530
|
+
## See elsewhere
|
|
531
|
+
|
|
532
|
+
- [State of Ruby Packagers](https://gist.github.com/YOU54F/3775e66e6090e0371c11601e6b75c305)
|
|
533
|
+
- [Traveling Ruby](https://github.com/trubygems/traveling-ruby)
|
|
534
|
+
|
|
529
535
|
## Credits
|
|
530
536
|
|
|
531
537
|
Lars Christensen and contributors for the OCRA project which this is forked from.
|
data/lib/ocran/direction.rb
CHANGED
|
@@ -514,14 +514,15 @@ module Ocran
|
|
|
514
514
|
builder.set_env_path("GEM_HOME", GEMDIR)
|
|
515
515
|
|
|
516
516
|
gem_paths = [GEMDIR]
|
|
517
|
-
#
|
|
518
|
-
#
|
|
519
|
-
#
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
517
|
+
# Gems installed under the Ruby prefix (exec_prefix) have their specs and
|
|
518
|
+
# extension dirs placed there via duplicate_to_exec_prefix. Include
|
|
519
|
+
# Gem.default_dir (relative to exec_prefix) in GEM_PATH so RubyGems can
|
|
520
|
+
# find and activate them at runtime. This is required on both Windows
|
|
521
|
+
# (e.g. fxruby/fox16 whose fox16_c.so lives in extension_dir under the
|
|
522
|
+
# Ruby prefix) and POSIX (e.g. error_highlight default gems).
|
|
523
|
+
default_gem_dir = Pathname(Gem.default_dir)
|
|
524
|
+
if default_gem_dir.subpath?(exec_prefix)
|
|
525
|
+
gem_paths << default_gem_dir.relative_path_from(exec_prefix)
|
|
525
526
|
end
|
|
526
527
|
builder.set_env_path("GEM_PATH", *gem_paths)
|
|
527
528
|
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
require "fiddle/import"
|
|
3
|
+
require "fiddle/types"
|
|
4
|
+
|
|
5
|
+
module Ocran
|
|
6
|
+
# Changes the Icon in a PE executable.
|
|
7
|
+
module EdIcon
|
|
8
|
+
extend Fiddle::Importer
|
|
9
|
+
dlload "kernel32.dll"
|
|
10
|
+
|
|
11
|
+
include Fiddle::Win32Types
|
|
12
|
+
typealias "LPVOID", "void*"
|
|
13
|
+
typealias "LPCWSTR", "char*"
|
|
14
|
+
|
|
15
|
+
module Successive
|
|
16
|
+
include Enumerable
|
|
17
|
+
|
|
18
|
+
def each
|
|
19
|
+
return to_enum(__method__) unless block_given?
|
|
20
|
+
|
|
21
|
+
entry = self
|
|
22
|
+
while true
|
|
23
|
+
yield(entry)
|
|
24
|
+
entry = self.class.new(tail)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def tail
|
|
29
|
+
to_ptr + self.class.size
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Icon file header
|
|
34
|
+
IconHeader = struct(
|
|
35
|
+
[
|
|
36
|
+
"WORD Reserved",
|
|
37
|
+
"WORD ResourceType",
|
|
38
|
+
"WORD ImageCount"
|
|
39
|
+
]
|
|
40
|
+
).include(Successive)
|
|
41
|
+
|
|
42
|
+
icon_info = [
|
|
43
|
+
"BYTE Width",
|
|
44
|
+
"BYTE Height",
|
|
45
|
+
"BYTE Colors",
|
|
46
|
+
"BYTE Reserved",
|
|
47
|
+
"WORD Planes",
|
|
48
|
+
"WORD BitsPerPixel",
|
|
49
|
+
"DWORD ImageSize"
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
# Icon File directory entry structure
|
|
53
|
+
IconDirectoryEntry = struct(icon_info + ["DWORD ImageOffset"]).include(Successive)
|
|
54
|
+
|
|
55
|
+
# Group Icon Resource directory entry structure
|
|
56
|
+
IconDirResEntry = struct(icon_info + ["WORD ResourceID"]).include(Successive)
|
|
57
|
+
|
|
58
|
+
class IconFile < IconHeader
|
|
59
|
+
def initialize(icon_filename)
|
|
60
|
+
@data = File.binread(icon_filename)
|
|
61
|
+
super(Fiddle::Pointer.to_ptr(@data))
|
|
62
|
+
|
|
63
|
+
entries_end = IconHeader.size + self.ImageCount * IconDirectoryEntry.size
|
|
64
|
+
if entries_end > @data.bytesize
|
|
65
|
+
raise "Icon file too small for declared ImageCount"
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
entries.each_with_index do |entry, i|
|
|
69
|
+
if entry.ImageOffset + entry.ImageSize > @data.bytesize
|
|
70
|
+
raise "Icon entry #{i} exceeds file bounds"
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def entries
|
|
76
|
+
IconDirectoryEntry.new(self.tail).take(self.ImageCount)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
class GroupIcon < IconHeader
|
|
81
|
+
attr_reader :size
|
|
82
|
+
|
|
83
|
+
def initialize(image_count, resource_type)
|
|
84
|
+
@size = IconHeader.size + image_count * IconDirResEntry.size
|
|
85
|
+
super(Fiddle.malloc(@size), Fiddle::RUBY_FREE)
|
|
86
|
+
self.Reserved = 0
|
|
87
|
+
self.ResourceType = resource_type
|
|
88
|
+
self.ImageCount = image_count
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def entries
|
|
92
|
+
IconDirResEntry.new(self.tail).take(self.ImageCount)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
MAKEINTRESOURCE = -> (i) { Fiddle::Pointer.new(i) }
|
|
97
|
+
RT_ICON = MAKEINTRESOURCE.(3)
|
|
98
|
+
RT_GROUP_ICON = MAKEINTRESOURCE.(RT_ICON.to_i + 11)
|
|
99
|
+
|
|
100
|
+
MAKELANGID = -> (p, s) { s << 10 | p }
|
|
101
|
+
LANG_NEUTRAL = 0x00
|
|
102
|
+
SUBLANG_DEFAULT = 0x01
|
|
103
|
+
LANGID = MAKELANGID.(LANG_NEUTRAL, SUBLANG_DEFAULT)
|
|
104
|
+
|
|
105
|
+
extern "DWORD GetLastError()"
|
|
106
|
+
extern "HANDLE BeginUpdateResourceW(LPCWSTR, BOOL)"
|
|
107
|
+
extern "BOOL EndUpdateResourceW(HANDLE, BOOL)"
|
|
108
|
+
extern "BOOL UpdateResourceW(HANDLE, LPCWSTR, LPCWSTR, WORD, LPVOID, DWORD)"
|
|
109
|
+
|
|
110
|
+
class << self
|
|
111
|
+
def update_icon(executable_filename, icon_filename)
|
|
112
|
+
update_resource(executable_filename) do |handle|
|
|
113
|
+
icon_file = IconFile.new(icon_filename)
|
|
114
|
+
icon_entries = icon_file.entries
|
|
115
|
+
|
|
116
|
+
# Create the RT_ICON resources
|
|
117
|
+
icon_entries.each_with_index do |entry, i|
|
|
118
|
+
if UpdateResourceW(handle, RT_ICON, 101 + i, LANGID, icon_file.to_i + entry.ImageOffset, entry.ImageSize) == 0
|
|
119
|
+
raise "failed to UpdateResource(#{GetLastError()})"
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Create the RT_GROUP_ICON structure
|
|
124
|
+
group_icon = GroupIcon.new(icon_file.ImageCount, icon_file.ResourceType)
|
|
125
|
+
group_icon.entries.zip(icon_entries).each_with_index do |(res, icon), i|
|
|
126
|
+
res.Width = icon.Width
|
|
127
|
+
res.Height = icon.Height
|
|
128
|
+
res.Colors = icon.Colors
|
|
129
|
+
res.Reserved = icon.Reserved
|
|
130
|
+
res.Planes = icon.Planes
|
|
131
|
+
res.BitsPerPixel = icon.BitsPerPixel
|
|
132
|
+
res.ImageSize = icon.ImageSize
|
|
133
|
+
res.ResourceID = 101 + i
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Save the RT_GROUP_ICON resource
|
|
137
|
+
if UpdateResourceW(handle, RT_GROUP_ICON, 100, LANGID, group_icon, group_icon.size) == 0
|
|
138
|
+
raise "Failed to create group icon(#{GetLastError()})"
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def update_resource(executable_filename)
|
|
144
|
+
handle = BeginUpdateResourceW(executable_filename.encode("UTF-16LE"), 0)
|
|
145
|
+
if handle == Fiddle::NULL
|
|
146
|
+
raise "Failed to BeginUpdateResourceW(#{GetLastError()})"
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
yield(handle)
|
|
150
|
+
|
|
151
|
+
if EndUpdateResourceW(handle, 0) == 0
|
|
152
|
+
raise "Failed to EndUpdateResourceW(#{GetLastError()})"
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
data/lib/ocran/stub_builder.rb
CHANGED
|
@@ -27,7 +27,6 @@ module Ocran
|
|
|
27
27
|
STUB_PATH = File.expand_path(WINDOWS ? "stub.exe" : "stub", base_dir)
|
|
28
28
|
STUBW_PATH = WINDOWS ? File.expand_path("stubw.exe", base_dir) : nil
|
|
29
29
|
LZMA_PATH = WINDOWS ? File.expand_path("lzma.exe", base_dir) : nil
|
|
30
|
-
EDICON_PATH = WINDOWS ? File.expand_path("edicon.exe", base_dir) : nil
|
|
31
30
|
|
|
32
31
|
def self.find_posix_lzma_cmd
|
|
33
32
|
if system("which lzma > /dev/null 2>&1")
|
|
@@ -122,7 +121,8 @@ module Ocran
|
|
|
122
121
|
|
|
123
122
|
# Embed icon resource (Windows only)
|
|
124
123
|
if icon_path && WINDOWS
|
|
125
|
-
|
|
124
|
+
require_relative "ed_icon"
|
|
125
|
+
EdIcon.update_icon(stub, icon_path.to_s)
|
|
126
126
|
end
|
|
127
127
|
|
|
128
128
|
File.open(stub, "ab") do |of|
|
data/lib/ocran/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ocran
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.4.
|
|
4
|
+
version: 1.4.3
|
|
5
5
|
platform: x86_64-linux
|
|
6
6
|
authors:
|
|
7
7
|
- Andi Idogawa
|
|
@@ -64,6 +64,7 @@ files:
|
|
|
64
64
|
- lib/ocran/command_output.rb
|
|
65
65
|
- lib/ocran/dir_builder.rb
|
|
66
66
|
- lib/ocran/direction.rb
|
|
67
|
+
- lib/ocran/ed_icon.rb
|
|
67
68
|
- lib/ocran/empty_source
|
|
68
69
|
- lib/ocran/file_path_set.rb
|
|
69
70
|
- lib/ocran/gem_spec_queryable.rb
|
|
@@ -102,7 +103,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
102
103
|
- !ruby/object:Gem::Version
|
|
103
104
|
version: '0'
|
|
104
105
|
requirements: []
|
|
105
|
-
rubygems_version: 4.0.
|
|
106
|
+
rubygems_version: 4.0.6
|
|
106
107
|
specification_version: 4
|
|
107
108
|
summary: OCRAN (One-Click Ruby Application Next) packages Ruby applications for distribution
|
|
108
109
|
on Windows, Linux, and macOS.
|