bazelbuild / bazelbuild/rules_apple

Inherting a class from dynamic framework(`ios_framework`) throws undefined symbol errors

Open
#2,264 9 comments 1 reaction 0 assignees View on GitHub
Dominant language
Starlark
Stars
593
Forks
334
Avg merge
16h 48m
Merged PRs (30d)
9

Description

### What's the issue?

We have a dynamic framework that has `open class` and we have a static library that inherits the open class from Framework and depends on the underlying `swift_library`. It looks something like this

#### Foo Framework
```
open class Foo {
public var name: String?
public init() { }

public convenience init(name: String) {
self.init()
self.name = name
}

private func someFunction() {
print("Hello world")
}
}
```

#### Bar Library
```
import Foo

public final class Bar: Foo {
public convenience init(name: String) {
self.init(name: name)
}
}
```

When I run Bazel build for release configuration `--compilation_mode=opt` , it throws undefied symbol error for the private function from dynamic framework `private func someFunction()`

### How to reproduce
To reproduce this clone - https://github.com/sanju-naik/Bazel-Example.git and check out the `dynamic-framework-issues` branch.

Running the following command should throw error - `bazel build --config=Release --ios_multi_cpus=sim_arm64 BazelDemo`

### Error Message
```/Users/sanju/Projects/Bazel-Example/BazelDemo/BUILD:75:16: Linking BazelDemo_bin failed: (Exit 1): wrapped_clang failed: error executing command (from target //:BazelDemo)
(cd /private/var/tmp/_bazel_sanju/e107e611dd65132537122ef1dabd8e89/execroot/__main__ && \
exec env - \
APPLE_SDK_PLATFORM=iPhoneSimulator \
APPLE_SDK_VERSION_OVERRIDE=16.4 \
PATH=/Users/sanju/Library/Caches/bazelisk/downloads/bazelbuild/bazel-6.3.2-darwin-arm64/bin:/opt/homebrew/opt/openjdk/bin:/Users/sanju/.rbenv/shims:/Users/sanju/.rbenv/bin:/opt/homebrew/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin \
XCODE_VERSION_OVERRIDE=14.3.0.14E222b \
ZERO_AR_DATE=1 \
external/local_config_cc/wrapped_clang @bazel-out/ios-sim_arm64-min12.0-applebin_ios-ios_sim_arm64-opt-ST-acb08275552e/bin/BazelDemo_bin-2.params)
# Configuration: b94fcb8744f284f7d0ecde69e1d097360d802dc23000b86c0429a22d42c495f9
# Execution platform: @local_config_platform//:host
Undefined symbols for architecture arm64:
"_$s3FooAAC12someFunction33_EDFAF2F1CEBC6FC422A5A3D516B36930LLyyF", referenced from:
_$s3BarAACN in libBar.a(Bar.swift.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Error in child process '/usr/bin/xcrun'. 1
Target //:BazelDemo failed to build
INFO: Elapsed time: 0.359s, Critical Path: 0.22s
INFO: 2 processes: 2 internal.
FAILED: Build did NOT complete successfully
```

## Note:
Build works fine in Debug mode i.e `--compilation_mode=dbg` , throws error only in case of Release mode, seems like when optimisations are turned on its dropping the private function?

Contributor guide

Open the contributing guide

Research direction

Clone the linked Bazel-Example repository, check out the dynamic-framework-issues branch, and inspect BazelDemo/BUILD along with the Foo and Bar framework/library definitions shown in the report. Run the provided Release build command, compare it with --compilation_mode=dbg, and trace the undefined symbol for Foo.someFunction. Done means the optimized iOS simulator build links successfully without the undefined symbol error.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift
Domain
build-system, mobile-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.