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
eldewy opened this Issue Sep 13, 2016 · 47 comments

Comments

Projects
None yet
@eldewy
Copy link

eldewy 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

This comment has been minimized.

Copy link

Philipp372 commented Sep 15, 2016

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

This comment has been minimized.

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

This comment has been minimized.

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?

@eldewy

This comment has been minimized.

Copy link
Author

eldewy commented Sep 19, 2016

@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

This comment has been minimized.

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 👍

@eldewy

This comment has been minimized.

Copy link
Author

eldewy commented Sep 22, 2016

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

@orta

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

Copy link

mdsb100 commented Oct 25, 2016

What version are you going to release it?

@seanyue

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

Copy link

qingxuluo commented Nov 15, 2016

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

@zeusent

This comment has been minimized.

Copy link

zeusent commented Feb 8, 2017

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

@zeusent

This comment has been minimized.

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

This comment has been minimized.

Copy link

ghost commented Feb 8, 2017

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

@zeusent

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

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 label Jul 27, 2017

@stale

This comment has been minimized.

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.

@dnkoutso

This comment has been minimized.

Copy link
Contributor

dnkoutso commented Jul 27, 2017

Will not close.

@dantoml dantoml added the t2:defect label Jul 27, 2017

@dantoml

This comment has been minimized.

Copy link
Member

dantoml commented Jul 27, 2017

I've just added the defect label which will stop it from auto closing.

@minuscorp

This comment has been minimized.

Copy link

minuscorp commented Sep 16, 2017

Any advance on this topic? It is common in third-party frameworks to have device-only slices to slim the framework size. It's very interesting for us developers to make podspec wrappers around those frameworks and push them into private specs, but the validation checks fails. Have to upgrade every version manually due to the linting using only simulator archs.

I think that adding some kind of flag in lint, like --device-only or --archs="arm64 armv7" might be flexible and useful in many use-cases.

Thank you!

@PhilippOtto89

This comment has been minimized.

Copy link

PhilippOtto89 commented Oct 11, 2017

Any news on this? I agree to minuscorp that it is good to have device-only frameworks to slim the framework size. But what makes the device-only frameworks more important is the fact that fat binaries seem to be rejected when submitting apps to the appstore.

There is an open radar on this:
http://www.openradar.me/radar?id=6409498411401216
Or is this app store submission issue not relevant anymore? Does anyone know about this?

Thanks!

@zhihuitang

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

Copy link
Member

paulb777 commented Oct 17, 2017

@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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

Copy link

minuscorp commented Nov 3, 2017

@dnkoutso You got it!

@dnkoutso

This comment has been minimized.

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

This comment has been minimized.

Copy link
Contributor

dnkoutso commented Nov 3, 2017

PR #7197

@dnkoutso

This comment has been minimized.

Copy link
Contributor

dnkoutso commented Nov 4, 2017

Merged. Closing this!

@dnkoutso dnkoutso closed this Nov 4, 2017

@lumialxk

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

Copy link

MarcoBrescianini commented Jun 8, 2018

@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

This comment has been minimized.

Copy link
Contributor

dnkoutso commented Jun 8, 2018

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

@hberenger

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

Copy link

ingocraft commented Nov 30, 2018

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

This comment has been minimized.

Copy link

Benny-iPhone commented Jan 2, 2019

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

This comment has been minimized.

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment