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

Ensure private headers are declared as such in a framework's generated module map. #3004

Merged
merged 4 commits into from Apr 18, 2015

Conversation

segiddins
Copy link
Member

Closes #2974.

\c @mrackwitz @kylef

@neonichu
Copy link
Member

neonichu commented Jan 5, 2015

Do we have a good reason to generate our module map differently from Xcode defaults (see #2974 (comment))?

def generate_private_header_exports
private_headers.reduce('') do |string, header|
string << %( private header "#{header}\n")
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not entirely sure if this is correct.

Shouldn't the output be something like:

module Foo {
  header "Foo.h"

  explicit module Private {
    header "Foo_Private.h"
  }
}

Ref: http://clang.llvm.org/docs/Modules.html#private-module-map-files

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There doesn't seem to be any tests to ensure generate works, can we add some? (I understand if you feel this is outside of this PR, can be done separately, but I think it makes sense to add them in this PR to make sure this works correctly).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, can add some tests later.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A header with the private specifier may not be included from outside the module itself.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There doesn't seem to be any tests to ensure generate works

That's the integration specs

@mrackwitz
Copy link
Member

@neonichu: In which way different?
Generally, we need module maps to inject our auto-generated umbrella header.
Do you mean different from only the export * declaration?

@neonichu
Copy link
Member

neonichu commented Jan 5, 2015

@mrackwitz I was referring to including the private headers in them, Xcode does not do that, it will merely include the actual files in a PrivateHeader directory.

@segiddins segiddins added this to the 0.36.0 milestone Jan 12, 2015
@segiddins
Copy link
Member Author

note to self: add unit test for spec with private headers

@kylef kylef added the s1:awaiting input Waiting for input from the original author label Jan 16, 2015
@segiddins segiddins force-pushed the seg-module-map-private-headers branch from 405dd92 to 56888d5 Compare January 19, 2015 05:36
@segiddins
Copy link
Member Author

@kylef rebased + added spec

@segiddins segiddins removed the s1:awaiting input Waiting for input from the original author label Jan 19, 2015
@neonichu
Copy link
Member

Hm, this only works if one specifies private_header_files manually, is that intended? I would have thought this would include all private headers, regardless of definition. Moreover, the private headers are not copied to the framework by CP, so this wouldn't even do anything rn, would it?

@kylef
Copy link
Contributor

kylef commented Jan 19, 2015

@neonichu A header wouldn't be private unless it has presence in the pod spec's private_header_files?

@neonichu
Copy link
Member

@kylef seems unintuitive for me, especially since we introduced Pods/Headers/{Private,Public} - that suggest that a header is either considered private or public by CP and cannot be neither.

This is also what http://guides.cocoapods.org/syntax/podspec.html#private_header_files suggests, so at the very least, we have to change that.

@neonichu
Copy link
Member

To clarify what I mean, the current implementation in this PR would add b.h to the module map in this scenario:

source_files = a.h b.h
private_header_files = b.h

but not in this one:

source_files = a.h b.h
public_header_files = a.h

I don't think that is intended.

@segiddins
Copy link
Member Author

Boris, I'm pretty sure it would in the latter. Check out the file accessor.

-Samuel E. Giddins

On Jan 19, 2015, at 4:02 AM, Boris Bügling notifications@github.com wrote:

To clarify what I mean, the current implementation in this PR would add b.h to the module map in this scenario:

source_files = a.h b.h
private_header_files = b.h
but not in this one:

source_files = a.h b.h
public_header_files = a.h

Reply to this email directly or view it on GitHub.

@neonichu
Copy link
Member

@segiddins didn't work for me in manual testing - will have a look at why that is the case, first wanted to confirm that I am not missing something and that behaviour was intended.

@neonichu
Copy link
Member

@segiddins So the file accessor is actually the issue.

https://github.com/CocoaPods/CocoaPods/pull/3004/files#diff-a1bd48eb509ce3365557319fdda59f25R130 contains only the contents of the private_header_files attribute of a spec. I think headers - public_headers should actually be the implementation of that method.

But fixing that breaks the build of frameworks anyway, possibly because the private headers are not actually copied into the framework. Unfortunately, the error message is only the ever elusive "Could not build Objective-C module".

@neonichu
Copy link
Member

Not copying the headers is indeed the issue, we need to add handling for private headers here https://github.com/CocoaPods/CocoaPods/blob/seg-module-map-private-headers/lib/cocoapods/installer/target_installer/pod_target_installer.rb#L68, similar to the public ones.

As this copies the headers into the PrivateHeaders directory, this also clears up my earlier confusion here #3004 (comment)

@segiddins segiddins changed the title Ensure private headers are declared as such in a framework's generated module map. [WIP] Ensure private headers are declared as such in a framework's generated module map. Jan 19, 2015
@kylef kylef added the s1:awaiting input Waiting for input from the original author label Jan 31, 2015
@segiddins
Copy link
Member Author

I think #3145 will make this work?

@neonichu neonichu modified the milestones: 0.37.0, 0.36.0 Feb 25, 2015
@segiddins segiddins assigned mrackwitz and unassigned segiddins Apr 3, 2015
@segiddins
Copy link
Member Author

@mrackwitz please see that this will work in conjunction with the custom modulemap PR?

@mrackwitz mrackwitz force-pushed the seg-module-map-private-headers branch from 56888d5 to 6645921 Compare April 16, 2015 11:08
@mrackwitz mrackwitz removed the s1:awaiting input Waiting for input from the original author label Apr 16, 2015
@mrackwitz
Copy link
Member

We could add -Wincomplete-umbrella to all generated Pod targets:

Any headers not included by the umbrella header should have explicit header declarations. Use the -Wincomplete-umbrella warning option to ask Clang to complain about headers not covered by the umbrella header or the module map.

This could help to find misconfigurations of the header visibility in the podspec with pod [spec|lib] lint. This could also be helpful in combination with custom modulemaps or we disable it in that case and don't add this additional flag for warnings. But the documentation doesn't cover how clang handles project headers, which are since #3145 possible with CocoaPods, by adding headers in the source_files of a podspec, which are neither matched by public_headers nor by private_headers.

@segiddins
Copy link
Member Author

@mrackwitz if we add -Wincomplete-umbrella, will this be mergable?

@mrackwitz
Copy link
Member

@segiddins: That should go in a separate issue.

@segiddins
Copy link
Member Author

In that case, what needs to be done for this to be merged?

mrackwitz added a commit to CocoaPods/cocoapods-integration-specs that referenced this pull request Apr 18, 2015
@mrackwitz mrackwitz force-pushed the seg-module-map-private-headers branch from 6645921 to d28b040 Compare April 18, 2015 21:28
@mrackwitz mrackwitz changed the title [WIP] Ensure private headers are declared as such in a framework's generated module map. Ensure private headers are declared as such in a framework's generated module map. Apr 18, 2015
@mrackwitz
Copy link
Member

Rebuilding the integration spec. ✅

@segiddins segiddins force-pushed the seg-module-map-private-headers branch from d28b040 to b1ef0f6 Compare April 18, 2015 21:47
segiddins added a commit that referenced this pull request Apr 18, 2015
Ensure private headers are declared as such in a framework's generated module map.
@segiddins segiddins merged commit 8bbe997 into master Apr 18, 2015
@segiddins segiddins deleted the seg-module-map-private-headers branch April 18, 2015 21:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Modules: Export private headers as private
5 participants