Closed kalub92 closed 3 months ago
@kalub92 Actually, cocoapods-spm has nothing to do with the module name. It's up to the package author to manage it. Linking frameworks/libraries/packages does not intervene in how the module name is treated.
If the target name is foo-ios
, for example, then the module name is foo_ios
.
let package = Package(
...
targets: [
.target(name: "foo-ios") // <-- HERE
]
)
(1) Therefore, please first make sure you're using the correct module name in Swift code: import foo_ios
(2) In case you're specifying the correct module name foo_ios
and it's still saying No such module 'foo_ios'
, it might be a linking issue (potentially caused by this plugin).
In this case, is it possible to have a demo to reproduce the issue? (you can use the example project for convenience)
Thank you!
Thanks for the clarification! The package is defined with the name PackageName-iOS
and shows up in Xcode like this: import PackageName_iOS
but I'm still seeing the No such module...
errors.
I'll try to get a sample project to you tomorrow to investigate! Thank you!
I was able to reproduce this! I created a new sample module called SamplePackageB-iOS
(link) where the only difference is a hyphenated name. I created a branch off of SamplePackageA
(on this branch) that consumes this package instead of the previous module, SamplePackageB
.
I forked cocoapods-spm
and the example project demonstrates this issue on this branch: kalub92/hyphenated_module_name_bug
First, I had to actually git reset
back to https://github.com/trinhngocthuyen/cocoapods-spm/commit/d6e0140a91f37fb69948ac8f215a1fd8a3594201 before the dylib
changes you made in order for pod install
to work... Might be a separate issue, but anyway – I am consuming my module like so in an abstract target (like the app I'm trying to resolve this for):
FYI, I removed a few dependencies because
Orcam
was experiencing a compilation error.
def spm_pods
spm_pkg "SamplePackageA",
:git => "https://github.com/kalub92/SamplePackageA.git",
:branch => "withHyphenatedDependency",
:linkage => :static,
:linking => {
# Prefer adding products to the "Link Binary With Libraries" section
:use_default_xcode_linking => true,
:linker_flags => ["-ld_classic"]
}
end
abstract_target 'Example' do
spm_pods
target "EX" do
pod "Logger", :path => "LocalPods/Logger"
# pod "CommonUI", :path => "LocalPods/CommonUI"
# pod "Services", :path => "LocalPods/Services"
spm_pkg "SnapKit",
:url => "https://github.com/SnapKit/SnapKit.git",
:version => "5.7.1",
:products => ["SnapKit-Dynamic"]
spm_pkg "SwiftUIX", :git => "https://github.com/SwiftUIX/SwiftUIX.git", :tag => "0.1.9"
spm_pkg "SwiftyBeaver", :git => "https://github.com/SwiftyBeaver/SwiftyBeaver.git", :tag => "2.0.0"
spm_pkg "opentelemetry-swift",
:git => "https://github.com/open-telemetry/opentelemetry-swift.git",
:branch => "main",
:products => ["OpenTelemetrySdk"]
spm_pkg "GoogleMaps",
:git => "https://github.com/googlemaps/ios-maps-sdk.git",
:version => "8.4.0",
:products => ["GoogleMaps", "GoogleMapsBase", "GoogleMapsCore"]
spm_pkg "DebugKit", :path => "LocalPackages/debug-kit"
end
target "EXTests" do
end
end
The pod install
command executes successfully, but when I attempt to run either the EX
or EX Tests
targets, I see this error related to the [CP] Copy Pods Resources
build phase:
To see if I could get around that, I deleted that phase manually from both EX
and EX Tests
targets, cleared out derived data, and cleaned the build folder.
When attempting to compile EX
target, I get a duplicate symbols error (gist):
When attempting to compile the EX Tests
target, I see that mentioned hyphenated No such module...
naming issue:
Thanks for the reproduction. I managed to make it work on this branch: demo/87. Kindly check this commit for the diff.
Highlights of the change:
Pods-<App>
), it's already usable for the <App>
target.
As a best practice, you should not have any SPM added to the App's xcodeproj.:use_default_xcode_linking => true
option.
-ld_classic
argument, causing the duplicate symbols :(.:use_default_xcode_linking
option.Tip: run make ex.install
for the shortcut to pod install together with some prebuilt macros (Orcam, MacroCodableKit)
I made the changes you suggested:
.xcodeproj
SPM packages and defined in Podfile instead:use_default_xcode_linking
This does resolve the No such module
/Module name is not a valid identifier
error, but now I'm seeing this in my project at work:
Missing required module 'ThirdPartyAdapter'
Which is a recursive dependency of the main SPM package I'm trying to import:
SamplePackageA
↳ SamplePackageB-iOS
↳ ThirdPartyAdapter
I'm working on reproducing this in the sample app project, but haven't had luck yet...
I was able to reproduce it in the sample project: link
After closer inspection, I made changes to the following modules to more closely follow the pattern established in our app:
When compiling, I first see this referencing the [CP] Copy Pods Resources
build phase:
Then, after removing that from EX
/EX Tests
, attempting to compile results in the error I see in my work project:
I checked out the demo code at the given commit 88f6b6e.
Below is the revision of the packages:
As I mentioned in the earlier comment, the "multiple commands produce..." error is because the same package was added to the main target (which is duplicated). Because this step fails, the subsequent steps might produce false-alarm errors.
Please remove the package from the main target because the package is transitively available when adding it to the Pods project already.
After removing it, the build succeeded from my end.
Do let me know if I missed any steps :)
Thanks for the reply! I just removed SamplePackageA
from the EX
project, which removed it (and SamplePackageAConfig
) from Link Binary with Libraries
as you'd expect.
Commit: https://github.com/trinhngocthuyen/cocoapods-spm/commit/1fd8bccf77365ce78ac4304a4fd380bca82c1e19
And I don't get the Multiple commands produce...
error anymore however, after cleaning the project and deleting derived data I still see the Missing required module 'ThirdPartyAdapter'
error.
I should add that I'm using Xcode 15.0 and am updating now to 15.3 to see if this is a possible linker bug in 15.0 that was resolved in a recent update.
Update: I upgraded Xcode to 15.3 and still see the same error.
Another update: after reading a bit about others experiencing similar problems and found that they avoid exposing transitive dependencies to the developer by using static linkage and the @_implementationOnly
modifier to import that dependency.
Even though this is an undocumented modifier, a few large frameworks (Firebase, for example), has been using this for a while: https://github.com/search?q=repo%3Afirebase%2Ffirebase-ios-sdk+%40+_implementationOnly&type=code
It seems that this was formalized in Swift 6.0: https://github.com/apple/swift-evolution/blob/main/proposals/0409-access-level-on-imports.md
Anyway, I made that change here and it resolved the Missing required module
issue and allows the app target and test target to compile and run successfully:
https://github.com/kalub92/SamplePackageA/blob/6eea4f37ae112c4fb7efabc1b87183622599f84b/Sources/SamplePackageA/SamplePackageA.swift#L2
Not sure if this helps figure out why the test target isn't able to see ThirdPartyAdapter
, but figured I'd share!
@kalub92 It's kind of weird as it actually works fine on my end (with the given commit 1fd8bcc). I'm using Xcode 15.3 though. I also verify on another machine by running on CI. And it works (refer to this job: https://github.com/trinhngocthuyen/exp/actions/runs/9095279979/job/24998161460).
My doubt is that the spm cache is not invalidated. Could you please help remove the .spm.pods
directory, run pod installation, then try again? Thank you!
~@trinhngocthuyen Strange... I did the following:~
.spm.pods
directory~DerivedData
& quit Xcode~pod install
~~But I'm still seeing the same error.~
⚠️ Update: Figured out why you were seeing it succeed on your end. See comment below.
Discovered why it was working on your end – I had made changes to the SamplePackageA
and SamplePackageB-iOS
which allowed compilation.
Just updated those packages back to their former settings they should have been at:
The behavior where the app target compiles successfully, but the test target does not is back with these changes.
I think it might have something to do with the .mm
& .hpp
files in ThirdPartyAdapter
? It's an adapter that is supposed to work with the provided .xcframeworks
in Frameworks/ThirdPartyVendor/iOS
. In my work project, that adapter is only imported in SamplePackageA
and not externally to it.
Hi @kalub92,
PR #88 should fix the above issue. Kindly help verify with the latest from main. Below are some more details:
publicHeadersPath: "foo"
in the target.
In this case, the package was using an implicit headers path (<Target>/include
), a corner case the plugin has not yet handled.Thank you for your collaborative effort! That means a lot :)
Thank you so much! This seems to have resolved the Missing required module...
error but now that I've gotten past that I am seeing a bunch of Undefined symbols...
errors from that adapter when attempting to link my podspec that takes in these packages as dependencies...
I'm seeing this in my work project, but I'm trying to configure my sample packages so that it reproduces the same behavior in the sample app.
"Undefined symbols..." typically means there's a library/framework/object that was not linked to the binary. May I know the undefined symbols? They should give us a clue about which binary was not linked.
I'm not able to share the particular symbols from my work project, but was able to reproduce this issue by adding some methods to the ThirdPartyAdapter
to wrap around the provided OneSignal.xcframework
:
This structure very closely resembles how my work project is configured with this dependency.
Please check out the latest commit for my fork and run the sample app and ensure that SamplePackageB-iOS is updated to its latest commit as well: https://github.com/kalub92/SamplePackageB-iOS/commit/064c476b28cdec893fcce53b09337f2dbc611f8a
Thanks for the update. I found the root cause. Working on a fix.
@kalub92 Would you mind checking again with the latest from main (fixed by https://github.com/trinhngocthuyen/cocoapods-spm/pull/93)? Thank you!
I'm on the latest and am seeing a new issue that can be reproduced in the cocoapods-spm
example app.
We're pulling in Firebase and a few of its products:
spm_pkg "Firebase",
:url => "https://github.com/firebase/firebase-ios-sdk.git",
:version => "8.14.0",
:products => ["FirebaseAnalytics", "FirebaseCrashlytics"]
When doing this, we get the following error upon pod install
:
Errno::ENOENT - No such file or directory @ rb_check_realpath_internal - .spm.pods/packages/metadata/Promises.json
/Users/cstultz/Documents/GitHub/trinhngocthuyen/lib/cocoapods-spm/helpers/io.rb:7:in `realpath'
/Users/cstultz/Documents/GitHub/trinhngocthuyen/lib/cocoapods-spm/helpers/io.rb:7:in `realpath'
/Users/cstultz/Documents/GitHub/trinhngocthuyen/lib/cocoapods-spm/helpers/io.rb:7:in `symlink'
/Users/cstultz/Documents/GitHub/trinhngocthuyen/lib/cocoapods-spm/swift/package/project_packages.rb:51:in `block in load'
/Users/cstultz/Documents/GitHub/trinhngocthuyen/lib/cocoapods-spm/swift/package/project_packages.rb:38:in `each'
/Users/cstultz/Documents/GitHub/trinhngocthuyen/lib/cocoapods-spm/swift/package/project_packages.rb:38:in `load'
/Users/cstultz/Documents/GitHub/trinhngocthuyen/lib/cocoapods-spm/swift/package/project_packages.rb:12:in `initialize'
/Users/cstultz/Documents/GitHub/trinhngocthuyen/lib/cocoapods-spm/resolver/recursive_target_resolver.rb:21:in `new'
/Users/cstultz/Documents/GitHub/trinhngocthuyen/lib/cocoapods-spm/resolver/recursive_target_resolver.rb:21:in `project_pkgs'
/Users/cstultz/Documents/GitHub/trinhngocthuyen/lib/cocoapods-spm/resolver/recursive_target_resolver.rb:31:in `block in resolve_recursive_targets'
/Users/cstultz/Documents/GitHub/trinhngocthuyen/lib/cocoapods-spm/resolver/recursive_target_resolver.rb:28:in `each'
/Users/cstultz/Documents/GitHub/trinhngocthuyen/lib/cocoapods-spm/resolver/recursive_target_resolver.rb:28:in `resolve_recursive_targets'
/Users/cstultz/Documents/GitHub/trinhngocthuyen/lib/cocoapods-spm/resolver/recursive_target_resolver.rb:15:in `resolve'
/Users/cstultz/Documents/GitHub/trinhngocthuyen/lib/cocoapods-spm/resolver.rb:24:in `each'
/Users/cstultz/Documents/GitHub/trinhngocthuyen/lib/cocoapods-spm/resolver.rb:24:in `resolve'
/Users/cstultz/Documents/GitHub/trinhngocthuyen/lib/cocoapods-spm/patch/installer.rb:59:in `block in resolve_spm_dependencies'
/Users/cstultz/.rvm/gems/ruby-3.1.0/gems/cocoapods-1.14.3/lib/cocoapods/user_interface.rb:64:in `section'
/Users/cstultz/Documents/GitHub/trinhngocthuyen/lib/cocoapods-spm/patch/installer.rb:57:in `resolve_spm_dependencies'
/Users/cstultz/Documents/GitHub/trinhngocthuyen/lib/cocoapods-spm/patch/installer.rb:13:in `block in <class:Installer>'
/Users/cstultz/.rvm/gems/ruby-3.1.0/gems/cocoapods-1.14.3/lib/cocoapods/installer.rb:162:in `install!'
/Users/cstultz/.rvm/gems/ruby-3.1.0/gems/cocoapods-1.14.3/lib/cocoapods/command/install.rb:52:in `run'
/Users/cstultz/.rvm/rubies/ruby-3.1.0/lib/ruby/gems/3.1.0/gems/claide-1.1.0/lib/claide/command.rb:334:in `run'
/Users/cstultz/.rvm/gems/ruby-3.1.0/gems/cocoapods-1.14.3/lib/cocoapods/command.rb:52:in `run'
/Users/cstultz/.rvm/gems/ruby-3.1.0/gems/cocoapods-1.14.3/bin/pod:55:in `<top (required)>'
/Users/cstultz/.rvm/gems/ruby-3.1.0/bin/pod:25:in `load'
/Users/cstultz/.rvm/gems/ruby-3.1.0/bin/pod:25:in `<main>'
/Users/cstultz/.rvm/gems/ruby-3.1.0/bin/ruby_executable_hooks:22:in `eval'
/Users/cstultz/.rvm/gems/ruby-3.1.0/bin/ruby_executable_hooks:22:in `<main>'
Updated my previous comment 👆
To validate that your fix above worked for the binary name detection and public headers issues I made a few other changes to more closely follow my app's structure:
Removed our Firebase dependency temporarily
Refactored TestKit
into NetworkTestKit
and AppTestKit
, which in our code basically do the following:
NetworkTestKit
takes in SamplePackageA
as an SPM dependency
Pod::CompactSpec.new do |s|
s.name = "NetworkTestKit"
s.spm_dependency "SamplePackageA/SamplePackageA"
end
AppTestKit
takes in NetworkTestKit
as a dependency
Pod::CompactSpec.new do |s|
s.name = "AppTestKit"
s.dependency "NetworkTestKit"
end
Made changes to SamplePackageB-iOS
to bring in more kinds of .xcframework
that help replicate our issue
With that, I am now able to compile the EX app target, but when the app launches, I see the following issue:
dyld[97467]: Library not loaded: @rpath/ogg.framework/ogg
Referenced from: <2DA628EF-071C-33D8-AA00-7B1A3EBC3599> /Users/cstultz/Library/Developer/Xcode/DerivedData/EX-dvopbqpxtghxchfetmgezzfsuptf/Build/Products/Debug-iphonesimulator/opus.framework/opus
Reason: tried: '/Users/cstultz/Library/Developer/Xcode/DerivedData/EX-dvopbqpxtghxchfetmgezzfsuptf/Build/Products/Debug-iphonesimulator/ogg.framework/ogg' (no such file), '/Users/cstultz/Library/Developer/Xcode/DerivedData/EX-dvopbqpxtghxchfetmgezzfsuptf/Build/Products/Debug-iphonesimulator/PackageFrameworks/ogg.framework/ogg' (no such file), '/Users/cstultz/Library/Developer/CoreSimulator/Devices/79B9F89A-CC2B-4846-BBA7-84E3AF0DBDA7/data/Containers/Bundle/Application/17870CCD-78D9-41F8-AEC7-90DE0A49E573/Frameworks/ogg.framework/ogg' (no such file), '/Users/cstultz/Library/Developer/Xcode/DerivedData/EX-dvopbqpxtghxchfetmgezzfsuptf/Build/Products/Debug-iphonesimulator/opus.framework/Frameworks/ogg.framework/ogg' (no such file), '/Users/cstultz/Library/Developer/CoreSimulator/Devices/79B9F89A-CC2B-4846-BBA7-84E3AF0DBDA7/data/Containers/Bundle/Application/17870CCD-78D9-41F8-AEC7-90DE0A49E573/EX.app/Frameworks/ogg.framework/ogg' (no such file), '/Users/cstultz/Library/Developer/CoreSimulator/Devices/79B9F89A-CC2B-4846-BBA7-84E3AF0DBDA7/data/Containers/Bundle/Application/17870CCD-78D9-41F8-AEC7-90DE0A49E573/EX.app/Frameworks/ogg.framework/ogg' (no such file), '/Library/Developer/CoreSimulator/Volumes/iOS_21E213/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 17.4.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/ogg.framework/ogg' (no such file)
And when attempting to compile the EXTests target, I am seeing a familiar issue again: Missing required module 'ThirdPartyAdapter'
Get the latest changes on my fork (branch: kalub92/hyphenated_module_name_bug
) here: https://github.com/kalub92/cocoapods-spm/commit/3a50a4a5292b9006c960dc2ef6284c40e45cb422
Hey @trinhngocthuyen - any update on the above issues?
Srr I'm a bit occupied lately. Will look into it this weekend.
Srr I'm a bit occupied lately. Will look into it this weekend.
Thank you! I really appreciate it. 😁
@kalub92 I fixed the issue (with Firebase) mentioned in https://github.com/trinhngocthuyen/cocoapods-spm/issues/87#issuecomment-2141028614 in #97. Kindly check again.
Regarding the issue about Library not loaded: @rpath/ogg.framework/ogg
, would you mind creating another dedicated issue for better tracking? Thank you!
@trinhngocthuyen Thank you – I've confirmed that with #97 I can install Firebase
via spm_pkg
.
Just raised a new issue for the Library not loaded...
bug: https://github.com/trinhngocthuyen/cocoapods-spm/issues/98
Thanks again for all your hard work – this is going to really help my team once it's working for us!
Hi @trinhngocthuyen, any update on this issue? 😁
Gonna follow up on the other thread/issue. For this thread, I think I'm gonna close as it's becoming more irrelevant with the original (which was not the case).
What happened?
When attempting to compile the test target for my project, I get the following errors:
Error 1 (
SwiftDriver
error buildingDependencyPackage-iOS
):Error 2 (building
PackageA
):It seems that the hyphenated
DependencyPackage-iOS
is an invalid module name, but I notice inPackageA
that when they've been importing this dependency asDependencyPackage_iOS
with an underscore. Doescocoapods-spm
account for this?I looked up the
Module name is not a valid identifier
error and saw that using hyphens in module names is not allowed but that there is a C99 modifier that can be used (e.g.c99extidentifier
) when linking frameworks to allow this:$(PRODUCT_NAME:c99extidentifier)
.Wondering if this is part of the issue?
CocoaPods environment
Stack
Installation Source
Plugins
Podfile
Anything else?
No response