Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow headers in test bundles /apps to be imported the same as in Xcode #18

Merged
merged 12 commits into from
Feb 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .bazelversion
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2.1.0
11 changes: 8 additions & 3 deletions .github/workflows/PR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,15 @@ jobs:
- name: Select Xcode 11.2
run: sudo xcode-select -s /Applications/Xcode_11.2.app
- name: Install Bazel
run: brew install bazel buildifier
run: brew install bazelisk buildifier
- name: Build and Test
run: bazel test //...
run: bazelisk test --local_test_jobs=2 //...
- uses: actions/upload-artifact@v1
if: failure()
with:
name: bazel-testlogs
path: bazel-testlogs
- name: buildifier
run: find . -type f \( -name 'WORKSPACE' -o -name '*.bzl' -o -name '*.bazel' \) | xargs buildifier --mode=diff
- name: Check docs
run: bazel run docs --nocheck_visibility && git diff --exit-code docs
run: bazelisk run docs --nocheck_visibility && git diff --exit-code docs
4 changes: 2 additions & 2 deletions .github/workflows/master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ jobs:
- name: Select Xcode 11.2
run: sudo xcode-select -s /Applications/Xcode_11.2.app
- name: Install Bazel
run: brew install bazel
run: brew install bazelisk
- name: Build and Test
run: bazel test //...
run: bazelisk test --local_test_jobs=2 //...
3 changes: 2 additions & 1 deletion docs/library_doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Propagates private headers, so they can be accessed if necessary
## apple_library

<pre>
apple_library(<a href="#apple_library-name">name</a>, <a href="#apple_library-library_tools">library_tools</a>, <a href="#apple_library-export_private_headers">export_private_headers</a>, <a href="#apple_library-kwargs">kwargs</a>)
apple_library(<a href="#apple_library-name">name</a>, <a href="#apple_library-library_tools">library_tools</a>, <a href="#apple_library-export_private_headers">export_private_headers</a>, <a href="#apple_library-namespace_is_module_name">namespace_is_module_name</a>, <a href="#apple_library-kwargs">kwargs</a>)
</pre>

Create libraries for native source code on Apple platforms.
Expand All @@ -82,6 +82,7 @@ reasonable defaults that mimic Xcode's behavior.
| name | The base name for all of the underlying targets. | none |
| library_tools | An optional dictionary containing overrides for default behaviors. | <code>{}</code> |
| export_private_headers | Whether private headers should be exported via a <code>PrivateHeaders</code> provider. | <code>True</code> |
| namespace_is_module_name | Whether the module name should be used as the namespace for header imports, instead of the target name. | <code>True</code> |
| kwargs | <p align="center"> - </p> | none |


Expand Down
7 changes: 4 additions & 3 deletions rules/app.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@ def ios_application(name, apple_library = apple_library, **kwargs):
kwargs: Arguments passed to the apple_library and ios_application rules as appropriate.
"""
infoplists = kwargs.pop("infoplists", [])
application_kwargs = {arg: kwargs.pop(arg, None) for arg in _IOS_APPLICATION_KWARGS}
library = apple_library(name = name, **kwargs)
application_kwargs = {arg: kwargs.pop(arg) for arg in _IOS_APPLICATION_KWARGS if arg in kwargs}
library = apple_library(name = name, namespace_is_module_name = False, **kwargs)

if not infoplists:
infoplists += ["@build_bazel_rules_ios//rules/test_host_app:Info.plist"]

kwargs["families"] = kwargs.pop("families", ["iphone", "ipad"])
application_kwargs["launch_storyboard"] = application_kwargs.pop("launch_storyboard", library.launch_screen_storyboard_name)
application_kwargs["families"] = application_kwargs.pop("families", ["iphone", "ipad"])

rules_apple_ios_application(
name = name,
Expand Down
16 changes: 11 additions & 5 deletions rules/framework.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def apple_framework(name, apple_library = apple_library, **kwargs):
library = apple_library(name = name, **kwargs)
apple_framework_packaging(
name = name,
framework_name = library.module_name,
framework_name = library.namespace,
transitive_deps = library.transitive_deps,
deps = library.lib_names,
visibility = kwargs.get("visibility", None),
Expand Down Expand Up @@ -141,12 +141,18 @@ def _apple_framework_packaging_impl(ctx):
destination = paths.join(framework_dir, "Headers", hdr.basename)
header_out.append(destination)

if not has_header:
# only thing is the generated module map -- we don't want it
continue

if SwiftInfo in dep and dep[SwiftInfo].direct_swiftmodules:
# apple_common.Objc.direct_module_maps is broken coming from swift_library
# (it contains one level of transitive module maps), so ignore SwiftInfo from swift_library,
# since it doesn't have a module_map field anyway
continue

# collect modulemaps
for modulemap in dep[apple_common.Objc].direct_module_maps:
if not has_header:
# only thing is the generated module map -- we don't want it
continue

modulemap_in = modulemap

binary_out = None
Expand Down
83 changes: 62 additions & 21 deletions rules/library.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ PrivateHeaders = provider(
},
)

_MANUAL = ["manual"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice, good idea tagging these as "manual"


def _private_headers_impl(ctx):
return [
PrivateHeaders(
Expand Down Expand Up @@ -107,6 +109,7 @@ module {module_name} {{
name = basename + "~",
destination = destination,
content = content,
tags = _MANUAL,
)
return destination

Expand Down Expand Up @@ -147,6 +150,7 @@ FOUNDATION_EXPORT const unsigned char {module_name}VersionString[];
name = basename + "~",
destination = destination,
content = content,
tags = _MANUAL,
)
return destination

Expand All @@ -161,6 +165,7 @@ def generate_resource_bundles(name, library_tools, module_name, resource_bundles
"PRODUCT_BUNDLE_IDENTIFIER": "com.cocoapods.%s" % bundle_name,
"PRODUCT_NAME": bundle_name,
},
tags = _MANUAL,
)
apple_resource_bundle(
name = target_name,
Expand All @@ -169,6 +174,7 @@ def generate_resource_bundles(name, library_tools, module_name, resource_bundles
library_tools["wrap_resources_in_filegroup"](name = target_name + "_resources", srcs = resource_bundles[bundle_name]),
],
infoplists = [name + ".info.plist"],
tags = _MANUAL,
)
bundle_target_names.append(target_name)
return bundle_target_names
Expand All @@ -183,7 +189,7 @@ _DefaultLibraryTools = {
def _uppercase_string(s):
return s.upper()

def apple_library(name, library_tools = {}, export_private_headers = True, **kwargs):
def apple_library(name, library_tools = {}, export_private_headers = True, namespace_is_module_name = True, **kwargs):
"""Create libraries for native source code on Apple platforms.

Automatically handles mixed-source libraries and comes with
Expand All @@ -195,6 +201,8 @@ def apple_library(name, library_tools = {}, export_private_headers = True, **kwa
default behaviors.
export_private_headers: Whether private headers should be exported via
a `PrivateHeaders` provider.
namespace_is_module_name: Whether the module name should be used as the
namespace for header imports, instead of the target name.
"""
library_tools = dict(_DefaultLibraryTools, **library_tools)
swift_sources = []
Expand Down Expand Up @@ -236,6 +244,7 @@ def apple_library(name, library_tools = {}, export_private_headers = True, **kwa
fail("Unable to compile %s in apple_framework %s" % (f, name))

module_name = kwargs.pop("module_name", name)
namespace = module_name if namespace_is_module_name else name
module_map = kwargs.pop("module_map", None)
cc_copts = kwargs.pop("cc_copts", [])
swift_copts = kwargs.pop("swift_copts", [])
Expand All @@ -249,6 +258,8 @@ def apple_library(name, library_tools = {}, export_private_headers = True, **kwa
pch = kwargs.pop("pch", "@build_bazel_rules_ios//rules/library:common.pch")
deps = kwargs.pop("deps", [])
data = kwargs.pop("data", [])
tags = kwargs.pop("tags", [])
tags_manual = tags if "manual" in tags else tags + _MANUAL
internal_deps = []
lib_names = []

Expand All @@ -257,6 +268,7 @@ def apple_library(name, library_tools = {}, export_private_headers = True, **kwa
apple_static_framework_import(
name = import_name,
framework_imports = native.glob(["%s/**/*" % vendored_static_framework]),
tags = _MANUAL,
)
deps += [import_name]
for vendored_dynamic_framework in kwargs.pop("vendored_dynamic_frameworks", []):
Expand All @@ -265,13 +277,15 @@ def apple_library(name, library_tools = {}, export_private_headers = True, **kwa
name = import_name,
framework_imports = native.glob(["%s/**/*" % vendored_dynamic_framework]),
deps = [],
tags = _MANUAL,
)
deps += [import_name]
for vendored_static_library in kwargs.pop("vendored_static_libraries", []):
import_name = "%s-%s-library-import" % (name, paths.basename(vendored_static_library))
native.objc_import(
name = import_name,
archives = [vendored_static_library],
tags = _MANUAL,
)
deps += [import_name]
for vendored_dynamic_library in kwargs.pop("vendored_dynamic_libraries", []):
Expand All @@ -292,17 +306,19 @@ def apple_library(name, library_tools = {}, export_private_headers = True, **kwa
native.filegroup(
name = public_hdrs_filegroup,
srcs = objc_hdrs,
tags = _MANUAL,
)

# Public hmaps are for vendored static libs to export their header only.
# Other dependencies' headermaps will be generated by li_ios_framework
# rules.
headermap(
name = public_hmap_name,
namespace = module_name,
namespace = namespace,
hdrs = [public_hdrs_filegroup],
hdr_providers = deps,
flatten_headers = True,
tags = _MANUAL,
)
internal_deps.append(public_hmap_name)

Expand All @@ -313,24 +329,28 @@ def apple_library(name, library_tools = {}, export_private_headers = True, **kwa
native.filegroup(
name = private_hdrs_filegroup,
srcs = objc_non_exported_hdrs + objc_private_hdrs + objc_hdrs,
tags = _MANUAL,
)
native.filegroup(
name = private_angled_hdrs_filegroup,
srcs = objc_non_exported_hdrs + objc_private_hdrs,
tags = _MANUAL,
)

headermap(
name = private_hmap_name,
namespace = module_name,
namespace = namespace,
hdrs = [private_hdrs_filegroup],
flatten_headers = False,
tags = _MANUAL,
)
internal_deps.append(private_hmap_name)
headermap(
name = private_angled_hmap_name,
namespace = module_name,
namespace = namespace,
hdrs = [private_angled_hdrs_filegroup],
flatten_headers = True,
tags = _MANUAL,
)
internal_deps.append(private_angled_hmap_name)
## END HMAP
Expand Down Expand Up @@ -375,7 +395,7 @@ def apple_library(name, library_tools = {}, export_private_headers = True, **kwa
cpp_libname = "%s_cpp" % name

# TODO: remove framework if set
if not module_map and (objc_hdrs or objc_private_hdrs or swift_sources):
if namespace_is_module_name and not module_map and (objc_hdrs or objc_private_hdrs or swift_sources):
umbrella_header = library_tools["umbrella_header_generator"](
name = name,
library_tools = library_tools,
Expand All @@ -398,30 +418,39 @@ def apple_library(name, library_tools = {}, export_private_headers = True, **kwa
)

if swift_sources:
swift_copts += [
"-Xcc",
"-fmodule-map-file=" + "$(execpath " + module_map + ")",
"-import-underlying-module",
]
if module_map:
swift_copts += [
"-Xcc",
"-fmodule-map-file=" + "$(execpath " + module_map + ")",
"-import-underlying-module",
]
swiftc_inputs = other_inputs + objc_hdrs
if module_map:
swiftc_inputs.append(module_map)
generated_header_name = module_name + "-Swift.h"
swift_library(
name = swift_libname,
module_name = module_name,
generated_header_name = generated_header_name,
srcs = swift_sources,
copts = swift_copts,
deps = deps + internal_deps + lib_names,
swiftc_inputs = other_inputs + objc_hdrs + [module_map],
swiftc_inputs = swiftc_inputs,
features = ["swift.no_generated_module_map"],
tags = tags_manual,
**kwargs
)
lib_names += [swift_libname]
extend_modulemap(
name = module_map + ".extended." + name,
destination = "%s.extended.modulemap" % name,
source = module_map,
swift_header = "%s-Swift.h" % swift_libname,
module_name = module_name,
)
module_map = "%s.extended.modulemap" % name
if module_map:
extend_modulemap(
name = module_map + ".extended." + name,
destination = "%s.extended.modulemap" % name,
source = module_map,
swift_header = generated_header_name,
module_name = module_name,
tags = _MANUAL,
)
module_map = "%s.extended.modulemap" % name

if cpp_sources and False:
native.cc_library(
Expand All @@ -430,9 +459,11 @@ def apple_library(name, library_tools = {}, export_private_headers = True, **kwa
hdrs = objc_hdrs,
copts = cc_copts,
deps = deps,
tags = tags_manual,
)
lib_names += [cpp_libname]

objc_library_data = library_tools["wrap_resources_in_filegroup"](name = objc_libname + "_data", srcs = data)
native.objc_library(
name = objc_libname,
srcs = objc_sources + objc_private_hdrs + objc_non_exported_hdrs,
Expand All @@ -446,19 +477,29 @@ def apple_library(name, library_tools = {}, export_private_headers = True, **kwa
weak_sdk_frameworks = weak_sdk_frameworks,
sdk_includes = sdk_includes,
pch = pch,
data = [library_tools["wrap_resources_in_filegroup"](name = objc_libname + "_data", srcs = data)],
data = [objc_library_data],
tags = tags_manual,
**kwargs
)
launch_screen_storyboard_name = name + "_launch_screen_storyboard"
native.filegroup(
name = launch_screen_storyboard_name,
srcs = [objc_library_data],
output_group = "launch_screen_storyboard",
tags = _MANUAL,
)
lib_names += [objc_libname]

if export_private_headers:
private_headers_name = "%s_private_headers" % name
lib_names += [private_headers_name]
_private_headers(name = private_headers_name, headers = objc_private_hdrs)
_private_headers(name = private_headers_name, headers = objc_private_hdrs, tags = _MANUAL)

return struct(
lib_names = lib_names,
transitive_deps = deps,
deps = lib_names + deps,
module_name = module_name,
launch_screen_storyboard_name = launch_screen_storyboard_name,
namespace = namespace,
)
Loading