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

Raise default macOS/iOS deployment target #9884

Closed
1 task done
DarkDust opened this issue Jun 25, 2020 · 39 comments · May be fixed by CocoaPods/Core#636
Closed
1 task done

Raise default macOS/iOS deployment target #9884

DarkDust opened this issue Jun 25, 2020 · 39 comments · May be fixed by CocoaPods/Core#636
Labels
help wanted Help from new or existing contributors would be greatly appreciated! s7:workaround available A workaround for the issue is available

Comments

@DarkDust
Copy link

DarkDust commented Jun 25, 2020

Report

What did you do?

Built a macOS project that includes pods which do not have the deployment target set for macOS (for example, Argon2).

What did you expect to happen?

Compile without errors and warnings.

What happened instead?

It seems that starting with Xcode 12, I get a warning when building those pods (I don't get them with Xcode 11):

The macOS deployment target 'MACOSX_DEPLOYMENT_TARGET' is set to 10.6, but the range of supported deployment target versions is 10.9 to 10.16.99.

Since 10.6 is ancient, it would be nice to raise the default deployment target for macOS to 10.9 to prevent this warning.

@dnkoutso
Copy link
Contributor

Yeap a PR would be nice and easy for this!

@dnkoutso dnkoutso added the d1:easy An easy ticket that is a good start for first-time contributors label Jun 25, 2020
@DarkDust
Copy link
Author

Alright, will do in the next days.

@dnkoutso dnkoutso added the help wanted Help from new or existing contributors would be greatly appreciated! label Jun 25, 2020
@Kaspik
Copy link

Kaspik commented Jun 30, 2020

The same is happening with iOS btw. Even tho Podfile has info about platform and it's version:

source 'https://cdn.cocoapods.org/'

platform :ios, '11.0'
use_frameworks!

XCode 12 shows dozens of warnings for every single pod about:
The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.0.99.

@dnkoutso Is it the same issue, or should I create a new one?

@dnkoutso dnkoutso changed the title Raise default macOS deployment target Raise default macOS/iOS deployment target Jul 23, 2020
@paulb777
Copy link
Member

See related Swift Package Manager issue discussion at https://forums.swift.org/t/minimum-ios-version-xcode-12-and-build-warnings/40224

@zackdotcomputer
Copy link

So to collect what I understand to be happening here:

  1. A podspec declares the packages minimum platform version for the platforms it supports
  2. Xcode 12 dropped support for some still-widely-used older platforms by, for example, eliminating support for iOS 8
  3. We are getting warnings because of the mismatch for pods that support iOS 8 (or other no-longer-supported platforms) trying to compile on Xcode 12.

This might be a naïve suggestion but, could we make the deployment target (for the targets which cocoapods generates for each pod) be set to either the minimum version specified in the podspec or the minimum version specified in the Podfile, whichever is greater?

@zackdotcomputer
Copy link

(Since the only alternative appears for the community to make many PRs to many pods to individually raise each of their minimum versions to iOS 9, which seems impractical.)

@paulb777 paulb777 self-assigned this Sep 19, 2020
@paulb777
Copy link
Member

paulb777 commented Sep 19, 2020

I have an initial implementation working and hope to have a PR up in a few days.

~/CocoaPods/CocoaPods (1-10-stable) $ git diff
diff --git a/lib/cocoapods/installer/analyzer.rb b/lib/cocoapods/installer/analyzer.rb
index c0cef420b..bdc1329c9 100644
--- a/lib/cocoapods/installer/analyzer.rb
+++ b/lib/cocoapods/installer/analyzer.rb
@@ -860,6 +860,9 @@ module Pod
           minimum = Version.new('8.0')
           deployment_target = [deployment_target, minimum].max
         end
+        deployment_target = [deployment_target, target_definitions.first.platform.deployment_target].max
         Platform.new(platform_name, deployment_target)
       end

@paulb777
Copy link
Member

Based on the discussion at #10070, this does not seem to be possible to be fixed in a non-breaking way. Instead, adding a post-install script to the Podfile is a better resolution.

For example, here is one for iOS:

post_install do |pi|
   pi.pods_project.targets.each do |t|
       t.build_configurations.each do |bc|
           bc.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '9.0'
       end
   end
end

@paulb777 paulb777 removed their assignment Sep 21, 2020
@dnkoutso
Copy link
Contributor

I would also recommend filing issues to pod authors to bump the deployment target in their podspecs.

@dnkoutso dnkoutso added s7:workaround available A workaround for the issue is available and removed d1:easy An easy ticket that is a good start for first-time contributors labels Sep 21, 2020
@dnkoutso
Copy link
Contributor

dnkoutso commented Sep 21, 2020

post_install do |pi|
   t = pi.pods_project.targets.find { |t| t.name == 'MyPod' }
   t.build_configurations.each do |bc|
     bc.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '9.0'
   end
end

@dnkoutso
Copy link
Contributor

dnkoutso commented Sep 21, 2020

I think I am going to close this. While CocoaPods does not offer a "first-class" API to override values it can do it via a post_install hook which is now the recommended way to override those values or any value for that matter and the above snippets should do the trick.

In the meantime I still recommend folks to update their podspecs and specify their deployment target to begin with or update them to bump them from 8.0.

@dnkoutso
Copy link
Contributor

Still open to suggestions and discussions here, I will re-open this if needed.

@tbechtum
Copy link

tbechtum commented Sep 25, 2020

Developing on a long-term project I am facing many of these warnings on the different cocoa pods.

  1. Do these warnings affect the library loader? On the storyboard my own custom views are not updated with casual errors mentioning different cocoa pods, seems to be related to this Xcode deployment target warnings.
  2. Updated the script and added if bc.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] == '8.0', please let me know if this is working also for your cases.

@tbechtum
Copy link

tbechtum commented Sep 25, 2020

This solution is working for my needs

post_install do |pi|
   pi.pods_project.targets.each do |t|
       t.build_configurations.each do |bc|
           if bc.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] == '8.0'
             bc.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '9.0'
           end
       end
   end
end

@Jon889
Copy link

Jon889 commented Oct 5, 2020

Why doesn't specifying the platform in the Podfile (eg platform :ios, '11.0') override the deployment target of pods? It could error/warn if the platform is lower than one of the pods deployment targets.

@paulb777
Copy link
Member

paulb777 commented Oct 5, 2020

The pod may be using macOS APIs deprecated or even deleted in 11.0 . Only the pod provider can reliably determine the correct minimum OS version in the podspec.

@burtsevyg
Copy link

burtsevyg commented Oct 14, 2020

My Podfile:

# DO NOT MODIFY -- auto-generated by Apache Cordova
source 'https://cdn.cocoapods.org/'
platform :ios, '11.0'
use_frameworks!
target 'Runner' do
        project 'Runner.xcodeproj'
        pod 'Firebase/Core', '6.33.0'
        pod 'Firebase/Auth', '6.33.0'
        pod 'Firebase/Messaging', '6.33.0'
        pod 'Firebase/Performance', '6.33.0'
        pod 'Firebase/RemoteConfig', '6.33.0'
        pod 'Firebase/InAppMessaging', '6.33.0'
        pod 'FirebaseFirestore', :tag => '6.33.0', :git => 'https://github.com/invertase/firestore-ios-sdk-frameworks.git'
        pod 'Firebase/Crashlytics', '6.33.0'
        pod 'GoogleSignIn', '5.0.2'
        pod 'GoogleTagManager', '7.1.4'
end

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
    end
  end
end

after run

cordova build ios --release

see in build log:

warning: The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.0.99. (in target 'GoogleUtilities' from project 'Pods')
warning: The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.0.99. (in target 'PromisesObjC' from project 'Pods')
warning: The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.0.99. (in target 'FirebaseMessaging' from project 'Pods')
warning: The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.0.99. (in target 'FirebaseCrashlytics' from project 'Pods')
warning: The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.0.99. (in target 'FirebaseCore' from project 'Pods')
warning: The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.0.99. (in target 'FirebaseAuth' from project 'Pods')
warning: The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.0.99. (in target 'FirebaseABTesting' from project 'Pods')
warning: The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.0.99. (in target 'AppAuth' from project 'Pods')
** BUILD FAILED **
The following build commands failed:
	CompileC ./platforms/ios/Pods/GoogleDataTransport/GoogleDataTransport/GDTCCTLibrary/Protogen/nanopb/cct.nanopb.c normal x86_64 c com.apple.compilers.llvm.clang.1_0.compiler

@tbechtum how to fix that?

@zackdotcomputer
Copy link

@burtsevyg

  1. Is there a reason you're deleting the deployment target from your pods rather than setting it to 9.0?

  2. Have you run pod install between making that change to your Podfile and running your build command? Because your function is in a post_install hook, rerunning pod install will be necessary.

(P.S. Implementation questions are usually best answered on StackOverflow - it's more set up for questions like this than Github Issues are...)

@renetik
Copy link

renetik commented Nov 11, 2020

When setting IPHONEOS_DEPLOYMENT_TARGET to 11 in post install , there is build error for material components library.

https://github.com/material-components/material-components-ios/issues/10071

Undefined symbols for architecture x86_64:
  "_MDMMotionCurveMakeBezier"

This library by google is quite popular so well I believe this is or eventually could affect a lot of users. So here in that bug report someone say you should not set in post install IPHONEOS_DEPLOYMENT_TARGET . He say it should be fixed by cocoapods (he is just some developer not google contributor looks like so doesn't matter probably) , so its little back and forth with this deployment target thing... I am dealing with this repeatedly for some year or so...

I used this:

post_install do |pi|
  pi.pods_project.targets.each do |t|
    t.build_configurations.each do |bc|
      bc.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0'
    end
  end
end

Now I am switching back to this hopefully I am free of issues for at last one year...

post_install do |pi|
  pi.pods_project.targets.each do |t|
    t.build_configurations.each do |bc|
      if bc.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] == '8.0'
        bc.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '9.0'
      end
    end
  end
end

@tbechtum
Copy link

tbechtum commented Nov 11, 2020

This post_install solution is only a workaround because this does not include that the source code of the pod project compiles successfully against the SDK of the desired deployment target. While we are talking about new developments I think it is fair enough to de-support the iOS 8 platform. May be you will not loose a lot of clients while there are not a lot of apps supporting still iOS 8.

@tbechtum
Copy link

Do you have statistics how many active projects are still supporting iOS 8? Thanks.

@nicolekapp
Copy link

Hi everyone, I've been reading everything you posted. I'm getting the same error but the thing is when I add this:

post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
end
end
end

And then try to run pod install this is what I'm getting:

-bash: /usr/local/bin/pod: /Applications/MAMP/Library/bin/ruby: bad interpreter: No such file or directory

What can I do to fix this?

@zackdotcomputer
Copy link

@nicolekapp Searching Stack Overflow says the bash error you're getting is complaining that ruby can't read the pod binary. I'm gonna guess that's because you're using the copy of ruby in the MAMP Application rather than one properly installed in the CLI (the system's built-in one or one from rbenv would be better). You should investigate and debug that on Stack Overflow, though, since that kind of system setup is out of the scope of a github issue.

Once you have ruby working, do let us know if that post_install config does what you expect? I'm far from expert in this, but I am surprised to see you're deleting the deployment target for your pods rather than setting it to the value you want?

@CodingMarkus
Copy link

I think this hook covers it all and actually mimics the behavior I would have expected from CocoaPods:

post_install do |installer|
    # Fix deployment target for pods that don't specify one
    # or specify one that is older than our own deployment target.
    desired_ios = Gem::Version.new(DEPLOYMENT_TARGET_IOS)
    desired_macos = Gem::Version.new(DEPLOYMENT_TARGET_MACOS)

    installer.pods_project.targets.each do |target|
        target.build_configurations.each do |config|
            settings = config.build_settings

            actual = Gem::Version.new(settings['IPHONEOS_DEPLOYMENT_TARGET'])
            if actual < desired_ios
                settings['IPHONEOS_DEPLOYMENT_TARGET'] = DEPLOYMENT_TARGET_IOS
            end

            actual = Gem::Version.new(settings['MACOSX_DEPLOYMENT_TARGET'])
            if actual < desired_macos
                settings['MACOSX_DEPLOYMENT_TARGET'] = DEPLOYMENT_TARGET_MACOS
            end
        end
    end
end

The important part here is that in case a pod has set a target and this target is newer than our own target, of course we must keep the target of the pod and not override it with a lower one as that cannot ever work. Raising the target is usually safe, unless the pod cannot be build for that target anymore but then it will noticeably fail to build and would have probably failed without that hook to begin with.

@paulb777
Copy link
Member

paulb777 commented Aug 31, 2021

Note that the hook in the comment above will cause extra warnings in code that is written to support the actual like firebase/firebase-ios-sdk#7873

@CodingMarkus
Copy link

@paulb777 That is a problem Firebase needs to address and unrelated to this issue. Setting a lower deployment target doesn't change the fact that your code uses deprecated API and lives on borrowed time, it just suppresses the warning but once Apple removes that API altogether, the code will fail to compile for newer OS releases and no set deployment target will prevent that from happening. The correct behavior is not not access deprecated API unless you know you are running on a system where it wasn't deprecated (e.g. by using @available).

@paulb777
Copy link
Member

@CodingMarkus No argument that the SDKs need to address. And they will have to before the APIs actually go away.

However, it would add a lot of extra testing and clutter for every SDK to test for each iOS version they support as a minimum before they actually stop supporting the absolute minimum.

@adt2
Copy link

adt2 commented Feb 25, 2022

I think this hook covers it all and actually mimics the behavior I would have expected from CocoaPods:

post_install do |installer|
    # Fix deployment target for pods that don't specify one
    # or specify one that is older than our own deployment target.
    desired_ios = Gem::Version.new(DEPLOYMENT_TARGET_IOS)
    desired_macos = Gem::Version.new(DEPLOYMENT_TARGET_MACOS)

    installer.pods_project.targets.each do |target|
        target.build_configurations.each do |config|
            settings = config.build_settings

            actual = Gem::Version.new(settings['IPHONEOS_DEPLOYMENT_TARGET'])
            if actual < desired_ios
                settings['IPHONEOS_DEPLOYMENT_TARGET'] = DEPLOYMENT_TARGET_IOS
            end

            actual = Gem::Version.new(settings['MACOSX_DEPLOYMENT_TARGET'])
            if actual < desired_macos
                settings['MACOSX_DEPLOYMENT_TARGET'] = DEPLOYMENT_TARGET_MACOS
            end
        end
    end
end

The important part here is that in case a pod has set a target and this target is newer than our own target, of course we must keep the target of the pod and not override it with a lower one as that cannot ever work. Raising the target is usually safe, unless the pod cannot be build for that target anymore but then it will noticeably fail to build and would have probably failed without that hook to begin with.

@CodingMarkus are DEPLOYMENT_TARGET_IOS and DEPLOYMENT_TARGET_MACOS meant to represent variables? In other words, should I replace those with, say, '11.0' and '12.1' or similar? Or just cut-and-paste your hook as-is? Sorry if this is a stupid question, but I'm new at this and just trying to figure out why my app that ran fine yesterday suddenly won't compile...

@CodingMarkus
Copy link

@CodingMarkus are DEPLOYMENT_TARGET_IOS and DEPLOYMENT_TARGET_MACOS meant to represent variables? In other words, should I replace those with, say, '11.0' and '12.1' or similar? Or just cut-and-paste your hook as-is?

You can copy the hook as is, you just somewhere have to define them above the hook, e.g.

DEPLOYMENT_TARGET_IOS = '13'
DEPLOYMENT_TARGET_MACOS = '10.12'

We define them at the very top of our Podifle, that way we can also use them elsewhere in our Podfile, e.g.

def commonBasicFrameworkPods
     pod '...', :inhibit_warnings => false
     pod '....'
     pod '....'
end


target 'Basic macOS Framework' do
     platform :osx, DEPLOYMENT_TARGET_MACOS
     commonBasicFrameworkPods
     # macOS only Pods below
     pod '...'
end


target 'Basic iOS Framework' do
     platform :ios, DEPLOYMENT_TARGET_IOS
     commonBasicFrameworkPods
     # iOS only Pods below
     pod '...'
     pod '...'
     pod '...'
end

And if we ever have to alter the deployment target of either platform, we only have to change that in on place at the very top of our Podfile, after all our Podfile lists 15 targets at the moment. Having to only change the target in just one central place makes it way easier, just like placing pods shared between targets into own defines as also shown above.

Sorry if this is a stupid question

Stupid would only be to waste plenty of time with trial and error because one is afraid to ask. If you get no reply or just a negative one, the later one is still an option but it should never be the first option to target.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Help from new or existing contributors would be greatly appreciated! s7:workaround available A workaround for the issue is available
Projects
None yet
Development

Successfully merging a pull request may close this issue.