Custom compiler options per file #589

Closed
strax opened this Issue Oct 11, 2012 · 8 comments

Projects

None yet

4 participants

@strax
strax commented Oct 11, 2012

It would be useful to specify custom linker options per-file basis. Podfile compiler_flags attribute could allow a hash where the keys are filenames or patterns and values are the custom compiler options for the corresponding file:

s.compiler_flags = {'Classes/Something.m' => '-f-no-objc-arc', 'Classes/**/*' => '-O0'}
Owner

You can already do that with subspecs. Did you investigate them?

strax commented Oct 11, 2012

Yes, I did, but subspecs seemed like a feature to break a large library into smaller modules semantically. They seemed like a wrong choice to go with when all you want is to have a compiler flag for a single file and not for others. Can you even wildcard match all files except one from subspecs?

Owner

The issue is that, imo, CocoaPods would become too complex resolving patterns across subspecs and orthogonally resolving patters for other attributes (like your proposal). There are many attributes that could have a filter like this. So, to keep things simple, subspecs serve the purpose of breaking a library semantically but _might also be used to isolate modules of code which require custom attributes (like compiler flags).

Can you even wildcard match all files except one from subspecs?

I don't know how many people have tested this feature but subspecs where designed to give the precedence to more
specific ones.

For example the following fragment, should assign the 'Classes/Something.m to the no-arc subspec.

#...
s.source_files = 'Classes/**/*'

s.subspec 'no-arc' do |sp|
  sp.source_files = 'Classes/Something.m'
end 
#...
strax commented Oct 11, 2012

Well, this isn't completely related to this issue but I already tried to disable ARC with the following:

Pod::Spec.new do |s|
  s.source_files = 'lib/**/*.{m,h}'
  s.requires_arc = true

  #...

  s.subspec 'no-arc' do |sp|
    sp.source_files = 'lib/UIKit/NSColor+TUIExtensions.m'
    sp.requires_arc = false
    sp.compiler_flags = '-fno-objc-arc'
  end
end

Didn't work with CocoaPods 0.15.1.

Owner

It might be that the specificity feature is not working.

Can you try with:

Pod::Spec.new do |s|
  s.source_files = FileList['lib/**/*.{m,h}'].exclude('lib/UIKit/NSColor+TUIExtensions.m')
  s.requires_arc = true

  #...

  s.subspec 'no-arc' do |sp|
    sp.source_files = 'lib/UIKit/NSColor+TUIExtensions.m'
    sp.requires_arc = false
  end
end

There is no need for the ARC compiler flags.

Owner

After discussing this issue we think that this case is limited and thus is not worth to add the feature to the DSL. For those which have this kind of need the subspecs should be a reasonable workaround. Note subspecs don't inherit source files from the parent anymore and thus the above discussion is outdated. A similar setup can be achieved with the exclude_files attribute.

ipmcc commented Feb 16, 2016

I'd like to add a +1 for the per-file compiler-flags feature. This flexibility is especially relevant when packaging up legacy open-source C libraries for easy consumption. You don't hit it this as much with Objective-C but with C libraries, the subspec workaround is really clunky due to linking.

If you have a file or two that need different compiler flags, and you put them in subspecs, then their link step fails (because the subspec can't see anything above it at the moment it's linked.) The only workaround I could find was to add -undefined dynamic_lookup to OTHER_LDFLAGS (or the more surgical -Wl,-U,_single_symbol_to_ignore). Since it appears that you can't specify per-subspec linker flags (i.e. sp.pod_target_xcconfig appears to be global to the entire Pod) you end up having those linker problems silenced for the whole Pod.

The problem with that is that you're effectively "hoping for the best" when it comes to linking, and any genuinely missing symbols won't be found until runtime, at which point they'll present as largely inscrutable to the end consumer of your Pod.

What would help? Well, this really turned into an "Old lady who swallowed the fly" situation. Let me recap:

  • I needed per-file compiler_flags (to compile some code that isn't mine, but which I'm trying to package)
  • So I made subspecs for those files
  • Because subspecs imply different units of linkage, I now have missing symbols in my subspecs
  • So I change the linker flags to ignore them
  • Because I appear to be unable to specify OTHER_LDFLAGS per-subspec
  • I end up suppressing the missing symbol errors for the whole Pod
  • And now I have potentially silent errors that would only de-cloak at a later time.

At the end of the day, in this specific case, I wouldn't be in this position if I could just specify per-file compiler_flags, but I also suspect that there's a case to be made here for per-subspec linker flags as well. If subspecs are going to be the shoehorn/workaround for all these various complex situations, then I'd argue that they ought to be more flexible.

Owner

You can specify an xcconfig or linker flags per subspec already.
In addition, please don't comment on years-old issues.

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