Skip to content

Commit

Permalink
feat: finish adding conditional build setting support (#185)
Browse files Browse the repository at this point in the history
- Add conditional support for `headerSearchPaths`.
- Add conditional support for `unsafeFlags`.
- Refactor tests for `swiftpkg_build_files`.

Related to #153.
  • Loading branch information
cgrindel authored Jan 28, 2023
1 parent a760f38 commit d0678e6
Show file tree
Hide file tree
Showing 5 changed files with 294 additions and 229 deletions.
33 changes: 8 additions & 25 deletions swiftpkg/internal/bzl_selects.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -37,25 +37,6 @@ def _new(value, kind = None, condition = None):
value = value,
)

def _new_default(kind, value):
"""Create a condition with the condition set to Bazel's default value.
Args:
kind: A `string` that identifies the value. This comes from the SPM dump
manifest. (e.g. `linkedFramework`)
value: The value associated with the condition.
Returns:
A `struct` representing a Swift package manager condition.
"""
return _new(
kind = kind,
condition = "//conditions:default",
value = value,
)

# GH153: Finish conditional support.

def _new_from_build_setting(build_setting):
"""Create conditions from an SPM build setting.
Expand All @@ -72,12 +53,13 @@ def _new_from_build_setting(build_setting):
for v in build_setting.values
]

if bsc.platforms != None and bsc.configuration != None:
platforms_len = len(bsc.platforms)
if platforms_len > 0 and bsc.configuration != None:
conditions = [
spm_platform_configurations.label(p, bsc.configuration)
for p in bsc.platforms
]
elif bsc.platforms != None:
elif platforms_len > 0:
conditions = [spm_platforms.label(p) for p in bsc.platforms]
elif bsc.configuration != None:
conditions = [spm_configurations.label(bsc.configuration)]
Expand All @@ -92,21 +74,23 @@ Found a build setting condition that had no platforms or a configuration. {}\
for c in conditions
]

def _new_kind_handler(transform, default = None):
def _new_kind_handler(transform = None, default = []):
"""Creates a struct that encapsulates the information needed to process a \
condition.
Args:
transform: A `function` that accepts a single value. The value for a
transform: Optional. A `function` that accepts a single value. The value for a
condition is passed this function. The return value is used as the
Starlark output.
default: Optional. The value that should be added to the `select` dict
for the kind.
for the kind. Defaults to `[]`.
Returns:
A `struct` representing the information needed to process and kind
condition.
"""
if transform == None:
transform = lambda v: v
return struct(
transform = transform,
default = default,
Expand Down Expand Up @@ -176,7 +160,6 @@ def _to_starlark(values, kind_handlers = {}):
bzl_selects = struct(
new_kind_handler = _new_kind_handler,
new = _new,
new_default = _new_default,
new_from_build_setting = _new_from_build_setting,
to_starlark = _to_starlark,
default_condition = _bazel_select_default_condition,
Expand Down
54 changes: 37 additions & 17 deletions swiftpkg/internal/pkginfos.bzl
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""API for creating and loading Swift package information."""

load("@cgrindel_bazel_starlib//bzllib:defs.bzl", "lists")
load(
"//config_settings/spm/configuration:configurations.bzl",
spm_configurations = "configurations",
Expand Down Expand Up @@ -242,7 +243,8 @@ def _new_build_settings_from_json(dump_map):
return [
_new_build_setting(
kind = build_setting_kind,
values = kind_type_values.values(),
# Some settings (e.g. unsafeFlags) are written as a list.
values = lists.flatten(kind_type_values.values()),
condition = condition,
)
for (build_setting_kind, kind_type_values) in kind_map.items()
Expand Down Expand Up @@ -679,7 +681,7 @@ def _new_target(

# MARK: - Build Settings

def _new_build_setting_condition(platforms = None, configuration = None):
def _new_build_setting_condition(platforms = [], configuration = None):
"""Create a build setting condition.
Args:
Expand All @@ -690,15 +692,15 @@ def _new_build_setting_condition(platforms = None, configuration = None):
Returns:
A `struct` representing build setting condition.
"""
if platforms == None and configuration == None:
if platforms == [] and configuration == None:
return None
if platforms != None:
for platform in platforms:
validations.in_list(
spm_platforms.all_values,
platform,
"Unrecognized platform. platform:",
)

for platform in platforms:
validations.in_list(
spm_platforms.all_values,
platform,
"Unrecognized platform. platform:",
)

if configuration != None:
validations.in_list(
Expand Down Expand Up @@ -742,19 +744,25 @@ def _new_clang_settings(build_settings):
"""
defines = []
hdr_srch_paths = []
unsafe_flags = []
for bs in build_settings:
if bs.kind == "define":
if bs.kind == build_setting_kinds.define:
defines.append(bs)
elif bs.kind == "headerSearchPath":
elif bs.kind == build_setting_kinds.header_search_path:
hdr_srch_paths.append(bs)
elif bs.kind == build_setting_kinds.unsafe_flags:
unsafe_flags.append(bs)
else:
# We do not recognize the setting.
pass
if len(defines) == 0 and len(hdr_srch_paths) == 0:
if len(defines) == 0 and \
len(hdr_srch_paths) == 0 and \
len(unsafe_flags) == 0:
return None
return struct(
defines = defines,
hdr_srch_paths = hdr_srch_paths,
unsafe_flags = unsafe_flags,
)

def _new_swift_settings(build_settings):
Expand All @@ -768,16 +776,20 @@ def _new_swift_settings(build_settings):
A `struct` representing the Swift settings.
"""
defines = []
unsafe_flags = []
for bs in build_settings:
if bs.kind == "define":
if bs.kind == build_setting_kinds.define:
defines.append(bs)
elif bs.kind == build_setting_kinds.unsafe_flags:
unsafe_flags.append(bs)
else:
# We do not recognize the setting.
pass
if len(defines) == 0:
if len(defines) == 0 and len(unsafe_flags) == 0:
return None
return struct(
defines = defines,
unsafe_flags = unsafe_flags,
)

def _new_linker_settings(build_settings):
Expand All @@ -793,9 +805,9 @@ def _new_linker_settings(build_settings):
linked_libraries = []
linked_frameworks = []
for bs in build_settings:
if bs.kind == "linkedLibrary":
if bs.kind == build_setting_kinds.linked_library:
linked_libraries.append(bs)
elif bs.kind == "linkedFramework":
elif bs.kind == build_setting_kinds.linked_framework:
linked_frameworks.append(bs)
else:
# We do not recognize the setting.
Expand Down Expand Up @@ -858,6 +870,14 @@ library_type_kinds = struct(
all_values = ["automatic", "dynamic", "static"],
)

build_setting_kinds = struct(
define = "define",
header_search_path = "headerSearchPath",
linked_framework = "linkedFramework",
linked_library = "linkedLibrary",
unsafe_flags = "unsafeFlags",
)

# MARK: - API Definition

pkginfos = struct(
Expand Down
Loading

0 comments on commit d0678e6

Please sign in to comment.