Add support for generation sources into a framework.

- Add a protoc objc option (generate_for_named_framework) to set the name of
  the framework all generated sources will be in.
- Tweak some comments/naming to make it clear what is the Protobuf framework
  vs. the framework for generated code.
- Update the objc README to document the new generation option to protoc.

This is working towards https://github.com/google/protobuf/issues/1457.
pull/1683/head
Thomas Van Lenten 9 years ago
parent 71f4a9c6f3
commit a2a3399a6f
  1. 17
      objectivec/README.md
  2. 42
      src/google/protobuf/compiler/objectivec/objectivec_file.cc
  3. 2
      src/google/protobuf/compiler/objectivec/objectivec_file.h
  4. 2
      src/google/protobuf/compiler/objectivec/objectivec_generator.cc
  5. 1
      src/google/protobuf/compiler/objectivec/objectivec_helpers.h

@ -123,8 +123,8 @@ never included when the message is encoded.
The Objective C classes/enums can be used from Swift code.
Objective C Generator Options
-----------------------------
Objective C Generator Proto File Options
----------------------------------------
**objc_class_prefix=\<prefix\>** (no default)
@ -133,6 +133,19 @@ be collisions. This option provides a prefix that will be added to the Enums
and Objects (for messages) generated from the proto. Convention is to base
the prefix on the package the proto is in.
Objective C Generator `protoc` Options
--------------------------------------
When generating Objective C code, `protoc` supports a `--objc_opt` argument; the
argument is comma-delimited name/value pairs (_key=value,key2=value2_). The
_keys_ are used to change the behavior during generation. The currently
supported keys are:
* `generate_for_framework_named`: The `value` used for this key will be used
when generating the `#import` statements in the generated code. Instead
of being plain `#import "some/path/file.pbobjc.h"` lines, they will be
framework based, i.e. - `#import <VALUE/file.pbobjc.h>`.
Contributing
------------

@ -54,14 +54,16 @@ namespace {
class ImportWriter {
public:
ImportWriter() {}
ImportWriter(const Options& options) : options_(options) {}
void AddFile(const FileGenerator* file);
void Print(io::Printer *printer) const;
private:
const Options options_;
vector<string> protobuf_framework_imports_;
vector<string> protobuf_non_framework_imports_;
vector<string> other_framework_imports_;
vector<string> other_imports_;
};
@ -72,6 +74,10 @@ void ImportWriter::AddFile(const FileGenerator* file) {
protobuf_framework_imports_.push_back(
FilePathBasename(file_descriptor) + extension);
protobuf_non_framework_imports_.push_back(file->Path() + extension);
} else if (!options_.generate_for_named_framework.empty()) {
other_framework_imports_.push_back(
options_.generate_for_named_framework + "/" +
FilePathBasename(file_descriptor) + extension);
} else {
other_imports_.push_back(file->Path() + extension);
}
@ -81,6 +87,8 @@ void ImportWriter::Print(io::Printer *printer) const {
assert(protobuf_non_framework_imports_.size() ==
protobuf_framework_imports_.size());
bool add_blank_line = false;
if (protobuf_framework_imports_.size() > 0) {
const string framework_name(ProtobufLibraryFrameworkName);
const string cpp_symbol(ProtobufFrameworkImportSymbol(framework_name));
@ -106,12 +114,29 @@ void ImportWriter::Print(io::Printer *printer) const {
printer->Print(
"#endif\n");
if (other_imports_.size() > 0) {
add_blank_line = true;
}
if (other_framework_imports_.size() > 0) {
if (add_blank_line) {
printer->Print("\n");
}
for (vector<string>::const_iterator iter = other_framework_imports_.begin();
iter != other_framework_imports_.end(); ++iter) {
printer->Print(
" #import <$header$>\n",
"header", *iter);
}
add_blank_line = true;
}
if (other_imports_.size() > 0) {
if (add_blank_line) {
printer->Print("\n");
}
for (vector<string>::const_iterator iter = other_imports_.begin();
iter != other_imports_.end(); ++iter) {
printer->Print(
@ -156,7 +181,7 @@ FileGenerator::~FileGenerator() {
}
void FileGenerator::GenerateHeader(io::Printer *printer) {
PrintFilePreamble(printer, "GPBProtocolBuffers.h");
PrintFileRuntimePreamble(printer, "GPBProtocolBuffers.h");
// Add some verification that the generated code matches the source the
// code is being compiled with.
@ -170,7 +195,7 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
// #import any headers for "public imports" in the proto file.
{
ImportWriter import_writer;
ImportWriter import_writer(options_);
const vector<FileGenerator *> &dependency_generators = DependencyGenerators();
for (vector<FileGenerator *>::const_iterator iter =
dependency_generators.begin();
@ -273,10 +298,10 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
void FileGenerator::GenerateSource(io::Printer *printer) {
// #import the runtime support.
PrintFilePreamble(printer, "GPBProtocolBuffers_RuntimeSupport.h");
PrintFileRuntimePreamble(printer, "GPBProtocolBuffers_RuntimeSupport.h");
{
ImportWriter import_writer;
ImportWriter import_writer(options_);
// #import the header for this proto file.
import_writer.AddFile(this);
@ -471,7 +496,10 @@ const vector<FileGenerator *> &FileGenerator::DependencyGenerators() {
return dependency_generators_;
}
void FileGenerator::PrintFilePreamble(
// Helper to print the import of the runtime support at the top of generated
// files. This currently only supports the runtime coming from a framework
// as defined by the official CocoaPod.
void FileGenerator::PrintFileRuntimePreamble(
io::Printer* printer, const string& header_to_import) const {
printer->Print(
"// Generated by the protocol buffer compiler. DO NOT EDIT!\n"

@ -88,7 +88,7 @@ class FileGenerator {
const Options options_;
const vector<FileGenerator*>& DependencyGenerators();
void PrintFilePreamble(
void PrintFileRuntimePreamble(
io::Printer* printer, const string& header_to_import) const;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileGenerator);

@ -59,6 +59,8 @@ bool ObjectiveCGenerator::Generate(const FileDescriptor* file,
for (int i = 0; i < options.size(); i++) {
if (options[i].first == "expected_prefixes_path") {
generation_options.expected_prefixes_path = options[i].second;
} else if (options[i].first == "generate_for_named_framework") {
generation_options.generate_for_named_framework = options[i].second;
} else {
*error = "error: Unknown generator option: " + options[i].first;
return false;

@ -46,6 +46,7 @@ namespace objectivec {
struct Options {
Options();
string expected_prefixes_path;
string generate_for_named_framework;
};
// Escape C++ trigraphs by escaping question marks to "\?".

Loading…
Cancel
Save