vcdeps 0.1.0 → 0.1.1
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/README.md +11 -258
- data/lib/vcdeps.rb +4 -180
- metadata +13 -87
- data/CHANGELOG.md +0 -43
- data/exe/vcdeps +0 -6
- data/lib/vcdeps/bootstrap.rb +0 -163
- data/lib/vcdeps/cli.rb +0 -206
- data/lib/vcdeps/doctor.rb +0 -263
- data/lib/vcdeps/installed.rb +0 -139
- data/lib/vcdeps/manifest.rb +0 -100
- data/lib/vcdeps/mkmf.rb +0 -125
- data/lib/vcdeps/runner.rb +0 -145
- data/lib/vcdeps/tool.rb +0 -146
- data/lib/vcdeps/triplet.rb +0 -77
- data/lib/vcdeps/vendor.rb +0 -160
- data/lib/vcdeps/version.rb +0 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a72a92f5f224eac26210881a8d240687611f1a143dd3b9d1f648bc2593db9e4a
|
|
4
|
+
data.tar.gz: 61ca6e252ee0455c494b5290290bbc97fba66c960580562f967b6f1143bfe97d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 65e2725d60ace8635b5434e73cc9ec34cd6bcd0debb0996aeaeb83504c63352e81184502571d5efe4677117203408ac8b30384cbd6abeab288b0f7f2610002b0
|
|
7
|
+
data.tar.gz: dbbcdf8aa111ff94b23b611a5275dea4646b9d55c1d1ca4a2c093bdc7d867879fce3cbedbbb22809ad44a84626403459f9e1ba69acdc18dea9b38ad12f6064dd
|
data/README.md
CHANGED
|
@@ -1,258 +1,11 @@
|
|
|
1
|
-
# vcdeps
|
|
2
|
-
|
|
3
|
-
**
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
You fix that, link, build a `.so` — and then it still won't load:
|
|
13
|
-
|
|
14
|
-
```
|
|
15
|
-
LoadError: 126: The specified module could not be found - .../foo.so
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
because Windows resolves a `.so`'s dependent DLLs through the standard search
|
|
19
|
-
order, which **never** looks in the `.so`'s own directory. vcdeps closes both
|
|
20
|
-
gaps: you declare your native dependencies in a `vcpkg.json` under `ext/`, call
|
|
21
|
-
`Vcdeps.mkmf!` from `extconf.rb`, and vcdeps locates (or bootstraps) vcpkg,
|
|
22
|
-
installs the ports **out of tree** with the dynamic-CRT triplet that matches an
|
|
23
|
-
`-MD` Ruby, prepends the include/lib paths so they win over Ruby's own opt-dir,
|
|
24
|
-
and vendors the runtime DLLs with a generated `Fiddle`-preload shim so the built
|
|
25
|
-
extension actually loads.
|
|
26
|
-
|
|
27
|
-
It is first of its kind. rake-compiler-dock is author-side MinGW-only
|
|
28
|
-
cross-compilation; rb_sys and ffi-compiler are GCC-oriented; nothing wired vcpkg
|
|
29
|
-
into mkmf before. vcdeps is the companion to [vcvars](https://github.com/main-path/vcvars)
|
|
30
|
-
(which loads the toolchain) the way vcpkg is the companion to MSVC.
|
|
31
|
-
|
|
32
|
-
## API summary
|
|
33
|
-
|
|
34
|
-
| What | API |
|
|
35
|
-
|---|---|
|
|
36
|
-
| extconf entry point (install + wire + vendor) | `Vcdeps.mkmf!(vendor:)` |
|
|
37
|
-
| install a manifest's ports out of tree | `Vcdeps.install!(manifest:)` |
|
|
38
|
-
| sync DLLs + licenses + preload shim into a gem | `Vcdeps.vendor!(installed, into:)` |
|
|
39
|
-
| add/refresh `builtin-baseline` | `Vcdeps.baseline!(manifest:)` |
|
|
40
|
-
| locate vcpkg (or raise with remedies) | `Vcdeps.tool` / `Vcdeps.tool!` |
|
|
41
|
-
| bootstrap a private vcpkg | `Vcdeps.bootstrap!` |
|
|
42
|
-
| CLI | `vcdeps doctor / where / install / vendor / baseline / bootstrap` |
|
|
43
|
-
|
|
44
|
-
## Requirements
|
|
45
|
-
|
|
46
|
-
- Windows with a native **MSVC (mswin)** Ruby (`RbConfig::CONFIG["target_os"]`
|
|
47
|
-
matches `/mswin/`). **Not supported on MinGW/UCRT.**
|
|
48
|
-
- Visual Studio 2017+ or Build Tools with the **Desktop development with C++**
|
|
49
|
-
workload (for `cl.exe` / `nmake`).
|
|
50
|
-
- A vcpkg instance. vcdeps finds one in this order: an explicit `VCPKG_ROOT`,
|
|
51
|
-
the VS-bundled vcpkg (the **vcpkg package manager** component —
|
|
52
|
-
`Microsoft.VisualStudio.Component.Vcpkg`, *Recommended* in that workload), a
|
|
53
|
-
validated `VCPKG_INSTALLATION_ROOT` (GitHub Actions), or a private instance
|
|
54
|
-
created by `vcdeps bootstrap`.
|
|
55
|
-
- [vcvars](https://github.com/main-path/vcvars) — installed automatically as a
|
|
56
|
-
runtime dependency.
|
|
57
|
-
|
|
58
|
-
## Install
|
|
59
|
-
|
|
60
|
-
```sh
|
|
61
|
-
gem install vcdeps
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
## Quick start
|
|
65
|
-
|
|
66
|
-
Four files turn a C extension into a vcpkg-backed gem.
|
|
67
|
-
|
|
68
|
-
```json
|
|
69
|
-
// ext/foo/vcpkg.json — builtin-baseline is MANDATORY (the VS-bundled and
|
|
70
|
-
// standalone vcpkg are git-registry instances; vcdeps hard-fails without it).
|
|
71
|
-
// Get a SHA with: vcdeps baseline --manifest ext/foo
|
|
72
|
-
{
|
|
73
|
-
"name": "foo",
|
|
74
|
-
"version": "0.1.0",
|
|
75
|
-
"dependencies": ["zlib", "bzip2"],
|
|
76
|
-
"builtin-baseline": "e5a1490e1409d175932ef6014519e9ae149ddb7c"
|
|
77
|
-
}
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
```ruby
|
|
81
|
-
# ext/foo/extconf.rb
|
|
82
|
-
# frozen_string_literal: true
|
|
83
|
-
require "mkmf"
|
|
84
|
-
|
|
85
|
-
unless RbConfig::CONFIG["target_os"] =~ /mswin/
|
|
86
|
-
abort <<~MSG
|
|
87
|
-
foo requires a native Windows MSVC (mswin) Ruby — it links vcpkg-built
|
|
88
|
-
native libraries and is built with cl.exe. Your Ruby is "#{RbConfig::CONFIG['arch']}".
|
|
89
|
-
MSG
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
require "vcdeps/mkmf"
|
|
93
|
-
Vcdeps.mkmf!(vendor: File.expand_path("../../lib/foo/vendor", __dir__))
|
|
94
|
-
|
|
95
|
-
have_header("zlib.h") or abort "zlib.h not found — run `vcdeps doctor`"
|
|
96
|
-
have_library("zlib") or abort "zlib.lib not found" # bare name; LIBARG adds .lib
|
|
97
|
-
have_header("bzlib.h") or abort "bzlib.h not found"
|
|
98
|
-
have_library("bz2") or abort "bz2.lib not found" # import-lib name != port name
|
|
99
|
-
create_makefile("foo/foo")
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
```ruby
|
|
103
|
-
# lib/foo.rb
|
|
104
|
-
# frozen_string_literal: true
|
|
105
|
-
require "foo/version"
|
|
106
|
-
preload = File.expand_path("foo/vendor/preload.rb", __dir__)
|
|
107
|
-
require preload if File.exist?(preload) # shim absent for static-md / no-DLL builds
|
|
108
|
-
require "foo/foo" # the compiled extension
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
```ruby
|
|
112
|
-
# Rakefile — unchanged suite shape; vcdeps needs no Rake hook (extconf does it all)
|
|
113
|
-
require "vcvars/rake" # load the MSVC build env so `rake compile` just works
|
|
114
|
-
require "rake/extensiontask"
|
|
115
|
-
require "rake/testtask"
|
|
116
|
-
spec = Gem::Specification.load("foo.gemspec")
|
|
117
|
-
Rake::ExtensionTask.new("foo", spec) { |ext| ext.lib_dir = "lib/foo" }
|
|
118
|
-
Rake::TestTask.new(test: :compile) do |t|
|
|
119
|
-
t.libs << "test" << "lib"
|
|
120
|
-
t.test_files = FileList["test/**/test_*.rb"]
|
|
121
|
-
t.warning = false
|
|
122
|
-
end
|
|
123
|
-
task default: :test
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
Then `rake compile && rake test`. End users override at install time with
|
|
127
|
-
standard mkmf semantics:
|
|
128
|
-
|
|
129
|
-
```sh
|
|
130
|
-
gem install foo -- --with-vcdeps-triplet=x64-windows-static-md # link static, ship no DLLs
|
|
131
|
-
gem install foo -- --with-vcdeps-dir=C:\prebuilt\foo-deps # bypass vcpkg entirely
|
|
132
|
-
set VCDEPS_BOOTSTRAP=1 && gem install foo # consent to private bootstrap
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
## How loading works
|
|
136
|
-
|
|
137
|
-
Beside-the-`.so` **does not work**: Windows resolves an extension's dependent
|
|
138
|
-
DLLs as if loaded by module name only, and the search order never checks the
|
|
139
|
-
`.so`'s own directory. "It worked when I ran it from that folder" is the current
|
|
140
|
-
directory (search step 11) fooling you — move the cwd and it breaks. vcdeps
|
|
141
|
-
generates a `preload.rb` shim that `Fiddle.dlopen`s each vendored DLL by
|
|
142
|
-
**absolute path** before the extension loads, so the loaded-module list (search
|
|
143
|
-
step 4, consulted before PATH) satisfies the imports. The
|
|
144
|
-
`x64-windows-static-md` triplet sidesteps the whole problem by linking the
|
|
145
|
-
libraries statically into the `.so` (no DLLs to vendor). One caveat: Ruby's own
|
|
146
|
-
`bin` ships `zlib1.dll` / `ffi-8.dll` / `yaml.dll`; if one is already loaded
|
|
147
|
-
under that name, it wins process-wide — `vcdeps doctor` and `vendor!` warn on
|
|
148
|
-
base-name collisions.
|
|
149
|
-
|
|
150
|
-
## Precompiled platform gems
|
|
151
|
-
|
|
152
|
-
The primary audience is **gem authors and their Windows CI** shipping
|
|
153
|
-
precompiled `x64-mswin64-140` gems so end users never compile. Build on Windows
|
|
154
|
-
CI, run `vcdeps vendor --into lib/<gem>/vendor`, then flip
|
|
155
|
-
`spec.platform = Gem::Platform.local`, drop `spec.extensions`, and include
|
|
156
|
-
`lib/<gem>/vendor/**/*` (the DLLs + `preload.rb` shim) in `spec.files`. The
|
|
157
|
-
source path (`gem install` → extconf → vcdeps → vcpkg) still works — it is the
|
|
158
|
-
author's dev loop and the fallback for exotic setups — but a cold libxml2-class
|
|
159
|
-
build at end-user install time is an accepted-but-discouraged slow path: vcdeps
|
|
160
|
-
streams vcpkg output live and leans on vcpkg's binary cache, so it is slow once,
|
|
161
|
-
never silent.
|
|
162
|
-
|
|
163
|
-
**License note:** vendored ports' `copyright` files ship in `vendor/licenses/`
|
|
164
|
-
for DLL builds **and** static-md builds (under static-md the port code is
|
|
165
|
-
statically linked into the shipped `.so`, so its copyright files are still
|
|
166
|
-
redistributed alongside it). Mind relink obligations for LGPL ports.
|
|
167
|
-
|
|
168
|
-
## CI recipe
|
|
169
|
-
|
|
170
|
-
`windows-latest`, a self-provided mswin Ruby (ruby/setup-ruby's `mswin` build is
|
|
171
|
-
x64 ruby-master; there are no RubyInstaller mswin builds). Invoke vcpkg by
|
|
172
|
-
explicit path, let `vcvars/rake` + vcdeps do the rest, and cache the binary
|
|
173
|
-
archives:
|
|
174
|
-
|
|
175
|
-
```yaml
|
|
176
|
-
- uses: actions/cache@v4
|
|
177
|
-
with:
|
|
178
|
-
path: ~/AppData/Local/vcpkg/archives # or $VCPKG_DEFAULT_BINARY_CACHE
|
|
179
|
-
key: vcpkg-${{ hashFiles('ext/**/vcpkg.json') }}-x64-windows-${{ env.VCPKG_TOOL_VERSION }}
|
|
180
|
-
- run: bundle exec rake compile
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
The default `files` binary-cache provider needs no secrets and is immune to
|
|
184
|
-
provider churn (the `x-gha` provider was removed upstream in June 2025 — vcdeps
|
|
185
|
-
never references it). The NuGet-on-GitHub-Packages alternative is also viable;
|
|
186
|
-
note that Microsoft's own docs currently contradict themselves on whether the
|
|
187
|
-
workflow `GITHUB_TOKEN` (with `packages: write`) suffices or a classic PAT is
|
|
188
|
-
required — try `GITHUB_TOKEN` first and fall back to a PAT if pushes return 401.
|
|
189
|
-
|
|
190
|
-
## Library API
|
|
191
|
-
|
|
192
|
-
```ruby
|
|
193
|
-
require "vcdeps"
|
|
194
|
-
|
|
195
|
-
Vcdeps.default_triplet # => "x64-windows" (arm64 -> "arm64-windows")
|
|
196
|
-
Vcdeps.home # => "C:\\Users\\me\\AppData\\Local\\vcdeps"
|
|
197
|
-
|
|
198
|
-
Vcdeps.tool # => #<struct Vcdeps::Tool ... source=:devenv> or nil
|
|
199
|
-
Vcdeps.tool! # raises Vcdeps::ToolNotFound (with remedies) on a miss
|
|
200
|
-
Vcdeps.bootstrap! # private vcpkg under <home>\vcpkg (consent-gated)
|
|
201
|
-
|
|
202
|
-
inst = Vcdeps.install!(manifest: "ext/foo")
|
|
203
|
-
inst.prefix # => "...\\installed\\<key>\\x64-windows"
|
|
204
|
-
inst.ports # => [#<struct Vcdeps::Port name="zlib" version="1.3.1" ...>]
|
|
205
|
-
inst.dlls # => ["...\\bin\\zlib1.dll", ...] (release only, never debug)
|
|
206
|
-
|
|
207
|
-
Vcdeps.vendor!(inst, into: "lib/foo/vendor") # DLLs + licenses + preload.rb (a SYNC)
|
|
208
|
-
Vcdeps.install!(manifest: "ext/foo") # 2nd call: marker hit, returns in <100 ms
|
|
209
|
-
Vcdeps.baseline!(manifest: "ext/foo") # => "9f3dca…" (writes builtin-baseline)
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
## Configuration
|
|
213
|
-
|
|
214
|
-
| Env var | Effect |
|
|
215
|
-
|---|---|
|
|
216
|
-
| `VCDEPS_HOME` | State root (default `%LOCALAPPDATA%\vcdeps`); keep it short + ASCII. |
|
|
217
|
-
| `VCDEPS_TRIPLET` | Triplet override (between `--with-vcdeps-triplet` and the derived default). |
|
|
218
|
-
| `VCDEPS_BOOTSTRAP` | `=1` consents to a private bootstrap from a non-interactive `gem install`. |
|
|
219
|
-
| `VCDEPS_METRICS` | `=1` re-enables vcpkg telemetry (disabled by default — a `gem install` must not phone home). |
|
|
220
|
-
|
|
221
|
-
Honored vcpkg vars pass through untouched: `VCPKG_ROOT`,
|
|
222
|
-
`VCPKG_DEFAULT_BINARY_CACHE`, `VCPKG_BINARY_SOURCES`, `VCPKG_DOWNLOADS`.
|
|
223
|
-
**Ignored on purpose:** `VCPKG_DEFAULT_TRIPLET` — a machine-global default for
|
|
224
|
-
unrelated C++ projects must never silently change a Ruby extension's ABI.
|
|
225
|
-
|
|
226
|
-
## Errors
|
|
227
|
-
|
|
228
|
-
```
|
|
229
|
-
Vcdeps::Error (root; everything vcdeps raises)
|
|
230
|
-
├── Vcdeps::ToolNotFound (no usable vcpkg anywhere — message lists remedies)
|
|
231
|
-
├── Vcdeps::BootstrapError (private bootstrap failed: download / bootstrap-standalone)
|
|
232
|
-
├── Vcdeps::ManifestError (vcpkg.json missing/unparsable/missing builtin-baseline)
|
|
233
|
-
├── Vcdeps::TripletError (unknown arch, static-CRT triplet, arch mismatch)
|
|
234
|
-
└── Vcdeps::InstallError (`vcpkg install` exited nonzero; carries #command/#status/#log_tail)
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
API-misuse uses Ruby's own `ArgumentError`/`TypeError`. No error ever prints a
|
|
238
|
-
multi-screen dump; `InstallError#log_tail` is capped at 4000 chars.
|
|
239
|
-
|
|
240
|
-
## Limitations
|
|
241
|
-
|
|
242
|
-
- **Manifest mode only** — the VS-bundled and standalone vcpkg instances have no
|
|
243
|
-
classic mode; vcdeps cannot offer one.
|
|
244
|
-
- **x64 support.** arm64-mswin is expected to work (the code is arch-neutral and
|
|
245
|
-
triplets derive from `RbConfig`) but is untested and unsupported until an
|
|
246
|
-
arm64-mswin Ruby distribution exists.
|
|
247
|
-
- **Cold builds are slow** — libxml2-class ports are tens of minutes the first
|
|
248
|
-
time; the binary cache amortizes it. The first use of a baseline needs network
|
|
249
|
-
for the registry git-tree fetch.
|
|
250
|
-
- **DLL base-name collisions** across gems, and against Ruby's own `bin\zlib1.dll`
|
|
251
|
-
et al.: first-loaded wins. vcdeps warns; it cannot arbitrate.
|
|
252
|
-
- **Ctrl-C during an install** kills `vcpkg.exe` (so its install-root lock is
|
|
253
|
-
released) but not the helper build processes it spawned (`git`/`cmake`/`ninja`/
|
|
254
|
-
`cl`); they exit on their own. Wait a moment, then rerun.
|
|
255
|
-
|
|
256
|
-
## License
|
|
257
|
-
|
|
258
|
-
[MIT](LICENSE.txt).
|
|
1
|
+
# vcdeps (discontinued)
|
|
2
|
+
|
|
3
|
+
**vcdeps is no longer maintained.** This final release (0.1.1) contains no
|
|
4
|
+
code: installing it compiles nothing, and `require "vcdeps"` raises a
|
|
5
|
+
`LoadError` explaining the discontinuation.
|
|
6
|
+
|
|
7
|
+
Use `vcpkg install <port>` with mkmf's --with-opt-dir, and Ruby core's `rb msvc` for the toolchain instead.
|
|
8
|
+
|
|
9
|
+
Earlier releases remain on RubyGems only because RubyGems does not allow
|
|
10
|
+
versions older than 30 days to be yanked. They are unmaintained and not
|
|
11
|
+
recommended.
|
data/lib/vcdeps.rb
CHANGED
|
@@ -1,180 +1,4 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
require "tmpdir"
|
|
6
|
-
require "vcdeps/version"
|
|
7
|
-
|
|
8
|
-
# vcdeps — vcpkg-powered native dependencies for Ruby C extensions on Windows
|
|
9
|
-
# (MSVC). Declare ports in a manifest, get correct mkmf flags and loadable
|
|
10
|
-
# runtime DLLs, no global state. Companion to vcvars (the toolchain) the way
|
|
11
|
-
# vcpkg is companion to MSVC.
|
|
12
|
-
#
|
|
13
|
-
# # in ext/<gem>/extconf.rb, after require "mkmf":
|
|
14
|
-
# require "vcdeps/mkmf"
|
|
15
|
-
# Vcdeps.mkmf!(vendor: File.expand_path("../../lib/foo/vendor", __dir__))
|
|
16
|
-
#
|
|
17
|
-
# Library use:
|
|
18
|
-
#
|
|
19
|
-
# require "vcdeps"
|
|
20
|
-
# inst = Vcdeps.install!(manifest: "ext/foo")
|
|
21
|
-
# Vcdeps.vendor!(inst, into: "lib/foo/vendor")
|
|
22
|
-
#
|
|
23
|
-
# Windows MSVC (mswin) Ruby only. Pure Ruby — no compiler required to install.
|
|
24
|
-
module Vcdeps
|
|
25
|
-
class Error < StandardError; end # root; everything vcdeps raises
|
|
26
|
-
class ToolNotFound < Error; end # no usable vcpkg anywhere
|
|
27
|
-
class BootstrapError < Error; end # private bootstrap failed
|
|
28
|
-
class ManifestError < Error; end # vcpkg.json missing/unparsable/no baseline
|
|
29
|
-
class TripletError < Error; end # unknown arch, static-CRT triplet, arch mismatch
|
|
30
|
-
|
|
31
|
-
# `vcpkg install` exited nonzero. Carries the exact failing argv, the child
|
|
32
|
-
# exit status, and the last <= 4000 chars of combined output (UTF-8 scrubbed).
|
|
33
|
-
class InstallError < Error
|
|
34
|
-
attr_reader :command, :status, :log_tail
|
|
35
|
-
|
|
36
|
-
def initialize(message, command:, status:, log_tail:)
|
|
37
|
-
super(message)
|
|
38
|
-
@command = command
|
|
39
|
-
@status = status
|
|
40
|
-
@log_tail = log_tail
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
module_function
|
|
45
|
-
|
|
46
|
-
# The vcdeps state root: ENV["VCDEPS_HOME"] or %LOCALAPPDATA%\vcdeps.
|
|
47
|
-
# Deliberately a SHORT path (vcpkg port builds break in deep trees, R§7).
|
|
48
|
-
def home
|
|
49
|
-
base = ENV["VCDEPS_HOME"]
|
|
50
|
-
base = File.join(ENV["LOCALAPPDATA"] || Dir.tmpdir, "vcdeps") if base.nil? || base.empty?
|
|
51
|
-
base.tr("/", "\\")
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
# Triplet for this Ruby (x64 -> "x64-windows", arm64 -> "arm64-windows", ...).
|
|
55
|
-
# Raises Vcdeps::TripletError for an unrecognized arch.
|
|
56
|
-
def default_triplet(arch = RbConfig::CONFIG["arch"])
|
|
57
|
-
Triplet.default(arch)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
# Locate a usable vcpkg (§2.3 resolution order). Returns a Tool or nil; with
|
|
61
|
-
# bootstrap: true a miss bootstraps a private instance instead of nil.
|
|
62
|
-
def tool(bootstrap: false, out: $stderr)
|
|
63
|
-
ToolFinder.find(bootstrap: bootstrap, out: out)
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
# tool(), but raises Vcdeps::ToolNotFound (with the three remedies) on a miss.
|
|
67
|
-
# Default consent for bootstrap comes from ENV so `gem install` can be
|
|
68
|
-
# unblocked without editing anything.
|
|
69
|
-
def tool!(bootstrap: ENV["VCDEPS_BOOTSTRAP"] == "1", out: $stderr)
|
|
70
|
-
found = tool(bootstrap: bootstrap, out: out)
|
|
71
|
-
return found if found
|
|
72
|
-
|
|
73
|
-
raise ToolNotFound, <<~MSG.strip
|
|
74
|
-
vcdeps: no usable vcpkg found. Pick one of:
|
|
75
|
-
(a) Install the VS "vcpkg package manager" component
|
|
76
|
-
(Microsoft.VisualStudio.Component.Vcpkg) — it is Recommended (not
|
|
77
|
-
Required) in the "Desktop development with C++" workload, so a
|
|
78
|
-
cl-capable box can still lack it.
|
|
79
|
-
(b) Set VCPKG_ROOT to an existing vcpkg instance.
|
|
80
|
-
(c) Run `vcdeps bootstrap` (or set VCDEPS_BOOTSTRAP=1 for non-interactive
|
|
81
|
-
installs).
|
|
82
|
-
See `vcdeps doctor` for details.
|
|
83
|
-
MSG
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
# Create the private, registration-free vcpkg instance under <home>\vcpkg
|
|
87
|
-
# (the vcpkg-init mechanism, R§2.4). Idempotent. Raises BootstrapError.
|
|
88
|
-
def bootstrap!(out: $stderr)
|
|
89
|
-
require "vcdeps/bootstrap"
|
|
90
|
-
Bootstrap.run!(out: out)
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
# Run `vcpkg install` for <manifest>\vcpkg.json into <home>\installed\<key>.
|
|
94
|
-
# Streams combined output to `out` (nil to silence). Fast path: a present
|
|
95
|
-
# .vcdeps-complete marker means the install is provably current and vcpkg is
|
|
96
|
-
# not invoked (force: true bypasses it). Triplet precedence: kwarg >
|
|
97
|
-
# ENV["VCDEPS_TRIPLET"] > default_triplet.
|
|
98
|
-
#
|
|
99
|
-
# Raises ManifestError / TripletError / ToolNotFound / InstallError.
|
|
100
|
-
def install!(manifest: Dir.pwd, triplet: nil, tool: nil, force: false, out: $stderr)
|
|
101
|
-
manifest_dir = File.expand_path(manifest)
|
|
102
|
-
|
|
103
|
-
# Pre-flight the manifest BEFORE locating the tool (a missing vcpkg.json or
|
|
104
|
-
# missing baseline must never invoke vcpkg, §5.1/§5.2).
|
|
105
|
-
Manifest.load!(manifest_dir)
|
|
106
|
-
|
|
107
|
-
resolved_triplet = resolve_triplet(triplet)
|
|
108
|
-
Triplet.validate!(resolved_triplet)
|
|
109
|
-
|
|
110
|
-
resolved_tool = tool || tool!(out: out)
|
|
111
|
-
|
|
112
|
-
key = Manifest.key(manifest_dir, resolved_triplet, resolved_tool.version)
|
|
113
|
-
install_root = File.join(home, "installed", key).tr("/", "\\")
|
|
114
|
-
|
|
115
|
-
installed = Installed.new(root: install_root, triplet: resolved_triplet,
|
|
116
|
-
manifest_dir: manifest_dir, key: key, tool: resolved_tool)
|
|
117
|
-
|
|
118
|
-
# Fast path: marker present and not forced.
|
|
119
|
-
return installed if !force && Runner.marker_present?(install_root)
|
|
120
|
-
|
|
121
|
-
FileUtils.mkdir_p(install_root)
|
|
122
|
-
command = Runner.install_args(resolved_tool.exe, resolved_triplet,
|
|
123
|
-
manifest_dir, install_root, home)
|
|
124
|
-
Runner.run_install(command, env: Runner.child_env(resolved_tool.root),
|
|
125
|
-
chdir: manifest_dir, out: out)
|
|
126
|
-
Runner.write_marker!(install_root, key, resolved_tool.version)
|
|
127
|
-
|
|
128
|
-
installed
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
# Sync an Installed's runtime DLLs (+ copyright files, + preload shim) into
|
|
132
|
-
# `into` (§2.2). SYNC, not copy: owns <into>\*.dll, <into>\licenses\* and
|
|
133
|
-
# <into>\preload.rb. Returns the list of files written.
|
|
134
|
-
def vendor!(installed, into:, licenses: true, shim: true, out: $stderr)
|
|
135
|
-
require "vcdeps/vendor"
|
|
136
|
-
Vendor.sync!(installed, into: File.expand_path(into),
|
|
137
|
-
licenses: licenses, shim: shim, out: out)
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
# Write/update "builtin-baseline" in <manifest>\vcpkg.json by running
|
|
141
|
-
# `vcpkg x-update-baseline --add-initial-baseline` with chdir: manifest.
|
|
142
|
-
# Returns the resulting baseline SHA (re-read from the manifest).
|
|
143
|
-
# Raises ManifestError / ToolNotFound / InstallError.
|
|
144
|
-
def baseline!(manifest: Dir.pwd, tool: nil, out: $stderr)
|
|
145
|
-
manifest_dir = File.expand_path(manifest)
|
|
146
|
-
path = File.join(manifest_dir, Manifest::MANIFEST_NAME)
|
|
147
|
-
unless File.exist?(path)
|
|
148
|
-
raise ManifestError, "vcdeps: no manifest at #{path.tr('/', '\\')} to add a " \
|
|
149
|
-
"baseline to."
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
resolved_tool = tool || tool!(out: out)
|
|
153
|
-
command = [resolved_tool.exe, "x-update-baseline", "--add-initial-baseline"]
|
|
154
|
-
Runner.run(command, env: Runner.child_env(resolved_tool.root),
|
|
155
|
-
chdir: manifest_dir, out: out)
|
|
156
|
-
|
|
157
|
-
manifest = Manifest.read_json(path)
|
|
158
|
-
manifest["builtin-baseline"].to_s
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
# Triplet precedence for install! (kwarg > VCDEPS_TRIPLET > default).
|
|
162
|
-
def resolve_triplet(kwarg)
|
|
163
|
-
return kwarg if kwarg && !kwarg.to_s.empty?
|
|
164
|
-
|
|
165
|
-
env = ENV["VCDEPS_TRIPLET"]
|
|
166
|
-
return env if env && !env.empty?
|
|
167
|
-
|
|
168
|
-
default_triplet
|
|
169
|
-
end
|
|
170
|
-
private_class_method :resolve_triplet
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
require "vcdeps/triplet"
|
|
174
|
-
require "vcdeps/tool"
|
|
175
|
-
require "vcdeps/manifest"
|
|
176
|
-
require "vcdeps/runner"
|
|
177
|
-
require "vcdeps/installed"
|
|
178
|
-
# NOTE: vcdeps/mkmf, vcdeps/vendor, vcdeps/bootstrap, vcdeps/doctor and
|
|
179
|
-
# vcdeps/cli are required lazily (mkmf must never be loaded into a normal
|
|
180
|
-
# process; the others are CLI-only or pulled in on first use).
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
raise LoadError, "vcdeps is discontinued and this release contains no code. Use `vcpkg install <port>` with mkmf's --with-opt-dir, and Ruby core's `rb msvc` for the toolchain instead." \
|
|
4
|
+
" Earlier vcdeps releases are unmaintained and not recommended."
|
metadata
CHANGED
|
@@ -1,105 +1,31 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: vcdeps
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ned
|
|
8
|
-
bindir:
|
|
8
|
+
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
-
dependencies:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
- - "~>"
|
|
17
|
-
- !ruby/object:Gem::Version
|
|
18
|
-
version: '0.1'
|
|
19
|
-
- - ">="
|
|
20
|
-
- !ruby/object:Gem::Version
|
|
21
|
-
version: 0.1.1
|
|
22
|
-
type: :runtime
|
|
23
|
-
prerelease: false
|
|
24
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
-
requirements:
|
|
26
|
-
- - "~>"
|
|
27
|
-
- !ruby/object:Gem::Version
|
|
28
|
-
version: '0.1'
|
|
29
|
-
- - ">="
|
|
30
|
-
- !ruby/object:Gem::Version
|
|
31
|
-
version: 0.1.1
|
|
32
|
-
- !ruby/object:Gem::Dependency
|
|
33
|
-
name: rake
|
|
34
|
-
requirement: !ruby/object:Gem::Requirement
|
|
35
|
-
requirements:
|
|
36
|
-
- - "~>"
|
|
37
|
-
- !ruby/object:Gem::Version
|
|
38
|
-
version: '13.0'
|
|
39
|
-
type: :development
|
|
40
|
-
prerelease: false
|
|
41
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
42
|
-
requirements:
|
|
43
|
-
- - "~>"
|
|
44
|
-
- !ruby/object:Gem::Version
|
|
45
|
-
version: '13.0'
|
|
46
|
-
- !ruby/object:Gem::Dependency
|
|
47
|
-
name: minitest
|
|
48
|
-
requirement: !ruby/object:Gem::Requirement
|
|
49
|
-
requirements:
|
|
50
|
-
- - "~>"
|
|
51
|
-
- !ruby/object:Gem::Version
|
|
52
|
-
version: '5.0'
|
|
53
|
-
type: :development
|
|
54
|
-
prerelease: false
|
|
55
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
56
|
-
requirements:
|
|
57
|
-
- - "~>"
|
|
58
|
-
- !ruby/object:Gem::Version
|
|
59
|
-
version: '5.0'
|
|
60
|
-
description: |
|
|
61
|
-
vcdeps wires Microsoft's vcpkg package manager into mkmf: declare native
|
|
62
|
-
dependencies in ext/<gem>/vcpkg.json, call Vcdeps.mkmf! from extconf.rb, and
|
|
63
|
-
vcdeps locates (or bootstraps) vcpkg, installs the ports out of tree with the
|
|
64
|
-
correct dynamic-CRT triplet, prepends the include/lib paths so they win over
|
|
65
|
-
Ruby's own opt-dir, and vendors the runtime DLLs with a generated
|
|
66
|
-
Fiddle-preload shim so the built extension actually loads.
|
|
67
|
-
|
|
68
|
-
It provides a library API (install!/vendor!/baseline!/tool!), the extconf
|
|
69
|
-
entry point Vcdeps.mkmf!, and a CLI (vcdeps doctor/where/install/vendor/
|
|
70
|
-
baseline/bootstrap). Manifest mode only; builds and caches live under
|
|
71
|
-
%LOCALAPPDATA%\vcdeps, never inside the gem. Windows MSVC (mswin) Ruby
|
|
72
|
-
only. Pure Ruby — no compiler required to install vcdeps itself.
|
|
73
|
-
executables:
|
|
74
|
-
- vcdeps
|
|
11
|
+
dependencies: []
|
|
12
|
+
description: vcdeps is discontinued. This final release contains no code and exists
|
|
13
|
+
only so that installing vcdeps explains the discontinuation instead of building
|
|
14
|
+
an unmaintained native extension.
|
|
15
|
+
executables: []
|
|
75
16
|
extensions: []
|
|
76
17
|
extra_rdoc_files: []
|
|
77
18
|
files:
|
|
78
|
-
- CHANGELOG.md
|
|
79
19
|
- LICENSE.txt
|
|
80
20
|
- README.md
|
|
81
|
-
- exe/vcdeps
|
|
82
21
|
- lib/vcdeps.rb
|
|
83
|
-
- lib/vcdeps/bootstrap.rb
|
|
84
|
-
- lib/vcdeps/cli.rb
|
|
85
|
-
- lib/vcdeps/doctor.rb
|
|
86
|
-
- lib/vcdeps/installed.rb
|
|
87
|
-
- lib/vcdeps/manifest.rb
|
|
88
|
-
- lib/vcdeps/mkmf.rb
|
|
89
|
-
- lib/vcdeps/runner.rb
|
|
90
|
-
- lib/vcdeps/tool.rb
|
|
91
|
-
- lib/vcdeps/triplet.rb
|
|
92
|
-
- lib/vcdeps/vendor.rb
|
|
93
|
-
- lib/vcdeps/version.rb
|
|
94
|
-
homepage: https://github.com/main-path/vcdeps
|
|
95
22
|
licenses:
|
|
96
23
|
- MIT
|
|
97
24
|
metadata:
|
|
98
|
-
homepage_uri: https://github.com/main-path/vcdeps
|
|
99
|
-
source_code_uri: https://github.com/main-path/vcdeps
|
|
100
|
-
changelog_uri: https://github.com/main-path/vcdeps/blob/main/CHANGELOG.md
|
|
101
|
-
bug_tracker_uri: https://github.com/main-path/vcdeps/issues
|
|
102
25
|
rubygems_mfa_required: 'true'
|
|
26
|
+
post_install_message: vcdeps is discontinued and this release contains no code. Use
|
|
27
|
+
`vcpkg install <port>` with mkmf's --with-opt-dir, and Ruby core's `rb msvc` for
|
|
28
|
+
the toolchain instead.
|
|
103
29
|
rdoc_options: []
|
|
104
30
|
require_paths:
|
|
105
31
|
- lib
|
|
@@ -107,7 +33,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
107
33
|
requirements:
|
|
108
34
|
- - ">="
|
|
109
35
|
- !ruby/object:Gem::Version
|
|
110
|
-
version: '
|
|
36
|
+
version: '2.0'
|
|
111
37
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
112
38
|
requirements:
|
|
113
39
|
- - ">="
|
|
@@ -116,6 +42,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
116
42
|
requirements: []
|
|
117
43
|
rubygems_version: 3.6.9
|
|
118
44
|
specification_version: 4
|
|
119
|
-
summary:
|
|
120
|
-
|
|
45
|
+
summary: Discontinued. Use `vcpkg install <port>` with mkmf's --with-opt-dir, and
|
|
46
|
+
Ruby core's `rb msvc` for the toolchain instead.
|
|
121
47
|
test_files: []
|
data/CHANGELOG.md
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
## [0.1.0] - 2026-06-27
|
|
4
|
-
|
|
5
|
-
Initial release.
|
|
6
|
-
|
|
7
|
-
- `Vcdeps.tool` / `Vcdeps.tool!` — locate a usable vcpkg, validated
|
|
8
|
-
(vcpkg.exe + `.vcpkg-root`), in resolution order: explicit `VCPKG_ROOT`, the
|
|
9
|
-
VS developer-env `VCPKG_ROOT`, the VS-bundled `VC\vcpkg`, a validated
|
|
10
|
-
`VCPKG_INSTALLATION_ROOT` (GitHub Actions), then a private bootstrap. `tool!`
|
|
11
|
-
raises `Vcdeps::ToolNotFound` with three actionable remedies.
|
|
12
|
-
- `Vcdeps.bootstrap!` — create a private, registration-free vcpkg under
|
|
13
|
-
`%LOCALAPPDATA%\vcdeps\vcpkg` (download `vcpkg.exe` over TLS, then
|
|
14
|
-
`bootstrap-standalone`). Idempotent; never elevates or touches the registry.
|
|
15
|
-
- `Vcdeps.install!` — run `vcpkg install` for `<manifest>\vcpkg.json` into an
|
|
16
|
-
out-of-tree root keyed on (manifest, triplet, tool version), streaming child
|
|
17
|
-
output live. A `.vcdeps-complete` marker makes a current install a no-op;
|
|
18
|
-
`force:` bypasses it. Builds/caches live under `%LOCALAPPDATA%\vcdeps`, never
|
|
19
|
-
inside the gem (the deep-path port-build trap).
|
|
20
|
-
- `Vcdeps.vendor!` — sync an install's runtime DLLs, per-port `copyright` files,
|
|
21
|
-
and a generated standalone `Fiddle`-preload shim into a vendor dir. SYNC, not
|
|
22
|
-
copy: it owns `*.dll`, `licenses\*`, and `preload.rb`, deleting stale owned
|
|
23
|
-
files so a removed port leaves no orphan DLL.
|
|
24
|
-
- `Vcdeps.baseline!` — add/refresh `builtin-baseline` via
|
|
25
|
-
`vcpkg x-update-baseline --add-initial-baseline`.
|
|
26
|
-
- `Vcdeps.mkmf!` — the extconf entry point: activate vcvars, install the ports
|
|
27
|
-
(or bypass via `--with-vcdeps-dir`), PREPEND the include/lib paths so the
|
|
28
|
-
vcpkg tree wins over Ruby's build-time opt-dir, and vendor the DLLs.
|
|
29
|
-
- `Vcdeps.default_triplet` and `Vcdeps::Triplet.validate!` — derive
|
|
30
|
-
`<arch>-windows` from `RbConfig`; reject static-CRT triplets and arch
|
|
31
|
-
mismatches; `VCPKG_DEFAULT_TRIPLET` is deliberately ignored.
|
|
32
|
-
- `vcdeps` CLI — `doctor`, `where`, `install`, `vendor`, `baseline`,
|
|
33
|
-
`bootstrap`, `version`, `help`.
|
|
34
|
-
- `vcdeps doctor` — diagnoses resolution, manifest baseline, opt-dir shadowing,
|
|
35
|
-
Ruby-bin DLL collisions, triplet sanity, binary-cache / offline readiness, and
|
|
36
|
-
`VCDEPS_HOME` hygiene.
|
|
37
|
-
|
|
38
|
-
Manifest mode only. Telemetry is disabled in every child unless
|
|
39
|
-
`VCDEPS_METRICS=1`. Supported platform: native MSVC (mswin) Ruby, x64.
|
|
40
|
-
arm64-mswin is expected to work (arch-neutral) but is untested and unsupported
|
|
41
|
-
until an arm64-mswin Ruby distribution exists. Windows MSVC (mswin) Ruby only.
|
|
42
|
-
|
|
43
|
-
[0.1.0]: https://github.com/main-path/vcdeps/releases/tag/v0.1.0
|