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

circular header inclusion problem in ObjC version pod? #4301

Closed
meritozh opened this issue Feb 9, 2018 · 6 comments
Closed

circular header inclusion problem in ObjC version pod? #4301

meritozh opened this issue Feb 9, 2018 · 6 comments

Comments

@meritozh
Copy link

meritozh commented Feb 9, 2018

Seems there is a circular header inclusion problem:

GPBWellKnownTypes.h -->  Any.pbobjc.h -->  GPBProtocolBuffers.h
// but also
GPBProtocolBuffers.h --> GPBWellKnownTypes.h

It can compile through pod 'Protobuf', but if I pre build several pods, include this pod, then combine them into one static library, wrap and produce an final static core.framework with custom module.modulemap, it can not work. Xcode raise two error could not build module core and cannot find interface declaration for 'GPBAny'.

module.modulemap:

framework module core {
...

explicit module Protobuf {
    header "Any.pbobjc.h"
    header "Api.pbobjc.h"
    header "Duration.pbobjc.h"
    header "Empty.pbobjc.h"
    header "FieldMask.pbobjc.h"
    header "GPBArray.h"
    header "GPBArray_PackagePrivate.h"
    header "GPBBootstrap.h"
    header "GPBCodedInputStream.h"
    header "GPBCodedInputStream_PackagePrivate.h"
    header "GPBCodedOutputStream.h"
    header "GPBCodedOutputStream_PackagePrivate.h"
    header "GPBDescriptor.h"
    header "GPBDescriptor_PackagePrivate.h"
    header "GPBDictionary.h"
    header "GPBDictionary_PackagePrivate.h"
    header "GPBExtensionInternals.h"
    header "GPBExtensionRegistry.h"
    header "GPBMessage.h"
    header "GPBMessage_PackagePrivate.h"
    header "GPBProtocolBuffers.h"
    header "GPBProtocolBuffers_RuntimeSupport.h"
    header "GPBRootObject.h"
    header "GPBRootObject_PackagePrivate.h"
    header "GPBRuntimeTypes.h"
    header "GPBUnknownField.h"
    header "GPBUnknownFieldSet.h"
    header "GPBUnknownFieldSet_PackagePrivate.h"
    header "GPBUnknownField_PackagePrivate.h"
    header "GPBUtilities.h"
    header "GPBUtilities_PackagePrivate.h"
    header "GPBWellKnownTypes.h"
    header "GPBWireFormat.h"
    header "Protobuf-umbrella.h"
    header "SourceContext.pbobjc.h"
    header "Struct.pbobjc.h"
    header "Timestamp.pbobjc.h"
    header "Type.pbobjc.h"
    header "Wrappers.pbobjc.h"
  }
...
}
@thomasvl
Copy link
Contributor

They are all #import directives, so the compiler make sure to only load the contents once. I'm not completely clear from you description what you are doing, but it sounds like you might be making your own packaging around a few pods? The one that could cause problems is if you are finding the headers via different imports and hence finding them in different spots. GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS is used to make the protobuf header use the #import <Protobuf/[name].h imports. The podpsec helps do this via some *_target_xcconfig directives. If you are manually setting up a target, you could have added an include path into the objectivec/google/protobuf subdirectory instead of setting up the GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS and that is causing the compiler to think there are multiple headers trying to define the same things.

@meritozh
Copy link
Author

meritozh commented Feb 15, 2018

Yes, I package several pods into one. I don't know how to describe it in detail.

I know Clang will only load header once if it load through #import. I just sort headers then hand code content of explicit module Protobuf in module.modulemap, it can not compile, but if I move header "Any.pbobjc.h" to last line, it can compile. I don't think headers order in modulemap can affect module parsing result, success or not. If I disable clang module, it can compile. Or comment this line, it also can compile: https://github.com/google/protobuf/blob/e34ec6077af141dd5dfc1c334ecdcce3c6b51612/objectivec/GPBProtocolBuffers.h#L44

Defining GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS won't affect result, I have change header path manually.

By process of elimination, I think circular header inclusion may cause some internal error when Clang parsing module. Also I need more testing, will update this issue if I have any process.

@meritozh
Copy link
Author

@thomasvl I test with a demo project. It seem circular inclusion will actually cause module parsing problem. Xcode raise error cannot find interface declaration for 'GPBAny'. Demo is here: https://github.com/meritozh/CircularIncludeTest

@meritozh
Copy link
Author

no response?

@thomasvl
Copy link
Contributor

no response?

Sorry, I don't think any of us that work on Apple platforms has gotten a chance to dig into this more and other things we work on have been higher priority.

My thought is since the pod has been around for a while without this coming up, it likely is specific to your setup and less likely to be a general problem.

The issue is open so if other people run into it they can also chime in and anyone looking to contribute could try looking at it also.

@meritozh
Copy link
Author

Thanks.
I'm interested in this problem. Maybe I will make a PR to fix it if I find a proper solution.

thomasvl added a commit to thomasvl/protobuf that referenced this issue Mar 30, 2018
Cut down on what is imported into the generated .pbobjc.h files to only
what is really needed. This should help compile times a little by not
making clang go fetch headers that aren't really needed.

BREAKING CHANGE: For anyone that only ever included .pbobjc.h files, but
then expected to be able to access some less common things like UnknownFields,
Descriptor based field access, etc. The code using those features needs to
include the specific GPB headers needed or just include GPBProtocolBuffers.h.

This also resolves some issues with include orders around the the WKTs.

Fixes protocolbuffers#4301
Fixes protocolbuffers#4403
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants