bazelbuild / bazelbuild/rules_apple
Inherting a class from dynamic framework(`ios_framework`) throws undefined symbol errors
- 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
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