erebrus 0.1.3 → 0.1.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 +4 -4
- data/examples/Buildfile +37 -3
- data/lib/erebrus/build_engine.rb +123 -1
- data/lib/erebrus/version.rb +1 -1
- data/sig/erebrus/build_engine.rbs +8 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1bf5fcdb4df2979ab91e097f590ba95f5bf9340e491003badda831ebd8898276
|
|
4
|
+
data.tar.gz: 5ef55f5ca03dbc62c4404515e853c7552d0e7eef9126861e721089c8d710913e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e8b82d1a8064ecace9fc87632277a345ed1b7840cdd3c8c110b9506bd5f9e22edd0b13363aa7cf9b2333743e0b1f739e4af22e04daa8dd2ce29e0d5db47686ea
|
|
7
|
+
data.tar.gz: 88803910630b9a10898d172540e852c733bc312b1303c9bc9c6d7ba61ae8f9a50632eb0a14792b77140c4eab4afcc5ec19f960e9c17097c84deac355743dac27
|
data/examples/Buildfile
CHANGED
|
@@ -192,21 +192,53 @@ target :parallel_compile, description: "Compile sources and tests in parallel" d
|
|
|
192
192
|
parallel :compile_sources, :compile_tests
|
|
193
193
|
end
|
|
194
194
|
|
|
195
|
+
# Demonstrate MSVC environment detection and setup (Windows only)
|
|
196
|
+
target :msvc_demo, description: "Detect MSVC and show version (Windows)" do
|
|
197
|
+
platform :windows do
|
|
198
|
+
conditional(msvc_available?) do
|
|
199
|
+
msvc_setup arch: "x64", version: "latest"
|
|
200
|
+
echo "MSVC Channel: ${MSVC_CHANNEL}"
|
|
201
|
+
echo "MSVC Version: ${MSVC_VERSION}"
|
|
202
|
+
run "where cl"
|
|
203
|
+
# Use cmd to ignore non-zero exit from cl /Bv
|
|
204
|
+
run "cmd /c \"cl /Bv & exit /b 0\""
|
|
205
|
+
end
|
|
206
|
+
conditional(!msvc_available?) do
|
|
207
|
+
echo "Visual Studio Build Tools not found. Install VS 2022/2019 Build Tools to enable MSVC."
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
target :msvc_preview_demo, description: "Detect VS Preview/Insiders and show version" do
|
|
213
|
+
platform :windows do
|
|
214
|
+
conditional(msvc_available?(version: "insiders")) do
|
|
215
|
+
msvc_setup arch: "x64", version: "insiders"
|
|
216
|
+
echo "MSVC Channel: ${MSVC_CHANNEL}"
|
|
217
|
+
echo "MSVC Version: ${MSVC_VERSION}"
|
|
218
|
+
run "where cl"
|
|
219
|
+
run "cmd /c \"cl /Bv & exit /b 0\""
|
|
220
|
+
end
|
|
221
|
+
conditional(!msvc_available?(version: "insiders")) do
|
|
222
|
+
echo "VS Preview/Insiders not found. Install Visual Studio Preview (Build Tools/Community)."
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
195
227
|
# Demonstrate conditional logic with system variables
|
|
196
228
|
target :system_specific, description: "Show system-specific behavior" do
|
|
197
229
|
echo "Detected system: ${HOST_OS} on ${HOST_ARCH}"
|
|
198
|
-
|
|
230
|
+
|
|
199
231
|
conditional(get_variable("HOST_OS") == "windows") do
|
|
200
232
|
echo "Running Windows-specific commands"
|
|
201
233
|
echo "User profile: ${HOME}"
|
|
202
234
|
echo "Temp directory: ${TEMP_DIR}"
|
|
203
235
|
end
|
|
204
|
-
|
|
236
|
+
|
|
205
237
|
conditional(get_variable("HOST_ARCH") == "x64") do
|
|
206
238
|
echo "64-bit architecture detected"
|
|
207
239
|
echo "Using optimized 64-bit settings"
|
|
208
240
|
end
|
|
209
|
-
|
|
241
|
+
|
|
210
242
|
# Show CPU-based logic
|
|
211
243
|
echo "System has ${CPU_COUNT} CPU cores available"
|
|
212
244
|
end
|
|
@@ -217,6 +249,8 @@ target :demo, description: "Run all demonstration features" do
|
|
|
217
249
|
depends_on :gen_config
|
|
218
250
|
depends_on :write_demo
|
|
219
251
|
depends_on :env_demo
|
|
252
|
+
depends_on :msvc_demo
|
|
253
|
+
depends_on :msvc_preview_demo
|
|
220
254
|
depends_on :system_specific
|
|
221
255
|
depends_on :build
|
|
222
256
|
depends_on :symlink_demo
|
data/lib/erebrus/build_engine.rb
CHANGED
|
@@ -411,6 +411,77 @@ module Erebrus
|
|
|
411
411
|
def detect_temp_dir
|
|
412
412
|
ENV["TMPDIR"] || ENV["TMP"] || ENV["TEMP"] || "/tmp"
|
|
413
413
|
end
|
|
414
|
+
|
|
415
|
+
public
|
|
416
|
+
# --- MSVC / Visual Studio environment helpers -------------------------
|
|
417
|
+
# Returns a Hash of environment variables configured by VsDevCmd for a given arch
|
|
418
|
+
def msvc_env(arch: "x64", version: "latest")
|
|
419
|
+
raise Error, "MSVC environment is only available on Windows" unless detect_host_os == "windows"
|
|
420
|
+
|
|
421
|
+
vsdevcmd = find_vsdevcmd(version: version)
|
|
422
|
+
raise Error, "Visual Studio Dev Cmd not found" unless vsdevcmd && File.exist?(vsdevcmd)
|
|
423
|
+
|
|
424
|
+
# Capture environment after activating VS developer environment
|
|
425
|
+
cmd = %Q{cmd.exe /c "\"#{vsdevcmd}\" -arch=#{arch} && set"}
|
|
426
|
+
output = `#{cmd}`
|
|
427
|
+
raise Error, "Failed to load MSVC environment" unless $?.success?
|
|
428
|
+
|
|
429
|
+
env = {}
|
|
430
|
+
output.each_line do |line|
|
|
431
|
+
line = line.strip
|
|
432
|
+
next if line.empty?
|
|
433
|
+
next unless line.include?("=")
|
|
434
|
+
k, v = line.split("=", 2)
|
|
435
|
+
env[k] = v
|
|
436
|
+
end
|
|
437
|
+
|
|
438
|
+
env
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
# Try to locate VsDevCmd.bat using vswhere, then fall back to well-known paths
|
|
442
|
+
def find_vsdevcmd(version: "latest")
|
|
443
|
+
# Normalize version request
|
|
444
|
+
v = (version || "latest").to_s.downcase
|
|
445
|
+
include_prerelease = (v == "insiders" || v == "preview" || v == "prerelease")
|
|
446
|
+
|
|
447
|
+
# First try vswhere
|
|
448
|
+
vswhere = File.join(ENV["ProgramFiles(x86)"] || "C:/Program Files (x86)", "Microsoft Visual Studio", "Installer", "vswhere.exe")
|
|
449
|
+
if File.exist?(vswhere)
|
|
450
|
+
# Prefer installations that have VC tools
|
|
451
|
+
flags = []
|
|
452
|
+
flags << "-products *"
|
|
453
|
+
flags << "-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64"
|
|
454
|
+
flags << "-latest" if v == "latest" || include_prerelease
|
|
455
|
+
flags << "-prerelease" if include_prerelease
|
|
456
|
+
property_cmd = %Q{"#{vswhere}" #{flags.join(" ")} -property installationPath}
|
|
457
|
+
install_path = `#{property_cmd}`.to_s.strip
|
|
458
|
+
if !$?.nil? && $?.success? && install_path && !install_path.empty?
|
|
459
|
+
vsdevcmd = File.join(install_path, "Common7", "Tools", "VsDevCmd.bat")
|
|
460
|
+
return vsdevcmd if File.exist?(vsdevcmd)
|
|
461
|
+
end
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
# Fallback to common installation paths
|
|
465
|
+
pf = ENV["ProgramFiles"] || "C:/Program Files"
|
|
466
|
+
pf86 = ENV["ProgramFiles(x86)"] || "C:/Program Files (x86)"
|
|
467
|
+
years = case v
|
|
468
|
+
when "2019" then ["2019", "2022", "2026"]
|
|
469
|
+
when "2022" then ["2022", "2019", "2026"]
|
|
470
|
+
when "2026" then ["2026", "2022", "2019"]
|
|
471
|
+
else ["2026", "2022", "2019"]
|
|
472
|
+
end
|
|
473
|
+
editions = ["Preview", "BuildTools", "Community", "Professional", "Enterprise"]
|
|
474
|
+
[pf, pf86].each do |base|
|
|
475
|
+
years.each do |year|
|
|
476
|
+
editions.each do |edition|
|
|
477
|
+
candidate = File.join(base, "Microsoft Visual Studio", year, edition, "Common7", "Tools", "VsDevCmd.bat")
|
|
478
|
+
return candidate if File.exist?(candidate)
|
|
479
|
+
end
|
|
480
|
+
end
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
nil
|
|
484
|
+
end
|
|
414
485
|
end
|
|
415
486
|
|
|
416
487
|
class TargetContext
|
|
@@ -460,6 +531,52 @@ module Erebrus
|
|
|
460
531
|
end
|
|
461
532
|
end
|
|
462
533
|
|
|
534
|
+
# Check if MSVC environment (VsDevCmd) is available on this machine
|
|
535
|
+
def msvc_available?(version: "latest")
|
|
536
|
+
!!(@engine&.find_vsdevcmd(version: version))
|
|
537
|
+
end
|
|
538
|
+
|
|
539
|
+
# Activate MSVC environment variables for subsequent actions in this target
|
|
540
|
+
def msvc_setup(options = {})
|
|
541
|
+
@target.action do |_context|
|
|
542
|
+
arch = options[:arch] || "x64"
|
|
543
|
+
version = options[:version] || "latest"
|
|
544
|
+
env = @engine&.msvc_env(arch: arch, version: version)
|
|
545
|
+
raise Error, "MSVC environment not found" unless env && env.any?
|
|
546
|
+
|
|
547
|
+
# Set env for this process so later run/system calls inherit it
|
|
548
|
+
env.each { |k, v| ENV[k] = v }
|
|
549
|
+
|
|
550
|
+
# Expose some useful MSVC-related variables to the build context
|
|
551
|
+
@engine&.set_variable("MSVC_VERSION", env["VCToolsVersion"] || env["VisualStudioVersion"] || "unknown")
|
|
552
|
+
@engine&.set_variable("MSVC_CHANNEL", (version.to_s.downcase =~ /(preview|insiders|prerelease)/ ? "preview" : "stable"))
|
|
553
|
+
@engine&.set_variable("VSINSTALLDIR", env["VSINSTALLDIR"]) if env["VSINSTALLDIR"]
|
|
554
|
+
@engine&.set_variable("VCToolsInstallDir", env["VCToolsInstallDir"]) if env["VCToolsInstallDir"]
|
|
555
|
+
@engine&.set_variable("WindowsSdkDir", env["WindowsSdkDir"]) if env["WindowsSdkDir"]
|
|
556
|
+
end
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
# Temporarily activate MSVC environment within the provided block
|
|
560
|
+
def with_msvc_env(options = {})
|
|
561
|
+
@target.action do |context|
|
|
562
|
+
arch = options[:arch] || "x64"
|
|
563
|
+
version = options[:version] || "latest"
|
|
564
|
+
env = @engine&.msvc_env(arch: arch, version: version)
|
|
565
|
+
raise Error, "MSVC environment not found" unless env && env.any?
|
|
566
|
+
|
|
567
|
+
backup = {}
|
|
568
|
+
env.each do |k, v|
|
|
569
|
+
backup[k] = ENV[k]
|
|
570
|
+
ENV[k] = v
|
|
571
|
+
end
|
|
572
|
+
begin
|
|
573
|
+
yield(context) if block_given?
|
|
574
|
+
ensure
|
|
575
|
+
env.each_key { |k| ENV[k] = backup[k] }
|
|
576
|
+
end
|
|
577
|
+
end
|
|
578
|
+
end
|
|
579
|
+
|
|
463
580
|
def move(source, destination)
|
|
464
581
|
@target.action do |context|
|
|
465
582
|
expanded_source = expand_variables(source, context)
|
|
@@ -675,7 +792,12 @@ module Erebrus
|
|
|
675
792
|
|
|
676
793
|
text.gsub(/\$\{(\w+)\}|\$(\w+)/) do |match|
|
|
677
794
|
var_name = ::Regexp.last_match(1) || ::Regexp.last_match(2)
|
|
678
|
-
|
|
795
|
+
# Prefer context, then engine variables, then ENV
|
|
796
|
+
context[var_name] ||
|
|
797
|
+
context[var_name.to_sym] ||
|
|
798
|
+
(@engine && @engine.get_variable(var_name)) ||
|
|
799
|
+
ENV[var_name] ||
|
|
800
|
+
match
|
|
679
801
|
end
|
|
680
802
|
end
|
|
681
803
|
end
|
data/lib/erebrus/version.rb
CHANGED
|
@@ -30,6 +30,9 @@ module Erebrus
|
|
|
30
30
|
|
|
31
31
|
def watch_file: (String pattern) { (String) -> untyped } -> void
|
|
32
32
|
def check_file_changes: () -> void
|
|
33
|
+
|
|
34
|
+
# MSVC helpers
|
|
35
|
+
def msvc_env: (arch?: String, version?: String) -> Hash[String, String]
|
|
33
36
|
end
|
|
34
37
|
|
|
35
38
|
class TargetContext
|
|
@@ -74,5 +77,10 @@ module Erebrus
|
|
|
74
77
|
def append: (String file, String content) -> Erebrus::Target
|
|
75
78
|
def with_env: (Hash[Symbol | String, untyped] vars) { (Hash[Symbol | String, untyped]) -> untyped } -> Erebrus::Target
|
|
76
79
|
def run_set: ((String | Symbol) name, String command) -> Erebrus::Target
|
|
80
|
+
|
|
81
|
+
# MSVC environment actions
|
|
82
|
+
def msvc_available?: (version?: String) -> bool
|
|
83
|
+
def msvc_setup: (Hash[Symbol | String, untyped] options) -> Erebrus::Target
|
|
84
|
+
def with_msvc_env: (Hash[Symbol | String, untyped] options) { (Hash[Symbol | String, untyped]) -> untyped } -> Erebrus::Target
|
|
77
85
|
end
|
|
78
86
|
end
|