Steps to reproduce:
- Create a new project in Xcode with template Cocoa Touch Framework, and name it TestFramework.
- Add another target in this project with template Cocoa Touch Static Library, and name it TestLibrary.
- In the auto-generated file TestLibrary.swift, add a public interface like:
public struct TestLibrary {
public init() { }
public let name = "static library"
}
- In target TestFramework, link libTestLibrary.a.
- In target TestFramework, create a new file with the name TestFramework.swift.
- In TestFramework.swift, import TestLibrary and use the API it provides without exposing any symbol in public, like
import TestLibrary
public struct TestFramework {
public init() { }
public let library = TestLibrary().name
}
- Build target TestFramework, and locate the product TestFramework.framework.
- Create a new project in Xcode with template Single View Application, and name it TestApplication.
- Drag the TestFramework.framework from step 7 into the Embedded Binaries build phase of TestApplication.
- In the file AppDelegate.swift of TestApplication, import TestFramework like
import UIKit
import TestFramework
- Run the app.
- At the line where TestFramework is imported, an error is prompted:
Missing required module 'TestLibrary'
- If you command-click on that
import TestFramework
, Xcode will generate the public interfaces of TestFramework, and it shows as:
import Foundation
import SwiftOnoneSupport
import TestFramework
import TestFramework.Swift
import TestLibrary
import UIKit
...
So this is where I got confused.
TestLibrary is statically linked with TestFramework, which means the binary of TestFramework has all the symbols from TestLibrary. Plus, TestFramework is not exposing any APIs from TestLibrary, but only using them. This means TestFramework is fully functional on its own regardless of TestLibrary being presented or not.
So why the .swiftmodule file of TestFramework creates an additional (probably unnecessary) dependency on TestLibrary?
As a result, when a user uses TestFramework to build an app, the app won't be able to compile because it can not find the TestLibrary, but it can run perfectly because it actually does not use TestLibrary directly if we can somehow bypass that dependency check.
So I am wondering if there is a way to remove a dependency from .swiftmodule file?
Or is there any compile/link flag I can pass in to prevent it generates any unnecessary dependency?
Just found another similar description of this problem while I was searching through the internet for a solution:
https://gist.github.com/briancroom/5d0f1b966fa9ef0ae4950e97f9d76f77