Skip to content

Commit

Permalink
Fix env variables and cc_copts for some pods (#122)
Browse files Browse the repository at this point in the history
  • Loading branch information
sergeykhliustin authored Mar 5, 2024
1 parent 1227822 commit 9aa89b6
Show file tree
Hide file tree
Showing 17 changed files with 149 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ struct BuildSettingsAnalyzer<S: XCConfigRepresentable> {
struct Result {
let swiftCopts: [String]
let objcCopts: [String]
let ccCopts: [String]
let linkOpts: [String]
let objcDefines: [String]
let xcconfig: [String: StarlarkNode]
Expand Down Expand Up @@ -46,6 +47,7 @@ struct BuildSettingsAnalyzer<S: XCConfigRepresentable> {
return Result(
swiftCopts: parser.swiftCopts,
objcCopts: parser.objcCopts,
ccCopts: parser.ccCopts,
linkOpts: parser.linkOpts,
objcDefines: parser.objcDefines,
xcconfig: parser.xcconfig
Expand Down
3 changes: 3 additions & 0 deletions Sources/BazelPodsCore/Targets/AppleFramework.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ struct AppleFramework: BazelTarget {

let objcCopts: [String]
let swiftCopts: [String]
let ccCopts: [String]
let linkOpts: [String]

var linkDynamic: Bool
Expand Down Expand Up @@ -65,6 +66,7 @@ struct AppleFramework: BazelTarget {
self.xcconfig = buildSettings.xcconfig
self.objcCopts = buildSettings.objcCopts
self.swiftCopts = buildSettings.swiftCopts
self.ccCopts = buildSettings.ccCopts
self.linkOpts = buildSettings.linkOpts

self.testonly = sdkDeps.testonly
Expand Down Expand Up @@ -125,6 +127,7 @@ struct AppleFramework: BazelTarget {
.named(name: "weak_sdk_frameworks", value: weakSdkFrameworks.toStarlark()),
.named(name: "objc_copts", value: objcCopts.toStarlark()),
.named(name: "swift_copts", value: swiftCopts.toStarlark()),
.named(name: "cc_copts", value: ccCopts.toStarlark()),
.named(name: "linkopts", value: linkOpts.toStarlark()),
.named(name: "xcconfig", value: xcconfig.toStarlark()),
.named(name: "visibility", value: ["//visibility:public"].toStarlark())
Expand Down
61 changes: 60 additions & 1 deletion Sources/BazelPodsCore/XCConfig/XCConfigParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@ final class XCConfigParser {
private(set) var objcCopts: [String] = []
private(set) var linkOpts: [String] = []
private(set) var objcDefines: [String] = []
private(set) var ccCopts: [String] = []
private let transformers: [String: XCConfigSettingTransformer]
private let options: BuildOptions
private static let defaultTransformers: [XCConfigSettingTransformer] = [
HeaderSearchPathTransformer(),
UserHeaderSearchPathTransformer(),
ApplicationExtensionAPIOnlyTransformer(),
CLANG_CXX_LANGUAGE_STANDARD_Transformer(),
LinkOptsListTransformer("OTHER_LDFLAGS"),
ObjCOptsListTransformer("OTHER_CFLAGS"),
ObjCOptsListTransformer("OTHER_CPLUSPLUSFLAGS"),
Expand All @@ -35,13 +39,16 @@ final class XCConfigParser {
init(_ config: [String: String],
options: BuildOptions,
transformers: [XCConfigSettingTransformer] = defaultTransformers) {
self.options = options

self.transformers = transformers.reduce([String: XCConfigSettingTransformer](), { result, transformer in
var result = result
result[transformer.key] = transformer
return result
})

let config = replaceEnvVars(in: config)

for key in config.keys.sorted() {
guard !XCSpecs.forceIgnore.contains(key) else { continue }
let node: StarlarkNode?
Expand All @@ -59,7 +66,7 @@ final class XCConfigParser {
node = nil
}
var handled = false
if let node = node {
if let node = node, !XCSpecs.xcconfigIgnore.contains(key) {
xcconfig[key] = node
handled = true
}
Expand All @@ -68,11 +75,63 @@ final class XCConfigParser {
objcCopts += (transformer as? ObjcCoptsProvider)?.objcCopts(value) ?? []
linkOpts += (transformer as? LinkOptsProvider)?.linkOpts(value) ?? []
objcDefines += (transformer as? ObjcDefinesProvider)?.objcDefines(value) ?? []
ccCopts += (transformer as? CCCOptsProvider)?.cccOpts(value) ?? []
handled = true
}
if !handled {
log_debug("unhandled xcconfig \(key)")
}
}
}

private func replaceEnvVars(in config: [String: String]) -> [String: String] {
var config = config.mapValues({
replacePodsEnvVars($0, options: options, absolutePath: false)
})
while config.contains(where: { !$0.value.envVariables.isEmpty }) {
config = config.reduce(into: config, { result, value in
let key = value.key
var value = value.value
let envVars = value.envVariables
for envKey in envVars {
if let envValue = result[envKey] {
value = value.replacingOccurrences(of: "$(\(envKey))", with: envValue)
value = value.replacingOccurrences(of: "${\(envKey)}", with: envValue)
} else {
value = value.replacingOccurrences(of: "$(\(envKey))", with: "")
value = value.replacingOccurrences(of: "${\(envKey)}", with: "")
}
}
result[key] = value
})
}
return config
}
}

private extension String {
static let ignore = [
"SDKROOT"
]
var envVariables: [String] {
var result = [String]()
let pattern = #"\$\(([^$)]+)\)|\$\{([^$}]+)\}"#
do {
let regex = try NSRegularExpression(pattern: pattern)
let matches = regex.matches(in: self, range: NSRange(self.startIndex..., in: self))

for match in matches {
let nsRange = match.range(at: 1)
if let range = Range(nsRange, in: self) {
let innerVarName = String(self[range])
if !Self.ignore.contains(innerVarName) {
result.append(innerVarName)
}
}
}
} catch {
log_debug("Error extracting env variables: \(error)")
}
return result
}
}
32 changes: 32 additions & 0 deletions Sources/BazelPodsCore/XCConfig/XCConfigSettingTransformer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ protocol ObjcDefinesProvider {
func objcDefines(_ value: String) -> [String]
}

protocol CCCOptsProvider {
func cccOpts(_ value: String) -> [String]
}

struct HeaderSearchPathTransformer: XCConfigSettingTransformer,
SwiftCoptsProvider,
ObjcCoptsProvider {
Expand All @@ -47,6 +51,26 @@ struct HeaderSearchPathTransformer: XCConfigSettingTransformer,
}
}

struct UserHeaderSearchPathTransformer: XCConfigSettingTransformer,
SwiftCoptsProvider,
ObjcCoptsProvider {
let key = "USER_HEADER_SEARCH_PATHS"

func swiftCopts(_ value: String) -> [String] {
return xcconfigSettingToList(value)
.reduce([String]()) { partialResult, path in
return partialResult + [
"-Xcc", "-I\(path.replacingOccurrences(of: "\"", with: ""))"
]
}
}

func objcCopts(_ value: String) -> [String] {
return xcconfigSettingToList(value)
.map({ "-I\($0.replacingOccurrences(of: "\"", with: ""))" })
}
}

struct ApplicationExtensionAPIOnlyTransformer: XCConfigSettingTransformer,
SwiftCoptsProvider,
ObjcCoptsProvider {
Expand Down Expand Up @@ -108,3 +132,11 @@ struct ObjcDefinesListTransformer: XCConfigSettingTransformer,
return xcconfigSettingToList(value)
}
}

struct CLANG_CXX_LANGUAGE_STANDARD_Transformer: XCConfigSettingTransformer, CCCOptsProvider {
let key = "CLANG_CXX_LANGUAGE_STANDARD"

func cccOpts(_ value: String) -> [String] {
return ["-std=\(value)"]
}
}
4 changes: 4 additions & 0 deletions Sources/BazelPodsCore/XCConfig/XCSpecs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ struct XCSpecs {
"GCC_C_LANGUAGE_STANDARD"
]

static let xcconfigIgnore: [String] = [
"CLANG_CXX_LANGUAGE_STANDARD"
]

// com.apple.compilers.llvm.clang.1_0
static let clang: [XElement] = [
("CLANG_ADDRESS_SANITIZER", .boolean),
Expand Down
6 changes: 3 additions & 3 deletions Tests/Recorded/FLEX/BUILD.bazel

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Tests/Recorded/LibTorch/BUILD.bazel

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Tests/Recorded/MMKV/BUILD.bazel

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Tests/Recorded/MMKVAppExtension/BUILD.bazel

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Tests/Recorded/MMKVCore/BUILD.bazel

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 11 additions & 4 deletions Tests/Recorded/Realm/BUILD.bazel

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions Tests/Recorded/RealmSwift/BUILD.bazel

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Tests/Recorded/Sentry/BUILD.bazel

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Tests/Recorded/WCDB/BUILD.bazel

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions Tests/Recorded/libwebp/BUILD.bazel

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Tests/Recorded/libzstd/BUILD.bazel

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Tests/Recorded/zxing-cpp/BUILD.bazel

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 9aa89b6

Please sign in to comment.