Pod specs defined in the Podfile don't respect compiler_flags #549

Closed
jonathanpenn opened this Issue Sep 23, 2012 · 8 comments

Comments

Projects
None yet
3 participants

I've found a bug in the latest release (0.14.0) that also exists on master. If I define a pod spec with compiler flags, those flags don't end up set in the final project file.

I'm doing it like this:

pod do |spec|
    # …
    spec.compiler_flags = "-Wno-implicit-int"
end

If I break out that spec into a separate .podspec file in the same directory and reference it in the pod method, it works just fine. So, it must be something about that inline definition.

I tried to dig in to fix it, but I'm getting confused about how these inline podspecs differ from ones defined in files. I suspect that it is related to the way podspecs inherit specs from a hierarchy. Maybe these inline specs don't have parents so thats why the compiler flags don't end up built properly?

If anyone can point me in the right direction to try to fix this, I'll make a pull request. But at the moment I'm a bit lost when I try to follow the code to figure out why this particular setting isn't propagating.

Owner

alloy commented Sep 24, 2012

This is where the flags are actually collected and added to the Xcode project. I didn’t quickly see what could have been the cause. Could you create a failing test?

Thanks for that tip! I followed it deeper into the code and found that the missing compiler_flags problem I was having was just a symptom of something a much more perplexing. It seems that inline pod specs are completely broken.

I'm unable to come up with a failing automated test to demonstrate the problem because it seems to be an integration problem with the ~/.cocoapods cache.

So, here's three simple steps you can run to reproduce the problem. Hopefully this gives you better context.

In a blank directory, create a Podfile with these contents:

platform :ios

pod do |s|
  s.name     = 'MyZBarLibWithCustomCompilerFlags'
  s.version  = '1.2'
  s.platform = :ios
  s.source   = { :git => 'https://github.com/ZBar/ZBar.git', :tag => 'iPhoneSDK-1.2' }

  s.resources    = 'iphone/res/{zbar-*.png,zbar-help.html}'

  s.source_files = 'include/zbar.h', 'zbar/**/*.h', 'iphone/*.h', 'iphone/include/**/*.h',
                   'zbar/{config,decoder,error,image,img_scanner,refcnt,scanner,symbol}.c',
                   'zbar/decoder/{code128,code39,ean,i25,qr_finder,databar,code93}.c',
                   'zbar/qrcode/{bch15_5,binarize,isaac,qrdec,qrdectxt,rs,util}.c',
                   'iphone/*.m'

  s.header_mappings_dir = 'zbar'

  s.frameworks   = 'AVFoundation', 'CoreGraphics', 'CoreMedia', 'CoreVideo', 'QuartzCore'

  s.library      = 'iconv'

  s.prefix_header_file = 'iphone/include/prefix.pch'

  # Here's the compiler flag I wanted to set so there are no warnings
  s.compiler_flags = "-w"
end

Next, try to install it without integration with an existing Xcode project like so:

be pod install --no-integrate

That should work just fine. The problem happens when you try to run the install again:

be pod install --no-integrate

Now, I see this error:

[!] Unable to find a pod named `MyZBarLibWithCustomCompilerFlags'

If I edit the Podfile to change the version or the inline pod name, it will reinstall just fine for the first time. If I delete the Podfile.lock, it also will install fine again the next time. But once it's in the cache and locked, trying to run the install process any more will show that error.

The reason this appeared to ignore my custom compiler_flags in my case was because I was using the same name (ZBarLib) in my inline pod spec as the original spec cached in ~/.cocoapods/master. If I blew away the Podfile.lock, then the first time I ran the install the compiler flag would show up. But every subsequent install would ignore my inline pod spec and load the cached spec instead (with no compiler flag).

For the demonstration above, the pod name I made up doesn't exist in the cache which is why pod install cannot find the pod on subsequent runs after the podfile is locked.

I tracked down the point where this happens to here in resolver.rb. As the comment suggests, the lockfile is asked for a more specific dependency if one is already installed. Once we get down to find_cached_set, the lookup will fail because the code expects that a pod already locked will be in the ~/.cocoapods/master cache.

My project isn't blocked on this. I can work around it by just using a .podspec file right in my project directory that I reference in the Podfile. But this bug still lingers. Any inline pod specs in a Podfile will fail like this (as far as I've been able to reproduce).

I was trying to edit it to fix the problem, but with all the moving parts, I realized that I'm a bit in over my head. Any suggestions on what we should do with this? Was there a point in the past that we know the inline pod specs worked? I admit I had never used them before until now when I wanted to disable warnings for an already existing pod.

Just saw that this issue has similar symptoms: #525

Owner

fabiopelosin commented Sep 25, 2012

I was trying to edit it to fix the problem, but with all the moving parts, I realized that I'm a bit in over my head.

I feel your pain :-) see #553.

Any suggestions on what we should do with this?

We have to decide how the lockfile should handle them and prevent them to be replaced by a non inline one. One of the areas that wasn't solved is how to detect that they were changed. Otherwise they should be always considered as :added or :changed by the lockfile, and no substitution with the strict dependency would happen. Also we could add a check in the resolver to ensure that an inline podspec is never locked. As you see this part is not stable yet.

Was there a point in the past that we know the inline pod specs worked? I admit I had never used them before until now when I wanted to disable warnings for an already existing pod.

I think that this got broken with v0.14 which introduced the resolution of the lockfile. However, inlined podspecs weren't correctly handled.

Awesome. Thanks for the clarification. Alas, I am so unfamiliar with the resolver and lockfile logic that I fear I would cause more harm than good trying to help fix it at this point. I don't need to use an inline podspec for my project, so this isn't a show stopper for me.

Since it's possible to just reference local podspec files bundled right along with the project itself, do we even need the inline podspecs? Since the feature is completely broken as it is anyway, what if the workflow was changed to just say "make up your own local podspec file and reference it" instead of declaring one inline. If that simplifies this whole resolution process, that would be a big win.

Owner

alloy commented Sep 26, 2012

@jonathanpenn You make a good point. Inline podspecs were mainly to get adoption going, but that might be less needed nowadays.

I only worry about where we store the spec, because right now the idea is that the user would be able to completely ignore the Pods directory.

Just caught up to speed with the discussion with issue #544. Looks like a great direction to me. Do we need to leave this issue open anymore?

Owner

fabiopelosin commented Oct 23, 2012

Moving to #616.

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