Skip to content

Commit

Permalink
Merge pull request #101 from kornilova-l/documentation
Browse files Browse the repository at this point in the history
Update documentation
  • Loading branch information
kornilova203 authored Jul 5, 2018
2 parents 753a512 + f9b771b commit 15ded8a
Show file tree
Hide file tree
Showing 14 changed files with 323 additions and 273 deletions.
160 changes: 1 addition & 159 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,165 +4,7 @@

This tool generates Scala Native bindings from C headers. It's built upon clang and Libtooling and thus respects the conventions of clang-tools.

## Usage

Calling the tool is pretty easy, you need to specify the file(s) and the name of the created bindings.

```sh
scala-native-bindgen --name uv /usr/include/uv.h --
```

Running the previous command wild also yield warnings along with the translation. To keep only the bindings please redirect the output to a file like this:

```sh
scala-native-bindgen --name uv /usr/include/uv.h -- > uv.scala
```

Run `scala-native-bindgen --help` to see all available options.

## Obtaining bindgen

There are 2 ways to obtain bindgen:
* [use docker container](#docker-container)
* [build binary from sources](#building)

### Docker container

This option requires [Docker].

Download docker image with the binary:

```sh
docker pull scalabindgen/scala-native-bindgen
```

Mount directories with required header files and run bindgen:

```sh
docker run -v "$(pwd)":/src -v /usr/include:/usr/include \
--rm scalabindgen/scala-native-bindgen \
relative/path/to/my_header.h --name my_header --
```

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 [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]: scripts/docker-bindgen.sh

## Building

Building `scala-native-bindgen` requires the following tools and libraries:

- [CMake] version 3.9 or higher
- [LLVM] and [Clang] version 5.0 or 6.0.

```sh
# On apt-based systems
apt install cmake clang-$LLVM_VERSION libclang-$LLVM_VERSION-dev llvm-$LLVM_VERSION-dev

# With `brew`
brew install cmake llvm@6
```

To run the tests you also need the required Scala Native libraries.
See the [Scala Native setup guide] for instructions on installing the dependencies.

```sh
mkdir -p bindgen/target
cd bindgen/target
cmake ..
make
./scala-native-bindgen --name ctype /usr/include/ctype.h --
```

To build a statically linked executable pass `-DSTATIC_LINKING=ON` when invoking `cmake`:

```sh
cmake -DSTATIC_LINKING=ON ..
```

Additional compiler and linker flags may be passed as environment variable sor their CMake
equivalent, e.g. to compile with debug symbols the following are the same:

```sh
cmake -DCMAKE_CXX_FLAGS=-g ..
CXXFLAGS=-g cmake ..
```

### Building with `docker-compose`

Alternatively, you can use [docker-compose] to build and test the program:

```sh
# Build the docker image with LLVM version 6.0.
docker-compose build ubuntu-18.04-llvm-6.0
# Build the bindgen tool and run the tests.
docker-compose run --rm ubuntu-18.04-llvm-6.0 ./script/test.sh
# Run the bindgen tool inside the container.
docker-compose run --rm ubuntu-18.04-llvm-6.0 \
bindgen/target/scala-native-bindgen --name union tests/samples/Union.h --
```

[CMake]: https://cmake.org/
[LLVM]: https://llvm.org/
[Clang]: https://clang.llvm.org/
[Scala Native setup guide]: http://www.scala-native.org/en/latest/user/setup.html
[docker-compose]: https://docs.docker.com/compose/

## Testing

The tests assume that the above instructions for building `scala-native-bindgen` from source
has been followed.

```sh
cd tests
sbt test
```

## Limitations

There are multiple unsupported cases that should be considered when generating bindings:

1. Currently bindgen does not support passing structs by value.
For example, it will not be possible to call these two functions from Scala Native code:
```c
struct MyStruct {
int a;
};

struct MyStruct returnStruct();

void handleStruct(struct MyStruct mystr);
```
To support such cases one should generate bindings for C wrapper functions that use pointers to structs instead of actual structs.
2. `#define`s for literals and variables are supported. For other types of `#define`s,
write wrapper functions that return defined values.
```c
// Supported
#define ESC 0x1b /* Defines for numerical and string literals. */
extern const int pi_const;
#define PI pi_const /* Defines aliasing extern variables. */

// Not supported (non-exhaustive list)
#define COLS (getenv("COLS") ? atoi(getenv("COLS")) : 80)
#define MAX(a, b) (a > b ? a : b)
```

3. There is no way to reuse already generated bindings.
Bindgen outputs bindings also for headers that were included in a given header. See [#2].
4. Type qualifiers `const`, `volatile` and `restrict` are not supported.
5. Extern variables are read-only. See [scala-native/scala-native#202].

[#2]: https://github.com/kornilova-l/scala-native-bindgen/issues/2
[scala-native/scala-native#202]: https://github.com/scala-native/scala-native/issues/202
[Documentation](https://kornilova-l.github.io/scala-native-bindgen/)

## License

Expand Down
11 changes: 11 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,14 @@ lazy val samples = project
)

lazy val tools = project in file("tools")

lazy val docs = project
.in(file("docs"))
.enablePlugins(GhpagesPlugin, ParadoxSitePlugin)
.settings(
paradoxTheme := Some(builtinParadoxTheme("generic")),
paradoxProperties in Paradox ++= Map(
"github.base_url" -> "https://github.com/kornilova-l/scala-native-bindgen/tree/master/"
),
git.remoteRepo := "[email protected]:kornilova-l/scala-native-bindgen.git"
)
1 change: 0 additions & 1 deletion docs/_config.yml

This file was deleted.

6 changes: 0 additions & 6 deletions docs/index.md

This file was deleted.

107 changes: 0 additions & 107 deletions docs/obtaining-bindgen.md

This file was deleted.

25 changes: 25 additions & 0 deletions docs/src/paradox/command-line-usage/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Command Line Usage

Calling the tool is pretty easy, you need to specify the file(s) and the name of the created bindings.

```sh
scala-native-bindgen --name uv /usr/include/uv.h --
```

Running the previous command wild also yield warnings along with the translation. To keep only the bindings please redirect the output to a file like this:

```sh
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 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. |
20 changes: 20 additions & 0 deletions docs/src/paradox/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Scala Native Bindgen

@@@ index

* [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)

@@@

This tool generates Scala Native bindings from C headers.
It's built upon clang and [LibTooling] and thus respects the conventions of clang-tools.

## License

This project is distributed under the Scala license.
@github[See LICENSE.txt for details](/LICENSE.txt)

[LibTooling]: https://clang.llvm.org/docs/LibTooling.html
35 changes: 35 additions & 0 deletions docs/src/paradox/limitations/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## Limitations

There are multiple unsupported cases that should be considered when generating bindings:

1. Currently bindgen does not support passing structs by value.
For example, it will not be possible to call these two functions from Scala Native code:

```c
struct MyStruct {
int a;
};

struct MyStruct returnStruct();

void handleStruct(struct MyStruct mystr);
```
To support such cases one should generate bindings for C wrapper functions that use pointers to structs instead of actual structs.
2. `#define`s for literals and variables are supported. For other types of `#define`s,
write wrapper functions that return defined values.

```c
// Supported
#define ESC 0x1b /* Defines for numerical and string literals. */
extern const int pi_const;
#define PI pi_const /* Defines aliasing extern variables. */

// Not supported (non-exhaustive list)
#define COLS (getenv("COLS") ? atoi(getenv("COLS")) : 80)
#define MAX(a, b) (a > b ? a : b)
```

3. There is no way to reuse already generated bindings.
Bindgen outputs bindings also for headers that were included in a given header. See @github[#2](#2).
4. Type qualifiers `const`, `volatile` and `restrict` are not supported.
5. Extern variables are read-only. See @github[scala-native/scala-native#202](scala-native/scala-native#202).
Loading

0 comments on commit 15ded8a

Please sign in to comment.