xccache 1.0.2 → 1.0.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/lib/xccache/cache/cachemap.rb +9 -6
- data/lib/xccache/command/base.rb +2 -1
- data/lib/xccache/command.rb +1 -0
- data/lib/xccache/core/config.rb +4 -4
- data/lib/xccache/core/live_log.rb +82 -0
- data/lib/xccache/core/log.rb +17 -7
- data/lib/xccache/core/sh.rb +22 -4
- data/lib/xccache/installer/integration/supporting_files.rb +1 -1
- data/lib/xccache/installer.rb +12 -2
- data/lib/xccache/spm/build.rb +11 -3
- data/lib/xccache/spm/desc/desc.rb +4 -0
- data/lib/xccache/spm/macro.rb +2 -2
- data/lib/xccache/spm/pkg/base.rb +27 -18
- data/lib/xccache/spm/pkg/proxy.rb +2 -2
- data/lib/xccache/spm/pkg/proxy_executable.rb +2 -1
- data/lib/xccache/spm/xcframework/slice.rb +12 -13
- data/lib/xccache/spm/xcframework/xcframework.rb +9 -12
- data/lib/xccache/swift/sdk.rb +33 -22
- metadata +31 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e985d50b212e526c36c94d40d93210a81850267fb205a3c2b10aee659357a039
|
4
|
+
data.tar.gz: 8e720a6bda28fc18cefd3bcc18b37aab2ecbf29acee27f688db5508ab9c38af2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f84d4d129ae5e4b5e07aa96dd47d9618d9f117f2a28679f49de286075173eac12c51e8c4c47b52d85da20d5fb024cd395b1e76c3203598a5199a05c278d6027
|
7
|
+
data.tar.gz: e0d610301f133cc22ede54d34db62e57bf1f98701b3f57b408217c6a92ccb21ba6a65a0296e102c98bd337963544d4333918aa9c4aa6556c1eea118343c7ef69
|
@@ -57,15 +57,18 @@ module XCCache
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def get_cache_data(type)
|
60
|
-
cache_data.select { |
|
60
|
+
cache_data.select { |_, v| v == type }.keys
|
61
61
|
end
|
62
62
|
|
63
63
|
def update_from_graph(graph)
|
64
|
-
cache_data =
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
64
|
+
cache_data =
|
65
|
+
graph["cache"]
|
66
|
+
.reject { |k, _| k.end_with?(".xccache") }
|
67
|
+
.to_h do |k, v|
|
68
|
+
next [k, :hit] if v
|
69
|
+
next [k, :ignored] if Config.instance.ignore?(k)
|
70
|
+
[k, :missed]
|
71
|
+
end
|
69
72
|
|
70
73
|
deps = graph["deps"]
|
71
74
|
edges = deps.flat_map { |k, xs| xs.map { |v| { :source => k, :target => v } } }
|
data/lib/xccache/command/base.rb
CHANGED
@@ -5,6 +5,7 @@ module XCCache
|
|
5
5
|
class Options
|
6
6
|
SDK = ["--sdk=foo,bar", "SDKs (iphonesimulator, iphoneos, macos, etc.)"].freeze
|
7
7
|
CONFIG = ["--config=foo", "Configuration (debug, release) (default: debug)"].freeze
|
8
|
+
LOG_DIR = ["--log-dir=foo", "Build log directory"].freeze
|
8
9
|
MERGE_SLICES = [
|
9
10
|
"--merge-slices/--no-merge-slices",
|
10
11
|
"Whether to merge with existing slices/sdks in the xcframework (default: true)",
|
@@ -19,7 +20,7 @@ module XCCache
|
|
19
20
|
end
|
20
21
|
|
21
22
|
def self.build_options
|
22
|
-
install_options + [MERGE_SLICES, LIBRARY_EVOLUTION]
|
23
|
+
install_options + [LOG_DIR, MERGE_SLICES, LIBRARY_EVOLUTION]
|
23
24
|
end
|
24
25
|
end
|
25
26
|
end
|
data/lib/xccache/command.rb
CHANGED
data/lib/xccache/core/config.rb
CHANGED
@@ -40,11 +40,11 @@ module XCCache
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def spm_local_pkgs_dir
|
43
|
-
@spm_local_pkgs_dir ||= Dir.prepare(spm_sandbox / "local"
|
43
|
+
@spm_local_pkgs_dir ||= Dir.prepare(spm_sandbox / "local")
|
44
44
|
end
|
45
45
|
|
46
|
-
def
|
47
|
-
@
|
46
|
+
def spm_xcconfigs_dir
|
47
|
+
@spm_xcconfigs_dir ||= Dir.prepare(spm_sandbox / "xcconfigs")
|
48
48
|
end
|
49
49
|
|
50
50
|
def spm_cache_dir
|
@@ -52,7 +52,7 @@ module XCCache
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def spm_binaries_dir
|
55
|
-
@spm_binaries_dir ||= Dir.prepare(spm_sandbox / "binaries"
|
55
|
+
@spm_binaries_dir ||= Dir.prepare(spm_sandbox / "binaries")
|
56
56
|
end
|
57
57
|
|
58
58
|
def spm_build_dir
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require "monitor"
|
2
|
+
require "tty-cursor"
|
3
|
+
require "tty-screen"
|
4
|
+
|
5
|
+
module XCCache
|
6
|
+
class LiveLog
|
7
|
+
include UI::Mixin
|
8
|
+
CURSOR_LOCK = Monitor.new
|
9
|
+
|
10
|
+
attr_reader :output, :max_lines, :lines, :cursor, :tee
|
11
|
+
|
12
|
+
def initialize(**options)
|
13
|
+
@output = options[:output] || $stdout
|
14
|
+
@max_lines = options[:max_lines] || 5
|
15
|
+
@n_sticky = 0
|
16
|
+
@lines = []
|
17
|
+
@cursor = TTY::Cursor
|
18
|
+
@screen = TTY::Screen
|
19
|
+
@tee = options[:tee]
|
20
|
+
end
|
21
|
+
|
22
|
+
def clear
|
23
|
+
commit do
|
24
|
+
output.print(cursor.clear_lines(lines.count + @n_sticky))
|
25
|
+
@lines = []
|
26
|
+
@n_sticky = 0
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def puts(line, sticky: false)
|
31
|
+
commit do
|
32
|
+
output.print(cursor.clear_lines(lines.count + 1))
|
33
|
+
if sticky
|
34
|
+
@n_sticky += 1
|
35
|
+
output.puts(truncated(line))
|
36
|
+
else
|
37
|
+
lines.shift if lines.count >= max_lines
|
38
|
+
lines << truncated(line)
|
39
|
+
end
|
40
|
+
output.puts(lines) # print non-sticky content
|
41
|
+
end
|
42
|
+
File.open(tee, "a") { |f| f << "#{line}\n" } if tee
|
43
|
+
end
|
44
|
+
|
45
|
+
def capture(header)
|
46
|
+
header_start = header.magenta.bold
|
47
|
+
header_success = "#{header} ✔".green.bold
|
48
|
+
header_error = "#{header} ✖".red.bold
|
49
|
+
puts(header_start, sticky: true)
|
50
|
+
yield if block_given?
|
51
|
+
clear
|
52
|
+
update_header(header_success)
|
53
|
+
rescue StandardError => e
|
54
|
+
update_header(header_error)
|
55
|
+
raise e
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def update_header(header)
|
61
|
+
commit do
|
62
|
+
n = lines.count + @n_sticky
|
63
|
+
output.print(cursor.up(n) + header + cursor.column(0) + cursor.down(n))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def commit
|
68
|
+
CURSOR_LOCK.synchronize do
|
69
|
+
yield
|
70
|
+
output.flush
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def truncated(msg)
|
75
|
+
msg.length > @screen.width ? "#{msg[...@screen.width - 3]}..." : msg
|
76
|
+
end
|
77
|
+
|
78
|
+
def ui_cls
|
79
|
+
self
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/lib/xccache/core/log.rb
CHANGED
@@ -5,13 +5,13 @@ module XCCache
|
|
5
5
|
module UI
|
6
6
|
@indent = 0
|
7
7
|
|
8
|
-
|
8
|
+
module Mixin
|
9
9
|
include Config::Mixin
|
10
10
|
attr_accessor :indent
|
11
11
|
|
12
12
|
def section(title, timing: false)
|
13
13
|
start = Time.new if timing
|
14
|
-
|
14
|
+
ui_cls.puts(title)
|
15
15
|
self.indent += 2
|
16
16
|
res = yield if block_given?
|
17
17
|
self.indent -= 2
|
@@ -22,25 +22,25 @@ module XCCache
|
|
22
22
|
else
|
23
23
|
"#{duration / 3600}h"
|
24
24
|
end
|
25
|
-
|
25
|
+
ui_cls.puts("-> Finished: #{title.dark} (#{duration})")
|
26
26
|
end
|
27
27
|
res
|
28
28
|
end
|
29
29
|
|
30
30
|
def message(message)
|
31
|
-
|
31
|
+
ui_cls.puts(message) if config.verbose?
|
32
32
|
end
|
33
33
|
|
34
34
|
def info(message)
|
35
|
-
|
35
|
+
ui_cls.puts(message)
|
36
36
|
end
|
37
37
|
|
38
38
|
def warn(message)
|
39
|
-
|
39
|
+
ui_cls.puts(message.yellow)
|
40
40
|
end
|
41
41
|
|
42
42
|
def error(message)
|
43
|
-
|
43
|
+
ui_cls.puts("[ERROR] #{message}".red)
|
44
44
|
end
|
45
45
|
|
46
46
|
def error!(message)
|
@@ -51,6 +51,16 @@ module XCCache
|
|
51
51
|
def puts(message)
|
52
52
|
$stdout.puts("#{' ' * self.indent}#{message}")
|
53
53
|
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def ui_cls
|
58
|
+
UI
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class << self
|
63
|
+
include Mixin
|
54
64
|
end
|
55
65
|
end
|
56
66
|
end
|
data/lib/xccache/core/sh.rb
CHANGED
@@ -17,14 +17,25 @@ module XCCache
|
|
17
17
|
|
18
18
|
def run(*args, env: nil, **options)
|
19
19
|
cmd = args.join(" ")
|
20
|
-
UI.message("$ #{cmd}".cyan.dark) if config.verbose? && options[:log_cmd] != false
|
21
|
-
return system(cmd) || (raise GeneralError, "Command '#{cmd}' failed") unless options[:capture]
|
22
20
|
|
23
21
|
out, err = [], []
|
22
|
+
handle_out = options[:handle_out] || proc { |l| out << l }
|
23
|
+
handle_err = options[:handle_err] || proc { |l| err << l }
|
24
|
+
if (live_log = options[:live_log])
|
25
|
+
handle_out = proc { |l| live_log.puts(l) }
|
26
|
+
handle_err = proc { |l| live_log.puts(l) }
|
27
|
+
live_log.puts("$ #{cmd}") if options[:log_cmd] != false
|
28
|
+
elsif options[:log_cmd] != false
|
29
|
+
UI.message("$ #{cmd}".cyan.dark)
|
30
|
+
end
|
31
|
+
|
32
|
+
use_popen = options[:capture] || options[:handle_out] || options[:handle_err] || options[:live_log]
|
33
|
+
return system(cmd) || (raise GeneralError, "Command '#{cmd}' failed") unless use_popen
|
34
|
+
|
24
35
|
popen3_args = env ? [env, cmd] : [cmd]
|
25
36
|
Open3.popen3(*popen3_args) do |_stdin, stdout, stderr, wait_thr|
|
26
|
-
stdout_thread = Thread.new { stdout.each { |l|
|
27
|
-
stderr_thread = Thread.new { stderr.each { |l|
|
37
|
+
stdout_thread = Thread.new { stdout.each { |l| handle_out.call(l.strip) } }
|
38
|
+
stderr_thread = Thread.new { stderr.each { |l| handle_err.call(l.strip) } }
|
28
39
|
[stdout_thread, stderr_thread].each(&:join)
|
29
40
|
result = wait_thr.value
|
30
41
|
result.exitstatus
|
@@ -32,6 +43,13 @@ module XCCache
|
|
32
43
|
end
|
33
44
|
[out.join("\n"), err.join("\n")]
|
34
45
|
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def log_cmd(cmd, live_log: nil)
|
50
|
+
return live_log.puts("$ #{cmd}") if live_log
|
51
|
+
UI.message("$ #{cmd}".cyan.dark)
|
52
|
+
end
|
35
53
|
end
|
36
54
|
end
|
37
55
|
end
|
@@ -11,7 +11,7 @@ module XCCache
|
|
11
11
|
|
12
12
|
def gen_xcconfigs
|
13
13
|
macros_config_by_targets.each do |target, hash|
|
14
|
-
xcconfig_path = config.
|
14
|
+
xcconfig_path = config.spm_xcconfigs_dir / "#{target}.xcconfig"
|
15
15
|
UI.message("XCConfig of target #{target} at: #{xcconfig_path}")
|
16
16
|
Xcodeproj::Config.new(hash).save_as(xcconfig_path)
|
17
17
|
end
|
data/lib/xccache/installer.rb
CHANGED
@@ -17,6 +17,7 @@ module XCCache
|
|
17
17
|
|
18
18
|
def perform_install
|
19
19
|
verify_projects!
|
20
|
+
recreate_config_dirs
|
20
21
|
projects.each { |project| migrate_umbrella_to_proxy(project) }
|
21
22
|
UI.message("Using cache dir: #{config.spm_cache_dir}")
|
22
23
|
config.ensure_file!
|
@@ -106,9 +107,9 @@ module XCCache
|
|
106
107
|
end
|
107
108
|
|
108
109
|
def inject_xcconfig_to_project(project)
|
109
|
-
group = project.xccache_config_group.ensure_synced_group(name: "xcconfigs", path: config.
|
110
|
+
group = project.xccache_config_group.ensure_synced_group(name: "xcconfigs", path: config.spm_xcconfigs_dir)
|
110
111
|
project.targets.each do |target|
|
111
|
-
xcconfig_path = config.
|
112
|
+
xcconfig_path = config.spm_xcconfigs_dir / "#{target.name}.xcconfig"
|
112
113
|
target.build_configurations.each do |build_config|
|
113
114
|
if (existing = build_config.base_configuration_xcconfig)
|
114
115
|
next if existing.path == xcconfig_path
|
@@ -145,5 +146,14 @@ module XCCache
|
|
145
146
|
ref.path = "xccache/packages/proxy/Package.swift"
|
146
147
|
end
|
147
148
|
end
|
149
|
+
|
150
|
+
def recreate_config_dirs
|
151
|
+
[
|
152
|
+
config.spm_binaries_dir,
|
153
|
+
config.spm_local_pkgs_dir,
|
154
|
+
config.spm_xcconfigs_dir,
|
155
|
+
config.spm_metadata_dir,
|
156
|
+
].each { |p| Dir.prepare(p, clean: true) }
|
157
|
+
end
|
148
158
|
end
|
149
159
|
end
|
data/lib/xccache/spm/build.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
module XCCache
|
2
2
|
module SPM
|
3
3
|
class Buildable
|
4
|
-
attr_reader :name, :module_name, :pkg_dir, :pkg_desc, :sdk, :sdks, :config, :path, :tmpdir, :library_evolution
|
4
|
+
attr_reader :name, :module_name, :pkg_dir, :pkg_desc, :sdk, :sdks, :config, :path, :tmpdir, :library_evolution,
|
5
|
+
:live_log
|
5
6
|
alias library_evolution? library_evolution
|
6
7
|
|
7
8
|
def initialize(options = {})
|
@@ -9,12 +10,15 @@ module XCCache
|
|
9
10
|
@module_name = @name.c99extidentifier
|
10
11
|
@pkg_dir = Pathname(options[:pkg_dir] || ".").expand_path
|
11
12
|
@pkg_desc = options[:pkg_desc]
|
13
|
+
@ctx_desc = options[:ctx_desc] # Context desc, could be an umbrella or a standalone pkg
|
12
14
|
@sdks = options[:sdks] || []
|
13
15
|
@sdk = options[:sdk] || @sdks&.first
|
14
16
|
@config = options[:config] || "debug"
|
15
17
|
@path = options[:path]
|
16
18
|
@tmpdir = options[:tmpdir]
|
17
19
|
@library_evolution = options[:library_evolution]
|
20
|
+
@sdks.each { |sdk| sdk.version = @ctx_desc.platforms[sdk.platform] } if @ctx_desc
|
21
|
+
@live_log = options[:live_log]
|
18
22
|
end
|
19
23
|
|
20
24
|
def build(options = {})
|
@@ -35,13 +39,17 @@ module XCCache
|
|
35
39
|
cmd << "-Xswiftc" << "-emit-module-interface"
|
36
40
|
cmd << "-Xswiftc" << "-no-verify-emitted-module-interface"
|
37
41
|
end
|
38
|
-
|
42
|
+
sh(cmd)
|
43
|
+
end
|
44
|
+
|
45
|
+
def sh(cmd)
|
46
|
+
Sh.run(cmd, live_log: live_log)
|
39
47
|
end
|
40
48
|
|
41
49
|
def swift_build_args
|
42
50
|
[
|
43
51
|
"--configuration", config,
|
44
|
-
"--triple", sdk.triple,
|
52
|
+
"--triple", sdk.triple(with_version: true),
|
45
53
|
]
|
46
54
|
end
|
47
55
|
|
@@ -19,6 +19,10 @@ module XCCache
|
|
19
19
|
raw["_metadata"] ||= {}
|
20
20
|
end
|
21
21
|
|
22
|
+
def platforms
|
23
|
+
@platforms ||= raw.fetch("platforms", []).to_h { |h| [h["platformName"].to_sym, h["version"]] }
|
24
|
+
end
|
25
|
+
|
22
26
|
def dependencies
|
23
27
|
@dependencies ||= fetch("dependencies", Dependency)
|
24
28
|
end
|
data/lib/xccache/spm/macro.rb
CHANGED
@@ -21,7 +21,7 @@ module XCCache
|
|
21
21
|
# -> WORKAROUND: Find the associated regular target and build it, then collect the tool binary
|
22
22
|
# ---------------------------------------------------------------------------------
|
23
23
|
associated_target = pkg_desc.targets.find { |t| t.direct_dependency_targets.include?(pkg_target) }
|
24
|
-
|
24
|
+
live_log.info(
|
25
25
|
"#{name.yellow.dark} is a macro target. " \
|
26
26
|
"Will build the associated target #{associated_target.name.dark} to get the tool binary."
|
27
27
|
)
|
@@ -30,7 +30,7 @@ module XCCache
|
|
30
30
|
raise GeneralError, "Tool binary not exist at: #{binary_path}" unless binary_path.exist?
|
31
31
|
binary_path.copy(to: path)
|
32
32
|
FileUtils.chmod("+x", path)
|
33
|
-
|
33
|
+
live_log.info("-> Macro binary: #{path}")
|
34
34
|
end
|
35
35
|
|
36
36
|
def products_dir
|
data/lib/xccache/spm/pkg/base.rb
CHANGED
@@ -22,14 +22,19 @@ module XCCache
|
|
22
22
|
|
23
23
|
def build(options = {})
|
24
24
|
validate!
|
25
|
-
targets = options.delete(:targets) || []
|
25
|
+
targets = (options.delete(:targets) || []).map { |t| t.split("/")[-1] }
|
26
26
|
raise GeneralError, "No targets were specified" if targets.empty?
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
Dir.create_tmpdir do |tmpdir|
|
29
|
+
targets.each_with_index do |t, i|
|
30
|
+
target_tmpdir = Dir.prepare(tmpdir / t)
|
31
|
+
log_dir = Dir.prepare(options[:log_dir] || target_tmpdir)
|
32
|
+
live_log = LiveLog.new(tee: log_dir / "build_#{t}.log")
|
33
|
+
live_log.capture("[#{i + 1}/#{targets.count}] Building target: #{t}") do
|
34
|
+
build_target(**options, target: t, live_log: live_log, tmpdir: target_tmpdir)
|
35
|
+
end
|
31
36
|
rescue StandardError => e
|
32
|
-
UI.error("
|
37
|
+
UI.error("Error: #{e}\n" + "For details, check out: #{live_log.tee}".yellow.bold)
|
33
38
|
raise e unless Config.instance.ignore_build_errors?
|
34
39
|
end
|
35
40
|
end
|
@@ -52,19 +57,19 @@ module XCCache
|
|
52
57
|
basename = options[:checksum] ? "#{target.name}-#{target.checksum}" : target.name
|
53
58
|
binary_path = out_dir / "#{basename}#{ext}"
|
54
59
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
60
|
+
cls = target.macro? ? Macro : XCFramework
|
61
|
+
cls.new(
|
62
|
+
name: target.name,
|
63
|
+
pkg_dir: root_dir,
|
64
|
+
config: config,
|
65
|
+
sdks: sdks,
|
66
|
+
path: binary_path,
|
67
|
+
tmpdir: options[:tmpdir],
|
68
|
+
pkg_desc: target_pkg_desc,
|
69
|
+
ctx_desc: pkg_desc || target_pkg_desc,
|
70
|
+
library_evolution: options[:library_evolution],
|
71
|
+
live_log: options[:live_log],
|
72
|
+
).build(**options)
|
68
73
|
return if (symlinks_dir = options[:symlinks_dir]).nil?
|
69
74
|
binary_path.symlink_to(symlinks_dir / target.name / "#{target.name}#{ext}")
|
70
75
|
end
|
@@ -75,6 +80,10 @@ module XCCache
|
|
75
80
|
@resolved = true
|
76
81
|
end
|
77
82
|
|
83
|
+
def pkg_desc
|
84
|
+
descs_by_name[root_dir.basename.to_s]
|
85
|
+
end
|
86
|
+
|
78
87
|
def pkg_desc_of_target(name, **options)
|
79
88
|
resolve
|
80
89
|
desc = descs.find { |d| d.has_target?(name) }
|
@@ -30,7 +30,7 @@ module XCCache
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def invalidate_cache(sdks: [])
|
33
|
-
UI.message("Invalidating cache (sdks: #{sdks.map(&:
|
33
|
+
UI.message("Invalidating cache (sdks: #{sdks.map(&:to_s).join(', ')})")
|
34
34
|
|
35
35
|
config.spm_cache_dir.glob("*/*.{xcframework,macro}").each do |p|
|
36
36
|
cmps = p.basename(".*").to_s.split("-")
|
@@ -45,7 +45,7 @@ module XCCache
|
|
45
45
|
|
46
46
|
# For regular targets, the xcframework must satisfy the sdk constraints (ie. containing all the slices)
|
47
47
|
metadata = XCFramework::Metadata.new(p / "Info.plist")
|
48
|
-
expected_triples = sdks.map { |sdk| sdk.triple(
|
48
|
+
expected_triples = sdks.map { |sdk| sdk.triple(with_vendor: false) }
|
49
49
|
missing_triples = expected_triples - metadata.triples
|
50
50
|
missing_triples.empty? ? accept_cache.call : reject_cache.call
|
51
51
|
end
|
@@ -4,11 +4,12 @@ module XCCache
|
|
4
4
|
class Proxy < Package
|
5
5
|
class Executable
|
6
6
|
REPO_URL = "https://github.com/trinhngocthuyen/xccache-proxy".freeze
|
7
|
-
VERSION_OR_SHA = "1.0.
|
7
|
+
VERSION_OR_SHA = "1.0.0".freeze
|
8
8
|
|
9
9
|
def run(cmd)
|
10
10
|
env = { "FORCE_OUTPUT" => "console", "FORCE_COLOR" => "1" } if Config.instance.ansi?
|
11
11
|
cmd = cmd.is_a?(Array) ? [bin_path.to_s] + cmd : [bin_path.to_s, cmd]
|
12
|
+
cmd << "--verbose" if Config.instance.verbose?
|
12
13
|
Sh.run(cmd, env: env)
|
13
14
|
end
|
14
15
|
|
@@ -4,10 +4,9 @@ module XCCache
|
|
4
4
|
module SPM
|
5
5
|
class FrameworkSlice < Buildable
|
6
6
|
def build(_options = {})
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
7
|
+
live_log.puts("Building #{name}.framework (#{config}, #{sdk})".cyan, sticky: true)
|
8
|
+
swift_build
|
9
|
+
create_framework
|
11
10
|
end
|
12
11
|
|
13
12
|
private
|
@@ -21,7 +20,7 @@ module XCCache
|
|
21
20
|
# WORKAROUND:
|
22
21
|
# - Overriding resource_bundle_accessor.swift to add `Frameworks/<Target>.framework` to the search list
|
23
22
|
# - Compiling this file into an `.o` file before using `libtool` to create the framework binary
|
24
|
-
|
23
|
+
live_log.info("Override resource_bundle_accessor")
|
25
24
|
template_name = use_clang? ? "resource_bundle_accessor.m" : "resource_bundle_accessor.swift"
|
26
25
|
source_path = tmpdir / File.basename(template_name)
|
27
26
|
obj_path = products_dir / "#{module_name}.build" / "#{source_path.basename}.o"
|
@@ -33,18 +32,18 @@ module XCCache
|
|
33
32
|
if use_clang?
|
34
33
|
cmd = ["xcrun", "clang"]
|
35
34
|
cmd << "-x" << "objective-c"
|
36
|
-
cmd << "-target" << sdk.triple << "-isysroot" << sdk.sdk_path
|
35
|
+
cmd << "-target" << sdk.triple(with_version: true) << "-isysroot" << sdk.sdk_path
|
37
36
|
cmd << "-o" << obj_path.to_s
|
38
37
|
cmd << "-c" << source_path
|
39
38
|
else
|
40
39
|
cmd = ["xcrun", "swiftc"]
|
41
40
|
cmd << "-emit-library" << "-emit-object"
|
42
41
|
cmd << "-module-name" << module_name
|
43
|
-
cmd << "-target" << sdk.triple << "-sdk" << sdk.sdk_path
|
42
|
+
cmd << "-target" << sdk.triple(with_version: true) << "-sdk" << sdk.sdk_path
|
44
43
|
cmd << "-o" << obj_path.to_s
|
45
44
|
cmd << source_path
|
46
45
|
end
|
47
|
-
|
46
|
+
sh(cmd)
|
48
47
|
end
|
49
48
|
|
50
49
|
def create_framework
|
@@ -67,7 +66,7 @@ module XCCache
|
|
67
66
|
cmd = ["libtool", "-static"]
|
68
67
|
cmd << "-o" << "#{path}/#{module_name}"
|
69
68
|
cmd << "-filelist" << objlist_path.to_s
|
70
|
-
|
69
|
+
sh(cmd)
|
71
70
|
FileUtils.chmod("+x", path / module_name)
|
72
71
|
end
|
73
72
|
|
@@ -85,7 +84,7 @@ module XCCache
|
|
85
84
|
def create_modules
|
86
85
|
copy_swiftmodules unless use_clang?
|
87
86
|
|
88
|
-
|
87
|
+
live_log.info("Creating framework modulemap")
|
89
88
|
Template.new("framework.modulemap").render(
|
90
89
|
{ :module_name => module_name, :target => name },
|
91
90
|
save_to: modules_dir / "module.modulemap"
|
@@ -93,7 +92,7 @@ module XCCache
|
|
93
92
|
end
|
94
93
|
|
95
94
|
def copy_headers
|
96
|
-
|
95
|
+
live_log.info("Copying headers")
|
97
96
|
swift_header_paths = products_dir.glob("#{module_name}.build/*-Swift.h")
|
98
97
|
paths = swift_header_paths + pkg_target.header_paths
|
99
98
|
paths.each { |p| process_header(p) }
|
@@ -130,7 +129,7 @@ module XCCache
|
|
130
129
|
end
|
131
130
|
|
132
131
|
def copy_swiftmodules
|
133
|
-
|
132
|
+
live_log.info("Copying swiftmodules")
|
134
133
|
swiftmodule_dir = Dir.prepare("#{modules_dir}/#{module_name}.swiftmodule")
|
135
134
|
swiftinterfaces = products_dir.glob("#{module_name}.build/#{module_name}.swiftinterface")
|
136
135
|
to_copy = products_dir.glob("Modules/#{module_name}.*") + swiftinterfaces
|
@@ -141,7 +140,7 @@ module XCCache
|
|
141
140
|
|
142
141
|
def copy_resource_bundles
|
143
142
|
resolve_resource_symlinks
|
144
|
-
|
143
|
+
live_log.info("Copying resource bundle to framework: #{resource_bundle_product_path.basename}")
|
145
144
|
resource_bundle_product_path.copy(to_dir: path)
|
146
145
|
end
|
147
146
|
|
@@ -21,35 +21,32 @@ module XCCache
|
|
21
21
|
tmp_existing_path = tmpdir / "existing.framework"
|
22
22
|
|
23
23
|
slices.each(&:build)
|
24
|
-
|
25
|
-
create_xcframework(from: slices.map(&:path), to: tmp_new_path)
|
26
|
-
end
|
24
|
+
create_xcframework(from: slices.map(&:path), to: tmp_new_path)
|
27
25
|
|
28
26
|
path.copy(to: tmp_existing_path) if path.exist? && merge_slices
|
29
27
|
path.rmtree if path.exist?
|
30
28
|
|
31
29
|
if merge_slices && tmp_existing_path.exist?
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
create_xcframework(from: framework_paths, to: path)
|
38
|
-
end
|
30
|
+
framework_paths =
|
31
|
+
[tmp_new_path, tmp_existing_path]
|
32
|
+
.flat_map { |p| p.glob("*/*.framework") }
|
33
|
+
.uniq { |p| p.parent.basename.to_s } # uniq by id (ex. ios-arm64), preferred new ones
|
34
|
+
create_xcframework(from: framework_paths, to: path)
|
39
35
|
else
|
40
36
|
path.parent.mkpath
|
41
37
|
tmp_new_path.copy(to: path)
|
42
38
|
end
|
43
|
-
|
39
|
+
live_log.info("-> XCFramework: #{path}")
|
44
40
|
end
|
45
41
|
|
46
42
|
def create_xcframework(options = {})
|
43
|
+
live_log.info("Creating xcframework from slices")
|
47
44
|
cmd = ["xcodebuild", "-create-xcframework"]
|
48
45
|
cmd << "-allow-internal-distribution" unless library_evolution?
|
49
46
|
cmd << "-output" << options[:to]
|
50
47
|
options[:from].each { |p| cmd << "-framework" << p }
|
51
48
|
cmd << "> /dev/null" # Only care about errors
|
52
|
-
|
49
|
+
sh(cmd)
|
53
50
|
end
|
54
51
|
end
|
55
52
|
end
|
data/lib/xccache/swift/sdk.rb
CHANGED
@@ -3,38 +3,45 @@ require "xccache/core/sh"
|
|
3
3
|
module XCCache
|
4
4
|
module Swift
|
5
5
|
class Sdk
|
6
|
-
attr_reader :name
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
15
|
-
:
|
16
|
-
:
|
17
|
-
:
|
6
|
+
attr_reader :name, :arch, :vendor, :platform
|
7
|
+
attr_accessor :version
|
8
|
+
|
9
|
+
NAME_TO_PLATFORM = {
|
10
|
+
:iphonesimulator => :ios,
|
11
|
+
:iphoneos => :ios,
|
12
|
+
:macos => :macos,
|
13
|
+
:watchos => :watchos,
|
14
|
+
:watchsimulator => :watchos,
|
15
|
+
:appletvos => :tvos,
|
16
|
+
:appletvsimulator => :tvos,
|
17
|
+
:xros => :xros,
|
18
|
+
:xrsimulator => :xros,
|
18
19
|
}.freeze
|
19
20
|
|
20
|
-
def initialize(name)
|
21
|
-
@name = name
|
22
|
-
|
23
|
-
|
21
|
+
def initialize(name, version: nil)
|
22
|
+
@name = name.to_sym
|
23
|
+
@vendor = "apple"
|
24
|
+
@arch = "arm64"
|
25
|
+
@platform = NAME_TO_PLATFORM.fetch(@name, @name)
|
26
|
+
@version = version
|
27
|
+
return if NAME_TO_PLATFORM.key?(@name)
|
28
|
+
raise GeneralError, "Unknown sdk: #{@name}. Must be one of #{NAME_TO_PLATFORM.keys}"
|
24
29
|
end
|
25
30
|
|
26
31
|
def to_s
|
27
|
-
name
|
32
|
+
name.to_s
|
28
33
|
end
|
29
34
|
|
30
|
-
def triple(
|
31
|
-
|
32
|
-
|
33
|
-
|
35
|
+
def triple(with_vendor: true, with_version: false)
|
36
|
+
cmps = [arch]
|
37
|
+
cmps << vendor if with_vendor
|
38
|
+
cmps << (with_version && version ? "#{platform}#{version}" : platform.to_s)
|
39
|
+
cmps << "simulator" if simulator?
|
40
|
+
cmps.join("-")
|
34
41
|
end
|
35
42
|
|
36
43
|
def sdk_name
|
37
|
-
name ==
|
44
|
+
name == :macos ? :macosx : name
|
38
45
|
end
|
39
46
|
|
40
47
|
def sdk_path
|
@@ -56,6 +63,10 @@ module XCCache
|
|
56
63
|
"-I#{developer_usr_lib_path}",
|
57
64
|
]
|
58
65
|
end
|
66
|
+
|
67
|
+
def simulator?
|
68
|
+
name.to_s.end_with?("simulator")
|
69
|
+
end
|
59
70
|
end
|
60
71
|
end
|
61
72
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xccache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thuyen Trinh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-06-
|
11
|
+
date: 2025-06-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: claide
|
@@ -38,6 +38,34 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: tty-cursor
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: tty-screen
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
70
|
name: xcodeproj
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -91,6 +119,7 @@ files:
|
|
91
119
|
- lib/xccache/core/error.rb
|
92
120
|
- lib/xccache/core/git.rb
|
93
121
|
- lib/xccache/core/hash.rb
|
122
|
+
- lib/xccache/core/live_log.rb
|
94
123
|
- lib/xccache/core/lockfile.rb
|
95
124
|
- lib/xccache/core/log.rb
|
96
125
|
- lib/xccache/core/parallel.rb
|