Skip to content

Commit

Permalink
Improve documentation (#708)
Browse files Browse the repository at this point in the history
* docs: Fix spelling of Nix and NixOS

* docs: Improve formatting of operating systems

* docs: Use `apt` instead of `apt-get` on Ubuntu

* docs: Fix sbt instructions

* docs: Use inline literals in interoperability table

* docs: Use footnotes in interoperability table

* docs: Add instructions for Arch Linux

* docs: Improve wording in environment setup

We should mention it in a separate chapter that Scala Native uses
Clang.

* docs: Add missing section on function pointers

* docs: Improve section on linking

* docs: Don't specify sbt version

* docs: Rephrase remark about `lib` prefix

* docs: Fix preposition on interoperability page

* docs: Add missing types to interoperability table

* docs: Improve wording of section on unchecked casts

* docs: Add section on platform-specific types

* docs: Add section on determining the size of types

* docs: Specify version for sbt

* docs: Move section on troubleshooting to FAQ

* docs: Fix enumeration on sbt page

* docs: Improve punctuation and grammar on sbt page

* docs: Clarify version numbers
  • Loading branch information
tindzk authored and densh committed May 17, 2017
1 parent d1255a5 commit d034230
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 73 deletions.
10 changes: 10 additions & 0 deletions docs/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,13 @@ FAQ
If you need to run Scala code in the browser, consider using
`Scala.js <https://www.scala-js.org>`_ instead.

Troubleshooting
---------------
When compiling your Scala Native project, the linker ``ld`` may fail with the following message:

::

relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC

It is likely that the ``LDFLAGS`` environment variable enables hardening. For example, this occurs when the ``hardening-wrapper`` package is installed on Arch Linux. It can be safely removed.

169 changes: 120 additions & 49 deletions docs/user/interop.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Extern objects are simple wrapper objects that demarcate scopes where methods
are treated as their native C ABI-friendly counterparts. They are
roughly analogous to header files with top-level function declarations in C.

For example to call C's ``malloc`` one might declare it as following:
For example, to call C's ``malloc`` one might declare it as following:

.. code-block:: scala
Expand All @@ -29,70 +29,93 @@ For example to call C's ``malloc`` one might declare it as following:
``native.extern`` on the right hand side of the method definition signifies
that the body of the method is defined elsewhere in a native library that is
available on the library path (see `Linking with native libraries`_.) Signature
of the extern function must match the signature of the original C function
(see `Finding the right signature`_.)
available on the library path (see `Linking with native libraries`_). The
signature of the external function must match the signature of the original C
function (see `Finding the right signature`_).

Finding the right signature
```````````````````````````

To find a correct signature for a given C function one must provide an
equivalent Scala type for each of the arguments:

===================== =========================
C Type Scala Type
===================== =========================
void Unit
bool native.CBool
char, signed char native.CChar
unsigned char native.CUnsignedChar (1)
short native.CShort
unsigned short native.CUnsignedShort (1)
int native.CInt
unsigned int native.CUnsignedInt (1)
long native.CLong
unsigned long native.CUnsignedLong (1)
long long native.CLongLong
unsigned long long native.CUnsignedLongLong (1)
size_t native.CSize
ptrdiff_t native.CPtrDiff (2)
wchar_t native.CWideChar
char16_t native.CChar16
char32_t native.CChar32
float native.CFloat
double native.CDouble
void* native.Ptr[Byte] (2)
int* native.Ptr[native.CInt] (2)
char* native.CString (2) (3)
int (\*)(int) native.CFunctionPtr1[native.CInt, native.CInt] (2) (4)
struct { int x, y; }* native.Ptr[native.CStruct2[native.CInt, native.CInt]] (2) (5)
struct { int x, y; } Not supported
===================== =========================

(1) See `Unsigned integer types`_.
(2) See `Pointer types`_.
(3) See `Byte strings`_.
(4) See `Function pointers`_.
(5) See `Memory layout types`_.
========================= =========================
C Type Scala Type
========================= =========================
``void`` ``Unit``
``bool`` ``native.CBool``
``char`` ``native.CChar``
``signed char`` ``native.CSignedChar``
``unsigned char`` ``native.CUnsignedChar`` [1_]
``short`` ``native.CShort``
``unsigned short`` ``native.CUnsignedShort`` [1_]
``int`` ``native.CInt``
``long int`` ``native.CLongInt``
``unsigned int`` ``native.CUnsignedInt`` [1_]
``unsigned long int`` ``native.CUnsignedLongInt`` [1_]
``long`` ``native.CLong``
``unsigned long`` ``native.CUnsignedLong`` [1_]
``long long`` ``native.CLongLong``
``unsigned long long`` ``native.CUnsignedLongLong`` [1_]
``size_t`` ``native.CSize``
``ptrdiff_t`` ``native.CPtrDiff`` [2_]
``wchar_t`` ``native.CWideChar``
``char16_t`` ``native.CChar16``
``char32_t`` ``native.CChar32``
``float`` ``native.CFloat``
``double`` ``native.CDouble``
``void*`` ``native.Ptr[Byte]`` [2_]
``int*`` ``native.Ptr[native.CInt]`` [2_]
``char*`` ``native.CString`` [2_] [3_]
``int (*)(int)`` ``native.CFunctionPtr1[native.CInt, native.CInt]`` [2_] [4_]
``struct { int x, y; }*`` ``native.Ptr[native.CStruct2[native.CInt, native.CInt]]`` [2_] [5_]
``struct { int x, y; }`` Not supported
========================= =========================

.. [1] See `Unsigned integer types`_.
.. [2] See `Pointer types`_.
.. [3] See `Byte strings`_.
.. [4] See `Function pointers`_.
.. [5] See `Memory layout types`_.
Linking with native libraries
`````````````````````````````

In C/C++ one has to typically pass an additional ``-l mylib`` flag to
dynamically link with a library. In Scala Native one can annotate libraries
to link with using ``@native.link`` annotation:
C compilers typically require to pass an additional ``-l mylib`` flag to
dynamically link with a library. In Scala Native, one can annotate libraries to
link with using the ``@native.link`` annotation.

.. code-block:: scala
@native.link("mylib")
@native.extern
object mylib {
...
def f(): Unit = native.extern
}
Whenever any of the members of ``mylib`` object are reachable, the Scala Native
linker will automatically link with the corresponding native library.

As in C, library names are specified without the ``lib`` prefix. For example,
the library `libuv <https://github.com/libuv/libuv>`_ corresponds to
``@native.link("uv")`` in Scala Native.

It is possible to rename functions using the ``@name`` annotation. Its use is
recommended to enforce the Scala naming conventions in bindings:

.. code-block:: scala
import scala.scalanative.native._
@link("uv")
@extern
object uv {
@name("uv_uptime")
def uptime(result: Ptr[CDouble]): Int = extern
}
If a library has multiple components, you could split the bindings into separate
objects as it is permitted to use the same ``@link`` annotation more than once.

Variadic functions
``````````````````

Expand Down Expand Up @@ -134,6 +157,24 @@ Store a field ``ptr->name = value`` ``!ptr._N = value``
Where ``N`` is the index of the field ``name`` in the struct.
See `Memory layout types`_ for details.

Function pointers
`````````````````

It is possible to use external functions that take function pointers:

.. code-block:: scala
// void test(char (*f)(void));
def test(f: CFunctionPtr1[CString, Unit]): Unit = native.extern
To pass a Scala function to ``CFunctionPtrN``, you need to use the conversion
function ``CFunctionPtr.fromFunctionN()``:

.. code-block:: scala
def f(s: CString): Unit = ???
def g(): Unit = test(CFunctionPtr.fromFunction1(f))
Memory management
`````````````````

Expand Down Expand Up @@ -241,7 +282,7 @@ strings (similarly to C):
import scalanative.native._
// CString is an alias to Ptr[CChar]
// CString is an alias for Ptr[CChar]
val msg: CString = c"Hello, world!"
stdio.printf(msg)
Expand All @@ -251,11 +292,41 @@ Additionally, we also expose two helper functions ``native.toCString`` and
Unchecked casts
```````````````

Quite often,C APIs expect user to perform unchecked casts to convert
between different pointer types and/or pointers and integers values. We provide
``obj.cast[T]`` that's defined in ``native.CCast`` implicit class, for this
use case. Unlike Scala's ``asInstanceOf``, ``cast`` doesn't provide any safety
guarantees.
Quite often, C interfaces expect the user to perform unchecked casts to convert
between different pointer types, or between pointers and integer values. For
this particular use case, we provide ``obj.cast[T]`` that is defined in the
implicit class ``native.CCast``. Unlike Scala's ``asInstanceOf``, ``cast`` does
not provide any safety guarantees.

Platform-specific types
-----------------------

Scala Native defines the type ``Word`` and its unsigned counterpart, ``UWord``.
A word corresponds to ``Int`` on 32-bit architectures and to ``Long`` on 64-bit
ones.

Size of types
-------------

In order to statically determine the size of a type, you can use the ``sizeof``
function which is Scala Native's counterpart of the eponymous C operator. It
returns the size in bytes:

.. code-block:: scala
println(sizeof[Byte]) // 1
println(sizeof[CBool]) // 1
println(sizeof[CShort]) // 2
println(sizeof[CInt]) // 4
println(sizeof[CLong]) // 8
It can also be used to obtain the size of a structure:

.. code-block:: scala
type TwoBytes = CStruct2[Byte, Byte]
println(sizeof[TwoBytes]) // 2
Unsigned integer types
----------------------
Expand Down
18 changes: 9 additions & 9 deletions docs/user/sbt.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Minimal sbt project

Start within a new folder, and create a file ``project/plugins.sbt`` as follows::

addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.2.1")
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.2.1")

Create a file ``project/build.properties`` to define the sbt version as follows::

Expand All @@ -22,18 +22,17 @@ define a new ``build.sbt``::

scalaVersion := "2.11.11"

and now you can write your first application in ``./src/main/scala/HelloWorld.scala``:
and now you can write your first application in ``./src/main/scala/Main.scala``:

.. code-block:: scala
package example
object Main {
def main(args: Array[String]): Unit =
println("Hello, world!")
}
now simply run ``sbt run`` to get everything compiled and have the expected output!
Now, simply run ``sbt run`` to get everything compiled and have the expected
output! Please refer to the :ref:`faq` if you encounter any problems.

Scala versions
--------------
Expand Down Expand Up @@ -95,7 +94,7 @@ Garbage collectors
Conservative generational garbage collector. More information is available
at the `project's page <https://www.hboehm.info/gc/>`_.

1. **none.**
2. **none.**

Garbage collector that allocates things without ever freeing them. Useful
for short-running command-line applications or applications where garbage
Expand All @@ -121,9 +120,10 @@ Cross compilation

`sbt-crossproject <https://github.com/scala-native/sbt-crossproject>`_ is an
sbt plugin that lets you cross-compile your projects against all three major
platforms in Scala: JVM, JavaScript via Scala.js and native via Scala Native.
It's based on the original cross-project idea from Scala.js and supports the
same syntax for existing JVM/JavaScript cross-projects. Please refer to project's
platforms in Scala: JVM, JavaScript via Scala.js, and native via Scala Native.
It is based on the original cross-project idea from Scala.js and supports the
same syntax for existing JVM/JavaScript cross-projects. Please refer to the
project's
`README <https://github.com/scala-native/sbt-crossproject/blob/master/README.md>`_
for details.

Expand Down
38 changes: 23 additions & 15 deletions docs/user/setup.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@
Environment setup
=================

This is what you will be doing, in a nutshell:
Scala Native has the following minimum system requirements:

* installation of sbt
* installation of LLVM and Clang
* installation of native libraries
* Java 8+
* sbt 0.13.x
* LLVM 3.7 or newer
* Native libraries
* Boehm GC 7.6.0
* Re2 2017-01-01

Installing sbt
--------------

Please refer to `this link <http://www.scala-sbt.org/release/docs/Setup.html>`_
for instructions for your OS.

Please note that you'll need Java 8 or more recent to use the Scala Native
toolchain.
for instructions for your operating system.

Installing LLVM, Clang and native libraries
-------------------------------------------
Expand All @@ -39,24 +39,32 @@ build time.
Here are install instructions for a number of operating systems Scala
Native has been used with:

Ubuntu::
**Ubuntu**
::

$ sudo apt install clang libgc-dev libunwind-dev libre2-dev

$ sudo apt-get install clang libgc-dev libunwind-dev libre2-dev
*Note:* libre2-dev is available since Xenial (16.04 LTS). Refer to `travis.yml <https://github.com/scala-native/scala-native/blob/master/.travis.yml>`_ to install from source.

Note: libre2-dev is available since Xenial (16.04 LTS). Refer to `travis.yml <https://github.com/scala-native/scala-native/blob/master/.travis.yml>`_ to install from source.
**Arch Linux**
::

macOS::
$ sudo pacman -S llvm gc re2

**macOS**
::

$ brew install llvm bdw-gc re2

FreeBSD::
**FreeBSD**
::

$ pkg install llvm38 boehm-gc libunwind re2

nix/nixOS::
**Nix/NixOS**
::

$ wget https://raw.githubusercontent.com/scala-native/scala-native/master/bin/scala-native.nix

$ nix-shell scala-native.nix -A clangEnv

Continue to :ref:`sbt`.
Expand Down

0 comments on commit d034230

Please sign in to comment.