diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..22e1a96 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +target/ +project/target +*.iml +.idea +*.ipr +*.iws diff --git a/Makefile b/Makefile index 2dd99a8..528646c 100644 --- a/Makefile +++ b/Makefile @@ -1,52 +1,19 @@ -CXX=g++ -CXX_FLAGS=-std=c++11 +CXX=clang++ -std=c++11 -stdlib=libc++ `pkg-config capnp --cflags --libs` -CAPNP_SOURCES=\ - src/capnp/AnyPointer.java\ - src/capnp/DecodeException.java\ - src/capnp/FieldSize.java\ - src/capnp/FromStructBuilder.java\ - src/capnp/FromStructReader.java\ - src/capnp/InputStreamMessageReader.java\ - src/capnp/ListPointer.java\ - src/capnp/ListBuilder.java\ - src/capnp/ListReader.java\ - src/capnp/MessageBuilder.java\ - src/capnp/MessageReader.java\ - src/capnp/PointerBuilder.java\ - src/capnp/PointerReader.java\ - src/capnp/SegmentBuilder.java\ - src/capnp/SegmentReader.java\ - src/capnp/StructBuilder.java\ - src/capnp/StructList.java\ - src/capnp/StructPointer.java\ - src/capnp/StructReader.java\ - src/capnp/StructSize.java\ - src/capnp/Text.java\ - src/capnp/WireHelpers.java\ - src/capnp/WirePointer.java\ - src/capnp/WordPointer.java - -CAPNP_COMPILATION_MARKER=org/capnproto/PointerReader.class - -CAPNPC_JAVA_SOURCES=src/compiler/capnpc-java.c++ +CAPNPC_JAVA_SOURCES=generator/src/main/cpp/compiler/capnpc-java.c++ .PHONY: all clean addressbook -all : capnpc-java addressbook capnp +all : capnpc-java addressbook clean : - rm -rf capnpc-java org examples/*.class - -capnp : $(CAPNP_COMPILATION_MARKER) - -$(CAPNP_COMPILATION_MARKER) : $(CAPNP_SOURCES) - javac -d . $(CAPNP_SOURCES) + rm capnpc-java + sbt clean capnpc-java : $(CAPNPC_JAVA_SOURCES) - $(CXX) $(CXX_FLAGS) -I/usr/local/include -L/usr/local/lib $(CAPNPC_JAVA_SOURCES) -lkj -lcapnp -o capnpc-java + $(CXX) -I/usr/local/include -g $(CAPNPC_JAVA_SOURCES) -o capnpc-java - -addressbook : capnp capnpc-java examples/AddressbookMain.java - capnp compile -o ./capnpc-java examples/addressbook.capnp - javac -cp .:examples examples/AddressbookMain.java +addressbook : capnpc-java + PWD=pwd + capnp compile -I$(PWD)/generator/src/main/cpp/compiler --src-prefix=examples/src/main/schema -o./capnpc-java:examples/src/main/generated examples/src/main/schema/addressbook.capnp + sbt examples/"run read" diff --git a/README.md b/README.md index a38c16f..34d51d6 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,11 @@ This is an experimental pure Java implementation of Cap'n Proto. -It doesn't do much yet. +It doesn't do much yet. An attempt to use SBT as the build system and integration with `make` is currently underway. -To get started, try this: +To get started with SBT, visit https://github.com/paulp/sbt-extras or to run direct, try `curl -s https://raw.githubusercontent.com/paulp/sbt-extras/master/sbt > ~/bin/sbt && chmod 0755 ~/bin/sbt` + +When you first build the project, try running `sbt update gen-idea`. This will bootstrap SBT and generate IntelliJ project files for those who wish to develop in an IDE. + +When running `make`, the supporting Java code will be built, and the sample schema will be run through the code generator as well to produce the Java binding. You can find the generated code in `/examples/src/main/generated/Addressbook.java` -``` -$ make -$ cd examples -$ echo '(people = [(id = 123, name = "Alice", email = "alice@example.com", employment = (school = "MIT"))])' \ - | capnp encode addressbook.capnp AddressBook | java -cp .:.. AddressbookMain read -``` \ No newline at end of file diff --git a/examples/AddressbookMain.java b/examples/src/main/java/org/capnproto/examples/AddressbookMain.java similarity index 81% rename from examples/AddressbookMain.java rename to examples/src/main/java/org/capnproto/examples/AddressbookMain.java index 542cbd9..c1f98ee 100644 --- a/examples/AddressbookMain.java +++ b/examples/src/main/java/org/capnproto/examples/AddressbookMain.java @@ -1,7 +1,11 @@ +package org.capnproto.examples; + import org.capnproto.MessageReader; import org.capnproto.StructList; import org.capnproto.InputStreamMessageReader; +import org.capnproto.examples.Addressbook.*; + public class AddressbookMain { public static void writeAddressBook() { @@ -10,16 +14,16 @@ public class AddressbookMain { public static void printAddressBook() throws java.io.IOException { MessageReader message = InputStreamMessageReader.create(System.in); - Addressbook.AddressBook.Reader addressbook = message.getRoot(Addressbook.AddressBook.Reader.factory); - StructList.Reader people = addressbook.getPeople(); + AddressBook.Reader addressbook = message.getRoot(AddressBook.Reader.factory); + StructList.Reader people = addressbook.getPeople(); int size = people.size(); for(int ii = 0; ii < size; ++ii) { - Addressbook.Person.Reader person = people.get(ii); + Person.Reader person = people.get(ii); System.out.println(person.getName() + ": " + person.getEmail()); - StructList.Reader phones = person.getPhones(); + StructList.Reader phones = person.getPhones(); for (int jj = 0; jj < phones.size(); ++jj) { - Addressbook.Person.PhoneNumber.Reader phone = phones.get(jj); + Person.PhoneNumber.Reader phone = phones.get(jj); String typeName = "UNKNOWN"; switch (phone.getType()) { case MOBILE : @@ -35,7 +39,7 @@ public class AddressbookMain { System.out.println(" " + typeName + " phone: " + phone.getNumber()); } - Addressbook.Person.Employment.Reader employment = person.getEmployment(); + Person.Employment.Reader employment = person.getEmployment(); switch (employment.which()) { case UNEMPLOYED : System.out.println(" unemployed"); diff --git a/examples/addressbook.capnp b/examples/src/main/schema/addressbook.capnp similarity index 95% rename from examples/addressbook.capnp rename to examples/src/main/schema/addressbook.capnp index 9c9b9ad..4981bf3 100644 --- a/examples/addressbook.capnp +++ b/examples/src/main/schema/addressbook.capnp @@ -26,6 +26,9 @@ using Cxx = import "/capnp/c++.capnp"; $Cxx.namespace("addressbook"); +using Java = import "/java_support/java.capnp"; +$Java.package("org.capnproto.examples"); + struct Person { id @0 :UInt32; name @1 :Text; diff --git a/src/compiler/capnpc-java.c++ b/generator/src/main/cpp/compiler/capnpc-java.c++ similarity index 99% rename from src/compiler/capnpc-java.c++ rename to generator/src/main/cpp/compiler/capnpc-java.c++ index f6ee5bc..8ebffb7 100644 --- a/src/compiler/capnpc-java.c++ +++ b/generator/src/main/cpp/compiler/capnpc-java.c++ @@ -27,13 +27,13 @@ #include -#include "capnp/serialize.h" +#include #include #include #include #include -#include "capnp/schema-loader.h" -#include "capnp/dynamic.h" +#include +#include #include #include #include @@ -57,6 +57,7 @@ namespace capnp { namespace { static constexpr uint64_t NAMESPACE_ANNOTATION_ID = 0xb9c6f99ebf805f2cull; +static constexpr uint64_t PACKAGE_ANNOTATION_ID = 0x9ee4c8f803b3b596ull; static constexpr const char* FIELD_SIZE_NAMES[] = { "VOID", "BIT", "BYTE", "TWO_BYTES", "FOUR_BYTES", "EIGHT_BYTES", "POINTER", "INLINE_COMPOSITE" @@ -1508,6 +1509,7 @@ private: kj::Vector> namespaceParts; kj::String namespacePrefix; + kj::StringPtr packageName; for (auto annotation: node.getAnnotations()) { if (annotation.getId() == NAMESPACE_ANNOTATION_ID) { @@ -1532,6 +1534,18 @@ private: break; } } + + for (auto annotation: node.getAnnotations()) { + if (annotation.getId() == PACKAGE_ANNOTATION_ID) { + packageName = annotation.getValue().getText(); + break; + } + } + + if (packageName.size() == 0) { + context.exitError(kj::str(displayName, ": must provide a Java package name.")); + } + auto nodeTexts = KJ_MAP(nested, node.getNestedNodes()) { return makeNodeText(namespacePrefix, "", nested.getName(), schemaLoader.get(nested.getId()), 1); }; @@ -1551,8 +1565,8 @@ private: return FileText { kj::strTree( "// Generated by Cap'n Proto compiler, DO NOT EDIT\n" - "// source: ", baseName(displayName), "\n", - "\n", + "// source: ", baseName(displayName), "\n\n", + "package ", packageName, ";\n\n", //"import org.capnproto;\n", // KJ_MAP(n, namespaceParts) { return kj::strTree("namespace ", n, " {\n"); }, "\n", "public class ", outerClassName, " {\n", diff --git a/generator/src/main/cpp/compiler/java_support/java.capnp b/generator/src/main/cpp/compiler/java_support/java.capnp new file mode 100644 index 0000000..4f44ff9 --- /dev/null +++ b/generator/src/main/cpp/compiler/java_support/java.capnp @@ -0,0 +1,3 @@ +@0xc5f1af96651f70ea; + +annotation package(file): Text; diff --git a/generator/src/main/cpp/compiler/java_support/java.capnp.c++ b/generator/src/main/cpp/compiler/java_support/java.capnp.c++ new file mode 100644 index 0000000..0098f4f --- /dev/null +++ b/generator/src/main/cpp/compiler/java_support/java.capnp.c++ @@ -0,0 +1,35 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: java.capnp + +#include "java.capnp.h" + +namespace capnp { +namespace schemas { +static const ::capnp::_::AlignedData<18> b_9ee4c8f803b3b596 = { + { 0, 0, 0, 0, 5, 0, 5, 0, + 150, 181, 179, 3, 248, 200, 228, 158, + 11, 0, 0, 0, 5, 0, 1, 0, + 234, 112, 31, 101, 150, 175, 241, 197, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 17, 0, 0, 0, 154, 0, 0, 0, + 25, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 20, 0, 0, 0, 2, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 106, 97, 118, 97, 46, 99, 97, 112, + 110, 112, 58, 112, 97, 99, 107, 97, + 103, 101, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 1, 0, + 12, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } +}; +const ::capnp::_::RawSchema s_9ee4c8f803b3b596 = { + 0x9ee4c8f803b3b596, b_9ee4c8f803b3b596.words, 18, nullptr, nullptr, + 0, 0, nullptr, nullptr, nullptr +}; +} // namespace schemas +namespace _ { // private +} // namespace _ (private) +} // namespace capnp diff --git a/generator/src/main/cpp/compiler/java_support/java.capnp.h b/generator/src/main/cpp/compiler/java_support/java.capnp.h new file mode 100644 index 0000000..d5f60ad --- /dev/null +++ b/generator/src/main/cpp/compiler/java_support/java.capnp.h @@ -0,0 +1,36 @@ +// Generated by Cap'n Proto compiler, DO NOT EDIT +// source: java.capnp + +#ifndef CAPNP_INCLUDED_c5f1af96651f70ea_ +#define CAPNP_INCLUDED_c5f1af96651f70ea_ + +#include + +#if CAPNP_VERSION != 4001 +#error "Version mismatch between generated code and library headers. You must use the same version of the Cap'n Proto compiler and library." +#endif + + + + +// ======================================================================================= + +namespace capnp { +namespace schemas { + +extern const ::capnp::_::RawSchema s_9ee4c8f803b3b596; + +} // namespace schemas +namespace _ { // private + + +} // namespace _ (private) +} // namespace capnp + +// ======================================================================================= + + +// ======================================================================================= + + +#endif // CAPNP_INCLUDED_c5f1af96651f70ea_ diff --git a/src/capnp/AnyPointer.java b/generator/src/main/java/org/capnproto/AnyPointer.java similarity index 100% rename from src/capnp/AnyPointer.java rename to generator/src/main/java/org/capnproto/AnyPointer.java diff --git a/src/capnp/DecodeException.java b/generator/src/main/java/org/capnproto/DecodeException.java similarity index 100% rename from src/capnp/DecodeException.java rename to generator/src/main/java/org/capnproto/DecodeException.java diff --git a/src/capnp/FieldSize.java b/generator/src/main/java/org/capnproto/FieldSize.java similarity index 100% rename from src/capnp/FieldSize.java rename to generator/src/main/java/org/capnproto/FieldSize.java diff --git a/src/capnp/FromStructBuilder.java b/generator/src/main/java/org/capnproto/FromStructBuilder.java similarity index 100% rename from src/capnp/FromStructBuilder.java rename to generator/src/main/java/org/capnproto/FromStructBuilder.java diff --git a/src/capnp/FromStructReader.java b/generator/src/main/java/org/capnproto/FromStructReader.java similarity index 100% rename from src/capnp/FromStructReader.java rename to generator/src/main/java/org/capnproto/FromStructReader.java diff --git a/src/capnp/InputStreamMessageReader.java b/generator/src/main/java/org/capnproto/InputStreamMessageReader.java similarity index 100% rename from src/capnp/InputStreamMessageReader.java rename to generator/src/main/java/org/capnproto/InputStreamMessageReader.java diff --git a/src/capnp/ListBuilder.java b/generator/src/main/java/org/capnproto/ListBuilder.java similarity index 100% rename from src/capnp/ListBuilder.java rename to generator/src/main/java/org/capnproto/ListBuilder.java diff --git a/src/capnp/ListPointer.java b/generator/src/main/java/org/capnproto/ListPointer.java similarity index 100% rename from src/capnp/ListPointer.java rename to generator/src/main/java/org/capnproto/ListPointer.java diff --git a/src/capnp/ListReader.java b/generator/src/main/java/org/capnproto/ListReader.java similarity index 100% rename from src/capnp/ListReader.java rename to generator/src/main/java/org/capnproto/ListReader.java diff --git a/src/capnp/MessageBuilder.java b/generator/src/main/java/org/capnproto/MessageBuilder.java similarity index 100% rename from src/capnp/MessageBuilder.java rename to generator/src/main/java/org/capnproto/MessageBuilder.java diff --git a/src/capnp/MessageReader.java b/generator/src/main/java/org/capnproto/MessageReader.java similarity index 100% rename from src/capnp/MessageReader.java rename to generator/src/main/java/org/capnproto/MessageReader.java diff --git a/src/capnp/PointerBuilder.java b/generator/src/main/java/org/capnproto/PointerBuilder.java similarity index 100% rename from src/capnp/PointerBuilder.java rename to generator/src/main/java/org/capnproto/PointerBuilder.java diff --git a/src/capnp/PointerReader.java b/generator/src/main/java/org/capnproto/PointerReader.java similarity index 100% rename from src/capnp/PointerReader.java rename to generator/src/main/java/org/capnproto/PointerReader.java diff --git a/src/capnp/SegmentBuilder.java b/generator/src/main/java/org/capnproto/SegmentBuilder.java similarity index 100% rename from src/capnp/SegmentBuilder.java rename to generator/src/main/java/org/capnproto/SegmentBuilder.java diff --git a/src/capnp/SegmentReader.java b/generator/src/main/java/org/capnproto/SegmentReader.java similarity index 100% rename from src/capnp/SegmentReader.java rename to generator/src/main/java/org/capnproto/SegmentReader.java diff --git a/src/capnp/StructBuilder.java b/generator/src/main/java/org/capnproto/StructBuilder.java similarity index 100% rename from src/capnp/StructBuilder.java rename to generator/src/main/java/org/capnproto/StructBuilder.java diff --git a/src/capnp/StructList.java b/generator/src/main/java/org/capnproto/StructList.java similarity index 100% rename from src/capnp/StructList.java rename to generator/src/main/java/org/capnproto/StructList.java diff --git a/src/capnp/StructPointer.java b/generator/src/main/java/org/capnproto/StructPointer.java similarity index 100% rename from src/capnp/StructPointer.java rename to generator/src/main/java/org/capnproto/StructPointer.java diff --git a/src/capnp/StructReader.java b/generator/src/main/java/org/capnproto/StructReader.java similarity index 100% rename from src/capnp/StructReader.java rename to generator/src/main/java/org/capnproto/StructReader.java diff --git a/src/capnp/StructSize.java b/generator/src/main/java/org/capnproto/StructSize.java similarity index 100% rename from src/capnp/StructSize.java rename to generator/src/main/java/org/capnproto/StructSize.java diff --git a/src/capnp/Text.java b/generator/src/main/java/org/capnproto/Text.java similarity index 100% rename from src/capnp/Text.java rename to generator/src/main/java/org/capnproto/Text.java diff --git a/src/capnp/WireHelpers.java b/generator/src/main/java/org/capnproto/WireHelpers.java similarity index 100% rename from src/capnp/WireHelpers.java rename to generator/src/main/java/org/capnproto/WireHelpers.java diff --git a/src/capnp/WirePointer.java b/generator/src/main/java/org/capnproto/WirePointer.java similarity index 100% rename from src/capnp/WirePointer.java rename to generator/src/main/java/org/capnproto/WirePointer.java diff --git a/src/capnp/WordPointer.java b/generator/src/main/java/org/capnproto/WordPointer.java similarity index 100% rename from src/capnp/WordPointer.java rename to generator/src/main/java/org/capnproto/WordPointer.java diff --git a/project/build.properties b/project/build.properties new file mode 100644 index 0000000..8ac605a --- /dev/null +++ b/project/build.properties @@ -0,0 +1 @@ +sbt.version=0.13.2 diff --git a/project/build.scala b/project/build.scala new file mode 100644 index 0000000..4a66949 --- /dev/null +++ b/project/build.scala @@ -0,0 +1,91 @@ +import sbt.Keys._ +import sbt._ +import org.sbtidea.SbtIdeaPlugin._ + +object Build extends sbt.Build { + + lazy val root = + project( + id = "capnproto-java", + base = file(".") + ).aggregate(generator, examples) + + lazy val generator = + project( + id = "generator", + base = file("generator") + ).settings(Defaults.itSettings: _*) + .settings(compile <<= compile in Compile dependsOn(compile in Test, compile in IntegrationTest)) + + lazy val examples = + project( + id = "examples", + base = file("examples") + ).dependsOn(generator) + .settings(unmanagedSourceDirectories in Compile += sourceDirectory.value / "main" / "generated") + .settings(publish := {}) + .settings(publishLocal := {}) + .settings(fork in run := true) + .settings(outputStrategy := Some(StdoutOutput)) + .settings(javaOptions in run ++= Seq( + "-ms2g", + "-mx2g", + "-XX:+AlwaysPreTouch", + "-XX:+TieredCompilation" + )) + + def project(id: String, base: File) = + Project( + id = id, + base = base, + settings = + Project.defaultSettings ++ + Shared.settings ++ + Seq(libraryDependencies ++= Shared.testDeps) + ).configs(IntegrationTest) +} + +object Shared { + + val testDeps = Seq( + "org.scalatest" %% "scalatest" % "2.1.6" % "it,test", + "org.scalacheck" %% "scalacheck" % "1.11.4" % "it,test" + ) + + val settings = Seq( + scalaVersion := "2.11.0", + scalacOptions := Seq( + "-deprecation", + "-feature", + "-optimise", + "-Yinline-warnings", + "-unchecked", + "-feature" + ), + resolvers += Resolver.sonatypeRepo("snapshots"), + resolvers += Resolver.sonatypeRepo("releases"), + shellPrompt := ShellPrompt.buildShellPrompt + ) +} + +object ShellPrompt { + object devnull extends ProcessLogger { + def info(s: => String) {} + def error(s: => String) {} + def buffer[T](f: => T): T = f + } + + def currBranch = ( + ("git status -sb" lines_! devnull headOption) + getOrElse "-" stripPrefix "## " + ) + + val buildShellPrompt = { + (state: State) => { + val currProject = Project.extract(state).currentProject.id + "[%s](%s)$ ".format( + currProject, currBranch /*, BuildSettings.buildVersion*/ + ) + } + } +} diff --git a/project/plugins.sbt b/project/plugins.sbt new file mode 100644 index 0000000..dcb18cc --- /dev/null +++ b/project/plugins.sbt @@ -0,0 +1,3 @@ +addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.5.2") + +addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.7.4") diff --git a/src/capnp/layout.java b/src/capnp/layout.java deleted file mode 100644 index d8da6a5..0000000 --- a/src/capnp/layout.java +++ /dev/null @@ -1,3 +0,0 @@ -package org.capnproto; - - diff --git a/version.sbt b/version.sbt new file mode 100644 index 0000000..e765444 --- /dev/null +++ b/version.sbt @@ -0,0 +1 @@ +version in ThisBuild := "0.1.0"