From 72df8446975d018616a4ff97f1d79f55c6d21af8 Mon Sep 17 00:00:00 2001 From: Thomas Van Lenten Date: Mon, 9 May 2016 13:53:20 -0400 Subject: Better support for using the proto library from a framework. - Add generator constant for the default framework name. - Add generator api for making the CPP symbol from the name. - Add generator api to see if it is a bundled proto file. - Output a CPP conditional and two imports for the core library headers. - Add helper for generating the #import for file headers to deal with the framework imports. - Add a reference from the unittests to a WKT to use that to inspect how imports generate. - Update the podspec to define the CPP symbol and require pods 1.0 (or later). Fixes https://github.com/google/protobuf/issues/1457 --- Protobuf.podspec | 6 +- objectivec/GPBProtocolBuffers.h | 39 +++-- objectivec/GPBWellKnownTypes.h | 15 +- objectivec/Tests/unittest_objc.proto | 9 ++ objectivec/google/protobuf/Any.pbobjc.h | 12 +- objectivec/google/protobuf/Any.pbobjc.m | 19 ++- objectivec/google/protobuf/Api.pbobjc.h | 12 +- objectivec/google/protobuf/Api.pbobjc.m | 25 ++- objectivec/google/protobuf/Duration.pbobjc.h | 12 +- objectivec/google/protobuf/Duration.pbobjc.m | 19 ++- objectivec/google/protobuf/Empty.pbobjc.h | 12 +- objectivec/google/protobuf/Empty.pbobjc.m | 19 ++- objectivec/google/protobuf/FieldMask.pbobjc.h | 12 +- objectivec/google/protobuf/FieldMask.pbobjc.m | 19 ++- objectivec/google/protobuf/SourceContext.pbobjc.h | 12 +- objectivec/google/protobuf/SourceContext.pbobjc.m | 19 ++- objectivec/google/protobuf/Struct.pbobjc.h | 12 +- objectivec/google/protobuf/Struct.pbobjc.m | 19 ++- objectivec/google/protobuf/Timestamp.pbobjc.h | 12 +- objectivec/google/protobuf/Timestamp.pbobjc.m | 19 ++- objectivec/google/protobuf/Type.pbobjc.h | 12 +- objectivec/google/protobuf/Type.pbobjc.m | 25 ++- objectivec/google/protobuf/Wrappers.pbobjc.h | 12 +- objectivec/google/protobuf/Wrappers.pbobjc.m | 19 ++- .../compiler/objectivec/objectivec_file.cc | 171 ++++++++++++++++----- .../protobuf/compiler/objectivec/objectivec_file.h | 5 +- .../compiler/objectivec/objectivec_helpers.cc | 54 ++++++- .../compiler/objectivec/objectivec_helpers.h | 17 +- 28 files changed, 543 insertions(+), 95 deletions(-) diff --git a/Protobuf.podspec b/Protobuf.podspec index 0bbd06df..d763f01d 100644 --- a/Protobuf.podspec +++ b/Protobuf.podspec @@ -10,6 +10,7 @@ Pod::Spec.new do |s| s.homepage = 'https://github.com/google/protobuf' s.license = 'New BSD' s.authors = { 'The Protocol Buffers contributors' => 'protobuf@googlegroups.com' } + s.cocoapods_version = '>= 1.0' s.source = { :git => 'https://github.com/google/protobuf.git', :tag => "v#{s.version}" } @@ -32,7 +33,10 @@ Pod::Spec.new do |s| # The following would cause duplicate symbol definitions. GPBProtocolBuffers is expected to be # left out, as it's an umbrella implementation file. s.exclude_files = 'objectivec/GPBProtocolBuffers.m' - s.header_mappings_dir = 'objectivec' + + # Set a CPP symbol so the code knows to use framework imports. + s.user_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1' } + s.pod_target_xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1' } s.ios.deployment_target = '7.1' s.osx.deployment_target = '10.9' diff --git a/objectivec/GPBProtocolBuffers.h b/objectivec/GPBProtocolBuffers.h index 677903ed..68d8854e 100644 --- a/objectivec/GPBProtocolBuffers.h +++ b/objectivec/GPBProtocolBuffers.h @@ -44,14 +44,33 @@ #import "GPBWellKnownTypes.h" #import "GPBWireFormat.h" +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + // Well-known proto types -#import "google/protobuf/Any.pbobjc.h" -#import "google/protobuf/Api.pbobjc.h" -#import "google/protobuf/Duration.pbobjc.h" -#import "google/protobuf/Empty.pbobjc.h" -#import "google/protobuf/FieldMask.pbobjc.h" -#import "google/protobuf/SourceContext.pbobjc.h" -#import "google/protobuf/Struct.pbobjc.h" -#import "google/protobuf/Timestamp.pbobjc.h" -#import "google/protobuf/Type.pbobjc.h" -#import "google/protobuf/Wrappers.pbobjc.h" +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import + #import + #import + #import + #import + #import + #import + #import + #import + #import +#else + #import "google/protobuf/Any.pbobjc.h" + #import "google/protobuf/Api.pbobjc.h" + #import "google/protobuf/Duration.pbobjc.h" + #import "google/protobuf/Empty.pbobjc.h" + #import "google/protobuf/FieldMask.pbobjc.h" + #import "google/protobuf/SourceContext.pbobjc.h" + #import "google/protobuf/Struct.pbobjc.h" + #import "google/protobuf/Timestamp.pbobjc.h" + #import "google/protobuf/Type.pbobjc.h" + #import "google/protobuf/Wrappers.pbobjc.h" +#endif diff --git a/objectivec/GPBWellKnownTypes.h b/objectivec/GPBWellKnownTypes.h index 28442fbe..311ac58e 100644 --- a/objectivec/GPBWellKnownTypes.h +++ b/objectivec/GPBWellKnownTypes.h @@ -30,8 +30,19 @@ #import -#import "google/protobuf/Duration.pbobjc.h" -#import "google/protobuf/Timestamp.pbobjc.h" +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import + #import +#else + #import "google/protobuf/Duration.pbobjc.h" + #import "google/protobuf/Timestamp.pbobjc.h" +#endif NS_ASSUME_NONNULL_BEGIN diff --git a/objectivec/Tests/unittest_objc.proto b/objectivec/Tests/unittest_objc.proto index f6ab6a24..914945eb 100644 --- a/objectivec/Tests/unittest_objc.proto +++ b/objectivec/Tests/unittest_objc.proto @@ -29,6 +29,7 @@ syntax = "proto2"; +import "google/protobuf/any.proto"; import "google/protobuf/unittest.proto"; package protobuf_unittest; @@ -447,3 +448,11 @@ message BoolOnlyMessage { optional bool bool_field_31 = 31; optional bool bool_field_32 = 32; } + +// Reference to a WKT to test (via generated code inspection), the handling +// of #imports. Within the WKTs, references to each other are just path +// based imports, but when reference from another proto file, they should be +// conditional to support the framework import style. +message WKTRefereceMessage { + optional google.protobuf.Any an_any = 1; +} diff --git a/objectivec/google/protobuf/Any.pbobjc.h b/objectivec/google/protobuf/Any.pbobjc.h index 4002a989..e9a8533a 100644 --- a/objectivec/google/protobuf/Any.pbobjc.h +++ b/objectivec/google/protobuf/Any.pbobjc.h @@ -1,7 +1,17 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/any.proto -#import "GPBProtocolBuffers.h" +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers.h" +#endif #if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001 #error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/google/protobuf/Any.pbobjc.m b/objectivec/google/protobuf/Any.pbobjc.m index 6a1bf894..25e5b4c4 100644 --- a/objectivec/google/protobuf/Any.pbobjc.m +++ b/objectivec/google/protobuf/Any.pbobjc.m @@ -1,8 +1,23 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/any.proto -#import "GPBProtocolBuffers_RuntimeSupport.h" -#import "google/protobuf/Any.pbobjc.h" +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "google/protobuf/Any.pbobjc.h" +#endif // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/google/protobuf/Api.pbobjc.h b/objectivec/google/protobuf/Api.pbobjc.h index d66df629..04341f47 100644 --- a/objectivec/google/protobuf/Api.pbobjc.h +++ b/objectivec/google/protobuf/Api.pbobjc.h @@ -1,7 +1,17 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/api.proto -#import "GPBProtocolBuffers.h" +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers.h" +#endif #if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001 #error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/google/protobuf/Api.pbobjc.m b/objectivec/google/protobuf/Api.pbobjc.m index 45a06e60..cd37edaa 100644 --- a/objectivec/google/protobuf/Api.pbobjc.m +++ b/objectivec/google/protobuf/Api.pbobjc.m @@ -1,10 +1,27 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/api.proto -#import "GPBProtocolBuffers_RuntimeSupport.h" -#import "google/protobuf/Api.pbobjc.h" -#import "google/protobuf/SourceContext.pbobjc.h" -#import "google/protobuf/Type.pbobjc.h" +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import + #import + #import +#else + #import "google/protobuf/Api.pbobjc.h" + #import "google/protobuf/SourceContext.pbobjc.h" + #import "google/protobuf/Type.pbobjc.h" +#endif // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/google/protobuf/Duration.pbobjc.h b/objectivec/google/protobuf/Duration.pbobjc.h index 29888d6c..4c3173d3 100644 --- a/objectivec/google/protobuf/Duration.pbobjc.h +++ b/objectivec/google/protobuf/Duration.pbobjc.h @@ -1,7 +1,17 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/duration.proto -#import "GPBProtocolBuffers.h" +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers.h" +#endif #if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001 #error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/google/protobuf/Duration.pbobjc.m b/objectivec/google/protobuf/Duration.pbobjc.m index 7dd6b64a..35daa3df 100644 --- a/objectivec/google/protobuf/Duration.pbobjc.m +++ b/objectivec/google/protobuf/Duration.pbobjc.m @@ -1,8 +1,23 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/duration.proto -#import "GPBProtocolBuffers_RuntimeSupport.h" -#import "google/protobuf/Duration.pbobjc.h" +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "google/protobuf/Duration.pbobjc.h" +#endif // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/google/protobuf/Empty.pbobjc.h b/objectivec/google/protobuf/Empty.pbobjc.h index f33db017..2d2a86bc 100644 --- a/objectivec/google/protobuf/Empty.pbobjc.h +++ b/objectivec/google/protobuf/Empty.pbobjc.h @@ -1,7 +1,17 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/empty.proto -#import "GPBProtocolBuffers.h" +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers.h" +#endif #if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001 #error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/google/protobuf/Empty.pbobjc.m b/objectivec/google/protobuf/Empty.pbobjc.m index 88753aaf..1bdd4949 100644 --- a/objectivec/google/protobuf/Empty.pbobjc.m +++ b/objectivec/google/protobuf/Empty.pbobjc.m @@ -1,8 +1,23 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/empty.proto -#import "GPBProtocolBuffers_RuntimeSupport.h" -#import "google/protobuf/Empty.pbobjc.h" +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "google/protobuf/Empty.pbobjc.h" +#endif // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/google/protobuf/FieldMask.pbobjc.h b/objectivec/google/protobuf/FieldMask.pbobjc.h index 73cbd8a5..52be4ab7 100644 --- a/objectivec/google/protobuf/FieldMask.pbobjc.h +++ b/objectivec/google/protobuf/FieldMask.pbobjc.h @@ -1,7 +1,17 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/field_mask.proto -#import "GPBProtocolBuffers.h" +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers.h" +#endif #if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001 #error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/google/protobuf/FieldMask.pbobjc.m b/objectivec/google/protobuf/FieldMask.pbobjc.m index 8c241afc..2721fdfa 100644 --- a/objectivec/google/protobuf/FieldMask.pbobjc.m +++ b/objectivec/google/protobuf/FieldMask.pbobjc.m @@ -1,8 +1,23 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/field_mask.proto -#import "GPBProtocolBuffers_RuntimeSupport.h" -#import "google/protobuf/FieldMask.pbobjc.h" +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "google/protobuf/FieldMask.pbobjc.h" +#endif // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/google/protobuf/SourceContext.pbobjc.h b/objectivec/google/protobuf/SourceContext.pbobjc.h index 8775348e..985d41d4 100644 --- a/objectivec/google/protobuf/SourceContext.pbobjc.h +++ b/objectivec/google/protobuf/SourceContext.pbobjc.h @@ -1,7 +1,17 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/source_context.proto -#import "GPBProtocolBuffers.h" +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers.h" +#endif #if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001 #error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/google/protobuf/SourceContext.pbobjc.m b/objectivec/google/protobuf/SourceContext.pbobjc.m index 95007126..6e3c9c07 100644 --- a/objectivec/google/protobuf/SourceContext.pbobjc.m +++ b/objectivec/google/protobuf/SourceContext.pbobjc.m @@ -1,8 +1,23 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/source_context.proto -#import "GPBProtocolBuffers_RuntimeSupport.h" -#import "google/protobuf/SourceContext.pbobjc.h" +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "google/protobuf/SourceContext.pbobjc.h" +#endif // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/google/protobuf/Struct.pbobjc.h b/objectivec/google/protobuf/Struct.pbobjc.h index 3924b4b7..3e2d55fd 100644 --- a/objectivec/google/protobuf/Struct.pbobjc.h +++ b/objectivec/google/protobuf/Struct.pbobjc.h @@ -1,7 +1,17 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/struct.proto -#import "GPBProtocolBuffers.h" +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers.h" +#endif #if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001 #error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/google/protobuf/Struct.pbobjc.m b/objectivec/google/protobuf/Struct.pbobjc.m index 60940027..39b12879 100644 --- a/objectivec/google/protobuf/Struct.pbobjc.m +++ b/objectivec/google/protobuf/Struct.pbobjc.m @@ -1,8 +1,23 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/struct.proto -#import "GPBProtocolBuffers_RuntimeSupport.h" -#import "google/protobuf/Struct.pbobjc.h" +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "google/protobuf/Struct.pbobjc.h" +#endif // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/google/protobuf/Timestamp.pbobjc.h b/objectivec/google/protobuf/Timestamp.pbobjc.h index 925dca84..d15de7c7 100644 --- a/objectivec/google/protobuf/Timestamp.pbobjc.h +++ b/objectivec/google/protobuf/Timestamp.pbobjc.h @@ -1,7 +1,17 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/timestamp.proto -#import "GPBProtocolBuffers.h" +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers.h" +#endif #if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001 #error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/google/protobuf/Timestamp.pbobjc.m b/objectivec/google/protobuf/Timestamp.pbobjc.m index f35e435d..06e3ef94 100644 --- a/objectivec/google/protobuf/Timestamp.pbobjc.m +++ b/objectivec/google/protobuf/Timestamp.pbobjc.m @@ -1,8 +1,23 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/timestamp.proto -#import "GPBProtocolBuffers_RuntimeSupport.h" -#import "google/protobuf/Timestamp.pbobjc.h" +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "google/protobuf/Timestamp.pbobjc.h" +#endif // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/google/protobuf/Type.pbobjc.h b/objectivec/google/protobuf/Type.pbobjc.h index 590d970b..93ee3cec 100644 --- a/objectivec/google/protobuf/Type.pbobjc.h +++ b/objectivec/google/protobuf/Type.pbobjc.h @@ -1,7 +1,17 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/type.proto -#import "GPBProtocolBuffers.h" +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers.h" +#endif #if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001 #error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/google/protobuf/Type.pbobjc.m b/objectivec/google/protobuf/Type.pbobjc.m index 5554a222..6c7b4efd 100644 --- a/objectivec/google/protobuf/Type.pbobjc.m +++ b/objectivec/google/protobuf/Type.pbobjc.m @@ -1,10 +1,27 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/type.proto -#import "GPBProtocolBuffers_RuntimeSupport.h" -#import "google/protobuf/Type.pbobjc.h" -#import "google/protobuf/Any.pbobjc.h" -#import "google/protobuf/SourceContext.pbobjc.h" +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import + #import + #import +#else + #import "google/protobuf/Type.pbobjc.h" + #import "google/protobuf/Any.pbobjc.h" + #import "google/protobuf/SourceContext.pbobjc.h" +#endif // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/google/protobuf/Wrappers.pbobjc.h b/objectivec/google/protobuf/Wrappers.pbobjc.h index 46510500..5593d348 100644 --- a/objectivec/google/protobuf/Wrappers.pbobjc.h +++ b/objectivec/google/protobuf/Wrappers.pbobjc.h @@ -1,7 +1,17 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/wrappers.proto -#import "GPBProtocolBuffers.h" +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers.h" +#endif #if GOOGLE_PROTOBUF_OBJC_GEN_VERSION != 30001 #error This file was generated by a different version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/google/protobuf/Wrappers.pbobjc.m b/objectivec/google/protobuf/Wrappers.pbobjc.m index 5cc6c2e4..b5405a7d 100644 --- a/objectivec/google/protobuf/Wrappers.pbobjc.m +++ b/objectivec/google/protobuf/Wrappers.pbobjc.m @@ -1,8 +1,23 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/wrappers.proto -#import "GPBProtocolBuffers_RuntimeSupport.h" -#import "google/protobuf/Wrappers.pbobjc.h" +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "google/protobuf/Wrappers.pbobjc.h" +#endif // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.cc b/src/google/protobuf/compiler/objectivec/objectivec_file.cc index ed4fc6a3..ccf5fbb4 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_file.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_file.cc @@ -50,6 +50,80 @@ const int32 GOOGLE_PROTOBUF_OBJC_GEN_VERSION = 30001; namespace compiler { namespace objectivec { +namespace { + +class ImportWriter { + public: + ImportWriter() {} + + void AddFile(const FileGenerator* file); + void Print(io::Printer *printer) const; + + private: + vector protobuf_framework_imports_; + vector protobuf_non_framework_imports_; + vector other_imports_; +}; + +void ImportWriter::AddFile(const FileGenerator* file) { + const FileDescriptor* file_descriptor = file->Descriptor(); + const string extension(".pbobjc.h"); + if (IsProtobufLibraryBundledProtoFile(file_descriptor)) { + protobuf_framework_imports_.push_back( + FilePathBasename(file_descriptor) + extension); + protobuf_non_framework_imports_.push_back(file->Path() + extension); + } else { + other_imports_.push_back(file->Path() + extension); + } +} + +void ImportWriter::Print(io::Printer *printer) const { + assert(protobuf_non_framework_imports_.size() == + protobuf_framework_imports_.size()); + + if (protobuf_framework_imports_.size() > 0) { + const string framework_name(ProtobufLibraryFrameworkName); + const string cpp_symbol(ProtobufFrameworkImportSymbol(framework_name)); + + printer->Print( + "#if $cpp_symbol$\n", + "cpp_symbol", cpp_symbol); + for (vector::const_iterator iter = protobuf_framework_imports_.begin(); + iter != protobuf_framework_imports_.end(); ++iter) { + printer->Print( + " #import <$framework_name$/$header$>\n", + "framework_name", framework_name, + "header", *iter); + } + printer->Print( + "#else\n"); + for (vector::const_iterator iter = protobuf_non_framework_imports_.begin(); + iter != protobuf_non_framework_imports_.end(); ++iter) { + printer->Print( + " #import \"$header$\"\n", + "header", *iter); + } + printer->Print( + "#endif\n"); + + if (other_imports_.size() > 0) { + printer->Print("\n"); + } + } + + if (other_imports_.size() > 0) { + for (vector::const_iterator iter = other_imports_.begin(); + iter != other_imports_.end(); ++iter) { + printer->Print( + " #import \"$header$\"\n", + "header", *iter); + } + } +} + +} // namespace + + FileGenerator::FileGenerator(const FileDescriptor *file, const Options& options) : file_(file), root_class_name_(FileClassName(file)), @@ -82,15 +156,7 @@ FileGenerator::~FileGenerator() { } void FileGenerator::GenerateHeader(io::Printer *printer) { - printer->Print( - "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" - "// source: $filename$\n" - "\n", - "filename", file_->name()); - - printer->Print( - "#import \"GPBProtocolBuffers.h\"\n" - "\n"); + PrintFilePreamble(printer, "GPBProtocolBuffers.h"); // Add some verification that the generated code matches the source the // code is being compiled with. @@ -102,14 +168,18 @@ void FileGenerator::GenerateHeader(io::Printer *printer) { "protoc_gen_objc_version", SimpleItoa(GOOGLE_PROTOBUF_OBJC_GEN_VERSION)); - const vector &dependency_generators = DependencyGenerators(); - for (vector::const_iterator iter = - dependency_generators.begin(); - iter != dependency_generators.end(); ++iter) { - if ((*iter)->IsPublicDependency()) { - printer->Print("#import \"$header$.pbobjc.h\"\n", - "header", (*iter)->Path()); + // #import any headers for "public imports" in the proto file. + { + ImportWriter import_writer; + const vector &dependency_generators = DependencyGenerators(); + for (vector::const_iterator iter = + dependency_generators.begin(); + iter != dependency_generators.end(); ++iter) { + if ((*iter)->IsPublicDependency()) { + import_writer.AddFile(*iter); + } } + import_writer.Print(printer); } printer->Print( @@ -198,27 +268,30 @@ void FileGenerator::GenerateHeader(io::Printer *printer) { } void FileGenerator::GenerateSource(io::Printer *printer) { - printer->Print( - "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" - "// source: $filename$\n" - "\n", - "filename", file_->name()); + // #import the runtime support. + PrintFilePreamble(printer, "GPBProtocolBuffers_RuntimeSupport.h"); - string header_file = Path() + ".pbobjc.h"; - printer->Print( - "#import \"GPBProtocolBuffers_RuntimeSupport.h\"\n" - "#import \"$header_file$\"\n", - "header_file", header_file); - const vector &dependency_generators = - DependencyGenerators(); - for (vector::const_iterator iter = - dependency_generators.begin(); - iter != dependency_generators.end(); ++iter) { - if (!(*iter)->IsPublicDependency()) { - printer->Print("#import \"$header$.pbobjc.h\"\n", - "header", (*iter)->Path()); + { + ImportWriter import_writer; + + // #import the header for this proto file. + import_writer.AddFile(this); + + // #import the headers for anything that a plain dependency of this proto + // file (that means they were just an include, not a "public" include). + const vector &dependency_generators = + DependencyGenerators(); + for (vector::const_iterator iter = + dependency_generators.begin(); + iter != dependency_generators.end(); ++iter) { + if (!(*iter)->IsPublicDependency()) { + import_writer.AddFile(*iter); + } } + + import_writer.Print(printer); } + printer->Print( "// @@protoc_insertion_point(imports)\n" "\n" @@ -356,8 +429,6 @@ void FileGenerator::GenerateSource(io::Printer *printer) { "// @@protoc_insertion_point(global_scope)\n"); } -const string FileGenerator::Path() const { return FilePath(file_); } - const vector &FileGenerator::DependencyGenerators() { if (file_->dependency_count() != dependency_generators_.size()) { set public_import_names; @@ -376,6 +447,34 @@ const vector &FileGenerator::DependencyGenerators() { return dependency_generators_; } +void FileGenerator::PrintFilePreamble( + io::Printer* printer, const string& header_to_import) const { + printer->Print( + "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "// source: $filename$\n" + "\n", + "filename", file_->name()); + + const string framework_name(ProtobufLibraryFrameworkName); + const string cpp_symbol(ProtobufFrameworkImportSymbol(framework_name)); + printer->Print( + "// This CPP symbol can be defined to use imports that match up to the framework\n" + "// imports needed when using CocoaPods.\n" + "#if !defined($cpp_symbol$)\n" + " #define $cpp_symbol$ 0\n" + "#endif\n" + "\n" + "#if $cpp_symbol$\n" + " #import <$framework_name$/$header$>\n" + "#else\n" + " #import \"$header$\"\n" + "#endif\n" + "\n", + "cpp_symbol", cpp_symbol, + "header", header_to_import, + "framework_name", framework_name); +} + } // namespace objectivec } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.h b/src/google/protobuf/compiler/objectivec/objectivec_file.h index 4c0fcd3f..7326c901 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_file.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_file.h @@ -62,7 +62,8 @@ class FileGenerator { void GenerateHeader(io::Printer* printer); const string& RootClassName() const { return root_class_name_; } - const string Path() const; + const string Path() const { return FilePath(file_); } + const FileDescriptor* Descriptor() const { return file_; } bool IsPublicDependency() const { return is_public_dep_; } @@ -87,6 +88,8 @@ class FileGenerator { const Options options_; const vector& DependencyGenerators(); + void PrintFilePreamble( + io::Printer* printer, const string& header_to_import) const; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator); }; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc index 196b39dd..65bf8348 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc @@ -293,13 +293,6 @@ string BaseFileName(const FileDescriptor* file) { return basename; } -string FileName(const FileDescriptor* file) { - string path = FilePath(file); - string basename; - PathSplit(path, NULL, &basename); - return basename; -} - string FilePath(const FileDescriptor* file) { string output; string basename; @@ -317,6 +310,19 @@ string FilePath(const FileDescriptor* file) { return output; } +string FilePathBasename(const FileDescriptor* file) { + string output; + string basename; + string directory; + PathSplit(file->name(), &directory, &basename); + basename = StripProto(basename); + + // CamelCase to be more ObjC friendly. + output = UnderscoresToCamelCase(basename, true); + + return output; +} + string FileClassPrefix(const FileDescriptor* file) { // Default is empty string, no need to check has_objc_class_prefix. string result = file->options().objc_class_prefix(); @@ -831,6 +837,40 @@ string BuildCommentsString(const SourceLocation& location) { return final_comments; } +// Making these a generator option for folks that don't use CocoaPods, but do +// want to put the library in a framework is an interesting question. The +// problem is it means changing sources shipped with the library to actually +// use a different value; so it isn't as simple as a option. +const char* const ProtobufLibraryFrameworkName = "Protobuf"; + +string ProtobufFrameworkImportSymbol(const string& framework_name) { + // GPB_USE_[framework_name]_FRAMEWORK_IMPORTS + string result = string("GPB_USE_"); + result += ToUpper(framework_name); + result += "_FRAMEWORK_IMPORTS"; + return result; +} + +bool IsProtobufLibraryBundledProtoFile(const FileDescriptor* file) { + // We don't check the name prefix or proto package because some files + // (descriptor.proto), aren't shipped generated by the library, so this + // seems to be the safest way to only catch the ones shipped. + const string name = file->name(); + if (name == "google/protobuf/any.proto" || + name == "google/protobuf/api.proto" || + name == "google/protobuf/duration.proto" || + name == "google/protobuf/empty.proto" || + name == "google/protobuf/field_mask.proto" || + name == "google/protobuf/source_context.proto" || + name == "google/protobuf/struct.proto" || + name == "google/protobuf/timestamp.proto" || + name == "google/protobuf/type.proto" || + name == "google/protobuf/wrappers.proto") { + return true; + } + return false; +} + namespace { // Internal helper class that parses the expected package to prefix mappings diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h index 3f56d94b..5898d692 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h @@ -62,15 +62,14 @@ bool IsRetainedName(const string& name); // handling under ARC. bool IsInitName(const string& name); -// Gets the name of the file we're going to generate (sans the .pb.h -// extension). This does not include the path to that file. -string FileName(const FileDescriptor* file); - // Gets the path of the file we're going to generate (sans the .pb.h // extension). The path will be dependent on the objectivec package // declared in the proto package. string FilePath(const FileDescriptor* file); +// Just like FilePath(), but without the directory part. +string FilePathBasename(const FileDescriptor* file); + // Gets the name of the root class we'll generate in the file. This class // is not meant for external consumption, but instead contains helpers that // the rest of the classes need @@ -169,6 +168,16 @@ string BuildFlagsString(const vector& strings); // Builds a HeaderDoc style comment out of the comments in the .proto file. string BuildCommentsString(const SourceLocation& location); +// The name the commonly used by the library when built as a framework. +// This lines up to the name used in the CocoaPod. +extern const char* const ProtobufLibraryFrameworkName; +// Returns the CPP symbol name to use as the gate for framework style imports +// for the given framework name to use. +string ProtobufFrameworkImportSymbol(const string& framework_name); + +// Checks if the file is one of the proto's bundled with the library. +bool IsProtobufLibraryBundledProtoFile(const FileDescriptor* file); + // Checks the prefix for a given file and outputs any warnings needed, if // there are flat out errors, then out_error is filled in and the result is // false. -- cgit v1.2.3