diff --git a/objectivec/README.md b/objectivec/README.md index 69fe631644..5982939290 100644 --- a/objectivec/README.md +++ b/objectivec/README.md @@ -172,6 +172,12 @@ supported keys are: lot of proto files included in it; and having multiple lines makes things easier to read. + * `runtime_import_prefix`: The `value` used for this key to be used as a + prefix on `#import`s of runtime provided headers in the generated files. + When integrating ObjC protos into a build system, this can be used to avoid + having to add the runtime directory to the header search path since the + generate `#import` will be more complete. + Contributing ------------ diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.cc b/src/google/protobuf/compiler/objectivec/objectivec_file.cc index 8c0305b154..58ca9c195b 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_file.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_file.cc @@ -242,6 +242,7 @@ void FileGenerator::GenerateHeader(io::Printer *printer) { ImportWriter import_writer( options_.generate_for_named_framework, options_.named_framework_to_proto_path_mappings_path, + options_.runtime_import_prefix, is_bundled_proto_); const string header_extension(kHeaderExtension); for (int i = 0; i < file_->public_dependency_count(); i++) { @@ -355,6 +356,7 @@ void FileGenerator::GenerateSource(io::Printer *printer) { ImportWriter import_writer( options_.generate_for_named_framework, options_.named_framework_to_proto_path_mappings_path, + options_.runtime_import_prefix, is_bundled_proto_); const string header_extension(kHeaderExtension); @@ -596,7 +598,8 @@ void FileGenerator::PrintFileRuntimePreamble( "// source: $filename$\n" "\n", "filename", file_->name()); - ImportWriter::PrintRuntimeImports(printer, headers_to_import, true); + ImportWriter::PrintRuntimeImports( + printer, headers_to_import, options_.runtime_import_prefix, true); printer->Print("\n"); } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc index 25338ad939..257e4f9abc 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc @@ -127,6 +127,13 @@ bool ObjectiveCGenerator::GenerateAll(const std::vector& // with generate_for_named_framework, or the relative path to it's include // path otherwise. generation_options.named_framework_to_proto_path_mappings_path = options[i].second; + } else if (options[i].first == "runtime_import_prefix") { + // Path to use as a prefix on #imports of runtime provided headers in the + // generated files. When integrating ObjC protos into a build system, + // this can be used to avoid having to add the runtime directory to the + // header search path since the generate #import will be more complete. + generation_options.runtime_import_prefix = + StripSuffixString(options[i].second, "/"); } else { *error = "error: Unknown generator option: " + options[i].first; return false; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc index 24c4546d90..8b2b719e03 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc @@ -1566,10 +1566,12 @@ bool ParseSimpleFile( ImportWriter::ImportWriter( const string& generate_for_named_framework, const string& named_framework_to_proto_path_mappings_path, + const string& runtime_import_prefix, bool include_wkt_imports) : generate_for_named_framework_(generate_for_named_framework), named_framework_to_proto_path_mappings_path_( named_framework_to_proto_path_mappings_path), + runtime_import_prefix_(runtime_import_prefix), include_wkt_imports_(include_wkt_imports), need_to_parse_mapping_file_(true) { } @@ -1618,7 +1620,7 @@ void ImportWriter::Print(io::Printer* printer) const { bool add_blank_line = false; if (!protobuf_imports_.empty()) { - PrintRuntimeImports(printer, protobuf_imports_); + PrintRuntimeImports(printer, protobuf_imports_, runtime_import_prefix_); add_blank_line = true; } @@ -1654,7 +1656,20 @@ void ImportWriter::Print(io::Printer* printer) const { void ImportWriter::PrintRuntimeImports( io::Printer* printer, const std::vector& header_to_import, + const string& runtime_import_prefix, bool default_cpp_symbol) { + + // Given an override, use that. + if (!runtime_import_prefix.empty()) { + for (const auto& header : header_to_import) { + printer->Print( + " #import \"$import_prefix$/$header$\"\n", + "import_prefix", runtime_import_prefix, + "header", header); + } + return; + } + const string framework_name(ProtobufLibraryFrameworkName); const string cpp_symbol(ProtobufFrameworkImportSymbol(framework_name)); diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h index 90e3fd1ab2..02f540f874 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h @@ -53,6 +53,7 @@ struct Options { std::vector expected_prefixes_suppressions; string generate_for_named_framework; string named_framework_to_proto_path_mappings_path; + string runtime_import_prefix; }; // Escape C++ trigraphs by escaping question marks to "\?". @@ -279,6 +280,7 @@ class PROTOC_EXPORT ImportWriter { public: ImportWriter(const string& generate_for_named_framework, const string& named_framework_to_proto_path_mappings_path, + const string& runtime_import_prefix, bool include_wkt_imports); ~ImportWriter(); @@ -287,6 +289,7 @@ class PROTOC_EXPORT ImportWriter { static void PrintRuntimeImports(io::Printer *printer, const std::vector& header_to_import, + const string& runtime_import_prefix, bool default_cpp_symbol = false); private: @@ -305,6 +308,7 @@ class PROTOC_EXPORT ImportWriter { const string generate_for_named_framework_; const string named_framework_to_proto_path_mappings_path_; + const string runtime_import_prefix_; const bool include_wkt_imports_; std::map proto_file_to_framework_name_; bool need_to_parse_mapping_file_;