Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pod lint fails when containing dynamic-frameworks without simulator architectures #5854

Closed
lukasdanzer opened this issue Sep 13, 2016 · 50 comments
Labels
r:vendored Issues related to vendored libraries and frameworks t2:defect These are known bugs. The issue should also contain steps to reproduce. PRs welcome!
Milestone

Comments

@lukasdanzer
Copy link

lukasdanzer commented Sep 13, 2016

Currently pod trunk is not usable for us as pod lint fails because simulator architectures (i386 and x86_64) are missing. BUT Apple rejects apps containing dynamic-frameworks with simulator architectures.

We deploy two variants of dynamic-framworks

  • one with all device and simulator architectures (for debugging)
  • one with device-only architectures (for app-submission).

pod lint fails with the following errors:

x86_64 in file SampleSDK/iOS/Sample.framework/Sample (3 slices)

  • NOTE | [SampleSDK/SampleSDK and more...] xcodebuild: fatal error: lipo: -remove's specified would result in an empty fat file
  • NOTE | [iOS] [SampleSDK/SampleSDK] xcodebuild: ld: warning: ld: warning: ignoring file SampleSDK/iOS/Sample.framework/Sample, missing required architecture x86_64 in file

We were forced to provide device-only architectures as Apple rejects app-submissions containing any simulator-architectures with

ERROR: ERROR ITMS-90087: "Unsupported Architectures. The executable for Sample.app/Frameworks/Sample.framework contains unsupported architectures '[x86_64, i386]'."

Similar issues:
#5275
http://stackoverflow.com/questions/36618252/cocoapods-podspec-push-without-build-simulator-architecture

@Philipp372
Copy link

I am also affected by this problem, that I aim to distribute a dynamic framework pod without the simulator architectures as they are not allowed when submitting an app to the AppStore.
Cocoapods team, pls advise.

@ghost
Copy link

ghost commented Sep 15, 2016

Thank you benasher44, it indeed is the same problem for me : #5877

We haven't submit to Apple yet, so I can't confirm eldewy's problem, but if it's the same here, it's a huge issue for my team.

Cocoapods team, could you please do something or advise us a working solution ?

Thanks

@orta
Copy link
Member

orta commented Sep 15, 2016

I'm not really sure of the answer here, 1.0 now has more strict linting rules because successfully working with other people's projects is becoming more complicated due to things like code-signing, frameworks and code-signing.

Perhaps a PR improving the linter specifically towards binary/dynamic framework pods that can take into account it's constraints better could be a way to move forwards?

@lukasdanzer
Copy link
Author

@orta
This is a problem only with dynamic.frameworks...
What are the next steps required by us? How should we proceed to enforce a change?
We want to move our podspecs to the public github repository, but cannot because of this issue.

@orta
Copy link
Member

orta commented Sep 20, 2016

Perhaps a PR improving the linter specifically towards binary/dynamic framework pods that can take into account it's constraints better could be a way to move forwards?

I think the next step is to look at validator.rb and make improvements specific to dynamic frameworks 👍

@lukasdanzer
Copy link
Author

how can I start a initiative that this improvement is made?

@orta
Copy link
Member

orta commented Sep 22, 2016

This project is open source and ran by volunteers in their spare time, you could start contributing by going through the getting started guide

An alternative is to commission an individual to add that feature for you instead.

@ernya
Copy link

ernya commented Sep 22, 2016

@eldewy I managed to go around this issue by replacing the code inside the xcodebuild function of validator.rb by that one :

def xcodebuild
      require 'fourflusher'
      command = ['clean', 'build', '-workspace', File.join(validation_dir, 'App.xcworkspace'), '-scheme', 'Pods-App', '-configuration', 'Release']
      case consumer.platform_name
      when :ios
        command += %w(-sdk iphoneos10.0 -destination=generic/iOS ONLY_ACTIVE_ARCH=NO ARCHS=armv7)
      when :watchos
        command += %w(CODE_SIGN_IDENTITY=- -sdk watchsimulator)
        command += Fourflusher::SimControl.new.destination(:oldest, 'watchOS', deployment_target)
      when :tvos
        command += %w(CODE_SIGN_IDENTITY=- -sdk appletvsimulator)
        command += Fourflusher::SimControl.new.destination(:oldest, 'tvOS', deployment_target)
      end

      output, status = _xcodebuild(command)

      unless status.success?
        message = 'Returned an unsuccessful exit code.'
        message += ' You can use `--verbose` for more information.' unless config.verbose?
        error('xcodebuild', message)
      end
      output
    end

I basically replicated the behaviour of 0.39 to allow our team to push pods. Please note that this is a quick and dirty fix, will only work for ios targets, is only working with xcode8, and might not work for you, but I thought it might help you while waiting for an official fix ;)

@mdsb100
Copy link

mdsb100 commented Oct 25, 2016

@orta
I see you are going to make improvements specific to dynamic frameworks by swift.

The famous third-party framework maybe is a static library. So could you provider a way to solve 'pod lint' from both static and dynamic, both library and framework, both objective-c and swift, even c++?

Not only solve this issue, but also we can ignore i386 or x86_64 to reduce time when 'pod lint' or 'pod repo push'.

@mdsb100
Copy link

mdsb100 commented Oct 25, 2016

What version are you going to release it?

@seanyue
Copy link

seanyue commented Oct 25, 2016

If cocoapods 0.39.0 have already been installed, the command pod _0.39.0_ spec/lib lint or pod _0.39.0_ repo push can be used for a workaround.

@mdsb100
Copy link

mdsb100 commented Oct 25, 2016

A temporary solution:use rvm.
For example:
rvm install ruby 2.2.2. Use 2.2.2 and install cocoapods 0.39.0.

rvm install ruby 2.3.1. Use ruby 2.3.1 and install cocoapods 1.1.1

You can flexibly switch pod's version by using 'rvm use'

@qingxuluo
Copy link

I have the same question yet,Can you tell me how you solved it?

@zeusent
Copy link

zeusent commented Feb 8, 2017

I'm having this issue as well. Is there any update on this?

@zeusent
Copy link

zeusent commented Feb 8, 2017

@ernya do I have to compile my own version of CocoaPods for that? Or where can I find the validator.rb file?

@ghost
Copy link

ghost commented Feb 8, 2017

@zeusent
moved from Cocoapods to Carthage, no more trouble ;)

@zeusent
Copy link

zeusent commented Feb 8, 2017

Thanks @LeT0C !

I've manually added the Podspec to my own private repo, thus skipping the pod lint. Installing and compiling the Pod works. So this definitely needs to be fixed in CocoaPods.

@ernya
Copy link

ernya commented Feb 8, 2017

@zeusent
To use my hotfix you have to edit your validator.rb file (On my machine it is located here : /usr/local/lib/ruby/gems/2.3.0/gems/cocoapods-1.1.0.rc.2/lib/cocoapods/validator.rb , change the versions if needed), and replace the old xcodebuild function (should be located near the end of the file) by my snippet of code.

A word of warning though : I didn't check that this fix is still working, I have switched to Carthage like @LeT0C , and have not used my fix recently, you might have to change stuff ;)

@dnkoutso
Copy link
Contributor

dnkoutso commented Feb 15, 2017

1.2.0 supports an option to skip-import-validation if you do not want to link your pod. This is the same as 0.39.0 behavior.

@dnkoutso
Copy link
Contributor

dnkoutso commented Feb 15, 2017

Actually I take it back, this is merged here #6420 but it has not been released yet.

@akramShokri
Copy link

akramShokri commented Apr 28, 2017

Hi,
This issue still exists. Does anyone have a fix for it? I tried @ernya 's hack and also this solution, but no luck and I still get the same error:
- ERROR | [iOS] xcodebuild: Returned an unsuccessful exit code. You can use--verbosefor more information. - NOTE | [iOS] xcodebuild: ld: warning: ignoring file mylib/mylib.framework/mylib, missing required architecture i386 in file mylib/mylib.framework/mylib (2 slices) - NOTE | [iOS] xcodebuild: ld: warning: ignoring file mylib/mylib.framework/mylib, missing required architecture x86_64 in file mylib/mylib.framework/mylib (2 slices) - NOTE | [iOS] xcodebuild: fatal error: lipo: -remove's specified would result in an empty fat file

@stale stale bot added the s1:awaiting input Waiting for input from the original author label Jul 27, 2017
@stale
Copy link

stale bot commented Jul 27, 2017

There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates.

@zhihuitang
Copy link

zhihuitang commented Oct 17, 2017

Still, exist.
But I was wondering how did the other frameworks handle this issue? like Fabric, Pushwoosh framework, why our App with these frameworks can be uploaded to AppStore?

Fabric also includes simulator architectures:

$ file Fabric.framework/Fabric
Fabric.framework/Fabric: Mach-O universal binary with 5 architectures: [arm_v7:current ar archive] [arm64]
Fabric.framework/Fabric (for architecture armv7):	current ar archive
Fabric.framework/Fabric (for architecture armv7s):	current ar archive
Fabric.framework/Fabric (for architecture i386):	current ar archive
Fabric.framework/Fabric (for architecture x86_64):	current ar archive
Fabric.framework/Fabric (for architecture arm64):	current ar archive

@jgongo
Copy link

jgongo commented Oct 17, 2017

They probably didn't use pod lint or pod push and instead uploaded the podspec using the API

@paulb777
Copy link
Member

@zhihuitang Fabric is built with static library frameworks. With static frameworks, the linker chooses the correct architectures at build time. This issue is about dynamic frameworks.

@zhihuitang
Copy link

zhihuitang commented Oct 17, 2017

Thanks @paulb777 .

I am using Xcode9+Swift4. I created a static Swift framework. The framework with 2 architectures(x86_64/i386+armv7/arm64) works well with Swift host App.
But it doesn't work with Objective-C host App. It says ld: library not found for -lswiftCore for architecture x86_64. I have no idea what it is talking about at all.

Is it because Xcode doesn't support Objective-C host App + Swift static framework ? Sigh......

Ld /Users/zhihuitang/Library/Developer/Xcode/DerivedData/demo8-gcigfrcdagsrxafknzmpkozjcfyq/Build/Products/Debug-iphonesimulator/demo8.app/demo8 normal x86_64
    cd /Users/zhihuitang/repo/ios/demo8
    export IPHONEOS_DEPLOYMENT_TARGET=11.0
    export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.0.sdk -L/Users/zhihuitang/Library/Developer/Xcode/DerivedData/demo8-gcigfrcdagsrxafknzmpkozjcfyq/Build/Products/Debug-iphonesimulator -F/Users/zhihuitang/Library/Developer/Xcode/DerivedData/demo8-gcigfrcdagsrxafknzmpkozjcfyq/Build/Products/Debug-iphonesimulator -F/Users/zhihuitang/repo/ios/demo8/demo8 -filelist /Users/zhihuitang/Library/Developer/Xcode/DerivedData/demo8-gcigfrcdagsrxafknzmpkozjcfyq/Build/Intermediates.noindex/demo8.build/Debug-iphonesimulator/demo8.build/Objects-normal/x86_64/demo8.LinkFileList -Xlinker -rpath -Xlinker @executable_path/Frameworks -mios-simulator-version-min=11.0 -dead_strip -Xlinker -object_path_lto -Xlinker /Users/zhihuitang/Library/Developer/Xcode/DerivedData/demo8-gcigfrcdagsrxafknzmpkozjcfyq/Build/Intermediates.noindex/demo8.build/Debug-iphonesimulator/demo8.build/Objects-normal/x86_64/demo8_lto.o -Xlinker -export_dynamic -Xlinker -no_deduplicate -Xlinker -objc_abi_version -Xlinker 2 -fobjc-arc -fobjc-link-runtime -Xlinker -sectcreate -Xlinker __TEXT -Xlinker __entitlements -Xlinker /Users/zhihuitang/Library/Developer/Xcode/DerivedData/demo8-gcigfrcdagsrxafknzmpkozjcfyq/Build/Intermediates.noindex/demo8.build/Debug-iphonesimulator/demo8.build/demo8.app.xcent -framework iddc -Xlinker -dependency_info -Xlinker /Users/zhihuitang/Library/Developer/Xcode/DerivedData/demo8-gcigfrcdagsrxafknzmpkozjcfyq/Build/Intermediates.noindex/demo8.build/Debug-iphonesimulator/demo8.build/Objects-normal/x86_64/demo8_dependency_info.dat -o /Users/zhihuitang/Library/Developer/Xcode/DerivedData/demo8-gcigfrcdagsrxafknzmpkozjcfyq/Build/Products/Debug-iphonesimulator/demo8.app/demo8

ld: library not found for -lswiftCore for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

@zhihuitang
Copy link

zhihuitang commented Oct 18, 2017

Finally, I found another workaround.
Basically, the idea is that we keep using the universal framework in Cocoapods.
But when achieving our host App in Xcode, we remove simulator achitectures (i386/x86_64) from the framework before action(pre-actions), and restore the framework after achiving(post-actions).

Steps:

  1. Add script to Archieve/pre-actions:
    image

  2. Add script to Archieve/post-actions:
    image

That is it. Then just archive as usual.

BTW: remember to use your own framework name in the scripts.

You also can find the detailed tutorial blog here

@dnkoutso
Copy link
Contributor

dnkoutso commented Nov 3, 2017

This is related to #7196 and I might make a change to make lipo a bit more lenient for both dSYM stripping and framework stripping.

@dnkoutso dnkoutso added this to the 1.4.0 milestone Nov 3, 2017
@dnkoutso
Copy link
Contributor

dnkoutso commented Nov 3, 2017

@paulb777 and others just to clarify the issue, this only happens on pre-build dynamic vendored frameworks in which they do not offer every single architecture.

The script then tries to strip invalid architectures and by doing so results in an empty fat file causing a failure in the script.

Am I understanding this correctly?

@minuscorp
Copy link

minuscorp commented Nov 3, 2017

@dnkoutso You got it!

@dnkoutso
Copy link
Contributor

dnkoutso commented Nov 3, 2017

So in order to solve this I decided to mimic Xcode's behavior (and specifically Xcode 9). Xcode will emit a warning if you try to link a library that does not contain the supported architecture. This should happen today because CocoaPods always adds -framework framework_namebut the problem is that our custom script phase will attempt to lipo every architecture out.

There is a more strict mode for ld to make Xcode compilation actually fail if a framework is missing the architecture required for the current target. This can be enabled by OTHER_LDFLAGS = -Xlinker -arch_errors_fatal but it is not the default behavior of Xcode. Even if it does become the default behavior linking occurs before our script phases so the build would fail.

I am going to be updating the shell script phases to be more lenient when it comes to stripping architectures for both the .framework and .framework.dSYM.

@dnkoutso
Copy link
Contributor

dnkoutso commented Nov 3, 2017

PR #7197

@dnkoutso
Copy link
Contributor

dnkoutso commented Nov 4, 2017

Merged. Closing this!

@dnkoutso dnkoutso closed this as completed Nov 4, 2017
@lumialxk
Copy link

lumialxk commented Mar 13, 2018

@dnkoutso
I got Undefined symbols for architecture i386. It seems --skip-import-validation didn't work for Swift host project.
PS: I lint successfully for another Objective-C project with the same dependency.

@dvdblk
Copy link

dvdblk commented Jun 3, 2018

@dnkoutso The exact same thing still happening here, 3rd party framework with only armv7 and arm64 archs. Cant get past the linting stage...

@MarcoBrescianini
Copy link

@dnkoutso The same thing happening to @lumialxk is happening to me too. I'm trying to push to a private repo a podspec for a project written in objective c, linking against a swift project and linking against an objective c project that is missing i386 architecture, and i cannot get past through the linting stage.

@dnkoutso
Copy link
Contributor

dnkoutso commented Jun 8, 2018

@MarcoBrescianini can you please upload a sample repo demonstrating the issue?

@hberenger
Copy link

hberenger commented Jul 3, 2018

Hi,
I also ran into the same issue while creating a private pod to wrap a third-party which does not provide i386 libraries : pod lib lint resulted into Undefined symbols for architecture i386.
Finally, I came up with the following workaround (which is a posteriori natural, since my project really doesn't need to be built on i386) : tell the podspec that the project is not buildable on 32 bit simulators, that is :

    subspec.pod_target_xcconfig = {
        'ARCHS[sdk=iphonesimulator*]' => '$(ARCHS_STANDARD_64_BIT)'
    }

(instead of the default ARCHS_STANDARD)

In case it helps... @MarcoBrescianini @dvdblk @lumialxk

@jgongo
Copy link

jgongo commented Oct 25, 2018

@lumialxk @dnkoutso I've created #8224 as this seems to be still present for Swift projects/pods

@ingocraft
Copy link

I almost have the same case with @hberenger . But the third-party in my private pod does not include both i386 and x86_64 libraries.
I add pod_target_xcconfig like this:

s.pod_target_xcconfig = { 'VALID_ARCHS[sdk=iphonesimulator*]' => '' }

after that, pod lib lint --skip-import-validation works for me.

I just hope "the lint" can ignore architecture i386 and x86_64. I'm not sure whether it is the right way, though it works.

@Benny-iPhone
Copy link

I almost have the same case with @hberenger . But the third-party in my private pod does not include both i386 and x86_64 libraries.
I add pod_target_xcconfig like this:

s.pod_target_xcconfig = { 'VALID_ARCHS[sdk=iphonesimulator*]' => '' }

after that, pod lib lint --skip-import-validation works for me.

I just hope "the lint" can ignore architecture i386 and x86_64. I'm not sure whether it is the right way, though it works.

worked for me, thank you so much

@caixindong
Copy link

caixindong commented Jan 11, 2019

This show how to fix

when :ios
        command += %w(CODE_SIGN_IDENTITY=- -sdk iphonesimulator ARCHS=x86_64)

https://github.com/caixindong/Cocoapods_fix_i386/blob/master/validator.rb

@yuanjilee
Copy link

I almost have the same case with @hberenger . But the third-party in my private pod does not include both i386 and x86_64 libraries.
I add pod_target_xcconfig like this:

s.pod_target_xcconfig = { 'VALID_ARCHS[sdk=iphonesimulator*]' => '' }

after that, pod lib lint --skip-import-validation works for me.

I just hope "the lint" can ignore architecture i386 and x86_64. I'm not sure whether it is the right way, though it works.

only the pod lib lint --skip-import-validation is useful, with out set pod_target_xcconfig

@anivaros
Copy link

anivaros commented Apr 8, 2020

Issue still exists.
Last versions of Xcode even don't compile frameworks in 32 bit arch. Please, make ability to skip validation of 32bit arch without Podspec modification.

@krpatelit
Copy link

krpatelit commented Jun 11, 2021

For me it works after adding --use-libraries along with --skip-import-validation , without add s.pod_target_xcconfig = { 'VALID_ARCHS[sdk=iphonesimulator*]' => '' }

pod lipo lint --skip-import-validation --allow-warnings --use-libraries mavspec XXXX.podspec
pod spec lint --skip-import-validation --allow-warnings --use-libraries mavspec XXXX.podspec
pod repo push --skip-import-validation --allow-warnings --use-libraries mavspec XXXX.podspec

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
r:vendored Issues related to vendored libraries and frameworks t2:defect These are known bugs. The issue should also contain steps to reproduce. PRs welcome!
Projects
None yet
Development

No branches or pull requests