From 4ab33612fffdafa67384aa43dfd92f30f1799cb5 Mon Sep 17 00:00:00 2001 From: kornilova-l Date: Wed, 4 Jul 2018 11:16:58 +0300 Subject: [PATCH] Add Using Generated Bindings section --- .gitignore | 1 + build.sbt | 7 +- .../main/paradox/obtaining-bindgen/index.md | 9 -- .../paradox/command-line-usage/index.md | 18 +-- docs/src/{main => }/paradox/index.md | 5 +- .../{main => }/paradox/limitations/index.md | 0 .../paradox/obtaining-bindgen/cmake.md | 0 .../obtaining-bindgen/docker-compose.md | 0 .../obtaining-bindgen/docker-container.md | 10 +- docs/src/paradox/obtaining-bindgen/index.md | 17 +++ .../using-generated-bindings/README.md | 112 ++++++++++++++++++ project/plugins.sbt | 3 +- 12 files changed, 154 insertions(+), 28 deletions(-) delete mode 100644 docs/src/main/paradox/obtaining-bindgen/index.md rename docs/src/{main => }/paradox/command-line-usage/index.md (57%) rename docs/src/{main => }/paradox/index.md (70%) rename docs/src/{main => }/paradox/limitations/index.md (100%) rename docs/src/{main => }/paradox/obtaining-bindgen/cmake.md (100%) rename docs/src/{main => }/paradox/obtaining-bindgen/docker-compose.md (100%) rename docs/src/{main => }/paradox/obtaining-bindgen/docker-container.md (66%) create mode 100644 docs/src/paradox/obtaining-bindgen/index.md create mode 100644 docs/src/paradox/using-generated-bindings/README.md diff --git a/.gitignore b/.gitignore index a89e3a2..72aaf91 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ target/ scripts/.coursier scripts/.scalafmt-* +/docs/_book/ diff --git a/build.sbt b/build.sbt index 6760b26..0ccfbee 100644 --- a/build.sbt +++ b/build.sbt @@ -91,10 +91,11 @@ lazy val tools = project in file("tools") lazy val docs = project .in(file("docs")) - .enablePlugins(ParadoxPlugin) + .enablePlugins(GhpagesPlugin, ParadoxSitePlugin) .settings( paradoxTheme := Some(builtinParadoxTheme("generic")), - paradoxProperties in Compile ++= Map( + paradoxProperties in Paradox ++= Map( "github.base_url" -> "https://github.com/kornilova-l/scala-native-bindgen/tree/master/" - ) + ), + git.remoteRepo := "git@github.com:kornilova-l/scala-native-bindgen.git" ) diff --git a/docs/src/main/paradox/obtaining-bindgen/index.md b/docs/src/main/paradox/obtaining-bindgen/index.md deleted file mode 100644 index 0b05368..0000000 --- a/docs/src/main/paradox/obtaining-bindgen/index.md +++ /dev/null @@ -1,9 +0,0 @@ -# Obtaining Bindgen - -@@@ index - - * [Use docker container](docker-container.md) - * [Build binary with CMake](cmake.md) - * [Build binary with docker-compose](docker-compose.md) - -@@@ diff --git a/docs/src/main/paradox/command-line-usage/index.md b/docs/src/paradox/command-line-usage/index.md similarity index 57% rename from docs/src/main/paradox/command-line-usage/index.md rename to docs/src/paradox/command-line-usage/index.md index 77445f1..52ddcd9 100644 --- a/docs/src/main/paradox/command-line-usage/index.md +++ b/docs/src/paradox/command-line-usage/index.md @@ -14,12 +14,12 @@ scala-native-bindgen --name uv /usr/include/uv.h -- > uv.scala ## Bindgen Options -| Option | Description | -|----------------------|--------------------------------------------------------------------------------------------------------------| -| `--link` | Library to link with, e.g. `--link` uv for libuv. | -| `--no-link` | Library is static and does not require linking. | -| `--name` | Scala object name that contains bindings. If `--no-link` is specified then `name` should match library name. | -| `--package` | Package name of generated Scala file. | -| `--exclude-prefix` | Functions and unused typedefs will be removed if their names have given prefix. | -| `--extra-arg` | Additional argument to append to the compiler command line. | -| `--extra-arg-before` | Additional argument to prepend to the compiler command line. | +| Option | Description | +|----------------------|---------------------------------------------------------------------------------| +| `--link` | Library to link with, e.g. `--link` uv for libuv. | +| `--no-link` | Library does not require linking. | +| `--name` | Scala object name that contains bindings. Default value set to library name. | +| `--package` | Package name of generated Scala file. | +| `--exclude-prefix` | Functions and unused typedefs will be removed if their names have given prefix. | +| `--extra-arg` | Additional argument to append to the compiler command line. | +| `--extra-arg-before` | Additional argument to prepend to the compiler command line. | diff --git a/docs/src/main/paradox/index.md b/docs/src/paradox/index.md similarity index 70% rename from docs/src/main/paradox/index.md rename to docs/src/paradox/index.md index 5c1e302..609e22b 100644 --- a/docs/src/main/paradox/index.md +++ b/docs/src/paradox/index.md @@ -2,9 +2,10 @@ @@@ index -* [Obtaining bindgen](obtaining-bindgen/index.md) -* [Usage](command-line-usage/index.md) +* [Obtaining Bindgen](obtaining-bindgen/index.md) +* [Command Line Usage](command-line-usage/index.md) * [Limitations](limitations/index.md) +* [Using Generated Bindings](using-generated-bindings/README.md) @@@ diff --git a/docs/src/main/paradox/limitations/index.md b/docs/src/paradox/limitations/index.md similarity index 100% rename from docs/src/main/paradox/limitations/index.md rename to docs/src/paradox/limitations/index.md diff --git a/docs/src/main/paradox/obtaining-bindgen/cmake.md b/docs/src/paradox/obtaining-bindgen/cmake.md similarity index 100% rename from docs/src/main/paradox/obtaining-bindgen/cmake.md rename to docs/src/paradox/obtaining-bindgen/cmake.md diff --git a/docs/src/main/paradox/obtaining-bindgen/docker-compose.md b/docs/src/paradox/obtaining-bindgen/docker-compose.md similarity index 100% rename from docs/src/main/paradox/obtaining-bindgen/docker-compose.md rename to docs/src/paradox/obtaining-bindgen/docker-compose.md diff --git a/docs/src/main/paradox/obtaining-bindgen/docker-container.md b/docs/src/paradox/obtaining-bindgen/docker-container.md similarity index 66% rename from docs/src/main/paradox/obtaining-bindgen/docker-container.md rename to docs/src/paradox/obtaining-bindgen/docker-container.md index 6852928..9f9ed8f 100644 --- a/docs/src/main/paradox/obtaining-bindgen/docker-container.md +++ b/docs/src/paradox/obtaining-bindgen/docker-container.md @@ -18,13 +18,15 @@ docker run -v "$(pwd)":/src -v /usr/include:/usr/include \ The docker image does not contain standard headers so it is important to mount all system include directories that are used by the header file -passed to `scala-native-bindgen`. See the @github[docker-bindgen.sh](/scripts/docker-bindgen.sh) script for -how to wrap the dockerized program. The `$CWD` of the container is -`/src` which should be mounted from `$(pwd)` in case relative paths are -used. +passed to `scala-native-bindgen`. + +See the [docker-bindgen.sh] script for how to wrap the dockerized program. +The `$CWD` of the container is `/src` which should be mounted from `$(pwd)` +in case relative paths are used. Note, the `scalabindgen/scala-native-bindgen:latest` image is updated on each merge to the `master` branch. [Docker]: https://www.docker.com/ + [docker-bindgen.sh]: https://github.com/kornilova-l/scala-native-bindgen/blob/master/scripts/docker-bindgen.sh \ No newline at end of file diff --git a/docs/src/paradox/obtaining-bindgen/index.md b/docs/src/paradox/obtaining-bindgen/index.md new file mode 100644 index 0000000..9686f48 --- /dev/null +++ b/docs/src/paradox/obtaining-bindgen/index.md @@ -0,0 +1,17 @@ +# Obtaining Bindgen + +@@@ index + +* [Use Docker Container](docker-container.md) +* [Build Binary with CMake](cmake.md) +* [Build Binary with docker-compose](docker-compose.md) + +@@@ + +There are 3 ways to obtain bindgen: + + * @ref:[Use docker container](docker-container.md) + + * @ref:[Build binary with CMake](cmake.md) + + * @ref:[Build binary with docker-compose](docker-compose.md) diff --git a/docs/src/paradox/using-generated-bindings/README.md b/docs/src/paradox/using-generated-bindings/README.md new file mode 100644 index 0000000..073831c --- /dev/null +++ b/docs/src/paradox/using-generated-bindings/README.md @@ -0,0 +1,112 @@ +# Using Generated Bindings + +Consider following header file: + +```c +struct point { + float x; + float y; +}; + +struct vector { + struct point a; + struct point b; +}; + +struct vector *add(struct vector *v1, struct vector *v2); +``` + +Bindgen will generate type aliases for the structs, binding for function `add` +and helper functions that make usage of structs easier. +```scala +import scala.scalanative._ +import scala.scalanative.native._ + +@native.link("mylib") +@native.extern +object mylib { + type struct_point = native.CStruct2[native.CFloat, native.CFloat] + type struct_vector = native.CStruct2[struct_point, struct_point] + def add(v1: native.Ptr[struct_vector], v2: native.Ptr[struct_vector]): native.Ptr[struct_vector] = native.extern +} + +import mylib._ + +object mylibHelpers { + + implicit class struct_point_ops(val p: native.Ptr[struct_point]) extends AnyVal { + def x: native.CFloat = !p._1 + def x_=(value: native.CFloat): Unit = !p._1 = value + def y: native.CFloat = !p._2 + def y_=(value: native.CFloat): Unit = !p._2 = value + } + + def struct_point()(implicit z: native.Zone): native.Ptr[struct_point] = native.alloc[struct_point] + + implicit class struct_vector_ops(val p: native.Ptr[struct_vector]) extends AnyVal { + def a: native.Ptr[struct_point] = p._1 + def a_=(value: native.Ptr[struct_point]): Unit = !p._1 = !value + def b: native.Ptr[struct_point] = p._2 + def b_=(value: native.Ptr[struct_point]): Unit = !p._2 = !value + } + + def struct_vector()(implicit z: native.Zone): native.Ptr[struct_vector] = native.alloc[struct_vector] +} +``` +Let's write code that creates two vectors, adds them and prints resulting +vector. + +First we need to create points for vectors. We will use `native.Zone` to +allocate struct (more information on memory management can be found +here: [Scala Native memory management]). + +Helper object `mylibHelpers` contains function for struct allocation. +To import it use `import mylibHelpers._` + +Let's create points for first vector: +```scala +import mylibHelpers._ +import scala.scalanative.native.Zone + +object Hello extends App { + Zone { implicit zone => + val vec1p1 = struct_point() + val vec1p2 = struct_point() + } +} +``` + +Now we want to set fields of created points. Scala Native provides access +to fields by using `_N` methods where `N` is index of a field +(see [Scala Native memory layout types]). + +Bindgen generates implicit helper classes that wrap calls to `_N` in functions +with meaningful names. We already imported helper class, so we can use the +functions: +```scala +vec1p1.x = 0 +vec1p1.y = 1 + +vec1p2.x = 6 +vec1p2.y = 3 +``` + +Lets create first vector. Note that `struct_vector` contains +fields of type `struct_point` but setters accept variables of type +`native.Ptr[struct_point]`. It helps to avoid Scala Native limitation that +does not allow passing structs and arrays by value +(see @github[scala-native/scala-native#555](scala-native/scala-native#555)). +```scala +val vec1 = struct_vector() +vec1.a = vec1p1 +vec1.b = vec1p2 +``` +Repeat these steps to create second vector. Once both vectors are created we can +call `add` function and print the result: +```scala +val vec3 = mylib.add(vec1, vec2) +println(s"(${vec3.a.x}, ${vec3.a.y}), (${vec3.b.x}, ${vec3.b.y})") +``` + + [Scala Native memory management]: http://www.scala-native.org/en/latest/user/interop.html#memory-management + [Scala Native memory layout types]: http://www.scala-native.org/en/latest/user/interop.html#memory-layout-types diff --git a/project/plugins.sbt b/project/plugins.sbt index 1373e8f..e7f571a 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,2 +1,3 @@ addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.3.7") -addSbtPlugin("com.lightbend.paradox" % "sbt-paradox" % "0.3.5") +addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "1.3.2") +addSbtPlugin("com.typesafe.sbt" % "sbt-ghpages" % "0.6.2")