Skip to content

Commit e487073

Browse files
Add support for compiler_flags and ability to override objc_copts, swift_copts, cc_copts and linkopts via user options (#149)
1 parent 954633e commit e487073

File tree

20 files changed

+182
-89
lines changed

20 files changed

+182
-89
lines changed

Makefile

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,9 @@ integration-generate-static:
105105
--patches bundle_deduplicate arm64_to_sim_forced missing_sdks \
106106
-a -d \
107107
--color yes \
108-
--log-level debug
108+
--log-level debug \
109+
--user-options \
110+
"MMKVCore.cc_copts += -fno-objc-arc"
109111

110112
integration-generate-dynamic:
111113
bazel run :bazelpods $(CONFIG) -- \
@@ -117,7 +119,9 @@ integration-generate-dynamic:
117119
--color yes \
118120
--log-level debug \
119121
--patches bundle_deduplicate arm64_to_sim_forced missing_sdks user_options \
120-
--user-options "CocoaLumberjack.platform_ios.sdk_frameworks += CoreGraphics"
122+
--user-options \
123+
"CocoaLumberjack.platform_ios.sdk_frameworks += CoreGraphics" \
124+
"MMKVCore.cc_copts += -fno-objc-arc"
121125

122126
integration-build-x86_64:
123127
bazel build $(CONFIG) //IntegrationTests:TestApp_iOS --ios_multi_cpus=x86_64

README.md

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,11 @@ OPTIONS:
9696
--patches <patches> Patches. It will be applied in the order listed here.
9797
Available options: bundle_deduplicate, arm64_to_sim, arm64_to_sim_forced, missing_sdks, user_options.
9898
user_options requires --user-options configured.
99-
If 'user_options' not specified, but --user_options exist, user_options patch are applied automatically.
99+
If 'user_options' not specified, but --user_options exist, user_options patch are applied automatically. (values: bundle_deduplicate, arm64_to_sim, arm64_to_sim_forced, missing_sdks, user_options)
100100
--user-options <user-options>
101101
User extra options.
102-
Supported fields: 'sdk_frameworks', 'sdk_dylibs', 'weak_sdk_frameworks', 'vendored_libraries', 'vendored_frameworks', 'vendored_xcframeworks', 'testonly', 'link_dynamic', 'data', 'objc_defines', 'runner', 'test_host', 'timeout'.
102+
Supported fields: 'sdk_frameworks', 'sdk_dylibs', 'weak_sdk_frameworks', 'vendored_libraries', 'vendored_frameworks', 'vendored_xcframeworks', 'testonly', 'link_dynamic', 'data', 'objc_defines', 'runner', 'test_host', 'timeout',
103+
'objc_copts', 'swift_copts', 'cc_copts', 'linkopts'.
103104
Supported operators: '+=' (append), '-=' (delete), ':=' (replace).
104105
Example:
105106
'SomePod.sdk_dylibs += something,something'
@@ -115,10 +116,10 @@ OPTIONS:
115116
--pods-root <pods-root> Pods root relative to workspace. Used for headers search paths (default: Pods)
116117
-f, --frameworks Packaging pods in dynamic frameworks if possible (same as `use_frameworks!`)
117118
--no-concurrency Disable concurrency.
118-
--log-level <log-level> Log level (debug|info|warning|error|none) (default: info)
119+
--log-level <log-level> Log level (debug|info|warning|error|none) (values: debug, info, warning, error, none; default: info)
119120
--use-bundler Option to use `bundle exec` for `pod` calls
120121
--tests-timeout <tests-timeout>
121-
(Optional) Default timeout for test targets (short|moderate|long|eternal)
122+
(Optional) Default timeout for test targets (short|moderate|long|eternal) (values: short, moderate, long, eternal)
122123
--pods-json <pods-json> Pods.json (default: Pods/Pods.json)
123124
--print-output Print BUILD files contents to terminal output
124125
--dry-run Dry run. Files will not be written
@@ -141,10 +142,11 @@ OPTIONS:
141142
--patches <patches> Patches. It will be applied in the order listed here.
142143
Available options: bundle_deduplicate, arm64_to_sim, arm64_to_sim_forced, missing_sdks, user_options.
143144
user_options requires --user-options configured.
144-
If 'user_options' not specified, but --user_options exist, user_options patch are applied automatically.
145+
If 'user_options' not specified, but --user_options exist, user_options patch are applied automatically. (values: bundle_deduplicate, arm64_to_sim, arm64_to_sim_forced, missing_sdks, user_options)
145146
--user-options <user-options>
146147
User extra options.
147-
Supported fields: 'sdk_frameworks', 'sdk_dylibs', 'weak_sdk_frameworks', 'vendored_libraries', 'vendored_frameworks', 'vendored_xcframeworks', 'testonly', 'link_dynamic', 'data', 'objc_defines', 'runner', 'test_host', 'timeout'.
148+
Supported fields: 'sdk_frameworks', 'sdk_dylibs', 'weak_sdk_frameworks', 'vendored_libraries', 'vendored_frameworks', 'vendored_xcframeworks', 'testonly', 'link_dynamic', 'data', 'objc_defines', 'runner', 'test_host', 'timeout',
149+
'objc_copts', 'swift_copts', 'cc_copts', 'linkopts'.
148150
Supported operators: '+=' (append), '-=' (delete), ':=' (replace).
149151
Example:
150152
'SomePod.sdk_dylibs += something,something'
@@ -160,10 +162,10 @@ OPTIONS:
160162
--pods-root <pods-root> Pods root relative to workspace. Used for headers search paths (default: Pods)
161163
-f, --frameworks Packaging pods in dynamic frameworks if possible (same as `use_frameworks!`)
162164
--no-concurrency Disable concurrency.
163-
--log-level <log-level> Log level (debug|info|warning|error|none) (default: info)
165+
--log-level <log-level> Log level (debug|info|warning|error|none) (values: debug, info, warning, error, none; default: info)
164166
--use-bundler Option to use `bundle exec` for `pod` calls
165167
--tests-timeout <tests-timeout>
166-
(Optional) Default timeout for test targets (short|moderate|long|eternal)
168+
(Optional) Default timeout for test targets (short|moderate|long|eternal) (values: short, moderate, long, eternal)
167169
--podspec <podspec> podspec.json
168170
--subspecs <subspecs> Subspecs list
169171
-h, --help Show help information.

Sources/BazelPodsCore/Analyzer/Analyzers/BuildSettingsAnalyzer.swift

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,7 @@ struct BuildSettingsAnalyzer<S: XCConfigRepresentable> {
3636
}
3737

3838
private func run() -> Result {
39-
let xcconfig = spec.collectAttribute(with: subspecs, keyPath: \.xcconfig).platform(platform) ?? [:]
40-
let podTargetXcconfig = spec.collectAttribute(with: subspecs, keyPath: \.podTargetXcconfig).platform(platform) ?? [:]
41-
let userTargetXcconfig = spec.collectAttribute(with: subspecs, keyPath: \.userTargetXcconfig).platform(platform) ?? [:]
42-
let mergedConfig = xcconfig
43-
.merging(podTargetXcconfig, uniquingKeysWith: { $1 })
44-
.merging(userTargetXcconfig, uniquingKeysWith: { $1 })
45-
let parser = XCConfigParser(mergedConfig, options: options)
39+
let parser = XCConfigParser(spec: spec, subspecs: subspecs, platform: platform, options: options)
4640

4741
return Result(
4842
swiftCopts: parser.swiftCopts,

Sources/BazelPodsCore/Core/UserOption.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ public struct UserOption {
5858
case runner(String)
5959
case test_host(String)
6060
case timeout(TestsTimeout)
61+
case objc_copts([String])
62+
case swift_copts([String])
63+
case cc_copts([String])
64+
case linkopts([String])
6165
}
6266
public enum KeyPath: String, CaseIterable {
6367
case sdk_frameworks
@@ -73,6 +77,10 @@ public struct UserOption {
7377
case runner
7478
case test_host
7579
case timeout
80+
case objc_copts
81+
case swift_copts
82+
case cc_copts
83+
case linkopts
7684
}
7785

7886
public init?(_ string: String) {
@@ -216,11 +224,20 @@ public struct UserOption {
216224
let timeout = TestsTimeout(rawValue: last)
217225
else {
218226
log_error(
227+
// swiftlint:disable:next line_length
219228
"Incorrect value for \(string). Should be one of \(TestsTimeout.allCases.map({ $0.rawValue }).joined(separator: ", "))). Skipping..."
220229
)
221230
return nil
222231
}
223232
attribute = .timeout(timeout)
233+
case .objc_copts:
234+
attribute = .objc_copts(value)
235+
case .swift_copts:
236+
attribute = .swift_copts(value)
237+
case .cc_copts:
238+
attribute = .cc_copts(value)
239+
case .linkopts:
240+
attribute = .linkopts(value)
224241
}
225242
self.name = name
226243
self.opt = opt

Sources/BazelPodsCore/Models/Specs/AppSpec.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public final class AppSpec: AppSpecRepresentable {
3838
let xcconfig: [String: String]
3939
let podTargetXcconfig: [String: String]
4040
let userTargetXcconfig: [String: String]
41+
let compilerFlags: [String]
4142

4243
let vendoredLibraries: [String]
4344
let vendoredFrameworks: [String]
@@ -70,6 +71,7 @@ public final class AppSpec: AppSpecRepresentable {
7071
xcconfig = Self.xcconfig(json: json)
7172
podTargetXcconfig = Self.podTargetXcconfig(json: json)
7273
userTargetXcconfig = Self.userTargetXcconfig(json: json)
74+
compilerFlags = Self.compilerFlags(json: json)
7375
vendoredLibraries = Self.vendoredLibraries(json: json)
7476
vendoredFrameworks = Self.vendoredFrameworks(json: json)
7577
infoPlist = Self.infoPlist(json: json)

Sources/BazelPodsCore/Models/Specs/PodSpec.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ enum PodSpecField: String {
9898
case prefixHeaderFile = "prefix_header_file"
9999
case prefixHeaderContents = "prefix_header_contents"
100100
case preservePaths = "preserve_paths"
101-
case compilerFlags = "compiler_flags"
102101
case subspecs
103102
case source
104103
case license
@@ -145,9 +144,9 @@ public final class PodSpec: PodSpecRepresentable {
145144
let podTargetXcconfig: [String: String]
146145
let userTargetXcconfig: [String: String]
147146
let xcconfig: [String: String]
147+
let compilerFlags: [String]
148148

149149
let subspecs: [PodSpec]
150-
let compilerFlags: [String]
151150
let source: PodSpecSource?
152151
let license: PodSpecLicense
153152
let defaultSubspecs: [String]
@@ -221,6 +220,7 @@ public final class PodSpec: PodSpecRepresentable {
221220
xcconfig = Self.xcconfig(json: json)
222221
podTargetXcconfig = Self.podTargetXcconfig(json: json)
223222
userTargetXcconfig = Self.userTargetXcconfig(json: json)
223+
compilerFlags = Self.compilerFlags(json: json)
224224

225225
// VendoredDependenciesRepresentable
226226
vendoredLibraries = Self.vendoredLibraries(json: json)
@@ -235,7 +235,6 @@ public final class PodSpec: PodSpecRepresentable {
235235
prefixHeaderContents = fieldMap[.prefixHeaderContents] as? String
236236

237237
preservePaths = strings(fromJSON: fieldMap[.preservePaths])
238-
compilerFlags = strings(fromJSON: fieldMap[.compilerFlags])
239238

240239
defaultSubspecs = strings(fromJSON: fieldMap[.defaultSubspecs])
241240

Sources/BazelPodsCore/Models/Specs/Protocols/XCConfigRepresentable.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ protocol XCConfigRepresentable: BaseRepresentable {
1111
var podTargetXcconfig: [String: String] { get }
1212
var userTargetXcconfig: [String: String] { get }
1313
var xcconfig: [String: String] { get }
14+
var compilerFlags: [String] { get }
1415
}
1516

1617
extension XCConfigRepresentable {
@@ -23,6 +24,7 @@ private enum Keys: String {
2324
case pod_target_xcconfig
2425
case user_target_xcconfig
2526
case xcconfig
27+
case compiler_flags
2628
}
2729

2830
extension XCConfigRepresentable {
@@ -37,4 +39,9 @@ extension XCConfigRepresentable {
3739
static func xcconfig(json: JSONDict) -> [String: String] {
3840
return extractValue(fromJSON: json[Keys.xcconfig.rawValue], default: [:])
3941
}
42+
43+
static func compilerFlags(json: JSONDict) -> [String] {
44+
let stringFlags = extractValue(fromJSON: json[Keys.compiler_flags.rawValue], default: "")
45+
return stringFlags.split(separator: " ").map { String($0) }
46+
}
4047
}

Sources/BazelPodsCore/Models/Specs/TestSpec.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public final class TestSpec: TestSpecRepresentable {
4545
let xcconfig: [String: String]
4646
let podTargetXcconfig: [String: String]
4747
let userTargetXcconfig: [String: String]
48+
let compilerFlags: [String]
4849

4950
let vendoredLibraries: [String]
5051
let vendoredFrameworks: [String]
@@ -84,6 +85,7 @@ public final class TestSpec: TestSpecRepresentable {
8485
xcconfig = Self.xcconfig(json: json)
8586
podTargetXcconfig = Self.podTargetXcconfig(json: json)
8687
userTargetXcconfig = Self.userTargetXcconfig(json: json)
88+
compilerFlags = Self.compilerFlags(json: json)
8789
vendoredLibraries = Self.vendoredLibraries(json: json)
8890
vendoredFrameworks = Self.vendoredFrameworks(json: json)
8991
infoPlist = Self.infoPlist(json: json)

Sources/BazelPodsCore/Patches/UserOptionsPatch.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,42 @@ struct UserOptionsPatch: Patch, TestSpecSpecificPatch {
109109
case .timeout:
110110
// test spec specific option
111111
break
112+
case .objc_copts(let value):
113+
switch option.opt {
114+
case .append:
115+
buildSettings.objcCopts += value
116+
case .delete:
117+
buildSettings.objcCopts.removeAll(where: { value.contains($0) })
118+
case .replace:
119+
buildSettings.objcCopts = value
120+
}
121+
case .swift_copts(let value):
122+
switch option.opt {
123+
case .append:
124+
buildSettings.swiftCopts += value
125+
case .delete:
126+
buildSettings.swiftCopts.removeAll(where: { value.contains($0) })
127+
case .replace:
128+
buildSettings.swiftCopts = value
129+
}
130+
case .cc_copts(let value):
131+
switch option.opt {
132+
case .append:
133+
buildSettings.ccCopts += value
134+
case .delete:
135+
buildSettings.ccCopts.removeAll(where: { value.contains($0) })
136+
case .replace:
137+
buildSettings.ccCopts = value
138+
}
139+
case .linkopts(let value):
140+
switch option.opt {
141+
case .append:
142+
buildSettings.linkOpts += value
143+
case .delete:
144+
buildSettings.linkOpts.removeAll(where: { value.contains($0) })
145+
case .replace:
146+
buildSettings.linkOpts = value
147+
}
112148
}
113149
}
114150
}

Sources/BazelPodsCore/XCConfig/XCConfigParser.swift

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import Foundation
99

10-
final class XCConfigParser {
10+
final class XCConfigParser<S: XCConfigRepresentable> {
1111
private(set) var xcconfig: [String: StarlarkNode] = [:]
1212
private(set) var swiftCopts: [String] = []
1313
private(set) var objcCopts: [String] = []
@@ -16,7 +16,7 @@ final class XCConfigParser {
1616
private(set) var ccCopts: [String] = []
1717
private let transformers: [String: XCConfigSettingTransformer]
1818
private let options: BuildOptions
19-
private static let defaultTransformers: [XCConfigSettingTransformer] = [
19+
private let defaultTransformers: [XCConfigSettingTransformer] = [
2020
HeaderSearchPathTransformer(),
2121
UserHeaderSearchPathTransformer(),
2222
ApplicationExtensionAPIOnlyTransformer(),
@@ -27,21 +27,23 @@ final class XCConfigParser {
2727
ObjcDefinesListTransformer("GCC_PREPROCESSOR_DEFINITIONS")
2828
]
2929

30-
convenience init(spec: PodSpec, subspecs: [PodSpec] = [], options: BuildOptions) {
31-
let resolved =
32-
spec.collectAttribute(with: subspecs, keyPath: \.xcconfig) <>
33-
spec.collectAttribute(with: subspecs, keyPath: \.podTargetXcconfig) <>
34-
spec.collectAttribute(with: subspecs, keyPath: \.userTargetXcconfig)
30+
convenience init(spec: S, subspecs: [S] = [], platform: Platform, options: BuildOptions) {
31+
let xcconfig = spec.collectAttribute(with: subspecs, keyPath: \.xcconfig).platform(platform) ?? [:]
32+
let podTargetXcconfig = spec.collectAttribute(with: subspecs, keyPath: \.podTargetXcconfig).platform(platform) ?? [:]
33+
let userTargetXcconfig = spec.collectAttribute(with: subspecs, keyPath: \.userTargetXcconfig).platform(platform) ?? [:]
34+
let mergedConfig = xcconfig
35+
.merging(podTargetXcconfig, uniquingKeysWith: { $1 })
36+
.merging(userTargetXcconfig, uniquingKeysWith: { $1 })
3537

36-
self.init(resolved.multi.ios ?? [:], options: options)
38+
let compilerFlags = spec.collectAttribute(with: subspecs, keyPath: \.compilerFlags).platform(platform) ?? []
39+
40+
self.init(mergedConfig, compilerFlags: compilerFlags, options: options)
3741
}
3842

39-
init(_ config: [String: String],
40-
options: BuildOptions,
41-
transformers: [XCConfigSettingTransformer] = defaultTransformers) {
43+
private init(_ config: [String: String], compilerFlags: [String], options: BuildOptions) {
4244
self.options = options
4345

44-
self.transformers = transformers.reduce([String: XCConfigSettingTransformer](), { result, transformer in
46+
self.transformers = defaultTransformers.reduce([String: XCConfigSettingTransformer](), { result, transformer in
4547
var result = result
4648
result[transformer.key] = transformer
4749
return result
@@ -82,6 +84,13 @@ final class XCConfigParser {
8284
log_debug("unhandled xcconfig \(key)")
8385
}
8486
}
87+
88+
for flag in compilerFlags {
89+
let normalized = replacePodsEnvVars(flag, options: options, absolutePath: false)
90+
if !normalized.isEmpty {
91+
ccCopts.append(normalized)
92+
}
93+
}
8594
}
8695

8796
private func replaceEnvVars(in config: [String: String]) -> [String: String] {

TestTools/Pods.json

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -388,13 +388,10 @@
388388
"version": "3.7.6"
389389
},
390390
"MMKV": {
391-
"version": "1.3.3"
391+
"version": "1.3.5"
392392
},
393393
"MMKVAppExtension": {
394-
"version": "1.3.3"
395-
},
396-
"MMKVCore": {
397-
"version": "1.3.3"
394+
"version": "1.3.5"
398395
},
399396
"MTHawkeye": {
400397
"version": "0.12.8"

TestTools/Pods_Integration.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@
6363
"LTMorphingLabel": {
6464
"version": "0.9.3"
6565
},
66+
"MMKV": {
67+
"version": "1.3.5"
68+
},
6669
"Material": {
6770
"version": "3.1.8"
6871
},
@@ -182,6 +185,9 @@
182185
"Kingfisher": {
183186
"version": "7.6.2"
184187
},
188+
"MMKV": {
189+
"version": "1.3.5"
190+
},
185191
"Moya": {
186192
"version": "15.0.0"
187193
},

Tests/Recorded/KSCrash/BUILD.bazel

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)