kompo 0.2.0 → 0.3.0
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/.devcontainer/Dockerfile +2 -4
- data/.devcontainer/devcontainer.json +2 -2
- data/.standard.yml +2 -0
- data/CHANGELOG.md +21 -0
- data/Gemfile +10 -2
- data/Gemfile.lock +115 -3
- data/README.md +117 -10
- data/Rakefile +12 -2
- data/docs/document.md.ja +31 -0
- data/exe/kompo +45 -14
- data/lib/fs.c.erb +6 -0
- data/lib/kompo/cache.rb +65 -0
- data/lib/kompo/kompo_ignore.rb +40 -0
- data/lib/kompo/tasks/build_native_gem.rb +191 -0
- data/lib/kompo/tasks/bundle_install.rb +224 -0
- data/lib/kompo/tasks/cargo_path.rb +59 -0
- data/lib/kompo/tasks/check_stdlibs.rb +58 -0
- data/lib/kompo/tasks/collect_dependencies.rb +101 -0
- data/lib/kompo/tasks/copy_gemfile.rb +46 -0
- data/lib/kompo/tasks/copy_project_files.rb +89 -0
- data/lib/kompo/tasks/find_native_extensions.rb +89 -0
- data/lib/kompo/tasks/homebrew.rb +83 -0
- data/lib/kompo/tasks/install_deps.rb +365 -0
- data/lib/kompo/tasks/install_ruby.rb +427 -0
- data/lib/kompo/tasks/kompo_vfs_path.rb +144 -0
- data/lib/kompo/tasks/kompo_vfs_version_check.rb +56 -0
- data/lib/kompo/tasks/make_fs_c.rb +202 -0
- data/lib/kompo/tasks/make_main_c.rb +65 -0
- data/lib/kompo/tasks/packing.rb +235 -0
- data/lib/kompo/tasks/ruby_build_path.rb +54 -0
- data/lib/kompo/tasks/work_dir.rb +84 -0
- data/lib/kompo/version.rb +2 -1
- data/lib/kompo.rb +47 -420
- data/lib/main.c.erb +28 -15
- data/rbs_collection.lock.yaml +116 -0
- data/rbs_collection.yaml +19 -0
- metadata +72 -8
- data/lib/kompo/kompo_fs.rb +0 -15
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9810a7219117daa1c6a82c2741df55d16acb20a7d59b6dec0609f2f6a68418dd
|
|
4
|
+
data.tar.gz: 0b304b0510ec458f50c75e94528d604f71fa9cc7f5cdbb7386bcf1671495ca02
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d678007c08242abee43dc8dd74a70a425701287336782b87f55e60624fa605ce1d844b345f14f70583e11dbccbcf507aec307b3cdcfc9a1472f5eab356d0c80c
|
|
7
|
+
data.tar.gz: ef31ac68e4ef6e15d1b98b1e71d97faf8385b36c3f75d85c918e970a0f47331845f4b994c1a4a68144ed730ca18331b21794b8c9dd543c881639c71c8042df02
|
data/.devcontainer/Dockerfile
CHANGED
|
@@ -3,9 +3,7 @@ FROM mcr.microsoft.com/devcontainers/base:ubuntu
|
|
|
3
3
|
RUN apt-get update && apt-get install -y clang
|
|
4
4
|
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
|
|
5
5
|
ENV PATH="/root/.cargo/bin:$PATH"
|
|
6
|
-
RUN git clone https://github.com/
|
|
6
|
+
RUN git clone https://github.com/ahogappa/kompo-vfs.git && \
|
|
7
7
|
cd kompo-vfs && \
|
|
8
|
-
sudo /root/.cargo/bin/cargo build --release
|
|
9
|
-
sudo cp target/release/kompo-cli /usr/local/bin && \
|
|
10
|
-
sudo cp target/release/libkompo.a /usr/local/lib
|
|
8
|
+
sudo /root/.cargo/bin/cargo build --release
|
|
11
9
|
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
},
|
|
14
14
|
"containerEnv": {
|
|
15
15
|
// "PATH": "/usr/local/cargo/bin:${containerEnv:PATH}",
|
|
16
|
-
"KOMPO_CLI": "/usr/local/bin/kompo-cli",
|
|
17
|
-
"LIB_KOMPO_DIR": "/usr/local/lib",
|
|
16
|
+
// "KOMPO_CLI": "/usr/local/bin/kompo-cli",
|
|
17
|
+
// "LIB_KOMPO_DIR": "/usr/local/lib",
|
|
18
18
|
},
|
|
19
19
|
// Features to add to the dev container. More info: https://containers.dev/features.
|
|
20
20
|
// "features": {},
|
data/.standard.yml
ADDED
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.3.0] - 2026-01-24
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- Use RTLD_NEXT for single binary creation process [#6](https://github.com/ahogappa/kompo/pull/6)
|
|
14
|
+
- Rewrite kompo with Taski-based parallel task system [#6](https://github.com/ahogappa/kompo/pull/6)
|
|
15
|
+
- Use ruby-build for Ruby installation [#5](https://github.com/ahogappa/kompo/pull/5)
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- Ability to configure options for Ruby build
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
- Fix error messages
|
data/Gemfile
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
source
|
|
3
|
+
source 'https://rubygems.org'
|
|
4
4
|
|
|
5
5
|
# Specify your gem's dependencies in kompo.gemspec
|
|
6
6
|
gemspec
|
|
7
7
|
|
|
8
|
-
gem
|
|
8
|
+
gem 'rake', '~> 13.0'
|
|
9
|
+
gem 'taski', '~> 0.8.0'
|
|
10
|
+
|
|
11
|
+
group :development, :test do
|
|
12
|
+
gem 'debug'
|
|
13
|
+
gem 'minitest'
|
|
14
|
+
gem 'simplecov', require: false
|
|
15
|
+
gem 'standard'
|
|
16
|
+
end
|
data/Gemfile.lock
CHANGED
|
@@ -1,20 +1,132 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
kompo (0.
|
|
4
|
+
kompo (0.3.0)
|
|
5
|
+
async
|
|
6
|
+
mini_portile2
|
|
7
|
+
pathspec
|
|
5
8
|
|
|
6
9
|
GEM
|
|
7
10
|
remote: https://rubygems.org/
|
|
8
11
|
specs:
|
|
9
|
-
|
|
12
|
+
ast (2.4.3)
|
|
13
|
+
async (2.35.0)
|
|
14
|
+
console (~> 1.29)
|
|
15
|
+
fiber-annotation
|
|
16
|
+
io-event (~> 1.11)
|
|
17
|
+
metrics (~> 0.12)
|
|
18
|
+
traces (~> 0.18)
|
|
19
|
+
console (1.34.2)
|
|
20
|
+
fiber-annotation
|
|
21
|
+
fiber-local (~> 1.1)
|
|
22
|
+
json
|
|
23
|
+
date (3.5.1)
|
|
24
|
+
debug (1.11.1)
|
|
25
|
+
irb (~> 1.10)
|
|
26
|
+
reline (>= 0.3.8)
|
|
27
|
+
docile (1.4.1)
|
|
28
|
+
erb (6.0.1)
|
|
29
|
+
fiber-annotation (0.2.0)
|
|
30
|
+
fiber-local (1.1.0)
|
|
31
|
+
fiber-storage
|
|
32
|
+
fiber-storage (1.0.1)
|
|
33
|
+
io-console (0.8.2)
|
|
34
|
+
io-event (1.14.2)
|
|
35
|
+
irb (1.16.0)
|
|
36
|
+
pp (>= 0.6.0)
|
|
37
|
+
rdoc (>= 4.0.0)
|
|
38
|
+
reline (>= 0.4.2)
|
|
39
|
+
json (2.18.0)
|
|
40
|
+
language_server-protocol (3.17.0.5)
|
|
41
|
+
lint_roller (1.1.0)
|
|
42
|
+
metrics (0.15.0)
|
|
43
|
+
mini_portile2 (2.8.9)
|
|
44
|
+
minitest (6.0.1)
|
|
45
|
+
prism (~> 1.5)
|
|
46
|
+
parallel (1.27.0)
|
|
47
|
+
parser (3.3.10.1)
|
|
48
|
+
ast (~> 2.4.1)
|
|
49
|
+
racc
|
|
50
|
+
pathspec (2.1.0)
|
|
51
|
+
pp (0.6.3)
|
|
52
|
+
prettyprint
|
|
53
|
+
prettyprint (0.2.0)
|
|
54
|
+
prism (1.8.0)
|
|
55
|
+
psych (5.3.1)
|
|
56
|
+
date
|
|
57
|
+
stringio
|
|
58
|
+
racc (1.8.1)
|
|
59
|
+
rainbow (3.1.1)
|
|
60
|
+
rake (13.3.1)
|
|
61
|
+
rdoc (7.0.2)
|
|
62
|
+
erb
|
|
63
|
+
psych (>= 4.0.0)
|
|
64
|
+
tsort
|
|
65
|
+
regexp_parser (2.11.3)
|
|
66
|
+
reline (0.6.3)
|
|
67
|
+
io-console (~> 0.5)
|
|
68
|
+
rubocop (1.82.1)
|
|
69
|
+
json (~> 2.3)
|
|
70
|
+
language_server-protocol (~> 3.17.0.2)
|
|
71
|
+
lint_roller (~> 1.1.0)
|
|
72
|
+
parallel (~> 1.10)
|
|
73
|
+
parser (>= 3.3.0.2)
|
|
74
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
75
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
|
76
|
+
rubocop-ast (>= 1.48.0, < 2.0)
|
|
77
|
+
ruby-progressbar (~> 1.7)
|
|
78
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
|
79
|
+
rubocop-ast (1.49.0)
|
|
80
|
+
parser (>= 3.3.7.2)
|
|
81
|
+
prism (~> 1.7)
|
|
82
|
+
rubocop-performance (1.26.1)
|
|
83
|
+
lint_roller (~> 1.1)
|
|
84
|
+
rubocop (>= 1.75.0, < 2.0)
|
|
85
|
+
rubocop-ast (>= 1.47.1, < 2.0)
|
|
86
|
+
ruby-progressbar (1.13.0)
|
|
87
|
+
simplecov (0.22.0)
|
|
88
|
+
docile (~> 1.1)
|
|
89
|
+
simplecov-html (~> 0.11)
|
|
90
|
+
simplecov_json_formatter (~> 0.1)
|
|
91
|
+
simplecov-html (0.13.2)
|
|
92
|
+
simplecov_json_formatter (0.1.4)
|
|
93
|
+
standard (1.53.0)
|
|
94
|
+
language_server-protocol (~> 3.17.0.2)
|
|
95
|
+
lint_roller (~> 1.0)
|
|
96
|
+
rubocop (~> 1.82.0)
|
|
97
|
+
standard-custom (~> 1.0.0)
|
|
98
|
+
standard-performance (~> 1.8)
|
|
99
|
+
standard-custom (1.0.2)
|
|
100
|
+
lint_roller (~> 1.0)
|
|
101
|
+
rubocop (~> 1.50)
|
|
102
|
+
standard-performance (1.9.0)
|
|
103
|
+
lint_roller (~> 1.1)
|
|
104
|
+
rubocop-performance (~> 1.26.0)
|
|
105
|
+
stringio (3.2.0)
|
|
106
|
+
taski (0.8.0)
|
|
107
|
+
prism (~> 1.4)
|
|
108
|
+
tsort
|
|
109
|
+
traces (0.18.2)
|
|
110
|
+
tsort (0.2.0)
|
|
111
|
+
unicode-display_width (3.2.0)
|
|
112
|
+
unicode-emoji (~> 4.1)
|
|
113
|
+
unicode-emoji (4.2.0)
|
|
10
114
|
|
|
11
115
|
PLATFORMS
|
|
12
116
|
aarch64-linux
|
|
13
117
|
arm64-darwin-23
|
|
118
|
+
arm64-darwin-24
|
|
119
|
+
arm64-darwin-25
|
|
120
|
+
x86_64-linux
|
|
14
121
|
|
|
15
122
|
DEPENDENCIES
|
|
123
|
+
debug
|
|
16
124
|
kompo!
|
|
125
|
+
minitest
|
|
17
126
|
rake (~> 13.0)
|
|
127
|
+
simplecov
|
|
128
|
+
standard
|
|
129
|
+
taski (~> 0.8.0)
|
|
18
130
|
|
|
19
131
|
BUNDLED WITH
|
|
20
|
-
2.
|
|
132
|
+
2.6.9
|
data/README.md
CHANGED
|
@@ -1,6 +1,31 @@
|
|
|
1
1
|
# Kompo
|
|
2
2
|
A tool to pack Ruby and Ruby scripts in one binary. This tool is still under development.
|
|
3
3
|
|
|
4
|
+
## Concept
|
|
5
|
+
|
|
6
|
+
Kompo makes it dead simple to distribute Ruby applications. Just run one command, and you get a single binary that works anywhere—no Ruby installation required.
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
$ kompo
|
|
10
|
+
$ ./main # That's it!
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Why Kompo?
|
|
14
|
+
|
|
15
|
+
- **Dead Simple**: One command to build, one file to distribute. No complex configuration, no build scripts, no Docker containers.
|
|
16
|
+
|
|
17
|
+
- **Zero Dependencies for Users**: Your users just download and run. No Ruby, no gems, no environment setup—it just works.
|
|
18
|
+
|
|
19
|
+
- **Full CRuby Compatibility**: Unlike mruby-based solutions, Kompo embeds the official CRuby interpreter. Your existing code, gems, and C extensions work without modification.
|
|
20
|
+
|
|
21
|
+
- **Cross-Platform**: Build binaries for macOS and Linux. (Windows support is planned)
|
|
22
|
+
|
|
23
|
+
- **Batteries Included**: All your gems, including native extensions, are bundled automatically.
|
|
24
|
+
|
|
25
|
+
### How It Works
|
|
26
|
+
|
|
27
|
+
Kompo uses a Virtual File System (VFS) to embed Ruby source code, gems, and the Ruby interpreter into a single binary. At runtime, the embedded VFS provides transparent access to these files, allowing Ruby to operate as if everything were installed normally on the filesystem.
|
|
28
|
+
|
|
4
29
|
## Installation
|
|
5
30
|
```sh
|
|
6
31
|
$ gem install kompo
|
|
@@ -9,35 +34,117 @@ $ gem install kompo
|
|
|
9
34
|
## Usage
|
|
10
35
|
|
|
11
36
|
### prerequisites
|
|
12
|
-
Install [
|
|
37
|
+
Install [kompo-vfs](https://github.com/ahogappa/kompo-vfs).
|
|
13
38
|
|
|
14
39
|
#### Homebrew
|
|
15
40
|
```sh
|
|
16
|
-
$ brew tap
|
|
17
|
-
$ brew install
|
|
41
|
+
$ brew tap ahogappa/kompo-vfs https://github.com/ahogappa/kompo-vfs.git
|
|
42
|
+
$ brew install ahogappa/kompo-vfs/kompo-vfs
|
|
18
43
|
```
|
|
19
44
|
|
|
20
45
|
### Building
|
|
21
46
|
To build komp-vfs, you need to have cargo installation.
|
|
22
47
|
```sh
|
|
23
|
-
$ git clone https://github.com/
|
|
48
|
+
$ git clone https://github.com/ahogappa/kompo-vfs.git
|
|
24
49
|
$ cd kompo-vfs
|
|
25
50
|
$ cargo build --release
|
|
26
51
|
```
|
|
27
|
-
|
|
52
|
+
|
|
53
|
+
## Options
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
Usage: kompo [options] [files...]
|
|
57
|
+
|
|
58
|
+
Options:
|
|
59
|
+
-e, --entrypoint=FILE Entry point file (default: main.rb)
|
|
60
|
+
-o, --output=DIR Output directory for the binary
|
|
61
|
+
--ruby-version=VERSION Ruby version to use (default: current Ruby version)
|
|
62
|
+
--ruby-source=PATH Path to Ruby source tarball or directory
|
|
63
|
+
--no-cache Build Ruby from source, ignoring cache
|
|
64
|
+
--no-stdlib Exclude Ruby standard library from binary
|
|
65
|
+
--local-vfs-path=PATH Path to local kompo-vfs for development
|
|
66
|
+
--clean[=VERSION] Clean cache (current version by default, or specify VERSION, or "all")
|
|
67
|
+
-t, --tree Show task dependency tree and exit
|
|
68
|
+
-h, --help Show help message
|
|
69
|
+
|
|
70
|
+
Files:
|
|
71
|
+
Additional files and directories to include in the binary
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Option Details
|
|
75
|
+
|
|
76
|
+
| Option | Description |
|
|
77
|
+
|--------|-------------|
|
|
78
|
+
| `-e, --entrypoint` | Specifies the main Ruby file to execute. Defaults to `main.rb`. |
|
|
79
|
+
| `-o, --output` | Directory where the final binary will be placed. Defaults to current directory. |
|
|
80
|
+
| `--ruby-version` | Ruby version to embed. Kompo will build and cache this version. |
|
|
81
|
+
| `--ruby-source` | Use a local Ruby source instead of downloading. Useful for custom Ruby builds. |
|
|
82
|
+
| `--no-cache` | Force a fresh Ruby build, ignoring any cached version. |
|
|
83
|
+
| `--no-stdlib` | Reduce binary size by excluding Ruby standard library. Only use if your app doesn't need stdlib. |
|
|
84
|
+
| `--local-vfs-path` | Use a local kompo-vfs build instead of Homebrew installation. Useful for development. |
|
|
85
|
+
| `--clean` | Remove cached Ruby builds. Use `--clean=all` to remove all versions. |
|
|
86
|
+
| `-t, --tree` | Display the task dependency graph and exit without building. |
|
|
87
|
+
|
|
88
|
+
### Examples
|
|
89
|
+
|
|
28
90
|
```sh
|
|
29
|
-
|
|
30
|
-
$
|
|
91
|
+
# Basic usage - pack main.rb and lib/ directory
|
|
92
|
+
$ kompo main.rb lib/
|
|
93
|
+
|
|
94
|
+
# Specify entry point and output directory
|
|
95
|
+
$ kompo -e app.rb -o ./dist src/ config/
|
|
96
|
+
|
|
97
|
+
# Use a specific Ruby version
|
|
98
|
+
$ kompo --ruby-version=3.3.0 main.rb
|
|
99
|
+
|
|
100
|
+
# Development: use local kompo-vfs
|
|
101
|
+
$ kompo --local-vfs-path=/path/to/kompo-vfs main.rb
|
|
102
|
+
|
|
103
|
+
# Clean all cached Ruby builds
|
|
104
|
+
$ kompo --clean=all
|
|
31
105
|
```
|
|
32
106
|
|
|
107
|
+
## .kompoignore
|
|
108
|
+
|
|
109
|
+
You can create a `.kompoignore` file in your project root to exclude files from the binary. This file follows the same syntax as `.gitignore`.
|
|
110
|
+
|
|
111
|
+
### Syntax
|
|
112
|
+
|
|
113
|
+
```gitignore
|
|
114
|
+
# Comments start with #
|
|
115
|
+
*.log # Ignore all .log files
|
|
116
|
+
tmp/ # Ignore tmp directory
|
|
117
|
+
**/cache/ # Ignore cache directories at any depth
|
|
118
|
+
!important.log # Negate pattern (don't ignore important.log)
|
|
119
|
+
spec/ # Ignore spec directory
|
|
120
|
+
test/ # Ignore test directory
|
|
121
|
+
node_modules/ # Ignore node_modules
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Supported Patterns
|
|
125
|
+
|
|
126
|
+
| Pattern | Description |
|
|
127
|
+
|---------|-------------|
|
|
128
|
+
| `*.log` | Glob pattern - matches all .log files |
|
|
129
|
+
| `tmp/` | Directory pattern - matches tmp directory and contents |
|
|
130
|
+
| `**/cache/` | Double star - matches cache at any depth |
|
|
131
|
+
| `!file` | Negation - excludes file from ignore list |
|
|
132
|
+
| `/config.yml` | Anchored - matches only at root level |
|
|
133
|
+
|
|
134
|
+
### Notes
|
|
135
|
+
|
|
136
|
+
- `.kompoignore` only affects project files, not Ruby standard library or gems
|
|
137
|
+
- Patterns are matched against paths relative to the project root
|
|
138
|
+
- Comments and empty lines are ignored
|
|
139
|
+
|
|
33
140
|
## examples
|
|
34
141
|
|
|
35
142
|
* hello
|
|
36
143
|
* simple hello world script.
|
|
37
144
|
* sinatra_and_sqlite
|
|
38
|
-
* sinatra app with sqlite3
|
|
145
|
+
* simple sinatra app with sqlite3.
|
|
39
146
|
* rails
|
|
40
|
-
*
|
|
147
|
+
* simple Rails 7.1 application.
|
|
41
148
|
|
|
42
149
|
## Development
|
|
43
150
|
|
|
@@ -45,4 +152,4 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
|
45
152
|
|
|
46
153
|
## Contributing
|
|
47
154
|
|
|
48
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
|
155
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ahogappa/kompo.
|
data/Rakefile
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
|
|
3
|
+
require 'bundler/gem_tasks'
|
|
4
|
+
require 'rake/testtask'
|
|
5
|
+
|
|
6
|
+
Rake::TestTask.new(:test) do |t|
|
|
7
|
+
t.libs << 'test'
|
|
8
|
+
t.libs << 'lib'
|
|
9
|
+
t.test_files = FileList['test/**/*_test.rb']
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
require 'standard/rake'
|
|
13
|
+
|
|
14
|
+
task default: %i[test standard]
|
data/docs/document.md.ja
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# 現状の仕様のまとめ
|
|
2
|
+
|
|
3
|
+
## 基本情報
|
|
4
|
+
kompoはワンバイナリにするファイルを作業ディレクトリにコピーします。
|
|
5
|
+
その作業ディレクトリはワンバイナリ化したプログラムが実行した時のルートディレクトリとします。
|
|
6
|
+
このとき作業ディレクトリのパス名やファイル名はプログラムの中に埋め込まれるため注意が必要です。(デフォルトではSecureRandomを使ってランダムなフォルダ名を生成します)
|
|
7
|
+
|
|
8
|
+
## kompoの制約
|
|
9
|
+
ワンバイナリ化したプログラム内にデータを書き込むことはできません。
|
|
10
|
+
この制約があるため、一部のrubyプロジェクトの場合ファイルや設定を工夫する必要があります。
|
|
11
|
+
|
|
12
|
+
例えばrailsのデータベースにsqliteを使う場合、デフォルトだとプロジェクトのtmp/以下にデータベースを配置します。
|
|
13
|
+
さらにこのディレクトリにはrailsの起動時に必要なディレクトリやファイルをいくつか書き込みます。
|
|
14
|
+
sampleにあるrailsではあらかじめtmp/以下に起動に必要なディレクトリやファイルを用意し、それをバイナリに含めることで起動時にディレクトリやファイルを作成しなくても良いようにしています。
|
|
15
|
+
|
|
16
|
+
一方sqliteのデータベースもここに設置されるのですが、これには書き込みがなされるため、tmp/以下に設置することはできません。
|
|
17
|
+
よってconfig/database.ymlを修正して、sqliteのデータベースは実行するマシンの絶対パスに配置するようにします。
|
|
18
|
+
|
|
19
|
+
簡単なrailsをワンバイナリ化する具体的な方法はsample/rails/sampleのREADME.mdやsample/rails/sample/config/database.ymlを参照してください。
|
|
20
|
+
|
|
21
|
+
## 拡張ライブラリが含まれる場合
|
|
22
|
+
拡張ライブラリが含まれるRubyプロジェクトの場合、拡張ライブラリをbuildできる環境が必要です。また環境が整っていても拡張ライブラリによってはうまくワンバイナリ化できない場合があります。
|
|
23
|
+
|
|
24
|
+
kompoは通常、拡張ライブラリを静的リンクするためにmkmf.rbを実行してMakefileを生成、コンパイルしアーカイブファイルを作ります。
|
|
25
|
+
そしてワンバイナリ化したプログラムを作成するときには、そのMakefileに含まれている情報をもとにinclude/やlib/のパスを指定してコンパイルします。
|
|
26
|
+
|
|
27
|
+
しかし、一部独自のbuild方法をとっているものがあり、Makefileから取得する情報が足りなかったりして失敗する可能性があります。
|
|
28
|
+
これに関してはなるべく対応していくつもりですが、完全に対応できるものではないので、拡張ライブラリのbuild方法をパッチするなり、自前でbuildしたものを使ってワンバイナリ化するなどする必要があります。
|
|
29
|
+
|
|
30
|
+
また当然ですが、拡張ライブラリ自体がクロスコンパイルに対応していない場合は、kompoを使ってもクロスコンパイルできません。
|
|
31
|
+
|
data/exe/kompo
CHANGED
|
@@ -1,20 +1,51 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
|
-
require_relative '../lib/kompo'
|
|
4
4
|
require 'optparse'
|
|
5
|
+
require_relative '../lib/kompo'
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
7
|
+
args = {}
|
|
8
|
+
opt = OptionParser.new do |o|
|
|
9
|
+
o.banner = 'Usage: kompo [options] [files...]'
|
|
10
|
+
o.separator ''
|
|
11
|
+
o.separator 'Options:'
|
|
12
|
+
|
|
13
|
+
o.on('-e', '--entrypoint=FILE', 'Entry point file (default: main.rb)') { |v| args[:entrypoint] = v }
|
|
14
|
+
o.on('-o', '--output=DIR', 'Output directory for the binary') { |v| args[:output_dir] = File.expand_path(v) }
|
|
15
|
+
o.on('--ruby-version=VERSION', "Ruby version to use (default: #{RUBY_VERSION})") { |v| args[:ruby_version] = v }
|
|
16
|
+
o.on('--ruby-source=PATH', 'Path to Ruby source tarball or directory') do |v|
|
|
17
|
+
args[:ruby_source_path] = File.expand_path(v)
|
|
18
|
+
end
|
|
19
|
+
o.on('--no-cache', 'Build Ruby from source, ignoring cache') { |_v| args[:no_cache] = true }
|
|
20
|
+
o.on('--no-stdlib', 'Exclude Ruby standard library from binary') { |_v| args[:no_stdlib] = true }
|
|
21
|
+
o.on('--local-vfs-path=PATH', 'Path to local kompo-vfs for development') do |v|
|
|
22
|
+
args[:local_kompo_vfs_path] = File.expand_path(v)
|
|
23
|
+
end
|
|
24
|
+
o.on('--clean[=VERSION]', 'Clean cache (current Ruby version by default, or specify VERSION, or "all")') do |v|
|
|
25
|
+
args[:clean_cache] = v.nil? ? RUBY_VERSION : v
|
|
26
|
+
end
|
|
27
|
+
o.on('-t', '--tree', 'Show task dependency tree and exit') do
|
|
28
|
+
puts Kompo::Packing.tree
|
|
29
|
+
exit(0)
|
|
30
|
+
end
|
|
31
|
+
o.on('-v', '--version', 'Show version') do
|
|
32
|
+
puts "kompo #{Kompo::VERSION}"
|
|
33
|
+
exit(0)
|
|
34
|
+
end
|
|
35
|
+
o.on('-h', '--help', 'Show this help message') do
|
|
36
|
+
puts o
|
|
37
|
+
exit(0)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
o.separator ''
|
|
41
|
+
o.separator 'Files:'
|
|
42
|
+
o.separator ' Additional files and directories to include in the binary'
|
|
18
43
|
end
|
|
44
|
+
opt.parse!(ARGV)
|
|
45
|
+
args[:files] = ARGV
|
|
19
46
|
|
|
20
|
-
|
|
47
|
+
if args[:clean_cache]
|
|
48
|
+
Kompo.clean_cache(args[:clean_cache])
|
|
49
|
+
else
|
|
50
|
+
Kompo::Packing.run_and_clean(args:)
|
|
51
|
+
end
|
data/lib/fs.c.erb
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
const char FILES[] = {<%= @file_bytes.join(',') %>};
|
|
2
|
+
const int FILES_SIZE = <%= @file_bytes.size %>;
|
|
3
|
+
const unsigned long long FILES_SIZES[] = {<%= @file_sizes.join(',') %>};
|
|
4
|
+
const char PATHS[] = {<%= @paths.join(',') %>};
|
|
5
|
+
const int PATHS_SIZE = <%= @paths.size %>;
|
|
6
|
+
const char WD[] = {<%= context.work_dir.bytes.join(',') %>,0};
|
data/lib/kompo/cache.rb
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
|
|
5
|
+
module Kompo
|
|
6
|
+
# Clean the cache for specified Ruby version
|
|
7
|
+
# @param version [String] Ruby version to clean, or "all" to clean all caches
|
|
8
|
+
def self.clean_cache(version)
|
|
9
|
+
kompo_cache = File.expand_path('~/.kompo/cache')
|
|
10
|
+
|
|
11
|
+
unless Dir.exist?(kompo_cache)
|
|
12
|
+
puts "Cache directory does not exist: #{kompo_cache}"
|
|
13
|
+
return
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
if version == 'all'
|
|
17
|
+
clean_all_caches(kompo_cache)
|
|
18
|
+
else
|
|
19
|
+
clean_version_cache(kompo_cache, version)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Clean all caches in the cache directory
|
|
24
|
+
def self.clean_all_caches(kompo_cache)
|
|
25
|
+
entries = Dir.glob(File.join(kompo_cache, '*'))
|
|
26
|
+
if entries.empty?
|
|
27
|
+
puts "No caches found in #{kompo_cache}"
|
|
28
|
+
return
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
entries.each do |entry|
|
|
32
|
+
FileUtils.rm_rf(entry)
|
|
33
|
+
puts "Removed: #{entry}"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
puts 'All caches cleaned successfully'
|
|
37
|
+
end
|
|
38
|
+
private_class_method :clean_all_caches
|
|
39
|
+
|
|
40
|
+
# Clean cache for a specific Ruby version
|
|
41
|
+
# New structure: ~/.kompo/cache/{version}/ contains all caches for that version
|
|
42
|
+
def self.clean_version_cache(kompo_cache, version)
|
|
43
|
+
version_cache_dir = File.join(kompo_cache, version)
|
|
44
|
+
|
|
45
|
+
unless Dir.exist?(version_cache_dir)
|
|
46
|
+
puts "No cache found for Ruby #{version}"
|
|
47
|
+
return
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Validate that version_cache_dir is under kompo_cache to prevent path traversal
|
|
51
|
+
real_kompo_cache = File.realpath(kompo_cache)
|
|
52
|
+
real_version_cache = File.realpath(version_cache_dir)
|
|
53
|
+
|
|
54
|
+
unless real_version_cache.start_with?(real_kompo_cache + File::SEPARATOR) ||
|
|
55
|
+
real_version_cache == real_kompo_cache
|
|
56
|
+
puts 'Error: Invalid cache path detected (possible path traversal)'
|
|
57
|
+
return
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
FileUtils.rm_rf(real_version_cache)
|
|
61
|
+
puts "Removed: #{real_version_cache}"
|
|
62
|
+
puts "Cache for Ruby #{version} cleaned successfully"
|
|
63
|
+
end
|
|
64
|
+
private_class_method :clean_version_cache
|
|
65
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'pathspec'
|
|
4
|
+
|
|
5
|
+
module Kompo
|
|
6
|
+
# Handler for .kompoignore file
|
|
7
|
+
# Uses pathspec gem for gitignore-compatible pattern matching
|
|
8
|
+
class KompoIgnore
|
|
9
|
+
FILENAME = '.kompoignore'
|
|
10
|
+
|
|
11
|
+
def initialize(project_dir)
|
|
12
|
+
@project_dir = project_dir
|
|
13
|
+
@pathspec = load_pathspec
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Check if the given relative path should be ignored
|
|
17
|
+
# @param relative_path [String] Path relative to work_dir
|
|
18
|
+
# @return [Boolean] true if the path should be ignored
|
|
19
|
+
def ignore?(relative_path)
|
|
20
|
+
return false unless @pathspec
|
|
21
|
+
|
|
22
|
+
@pathspec.match(relative_path)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Check if .kompoignore file exists and is enabled
|
|
26
|
+
# @return [Boolean] true if .kompoignore file exists
|
|
27
|
+
def enabled?
|
|
28
|
+
!@pathspec.nil?
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def load_pathspec
|
|
34
|
+
ignore_file = File.join(@project_dir, FILENAME)
|
|
35
|
+
return nil unless File.exist?(ignore_file)
|
|
36
|
+
|
|
37
|
+
PathSpec.from_filename(ignore_file)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|