Git Product home page Git Product logo

rules_apple's Introduction

Apple Rules for Bazel

This repository contains rules for Bazel that can be used to bundle applications for Apple platforms.

These rules handle the linking and bundling of applications and extensions (that is, the formation of an .app with an executable and resources, archived in an .ipa). Compilation is still performed by the existing objc_library rule in Bazel, and by the swift_library rule available from rules_swift.

If you are looking for an easy way to build mixed language frameworks, check out rules_ios.

Reference documentation

Click here for the reference documentation for the rules and other definitions in this repository.

Quick setup

Copy the latest MODULE.bazel or WORKSPACE snippet from the releases page.

Examples

Minimal example:

load("@build_bazel_rules_apple//apple:ios.bzl", "ios_application")
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")

swift_library(
    name = "MyLibrary",
    srcs = glob(["**/*.swift"]),
    data = [":Main.storyboard"],
)

# Links code from "deps" into an executable, collects and compiles resources
# from "deps" and places them with the executable in an .app bundle, and then
# outputs an .ipa with the bundle in its Payload directory.
ios_application(
    name = "App",
    bundle_id = "com.example.app",
    families = [
        "iphone",
        "ipad",
    ],
    infoplists = [":Info.plist"],
    minimum_os_version = "15.0",
    deps = [":MyLibrary"],
)

See the examples directory for sample applications.

Supported bazel versions

rules_apple and rules_swift are often affected by changes in bazel itself. This means you generally need to update these rules as you update bazel.

You can also see the supported bazel versions in the notes for each release on the releases page.

Besides these constraints this repo follows semver as best as we can since the 1.0.0 release.

Bazel release Minimum supported rules version Final supported rules version Supporting Branch
8.x (most recent rolling) 2.* current master
7.x 2.* current master
6.x 2.* current master
5.x 0.33.0 1.* bazel/5.x
4.x 0.30.0 0.32.0 N/A
3.x 0.20.0 0.21.2 N/A

rules_apple's People

Contributors

alexeagle avatar allevato avatar balestrapatrick avatar brentleyjones avatar c-parsons avatar dabelknap avatar davidgoldman avatar dflems avatar gabebear avatar github-actions[bot] avatar googlewalt avatar jszumski avatar kastiglione avatar kaylathar avatar keith avatar luispadron avatar mattrobmattrob avatar maxwelle avatar mccorkill1 avatar nglevin avatar rahul-malik avatar rickeylev avatar sebastianv1 avatar segiddins avatar sergiocampama avatar steeve avatar stravinskii avatar swiple-rules-gardener avatar thii avatar thomasvl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rules_apple's Issues

Use --preserve-metadata=identifier,entitlements option when signing embedded frameworks

When a .framework is embedded in an app/extension, Xcode uses the --preserve-metadata=identifier,entitlements option to sign it. It does NOT use the host app(ex)'s entitlements or provisioning profile. We should do the same in the bundling rules.

Likewise, when signing the Swift dylibs, Xcode omits the --preserve-metadata option as well (and also uses no entitlements). It's unclear whether that option would make a difference for those.

method invocation returned None, please file a bug report: xcode_version().

Got this message when I tried to bazel build a simple pure swift_library.

Bazel version details:
Build label: 0.5.2-homebrew
Build target: bazel-out/darwin_x86_64-opt/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar
Build time: Tue Jun 27 20:24:06 2017 (1498595046)
Build timestamp: 1498595046
Build timestamp as int: 1498595046

rules_apple, included into workspace as: https://github.com/bazelbuild/rules_apple/archive/4ac137080708924f6da02f8165b1c53b99d2d1c7.zip

xcode-select -p prints:
/Applications/Xcode-beta.app/Contents/Developer
(Version 9 beta 3)

Warn if there are missing @2x/@3x assets

We should consider printing warnings (or look at whether actool already does so and make that output more presentable) if a user has any asset catalogs that contain @1x assets but are missing @2x/@3x assets.

objc_framework not bundled correctly into ios_application

I have an ios_application which relies on RxCocoa: https://github.com/ReactiveX/RxSwift.

I have downloaded the .framework file from its releases: 3.4.1 and tried adding a build file as follows:

package(default_visibility = ["//visibility:public"])

objc_framework(
    name = "RxCocoa",
    framework_imports = [
        "Carthage/Build/iOS/RxCocoa.framework"
    ],
    is_dynamic = 0,
)

This causes the error at application runtime:

dyld: Library not loaded: @rpath/RxCocoa.framework/RxCocoa
  Referenced from: /Users/[REDACTED]/Library/Developer/CoreSimulator/Devices/480214EA-7464-4111-A88A-A2D5DC468785/data/Containers/Bundle/Application/EB21E332-5A4F-4953-BE43-F2A97CB6EB40/[REDACTED]Example.app/FLComponentExample
  Reason: image not found

If I change is_dynamic to 1, I get this error at compile time:

Showing All Messages
  (exec env - \
    APPLE_SDK_PLATFORM=iPhoneSimulator \
    APPLE_SDK_VERSION_OVERRIDE=10.3 \
    DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer\
    SDKROOT=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator10.3.sdk\
    XCODE_VERSION_OVERRIDE=8.3.2 \
    bazel-out/darwin_x86_64-dbg/bin/[REDACTED]/[REDACTED]Example.process-and-sign.sh)

Use --sandbox_debug to see verbose messages from the sandbox.

bazel-out/darwin_x86_64-dbg/bin/[REDACTED]/[REDACTED]Example.archive-root/Payload/[REDACTED]Example.app/Frameworks/RxCocoa.framework: bundle format unrecognized, invalid, or unsuitable

Note:
This framework contains both objc and swift modules.

Tulsi fails when a swift_library has dependencies

[5:43:56 pm](2): Failed to retrieve information about the Bazel workspace. This usually means that the contents of a BUILD file are incorrect or flags are missing. Read the message log carefully for details. [Details]: ERROR: /private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/KeychainAccess/BUILD.bazel:4:1: in @build_bazel_rules_apple//apple/bundling:apple_bundling_aspect.bzl%apple_bundling_aspect aspect on swift_library rule @KeychainAccess//:KeychainAccess: Aspect implementation doesn't return a struct.
ERROR: Analysis of aspect '/tulsi/tulsi_aspects%tulsi_sources_aspect of //FLKeychain:FLKeychain' failed; build aborted.

The example build file for @KeychainAccess//:KeychainAccess:

load("@build_bazel_rules_apple//apple:swift.bzl", "swift_library")
package(default_visibility = ["//visibility:public"])

swift_library(
    name = "KeychainAccess",
    srcs = glob(["Lib/KeychainAccess/*.swift"]),
    module_name = "KeychainAccess",
)

The workspace file:

new_git_repository(
    name = "KeychainAccess",
    remote = "https://github.com/kishikawakatsumi/KeychainAccess.git",
    tag = "v3.0.2",
    build_file = "Vendor/KeychainAccess.BUILD",
)

Storyboards from objc_bundle_library are not being bundled

Storyboards from objc_bundle_library are missing in the final bundle. This is likely a bug in the way that we handle either the compilation step or the linking step for storyboards (the latter is what copies the files into what is supposed to represent the directory structure of the final app/extension).

Validate the format of the bundle_id attribute

Validate the bundle_id attribute early in the rule to make sure that it's well-formed. (This is separate from the validation already being done between apps and extensions). We would reject bundle IDs that have, for example, spaces in them.

Regression: Unexpected clang argument for extension targets

@c-parsons :
We have a share and siri ios_extension rule in our application and they have a few dependencies like the Facebook SDK.

They've been building correctly but as of this PR we are getting failures because -fapplication-extension is passed and fails on third-party code.

Additionally we are unable to specify extension_safe=False in our rule definition without encountering an error since it seems to already be hard-coded to True.

objc_library deps swift_library failed

I write a swift_library

swift_library(
    name = "hello",
    srcs = ["Sources/Hello.swift"],
)

and a objc_library deps it.

objc_library(
    name = "Sources",
    srcs = [
        "Sources/AppDelegate.h",
        "Sources/AppDelegate.m",
        "Sources/main.m",
    ],
    resources = [
        "Resources/Main.storyboard",
    ],
    deps = [":hello"],
)

but swift_library generate a empty hello-Swift.h file

// Generated by Apple Swift version 3.1 effective-3 (swiftlang-802.0.53 clang-802.0.42)
#pragma clang diagnostic push

#if defined(__has_include) && __has_include(<swift/objc-prologue.h>)
# include <swift/objc-prologue.h>
#endif

#pragma clang diagnostic ignored "-Wauto-import"
#include <objc/NSObject.h>
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>

#if !defined(SWIFT_TYPEDEFS)
# define SWIFT_TYPEDEFS 1
# if defined(__has_include) && __has_include(<uchar.h>)
#  include <uchar.h>
# elif !defined(__cplusplus) || __cplusplus < 201103L
typedef uint_least16_t char16_t;
typedef uint_least32_t char32_t;
# endif
typedef float swift_float2  __attribute__((__ext_vector_type__(2)));
typedef float swift_float3  __attribute__((__ext_vector_type__(3)));
typedef float swift_float4  __attribute__((__ext_vector_type__(4)));
typedef double swift_double2  __attribute__((__ext_vector_type__(2)));
typedef double swift_double3  __attribute__((__ext_vector_type__(3)));
typedef double swift_double4  __attribute__((__ext_vector_type__(4)));
typedef int swift_int2  __attribute__((__ext_vector_type__(2)));
typedef int swift_int3  __attribute__((__ext_vector_type__(3)));
typedef int swift_int4  __attribute__((__ext_vector_type__(4)));
typedef unsigned int swift_uint2  __attribute__((__ext_vector_type__(2)));
typedef unsigned int swift_uint3  __attribute__((__ext_vector_type__(3)));
typedef unsigned int swift_uint4  __attribute__((__ext_vector_type__(4)));
#endif

#if !defined(SWIFT_PASTE)
# define SWIFT_PASTE_HELPER(x, y) x##y
# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y)
#endif
#if !defined(SWIFT_METATYPE)
# define SWIFT_METATYPE(X) Class
#endif
#if !defined(SWIFT_CLASS_PROPERTY)
# if __has_feature(objc_class_property)
#  define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__
# else
#  define SWIFT_CLASS_PROPERTY(...)
# endif
#endif

#if defined(__has_attribute) && __has_attribute(objc_runtime_name)
# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X)))
#else
# define SWIFT_RUNTIME_NAME(X)
#endif
#if defined(__has_attribute) && __has_attribute(swift_name)
# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X)))
#else
# define SWIFT_COMPILE_NAME(X)
#endif
#if defined(__has_attribute) && __has_attribute(objc_method_family)
# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X)))
#else
# define SWIFT_METHOD_FAMILY(X)
#endif
#if defined(__has_attribute) && __has_attribute(noescape)
# define SWIFT_NOESCAPE __attribute__((noescape))
#else
# define SWIFT_NOESCAPE
#endif
#if defined(__has_attribute) && __has_attribute(warn_unused_result)
# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
# define SWIFT_WARN_UNUSED_RESULT
#endif
#if !defined(SWIFT_CLASS_EXTRA)
# define SWIFT_CLASS_EXTRA
#endif
#if !defined(SWIFT_PROTOCOL_EXTRA)
# define SWIFT_PROTOCOL_EXTRA
#endif
#if !defined(SWIFT_ENUM_EXTRA)
# define SWIFT_ENUM_EXTRA
#endif
#if !defined(SWIFT_CLASS)
# if defined(__has_attribute) && __has_attribute(objc_subclassing_restricted)
#  define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA
#  define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
# else
#  define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
#  define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
# endif
#endif

#if !defined(SWIFT_PROTOCOL)
# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
#endif

#if !defined(SWIFT_EXTENSION)
# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__)
#endif

#if !defined(OBJC_DESIGNATED_INITIALIZER)
# if defined(__has_attribute) && __has_attribute(objc_designated_initializer)
#  define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
# else
#  define OBJC_DESIGNATED_INITIALIZER
# endif
#endif
#if !defined(SWIFT_ENUM)
# define SWIFT_ENUM(_type, _name) enum _name : _type _name; enum SWIFT_ENUM_EXTRA _name : _type
# if defined(__has_feature) && __has_feature(generalized_swift_name)
#  define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_EXTRA _name : _type
# else
#  define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) SWIFT_ENUM(_type, _name)
# endif
#endif
#if !defined(SWIFT_UNAVAILABLE)
# define SWIFT_UNAVAILABLE __attribute__((unavailable))
#endif
#if !defined(SWIFT_UNAVAILABLE_MSG)
# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg)))
#endif
#if !defined(SWIFT_AVAILABILITY)
# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__)))
#endif
#if !defined(SWIFT_DEPRECATED)
# define SWIFT_DEPRECATED __attribute__((deprecated))
#endif
#if !defined(SWIFT_DEPRECATED_MSG)
# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__)))
#endif
#if defined(__has_feature) && __has_feature(modules)
#endif

#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch"
#pragma clang diagnostic ignored "-Wduplicate-method-arg"
#pragma clang diagnostic pop

my hello.swift

import UIKit
@objc
class SwiftHello: NSObject {
    func hello() {
        print("Hello from swift")
    }
}

my AppDelegate.m

#import "examples/ios/HelloWorld/Sources/AppDelegate.h"

#import "examples/ios/HelloWorld/hello-Swift.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    SwiftHello *hello = [[SwiftHello alloc] init];
    [hello hello];
    
  return YES;
}

@end

error is

ERROR: /Users/abc/Downloads/rules_apple-master/examples/ios/HelloWorld/BUILD:8:1: null failed: Process exited with status 1 [sandboxed].
examples/ios/HelloWorld/Sources/AppDelegate.m:24:5: error: use of undeclared identifier 'SwiftHello'
    SwiftHello *hello = [[SwiftHello alloc] init];
    ^

transitive dependency failed (oc ->(deps) swift ->(deps) oc/swift)

I have a objc_library test , it depend a swift_library s, and s depend another objc_library oc . Then I build test library bazel build //:test, I got a error.

my oc library file OCObject.h

#import <Foundation/Foundation.h>
@interface OCObject : NSObject
@end
@protocol OCDelegate <NSObject>
- (void)hello;
@end

OCObject.m

#import "OCObject.h"
@implementation OCObject
@end

my swift library file SwiftClass.swift

import UIKit
import _oc
public class SwiftClass: NSObject, OCDelegate {   
    var oc1: OCObject?  
    public func hello() {      
    }
}

my test class file

#import "swift-Swift.h"

my swift-Swift.h

#if defined(__has_feature) && __has_feature(modules)
@import ObjectiveC;
@import _oc;
#endif

#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch"
#pragma clang diagnostic ignored "-Wduplicate-method-arg"

SWIFT_CLASS("_TtC5swift10SwiftClass")
@interface SwiftClass : NSObject <OCDelegate>
- (void)hello;
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end

#pragma clang diagnostic pop

error is

ERROR: /Users/abc/Desktop/a/BUILD:21:1: null failed: Process exited with status 1 [sandboxed].
In file included from a/ViewController.m:10:
bazel-out/ios-x86_64-min8.1-applebin_ios-darwin_x86_64-fastbuild/genfiles/swift-Swift.h:136:9: fatal error: module '_oc' not found
@import _oc;
 ~~~~~~~^~~
1 error generated.
Use --strategy=ObjcCompile=standalone to disable sandboxing for the failing actions.
Target //:a failed to build
Use --verbose_failures to see the command lines of failed build steps.

But I build swift librarybazel build //:swift . It success
my build file

objc_library(
    name = "test",
    srcs = [
        "a/AppDelegate.m",
        "a/ViewController.m",
        "a/main.m",
    ],
    deps = [":swift",],
    enable_modules = 1,
    resources = ["a/Base.lproj/Main.storyboard"],
    hdrs = glob(["a/AppDelegate.h", "a/ViewController.h"]),
)
swift_library(
    name = "swift",
    module_name = "swift",
    srcs = ["a/SwiftClass.swift"],
    deps = [":oc"],
)
objc_library(
    name = "oc",
    enable_modules = 1,
    srcs = ["a/OCObject.m"],
    hdrs = ["a/OCObject.h"],
)

my code
test.zip

Support compiling texture atlases

When Xcode sees a .atlas folder in a project, it automatically runs the TextureAtlas tool on it. It doesn't pass any special arguments, however (you can run xcrun TextureAtlas with no arguments to see what it accepts).

Our rules should look at doing the same. We can support texture atlases in two ways:

  1. Detect .atlas folders during resource processing and do what Xcode does
  2. Add an apple_texture_atlas rule that provides the full set of command options as attributes, separately compiles a .atlas into a .atlasc, and propagates that via the AppleResource provider. The resource processor will see .atlasc as an unrecognized type and simply copy it into the bundle verbatim.

Tulsi fails loading ios.bzl

[5:35:55 pm](0): Bazel command info:
"/Users/lswithenbank/Code/bazel-master/bazel" "--max_idle_secs=60" "query" "--announce_rc" "--noimplicit_deps" "--order_output=no" "--noshow_loading_progress" "--noshow_progress" "kind(rule, FLKeychain:all)" "--output" "xml"
Exited with code 7

Another command is running (pid = 29971).  Waiting for it to complete...
Another command (pid=29971) is running.  Waiting for it to complete...
____Options provided by the client:
  Inherited 'common' options: --isatty=0 --terminal_columns=80
ERROR: /private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/build_bazel_rules_apple/apple/bundling/ios_rules.bzl:114:1: Traceback (most recent call last):
	File "/private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/build_bazel_rules_apple/apple/bundling/ios_rules.bzl", line 114
		merge_dictionaries(common_rule_attributes(), {"app_ic...))})
	File "/private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/build_bazel_rules_apple/apple/bundling/ios_rules.bzl", line 114, in merge_dictionaries
		common_rule_attributes()
	File "/private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/build_bazel_rules_apple/apple/bundling/rule_attributes.bzl", line 217, in common_rule_attributes
		merge_dictionaries(_tool_attributes(), simple_path_fo...(), ..., <2 more arguments>), "bundle_id": attr.string(mandatory = True), "infoplists": attr.label_list(allow_files = [".plist"], mandator..., ...), "ipa_post_processor": attr.label(allow_files = True, executable = T..., ..."), "minimum_os_version": attr.string(mandatory = False), "provisioning_profile": attr.label(allow_files = [".mobileprovision...], ...), "strings": attr.label_list(allow_files = [".strings"]), "_propagates_frameworks": attr.bool(default = False), "_requires_signing_for_device": attr.bool(default = True), "_skip_signing": attr.bool(default = False)})
	File "/private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/build_bazel_rules_apple/apple/bundling/rule_attributes.bzl", line 221, in merge_dictionaries
		attr.label(aspects = [apple_bundling_aspect..., <2 more arguments>)
Illegal argument: element in 'providers' is of unexpected type. Should be list of string, but got provider. Notice: one single list of string as 'providers' is still supported..
ERROR: /private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/build_bazel_rules_apple/apple/bundling/ios_rules.bzl:157:13: Traceback (most recent call last):
	File "/private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/build_bazel_rules_apple/apple/bundling/ios_rules.bzl", line 155
		rule(_ios_application_impl, attrs = _IO..., <3 more arguments>)
	File "/private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/build_bazel_rules_apple/apple/bundling/ios_rules.bzl", line 157, in rule
		_IOS_APPLICATION_ATTRIBUTES
name '_IOS_APPLICATION_ATTRIBUTES' is not defined.
ERROR: /private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/build_bazel_rules_apple/apple/bundling/ios_rules.bzl:195:1: Traceback (most recent call last):
	File "/private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/build_bazel_rules_apple/apple/bundling/ios_rules.bzl", line 195
		merge_dictionaries(common_rule_attributes(), {"app_ic...)})
	File "/private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/build_bazel_rules_apple/apple/bundling/ios_rules.bzl", line 195, in merge_dictionaries
		common_rule_attributes()
	File "/private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/build_bazel_rules_apple/apple/bundling/rule_attributes.bzl", line 217, in common_rule_attributes
		merge_dictionaries(_tool_attributes(), simple_path_fo...(), ..., <2 more arguments>), "bundle_id": attr.string(mandatory = True), "infoplists": attr.label_list(allow_files = [".plist"], mandator..., ...), "ipa_post_processor": attr.label(allow_files = True, executable = T..., ..."), "minimum_os_version": attr.string(mandatory = False), "provisioning_profile": attr.label(allow_files = [".mobileprovision...], ...), "strings": attr.label_list(allow_files = [".strings"]), "_propagates_frameworks": attr.bool(default = False), "_requires_signing_for_device": attr.bool(default = True), "_skip_signing": attr.bool(default = False)})
	File "/private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/build_bazel_rules_apple/apple/bundling/rule_attributes.bzl", line 221, in merge_dictionaries
		attr.label(aspects = [apple_bundling_aspect..., <2 more arguments>)
Illegal argument: element in 'providers' is of unexpected type. Should be list of string, but got provider. Notice: one single list of string as 'providers' is still supported..
ERROR: /private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/build_bazel_rules_apple/apple/bundling/ios_rules.bzl:229:13: Traceback (most recent call last):
	File "/private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/build_bazel_rules_apple/apple/bundling/ios_rules.bzl", line 227
		rule(_ios_extension_impl, attrs = _IOS_..., <2 more arguments>)
	File "/private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/build_bazel_rules_apple/apple/bundling/ios_rules.bzl", line 229, in rule
		_IOS_EXTENSION_ATTRIBUTES
name '_IOS_EXTENSION_ATTRIBUTES' is not defined.
ERROR: /private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/build_bazel_rules_apple/apple/bundling/ios_rules.bzl:265:1: Traceback (most recent call last):
	File "/private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/build_bazel_rules_apple/apple/bundling/ios_rules.bzl", line 265
		merge_dictionaries(common_rule_attributes(), {"binary..., <3 more arguments>), "hdrs": attr.label_list(allow_files = [".h"]), "families": attr.string_list(mandatory = True), "linkopts": attr.string_list(), "_allowed_families": attr.string_list(default = ["iphone", "ipad"]), "_bundle_extension": attr.string(default = ".framework"), "_needs_pkginfo": attr.bool(default = False), "_path_in_archive_format": attr.string(default = "%s"), "_platform_type": attr.string(default = str(apple_common.platf...)), "_propagates_frameworks": attr.bool(default = True), "_skip_signing": attr.bool(default = True)})
	File "/private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/build_bazel_rules_apple/apple/bundling/ios_rules.bzl", line 265, in merge_dictionaries
		common_rule_attributes()
	File "/private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/build_bazel_rules_apple/apple/bundling/rule_attributes.bzl", line 217, in common_rule_attributes
		merge_dictionaries(_tool_attributes(), simple_path_fo...(), ..., <2 more arguments>), "bundle_id": attr.string(mandatory = True), "infoplists": attr.label_list(allow_files = [".plist"], mandator..., ...), "ipa_post_processor": attr.label(allow_files = True, executable = T..., ..."), "minimum_os_version": attr.string(mandatory = False), "provisioning_profile": attr.label(allow_files = [".mobileprovision...], ...), "strings": attr.label_list(allow_files = [".strings"]), "_propagates_frameworks": attr.bool(default = False), "_requires_signing_for_device": attr.bool(default = True), "_skip_signing": attr.bool(default = False)})
	File "/private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/build_bazel_rules_apple/apple/bundling/rule_attributes.bzl", line 221, in merge_dictionaries
		attr.label(aspects = [apple_bundling_aspect..., <2 more arguments>)
Illegal argument: element in 'providers' is of unexpected type. Should be list of string, but got provider. Notice: one single list of string as 'providers' is still supported..
ERROR: /private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/build_bazel_rules_apple/apple/bundling/ios_rules.bzl:302:13: Traceback (most recent call last):
	File "/private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/build_bazel_rules_apple/apple/bundling/ios_rules.bzl", line 300
		rule(_ios_framework_impl, attrs = _IOS_..., <2 more arguments>)
	File "/private/var/tmp/_bazel_lswithenbank/a36946a2b8731dcc3591b08e68f5ca48/external/build_bazel_rules_apple/apple/bundling/ios_rules.bzl", line 302, in rule
		_IOS_FRAMEWORK_ATTRIBUTES
name '_IOS_FRAMEWORK_ATTRIBUTES' is not defined.
ERROR: while parsing 'FLKeychain:all': error loading package 'FLKeychain': Extension file 'apple/bundling/ios_rules.bzl' has errors.

Bring Apple-specific build tools into this repo from @bazel_tools

Tools like actoolwrapper, ibtoolwrapper, and so forth should be added to this repository since they are Apple-specific.

This is also important because it lets us update them in sync with the bundling rules that use them; if they remain in @bazel_tools, they are tied to specific Bazel releases.

Settings.app Acknowledgements.plist is missing?

Good afternoon, I'm using Bazel and rules_apple to compile an iOS app and more 👍

I've got several third party dependencies. For attribution, I'd like to expose the licenses to users in Settings.app

Is there a way to generate this for all of my deps? I noticed that objc_library ( and all other build rules ) are supposed to have licenses as an attribute.

It wasn't clear to me if this is supported in iOS and I couldn't find anything related in rules_apple or the docs. Previously, this plist was governed by with CocoaPods, which automatically generates this plist, and sets up the bundle. It'd be awesome if Bazel had this ability!

Rename "ipa_post_processor" attribute

This was inherited from the native rules, but not all rules produce an IPA now (for example, ios_extension produces a .zip), so the name is inaccurate.

Something like bundle_post_processor might be more reasonable. We'll still need to support the old attribute (and emit a warning) for some time before it can be deleted.

Use SDK version as a soft default for minimum OS version

Bazel currently has arbitrary hardcoded minimum OS versions for each platform.

Once #43 is resolved, we should stop relying on the --{i,tv,watch}os_minimum_os flags entirely and use the SDK version as the soft default instead. It will print a warning notifying users that they are using this soft default and that they should make the minimum version explicit if they want predictable builds. (By not making the attribute mandatory, we replicate Xcode's defaults and we don't penalize the use case of quickly whipping up a BUILD target for experimentation/prototypes.)

Trouble building a commandline macOS swift binary

Hi! I'm trying to create a simple commandline swift script that runs on the macos host.

load("@build_bazel_rules_apple//apple:swift.bzl", "swift_library")

swift_library(
  name = "_nail",
  module_name = "Nail",
  srcs = glob(["Sources/**/*.swift"]),
  copts = ["-whole-module-optimization"]
)

apple_binary(
    name = "nail",
    srcs = [":dummy"],
    deps = [":_nail"],
    platform_type = "macos"
)

Here are errors I see with various flags:

bazel build '//tools/nail'

Unhandled exception thrown during build; message: Unrecoverable error while evaluating node 'CONFIGURED_TARGET://tools/nail:nail 541ffbf00c88336544281a1746b162b8 (1907095672 344891327)' (requested by nodes )
INFO: Elapsed time: 0.190s
java.lang.RuntimeException: Unrecoverable error while evaluating node 'CONFIGURED_TARGET://tools/nail:nail 541ffbf00c88336544281a1746b162b8 (1907095672 344891327)' (requested by nodes )
	at com.google.devtools.build.skyframe.ParallelEvaluator$Evaluate.run(ParallelEvaluator.java:472)
	at com.google.devtools.build.lib.concurrent.AbstractQueueVisitor$WrappedRunnable.run(AbstractQueueVisitor.java:497)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalArgumentException: Unhandled platform MACOS
	at com.google.devtools.build.lib.rules.objc.LegacyCompilationSupport.commonLinkAndCompileFlagsForClang(LegacyCompilationSupport.java:845)
	at com.google.devtools.build.lib.rules.objc.LegacyCompilationSupport.linkCommandLine(LegacyCompilationSupport.java:733)
	at com.google.devtools.build.lib.rules.objc.LegacyCompilationSupport.registerLinkAction(LegacyCompilationSupport.java:624)
	at com.google.devtools.build.lib.rules.objc.LegacyCompilationSupport.registerLinkActions(LegacyCompilationSupport.java:592)
	at com.google.devtools.build.lib.rules.objc.MultiArchBinarySupport.registerActions(MultiArchBinarySupport.java:169)
	at com.google.devtools.build.lib.rules.objc.AppleBinary.create(AppleBinary.java:144)
	at com.google.devtools.build.lib.rules.objc.AppleBinary.create(AppleBinary.java:53)
	at com.google.devtools.build.lib.analysis.ConfiguredTargetFactory.createRule(ConfiguredTargetFactory.java:279)
	at com.google.devtools.build.lib.analysis.ConfiguredTargetFactory.createConfiguredTarget(ConfiguredTargetFactory.java:178)
	at com.google.devtools.build.lib.skyframe.SkyframeBuildView.createConfiguredTarget(SkyframeBuildView.java:489)
	at com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.createConfiguredTarget(ConfiguredTargetFunction.java:1128)
	at com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.compute(ConfiguredTargetFunction.java:261)
	at com.google.devtools.build.skyframe.ParallelEvaluator$Evaluate.run(ParallelEvaluator.java:398)
	... 4 more
java.lang.RuntimeException: Unrecoverable error while evaluating node 'CONFIGURED_TARGET://tools/nail:nail 541ffbf00c88336544281a1746b162b8 (1907095672 344891327)' (requested by nodes )
	at com.google.devtools.build.skyframe.ParallelEvaluator$Evaluate.run(ParallelEvaluator.java:472)
	at com.google.devtools.build.lib.concurrent.AbstractQueueVisitor$WrappedRunnable.run(AbstractQueueVisitor.java:497)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalArgumentException: Unhandled platform MACOS
	at com.google.devtools.build.lib.rules.objc.LegacyCompilationSupport.commonLinkAndCompileFlagsForClang(LegacyCompilationSupport.java:845)
	at com.google.devtools.build.lib.rules.objc.LegacyCompilationSupport.linkCommandLine(LegacyCompilationSupport.java:733)
	at com.google.devtools.build.lib.rules.objc.LegacyCompilationSupport.registerLinkAction(LegacyCompilationSupport.java:624)
	at com.google.devtools.build.lib.rules.objc.LegacyCompilationSupport.registerLinkActions(LegacyCompilationSupport.java:592)
	at com.google.devtools.build.lib.rules.objc.MultiArchBinarySupport.registerActions(MultiArchBinarySupport.java:169)
	at com.google.devtools.build.lib.rules.objc.AppleBinary.create(AppleBinary.java:144)
	at com.google.devtools.build.lib.rules.objc.AppleBinary.create(AppleBinary.java:53)
	at com.google.devtools.build.lib.analysis.ConfiguredTargetFactory.createRule(ConfiguredTargetFactory.java:279)
	at com.google.devtools.build.lib.analysis.ConfiguredTargetFactory.createConfiguredTarget(ConfiguredTargetFactory.java:178)
	at com.google.devtools.build.lib.skyframe.SkyframeBuildView.createConfiguredTarget(SkyframeBuildView.java:489)
	at com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.createConfiguredTarget(ConfiguredTargetFunction.java:1128)
	at com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.compute(ConfiguredTargetFunction.java:261)
	at com.google.devtools.build.skyframe.ParallelEvaluator$Evaluate.run(ParallelEvaluator.java:398)
	... 4 more

and

bazel build '//tools/nail'  --apple_crosstool_transition   --experimental_objc_crosstool=all

Unhandled exception thrown during build; message: Unrecoverable error while evaluating node 'CONFIGURED_TARGET:@bazel_tools//tools/objc:dummy_lib 12cfa70c0d8f30f02088acb09a2168d3 (117387724 1986241952)' (requested by nodes 'CONFIGURED_TARGET://tools/nail:nail 12cfa70c0d8f30f02088acb09a2168d3 (2050766030 1986241952)')
INFO: Elapsed time: 1.599s
java.lang.RuntimeException: Unrecoverable error while evaluating node 'CONFIGURED_TARGET:@bazel_tools//tools/objc:dummy_lib 12cfa70c0d8f30f02088acb09a2168d3 (117387724 1986241952)' (requested by nodes 'CONFIGURED_TARGET://tools/nail:nail 12cfa70c0d8f30f02088acb09a2168d3 (2050766030 1986241952)')
	at com.google.devtools.build.skyframe.ParallelEvaluator$Evaluate.run(ParallelEvaluator.java:472)
	at com.google.devtools.build.lib.concurrent.AbstractQueueVisitor$WrappedRunnable.run(AbstractQueueVisitor.java:497)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalStateException: objc_library rule @bazel_tools//tools/objc:dummy_lib : These artifacts do not have a generating action:
bazel-out/ios_x86_64-fastbuild/genfiles/external/bazel_tools/tools/objc/dummy_lib.modulemaps/module.modulemap
No origin, run with --experimental_extended_sanity_checks
These actions were checked:
com.google.devtools.build.lib.analysis.actions.ParameterFileWriteAction FileWrite
    bazel-out/ios_x86_64-fastbuild/bin/external/bazel_tools/tools/objc/dummy_lib-archive.objlist
com.google.devtools.build.lib.rules.cpp.CppCompileAction ObjcCompile
    bazel-out/ios_x86_64-fastbuild/bin/external/bazel_tools/tools/objc/_objs/dummy_lib/external/bazel_tools/tools/objc/objc_dummy.o
    bazel-out/ios_x86_64-fastbuild/bin/external/bazel_tools/tools/objc/_objs/dummy_lib/external/bazel_tools/tools/objc/objc_dummy.d
com.google.devtools.build.lib.rules.cpp.CppLinkAction CppLink
    bazel-out/ios_x86_64-fastbuild/bin/external/bazel_tools/tools/objc/libdummy_lib.a
com.google.devtools.build.lib.analysis.actions.ParameterFileWriteAction FileWrite
    bazel-out/ios_x86_64-fastbuild/bin/external/bazel_tools/tools/objc/libdummy_lib.so-2.params
com.google.devtools.build.lib.rules.cpp.CppLinkAction CppLink
    bazel-out/ios_x86_64-fastbuild/bin/external/bazel_tools/tools/objc/libdummy_lib.so
com.google.devtools.build.lib.rules.cpp.CppLinkAction CppLink
    bazel-out/ios_x86_64-fastbuild/bin/external/bazel_tools/tools/objc/dummy_lib_fully_linked.a
com.google.devtools.build.lib.analysis.actions.BinaryFileWriteAction FileWrite
    bazel-out/ios_x86_64-fastbuild/bin/external/bazel_tools/tools/objc/dummy_lib.xcodeproj-control
com.google.devtools.build.lib.analysis.actions.SpawnAction GenerateXcodeproj
    bazel-out/ios_x86_64-fastbuild/bin/external/bazel_tools/tools/objc/dummy_lib.xcodeproj/project.pbxproj

	at com.google.devtools.build.lib.analysis.CachingAnalysisEnvironment.verifyGeneratedArtifactHaveActions(CachingAnalysisEnvironment.java:150)
	at com.google.devtools.build.lib.analysis.CachingAnalysisEnvironment.disable(CachingAnalysisEnvironment.java:113)
	at com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.createConfiguredTarget(ConfiguredTargetFunction.java:1144)
	at com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.compute(ConfiguredTargetFunction.java:261)
	at com.google.devtools.build.skyframe.ParallelEvaluator$Evaluate.run(ParallelEvaluator.java:398)
	... 4 more
java.lang.RuntimeException: Unrecoverable error while evaluating node 'CONFIGURED_TARGET:@bazel_tools//tools/objc:dummy_lib 12cfa70c0d8f30f02088acb09a2168d3 (117387724 1986241952)' (requested by nodes 'CONFIGURED_TARGET://tools/nail:nail 12cfa70c0d8f30f02088acb09a2168d3 (2050766030 1986241952)')
	at com.google.devtools.build.skyframe.ParallelEvaluator$Evaluate.run(ParallelEvaluator.java:472)
	at com.google.devtools.build.lib.concurrent.AbstractQueueVisitor$WrappedRunnable.run(AbstractQueueVisitor.java:497)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalStateException: objc_library rule @bazel_tools//tools/objc:dummy_lib : These artifacts do not have a generating action:
bazel-out/ios_x86_64-fastbuild/genfiles/external/bazel_tools/tools/objc/dummy_lib.modulemaps/module.modulemap
No origin, run with --experimental_extended_sanity_checks
These actions were checked:
com.google.devtools.build.lib.analysis.actions.ParameterFileWriteAction FileWrite
    bazel-out/ios_x86_64-fastbuild/bin/external/bazel_tools/tools/objc/dummy_lib-archive.objlist
com.google.devtools.build.lib.rules.cpp.CppCompileAction ObjcCompile
    bazel-out/ios_x86_64-fastbuild/bin/external/bazel_tools/tools/objc/_objs/dummy_lib/external/bazel_tools/tools/objc/objc_dummy.o
    bazel-out/ios_x86_64-fastbuild/bin/external/bazel_tools/tools/objc/_objs/dummy_lib/external/bazel_tools/tools/objc/objc_dummy.d
com.google.devtools.build.lib.rules.cpp.CppLinkAction CppLink
    bazel-out/ios_x86_64-fastbuild/bin/external/bazel_tools/tools/objc/libdummy_lib.a
com.google.devtools.build.lib.analysis.actions.ParameterFileWriteAction FileWrite
    bazel-out/ios_x86_64-fastbuild/bin/external/bazel_tools/tools/objc/libdummy_lib.so-2.params
com.google.devtools.build.lib.rules.cpp.CppLinkAction CppLink
    bazel-out/ios_x86_64-fastbuild/bin/external/bazel_tools/tools/objc/libdummy_lib.so
com.google.devtools.build.lib.rules.cpp.CppLinkAction CppLink
    bazel-out/ios_x86_64-fastbuild/bin/external/bazel_tools/tools/objc/dummy_lib_fully_linked.a
com.google.devtools.build.lib.analysis.actions.BinaryFileWriteAction FileWrite
    bazel-out/ios_x86_64-fastbuild/bin/external/bazel_tools/tools/objc/dummy_lib.xcodeproj-control
com.google.devtools.build.lib.analysis.actions.SpawnAction GenerateXcodeproj
    bazel-out/ios_x86_64-fastbuild/bin/external/bazel_tools/tools/objc/dummy_lib.xcodeproj/project.pbxproj

	at com.google.devtools.build.lib.analysis.CachingAnalysisEnvironment.verifyGeneratedArtifactHaveActions(CachingAnalysisEnvironment.java:150)
	at com.google.devtools.build.lib.analysis.CachingAnalysisEnvironment.disable(CachingAnalysisEnvironment.java:113)
	at com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.createConfiguredTarget(ConfiguredTargetFunction.java:1144)
	at com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.compute(ConfiguredTargetFunction.java:261)
	at com.google.devtools.build.skyframe.ParallelEvaluator$Evaluate.run(ParallelEvaluator.java:398)
	... 4 more

As far as I can tell there is no way to control the platform_type from the commandline, so this build fails if I depend on anything macos specific but the swift compiler invocation looks okay.

bazel build -s '//tools/nail:_nail'

Additionally, I tried with a dummy objc main file as a source for apple_binary, I still get errors on the swift_library step. Here is the dummy file I used:

genrule(
    name = "dummy",
    cmd = """
        cat >$(OUTS) <<EOF
        #import "_nail.h"
        int main(int argc, char *argv[]) {
          @autoreleasepool {
            [Nail main];
          }
        }
        EOF
    """,
    srcs = [],
    outs = ["dummy.m"]
)

I'm on bazel 0.5.0 rc8

Am I doing something wrong here? Thanks!

Storyboard linking fails when using multiple swift modules

It seems I can't link storyboards if they aren't in the same swift_library.
Example:

swift_library(
   name = "Hello",
   srcs = ["Hello.swift"],
   resources = ["Resources/hello.storyboard"],
)

swift_library(
    name = "Goodbye",
    srcs = ["Goodbye.swift"],
    resources = ["Resources/en.lproj/Main.storyboard"],
)

ios_application(
    name = "Test",
    bundle_id = "com.test.Test",
    families = ["iphone"],
    infoplists = [ "Info.plist"],
    deps = [
        ":Hello",
        ":GoodBye",
    ],
)

This will fail with something similar to:

ERROR: file 'Example/Test.resources/linked-storyboards.zip' is generated by these conflicting actions:
Label: //Example:Test
RuleClass: ios_application rule
Configuration: c8250482a0237484f044a550688d69ab
Mnemonic: StoryboardLink
Action key: ce8878c46f578d55651681f44aff919a, 4f7b230321ccf180aa08f3293a67473b
Progress message: StoryboardLink Example/Test.resources/linked-storyboards.zip
PrimaryInput: File:[[[REDACTED]]Example/Test.resources/hello.storyboard.zip, File:[[REDACTED]Example/Test.resources/en.lproj/Main.storyboard.zip
PrimaryOutput: File:[[REDACTED]Example/Test.resources/linked-storyboards.zip
.

Allow output of bundling rules to be the bundle directory instead of IPA/ZIP

Tree artifacts are available experimentally in Bazel, so we should be able to have the output of the bundling rules be the bundle itself (e.g., a .app folder) instead of an IPA or ZIP file.

This will speed up the bundling by not requiring files to be zipped/unzipped internally, and then tools like Tulsi can use the output directory instead of unzipping the final archive as well.

We could try implementing this early with an experimental --define to control whether it's used or not.

Separate bundling rules from archive rules

Building the bundle and packaging the archive should be two separate rules, to separate the act of building a runnable artifact from building a distributable artifact.

Building the bundle should just build the .app/.appex/.framework/.whatever and the directory is the output.

Packaging the archive should only be available for top-level bundles (like iOS, tvOS, macOS applications, but not watchOS applications) and those rules should take the bundle above as a dependency. Then that rule, not the bundling rule, will handle packaging any support dependencies needed in the archive (like bitcode symbols, SwiftSupport libraries, etc.)

Blocked by #49.

ios_application_swift_test is known to fail for device builds

This test includes a test for code signing that verifies that the signature of the application matches the signature of the Swift dylibs that are bundled with it.

The problem is that the integration tests mock provisioning by default and ad hoc sign the bundle even for device builds, unless an alternate certificate is provided on the command line. So the identities of the app and the Swift dylibs don't match (because the Swift libraries are already signed by Apple) and the test fails:

test_swift_dylibs_are_signed_with_same_certificate_as_app FAILED: Expected '1', was '2' .

We need to look into another way of extracting code-sign output that ignores this distinction while still catching valid mismatches between app and dylibs.

Module names from objc_library targets have an unexpected _ prefix

Consider the following BUILD file:

# Description:
# Motion interchange format.

licenses(["notice"])  # Apache 2.0

exports_files(["LICENSE"])

objc_library(
    name = "MotionInterchange",
    srcs = glob([
        "src/*.m",
        "src/private/*.m",
    ]),
    hdrs = glob([
        "src/*.h",
        "src/private/*.h",
    ]),
    enable_modules = 1,
    includes = ["src"],
    visibility = ["//visibility:public"],
    copts = [
        "-Wall",  # Standard known-to-be-bugs warnings.
        "-Wcast-align",  # Casting a pointer such that alignment is broken.
        "-Wconversion",  # Numeric conversion warnings.
        "-Wdocumentation",  # Documentation checks.
        "-Werror",  # All warnings as errors.
        "-Wextra",  # Many useful extra warnings.
        "-Wimplicit-atomic-properties",  # Dynamic properties should be non-atomic.
        "-Wmissing-prototypes",  # Global function is defined without a previous prototype.
        "-Wno-error=deprecated",  # Deprecation warnings are never errors.
        "-Wno-error=deprecated-implementations",  # Deprecation warnings are never errors.
        "-Wno-sign-conversion",  # Do not warn on sign conversions.
        "-Wno-unused-parameter",  # Do not warn on unused parameters.
        "-Woverlength-strings",  # Strings longer than the C maximum.
        "-Wshadow",  # Local variable shadows another variable, parameter, etc.
        "-Wstrict-selector-match",  # Compiler can't figure out the right selector.
        "-Wundeclared-selector",  # Compiler doesn't see a selector.
        "-Wunreachable-code",  # Code will never be reached.
    ]
)

load("@build_bazel_rules_apple//apple:swift.bzl", "swift_library")

swift_library(
    name = "UnitTestsSwiftLib",
    srcs = glob([
        "tests/unit/*.swift",
    ]),
    deps = [":MotionInterchange"],
    visibility = ["//visibility:private"],
)

objc_library(
    name = "UnitTestsLib",
    srcs = glob([
        "tests/unit/*.m",
    ]),
    deps = [":MotionInterchange"],
    visibility = ["//visibility:private"],
)

load("@build_bazel_rules_apple//apple:ios.bzl", "ios_unit_test")

ios_unit_test(
    name = "UnitTests",
    deps = [
      ":UnitTestsLib",
      ":UnitTestsSwiftLib"
    ],
    minimum_os_version = "8.0",
    timeout = "short",
    visibility = ["//visibility:private"],
)

In a UnitTestsSwiftLib source file, the following import statement exists:

import MotionInterchange

However, when I run:

bazel test //:UnitTests

I get the following error:

error: no such module 'MotionInterchange'

If I run bazel with -s (thank you @allevato for the tip) and look at the module map, I see the following:

module "_MotionInterchange" {
  export *
  header "../../../../src/MDMMotionCurve.h"
  header "../../../../src/MDMMotionRepetition.h"
  header "../../../../src/MDMMotionTiming.h"
  header "../../../../src/MotionInterchange.h"

Changing my import to _MotionInterchange works, but is undesirable.

Expected behavior: bazel generates a module named MotionInterchange
Actual behavior: bazel generates a module named _MotionInterchange

Tests that use resources are failing

objc_library and objc_bundle_library use path relativization logic that is incorrect when an explicit repository reference is the path root (i.e., @build_bazel_rules_apple//test/testdata/...).

The fix will require changes in Bazel's native code, but I'm tracking it here too since it affects us.

Add bundles, resources, structured_resources to swift_library.

swift_library should be able to propagate resources and bundles to applications/extensions/frameworks just like objc_library can.

This was almost working but had some weird issues with certain dependency graphs where the aspect wasn't drilling down into other deps for unknown reasons. Gotta investigate.

Incremental swift compilation

Through some cursory tests to integrate bazel into our all swift project, we noticed that bazel doesn't currently support incremental swift compilation.

We've taken a stab at adding this by adding the -incremental and -emit-dependencies compiler flags and adding the dependency information to the output_file_map.json.

If I then run the commands that are being ran by bazel manually, I get incremental compilation, but running from bazel, it does not work incrementally. It seems as though bazel is removing the previously generated files after each change.

Is there a reason the initial Swift support didn't support incremental compilation? Also are there any plans to add this? I would be happy to submit a PR for the changes we've made if you can point me in the right direction on the problems we've ran in to.

Thanks!

(This was copied over from bazelbuild/bazel#2781)

Add bundle_name attribute to all bundling rules to override target name

Sometimes you don't want to use the target's name as the bundle's name, so we should add an optional bundle_name attribute that lets the user override that.

For example, currently this produces Foo.app and it can't be changed:

ios_application(
    name = "Foo",
    ...
)

So we should add this to get SomethingOtherThanFoo.app (note that the extension is still determined by the rule):

ios_application(
    name = "Foo",
    bundle_name = "SomethingOtherThanFoo",
    ...
)

Support Core Data mapping models

We don't currently have a way to compile Core Data mapping models (.xcmappingmodel/ bundles).

With resources being processed now based on file extension, it should be straightforward to add support for running mapc on these and bundling them with the application/extension.

Rewrite resource bundling rules

objc_bundle and objc_bundle_library should be deprecated and replaced with a single unified rule written in Skylark.

The rule would not do any bundling itself, but merely propagate AppleResource providers that tell the depending target where (i.e., what *.bundle directory) the resources should be included in.

objc_bundle makes very specific assumptions about the file layout (that is, it copies it verbatim, preserving any directory structure), so we need to figure out how to support that cleanly. structured_resources gets us part of the way there, but there are subtle path-handling cases that differ.

Migrate legacy providers to modern providers

The Apple bundling rules make significant use of providers to propagate information about resources, bundle types, etc. We need to migrate to modern providers (the provider() function, instead of string-keyed structs) and document them as public API.

Build fails for empty .strings files

If a .strings file is empty (and perhaps in other cases that haven't been tested yet, such as a file that contains only comments), the build will fail.

This is because we use plutil to convert the files to binary, whereas Xcode's CopyStringsFile step uses builtin-copyStrings. We don't have access to that, and it appears to have slightly different semantics for empty files.

Supporting this will probably require wrapping plutil in a small script for .strings file actions.

Always convert .strings/.plist to binary format

If a .strings file or .plist file comes into a bundle via objc_bundle or the structured_resources attribute of a library, it's copied verbatim instead of being processed like other resources.

There's no reason to do this, however; we should unconditionally convert all .strings and .plist files to binary no matter where they come from. Users should not expect these files to remain in their original form, and there's a decent amount of space to be saved especially for .strings files that have a large number of comments.

Asset Catalog Compile Failed with 2 swift Libraries

I think this is similar to #64 but for .png files.

Example build file:

swift_library(
    name = "Test",
    srcs = glob(["Test/**/*.swift"]),
    module_name = "Test",
    copts = ["-whole-module-optimization"],
    resources = glob([
        "Test/Resources/*.png",
        "Test/Resources/**/*.png",
        "Test/Resources/*.xib",
        "Test/Resources/**/*.xib",
        "Test/Resources/*.xcassets",
        "Test/Resources/**/*.xcassets",
        "Test/Resources/*.storyboard",
        "Test/Resources/**/*.storyboard",
    ]), 
)

swift_library(
    name = "Test2",
    srcs = glob(["Test2/Classes/**/*.swift"]),
    module_name = "Test2",
    copts = ["-whole-module-optimization"],
    deps = [
        ":Test",
    ],
    resources = glob([
        "Test2/Resources/*.png",
        "Test2/Resources/**/*.png",
        "Test2/Resources/*.nib",
        "Test2/Resources/**/*.nib",
        "Test2/Resources/*.xib",
        "Test2/Resources/**/*.xib",
        "Test2/Resources/*.storyboard",
        "Test2/Resources/**/*.storyboard",
        "Test2/Resources/*.xcassets",
        "Test2/Resources/**/*.xcassets",
    ])
)

ios_application(
    name = "Test2Example",
    bundle_id = "com.Test2Example",
    families = ["iphone"],
    minimum_os_version = "9.0",
    infoplists = glob([
        "Info.plist",
    ]),
    deps = [
        ":Test2",
    ],
)

ERROR:

Showing All Messages
ERROR: file 'Example/Test2Example.resources/actool-output.zip' is generated by these conflicting actions:
Label: //Example:Test2Example
RuleClass: ios_application rule
Configuration: 5caa06091ce5d82dc46414d4e65e8522
Mnemonic: AssetCatalogCompile
Action key: 0b1f24797225c2ad1aeae674712feac3, cf0b7f338f9207186d97209f351b9e6d
Progress message: AssetCatalogCompile Example/Test2Example.resources/actool-output.zip
PrimaryInput: File:[REDACTED]Test/Resources/images.xcassets/Alerts/Alert_Contest_Award_Icon.imageset/Award Dialog [email protected], File:[REDACTED]Example2/Test2/Resources/Images.xcassets/Chat/Filetypes/filetype-generic.imageset/filetype-generic.png
PrimaryOutput: File:[[REDACTED]bazel-out/darwin_x86_64-dbg/bin]Example2/Test2Example.resources/actool-output.zip
.
ERROR: Analysis of target '//Example2:Test2Example' failed; build aborted.

application-identifier entitlement in Simulator

#63 describes how entitlements are not applied unless a provisioning profile is set. To an extent, this is an expected behavior as some entitlements require replacing variables like $(AppIdentifierPrefix) which require a provisioning profile in order to get that value.

This gets a little trickier with Simulator builds as they do not explicitly require entitlements or a provisioning profile in order to build. When building with Xcode 8 targeting iOS 10 Simulator, Xcode will always add the application-identifier entitlement regardless of your entitlement settings. This entitlement seems to be required to use certain APIs, for instance the Keychain API via Security.framework.

I've created a workaround that wraps ios_application and adds a __entitlements text segment with a blank value for application-identifier when the value for provisioning_profile is not set. This seems to work to make those APIs available again, but I'm not sure how sound of a solution it is or if it may cause other problems.

Perhaps this is a thing that the bazel apple rules should do automatically to give it more parity with how Xcode does simulator builds?

Sanitize target name before using it as a C symbol for debug entitlements

When we create a C function for the linker when injecting debug entitlements, we construct it from the build target's name. This can, however, contain characters that are not valid in a C symbol—the most common one being the hyphen.

The name should be sanitized before being used as a symbol.

Add "minimum_os_version" attribute to bundle rules

Now that apple_binary has a minimum_os_version attribute, add it to the bundle rules as well. This will let multiple bundles that are part of the same build (i.e., an application and its extension) to have different minimum OS versions.

This is important if users want to adopt very new extensions (like iMessage extensions in iOS 10) while still allowing their core app to support older versions of iOS.

Bundle Bitcode symbol maps with the IPA

For Bitcode builds, those symbol maps should be included in the final IPA—I believe Xcode uses the BCSymbolMaps folder, a sibling of Payload, to send these to Apple so that it can process them.

Validate CFBundleVersion and CFBundleShortVersionString

Info.plist processing should validate the version values that end up in the final plist and cause a build failure if they are invalid.

Unfortunately, Apple's own documentation isn't quite consistent with what they actually accept in submissions, so doing this correctly is a bit trickier than it should be. We don't want to have false positives or false negatives.

ios_application fails when using provisioning_profile

I'm running latest master version of bazel and the apple rules. I have a sample application, which is setup to use a real provisioning profile for this sample app id. I'm running into the following error when attempting to build the ios_application target.

INFO: Found 1 target...
ERROR: /Users/fitz/Code/bazel-examples/HelloBuck/HelloBuck/BUILD:14:1: error executing shell command: 'set -e && PLIST=$(mktemp -t entitlements.plist) && trap "rm ${PLIST}" EXIT && security cms -D -i "HelloBuck/provisioning/integration_testing.mobileprovision" > ${PLIST} && /usr/libexec/PlistBuddy -...' failed: bash failed: error executing command
  (exec env - \
  /bin/bash -c 'set -e && PLIST=$(mktemp -t entitlements.plist) && trap "rm ${PLIST}" EXIT && security cms -D -i "HelloBuck/provisioning/integration_testing.mobileprovision" > ${PLIST} && /usr/libexec/PlistBuddy -x -c '\''Print Entitlements'\'' ${PLIST} > "bazel-out/local-fastbuild/bin/HelloBuck/entitlements/Peloton_entitlements.entitlements_with_variables"')

Use --sandbox_debug to see verbose messages from the sandbox.
security: SecPolicySetValue: One or more parameters passed to a function were not valid.
security: cert import failed: UNIX[Operation not permitted]
security: problem decoding
Use --strategy=ExtractAppleEntitlements=standalone to disable sandboxing for the failing actions.
WARNING: Cannot delete sandbox directory after action execution: /private/var/tmp/_bazel_fitz/eee1aeec8b965ffb8dc3e98cab7ac9b9/bazel-sandbox/9050354069223113742 (java.io.IOException: /private/var/tmp/_bazel_fitz/eee1aeec8b965ffb8dc3e98cab7ac9b9/bazel-sandbox/9050354069223113742/execroot/HelloBuck (Directory not empty)).
Target //HelloBuck:Peloton failed to build
INFO: Elapsed time: 0.497s, Critical Path: 0.43s

WORKSPACE

load('@bazel_tools//tools/build_defs/repo:git.bzl', 'git_repository')

git_repository(
  name = "build_bazel_rules_apple",
  remote = "https://github.com/bazelbuild/rules_apple.git",
  commit = "fe6b902e0c6e17247706d8c8fdb8f83b1644cfa6"
)

BUILD

package(default_visibility = ["//visibility:public"])

licenses(["notice"])

load("@build_bazel_rules_apple//apple:ios.bzl", "ios_application")
load("@build_bazel_rules_apple//apple:swift.bzl", "swift_library")

swift_library(
  name = "lib",
  srcs = glob(["*.swift"])
)

ios_application(
    name = "HelloWorld",
    bundle_id = "com.Peloton.HelloWorld",
    families = [
        "iphone",
        "ipad",
    ],
    infoplists = [":Info.plist"],
    launch_storyboard = "Resources/LaunchScreen.storyboard",
    deps = [":lib"],
    provisioning_profile = "//HelloBuck/provisioning:integration_testing.mobileprovision",
)

Locally when I run security cms -D -i integration_testing.mobileprovision it outputs on stderr security: SecPolicySetValue: One or more parameters passed to a function were not valid. However, it also prints out the decoded plist on stdout. This appears to be a known issue with mac os sierra.

Set up Bazel continuous integration

We need to get our integration tests running on Bazel CI and hooked into pull requests. Also, get the little badges in our README that show the current build status.

Support building macOS applications and extensions

Some of the pieces are already in place in the core bundler (i.e., the differing directory structure between macOS and other platforms), but we need to provide rules for building macOS apps (both UI and command line) and extensions.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.