New README.md.

pull/13171/head
Joshua Haberman 6 years ago
parent a8f719c98d
commit ae107c7ab9
  1. 135
      README.md

@ -1,53 +1,132 @@
# μpb - a small protobuf implementation in C
[![Build Status](https://travis-ci.org/google/upb.svg?branch=master)](https://travis-ci.org/google/upb)
[![Coverage Status](https://img.shields.io/coveralls/google/upb.svg)](https://coveralls.io/r/google/upb?branch=master)
μpb is a small protobuf implementation written in C.
|Platform|Build Status|
|--------|------------|
|macOS|[![Build Status](https://storage.googleapis.com/upb-kokoro-results/status-badge/macos.png)](https://fusion.corp.google.com/projectanalysis/summary/KOKORO/prod%3Aupb%2Fmacos%2Fcontinuous)|
|ubuntu|[![Build Status](https://storage.googleapis.com/upb-kokoro-results/status-badge/ubuntu.png)](https://fusion.corp.google.com/projectanalysis/summary/KOKORO/prod%3Aupb%2Fubuntu%2Fcontinuous)|
μpb (often written 'upb') is a small protobuf implementation written in C.
upb generates a C API for creating, parsing, and serializing messages
as declared in `.proto` files. upb is heavily arena-based -- all
messages always live in an arena. You control where the arena gets
memory from, so the arena can come from stack memory, for example.
Here is a simple example (`ConformanceRequest` and `ConformanceResponse`
are generated message types):
```c
#include "conformance/conformance.upb.h"
void foo(const char* data, size_t size) {
upb_arena *arena;
conformance_ConformanceRequest *request;
conformance_ConformanceResponse *response;
arena = upb_arena_new();
request = conformance_ConformanceRequest_parse(data, size, arena);
response = conformance_ConformanceResponse_new(arena);
switch (conformance_ConformanceRequest_payload_case(request)) {
case conformance_ConformanceRequest_payload_protobuf_payload: {
upb_strview payload = conformance_ConformanceRequest_protobuf_payload(request);
// ...
break;
}
case conformance_ConformanceRequest_payload_NOT_SET:
fprintf(stderr, "conformance_upb: Request didn't have payload.\n");
break;
default: {
static const char msg[] = "Unsupported input format.";
conformance_ConformanceResponse_set_skipped(
response, upb_strview_make(msg, sizeof(msg)));
break;
}
}
upb_arena_free(arena);
}
```
Messages are opaque, so you always have to use generated getter/setter
methods to read/write fields. This is somewhat unfortunate for C
because the function names are long, but this is necessary to provide
correct semantics for oneof fields, proto2 presence, etc. It is also
necessary for providing a stable ABI, in cases where that is desired.
API and ABI are both subject to change! Please do not distribute
as a shared library for this reason (for now at least).
## Building the core libraries
## Using upb in your project
The core libraries are pure C99 and have no dependencies.
Currently only Bazel is supported (CMake support is partial and incomplete
but full CMake support is an eventual goal).
$ make
To use upb in your Bazel project, first add upb to your `WORKSPACE` file,
either as a `git_repository()` or as a `new_local_repository()` with a
Git Submodule:
This will create a separate C library for each core library
in `lib/`. They are built separately to help your binaries
slim, so you don't need to link in things you neither want
or need.
```python
# Add this to your WORKSPACE file.
git_repository(
name = "upb",
remote = "https://github.com/protocolbuffers/upb.git",
# You may want to substitute a more recent commit here.
commit = "d5af87d06bbe3abad66970ce9c7ae0a7de8bb3c6",
)
```
Other useful targets:
Then in your BUILD file you can add `upb_proto_library()` rules that
generate code for a corresponding `proto_library()` rule. For
example:
$ make tests
$ make test
```python
# Add this to your BUILD file.
load(":upb_proto_library.bzl", "upb_proto_library")
## C and C++ API
proto_library(
name = "foo_proto",
srcs = ["foo.proto"],
)
The public C/C++ API is defined by all of the .h files in
`upb/` except `.int.h` files (which are internal-only).
upb_proto_library(
name = "foo_upbproto",
deps = [":foo_proto"],
)
## Lua bindings
cc_library(
name = "lib_that_uses_protos",
srcs = ["lib_that_uses_protos.cc"],
deps = [":foo_upbproto"],
)
```
Lua bindings provide μpb's functionality to Lua programs.
The bindings target Lua 5.1, Lua 5.2, LuaJIT, and (soon) Lua 5.3.
Then in your `.c` file you can #include the generated header:
To build the Lua bindings, the Lua libraries must be installed. Once
they are installed, run:
```c
#include "foo.upb.h"
$ make lua
/* Insert code that uses generated types. */
```
Note that if the Lua headers are not in a standard place, you may
need to pass custom flags:
## Old "handlers" interfaces
$ make lua USER_CPPFLAGS=`pkg-config lua5.2 --cflags`
This library contains several semi-deprecated interfaces (see BUILD
file for more info about which interfaces are deprecated). These
deprecated interfaces are still used in some significant projects,
such as the Ruby and PHP C bindings for protobuf in the [main protobuf
repo](https://github.com/protocolbuffers/protobuf). The goal is to
migrate the Ruby/PHP bindings to use the newer, simpler interfaces
instead. Please do not use the old interfaces in new code.
To test the Lua bindings:
## Lua bindings
$ make testlua
This repo has some Lua bindings for the core library. These are
experimental and very incomplete. These are currently included in
order to validate that the C API is suitable for wrapping. As the
project matures these Lua bindings may become publicly available.
## Contact

Loading…
Cancel
Save