On Wed, 10 Apr 2024 14:34:25 GMT, Jorn Vernee <jvernee@openjdk.org> wrote:
Add a comprehensive jextract guide under a new `doc/` folder.
This is meant as a comprehensive guide about the features of jextract and the code that it generates (including both examples from header files, the code that jextract generates, and corresponding Java user code). This is a first cut, and I'm anticipating quite a bit of comments.
Some sections of the readme have been moved to the guide (with minor edits here and there), and replaced by a link in the readme.
Jorn Vernee has updated the pull request incrementally with one additional commit since the last revision:
Phrasing
Co-authored-by: Maurizio Cimadamore <54672762+mcimadamore@users.noreply.github.com>
An excellent guide. I read through all of it as someone who already used jextract and left some minor grammar comments that I found to help with the flow, but I would like to point out something more confusing with the structure. The first part is about running jextract, including a short review of an example, followed by an explanation about loading libraries. It looks like this section explains the arguments/options passed to the tool, but it skips the discussion about the macros option (appears much later in Preprocessor Definitions) and other options. The second part is about the code that is generated, but then there is an explanation about `--header-class-name` and `--target-package`, which should be part of the previous part. I would expect that by the time the user gets to learning about the generated Java code, they would know what commands generated it. Also: * Did you leave out "Bitfields" on purpose? * Can a ToC be generated? doc/GUIDE.md line 11:
9: archive of native functions and global variables. The user then has to look up the functions 10: they want to call using a `SymbolLookup`, and finally _link_ the functions by using the 11: `Linker::downcallHandle` method. Additionally, a client may need to create function pointer for
pointer -> pointers doc/GUIDE.md line 18:
16: 17: This guide shows how to run the jextract tool, and how to use the Java code that it generates. 18: The samples under [`samples`](samples) direcotry are also a good source of examples.
"under **the** samples directory" doc/GUIDE.md line 29:
27: library called `mylib` stored at `/path/to/mylib` that has a directory `/path/to/mylib/include` 28: where the header files of that library are stored. And let's say that we have a shell open 29: in the root directory of the Java project we're working on, which has an `src` source
"a `src`" probably. doc/GUIDE.md line 30:
28: where the header files of that library are stored. And let's say that we have a shell open 29: in the root directory of the Java project we're working on, which has an `src` source 30: directory corresponding to,the root package. A typical way to run jextract would be like
Space after the comma. doc/GUIDE.md line 48:
46: - `--include-dir /path/to/mylib/include` specifies a header file search directory, which 47: is used to find header files included through `#include` in the main header file. 48: - `--output src` specifies the root directory for the output. This matches to root package
"matches **the** root" doc/GUIDE.md line 51:
49: of the project's source directory. 50: - `--target-package org.jextract.mylib` specifies the target package to which the generated 51: classes and interfaces will belong. (note that jextract will automatically create the
note -> Note doc/GUIDE.md line 72:
70: to load libraries specified by `<libspec>`. If `<libspec>` denotes a library name, the 71: name is then mapped to a platform dependent name using [`System::mapLibraryName`](https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/lang/Syste...)). 72: This means for instance that on Linux, when specifying `--library mylib` the bindings will
Commas help here: "This means, for instance," doc/GUIDE.md line 75:
73: On Mac the relevant environment variable is `DYLD_LIBRARY_PATH`, and on Windows the variable is `PATH`. 74: Though, for the latter the overall library search mechanism is entirely different (described [here](https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-se...)). 75: When using the HotSpot JVM, the `-Xlog:library` option can als be use to log where the JVM is trying to load a library from,
als -> also use -> used doc/GUIDE.md line 80:
78: and on Windows the variable is `PATH`. Though, for the latter the overall library search 79: mechanism is entirely different (described [here](https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-se...)). 80: When using the HotSpot JVM, the `-Xlog:library` option can als be use to log where the JVM
als -> also use -> used doc/GUIDE.md line 84:
82: 83: The `<libspec>` argument of the `--library` option can either be a library name, such as, 84: `mylib` which will, be mapped to a platform specific name using [`System::mapLibraryName`](https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/lang/Syste...)), or a path to a library file (either relative or
Comma after `mylib` instead of after `will`. doc/GUIDE.md line 84:
82: 83: The `<libspec>` argument of the `--library` option can either be a library name, such as, 84: `mylib` which will, be mapped to a platform specific name using [`System::mapLibraryName`](https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/lang/Syste...)), or a path to a library file (either relative or
This was already mentioned in the previous paragraph. doc/GUIDE.md line 85:
83: The `<libspec>` argument of the `--library` option can either be a library name, such as, 84: `mylib` which will, be mapped to a platform specific name using [`System::mapLibraryName`](https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/lang/Syste...)), or a path to a library file (either relative or 85: absolute) if `<libspec>` is prefixed with the `:` character, such as `mylib.dll`.
Shouldn't the example then be `:mylib.dll`? doc/GUIDE.md line 106:
104: some examples of how to use the generated Java code. 105: 106: Most of the code that jextract generates will be available through a single class. By default
"By default," doc/GUIDE.md line 126:
124: ``` 125: 126: Where `org.mypackage` is the package into which jextract put the generates source files
"puts the generated" doc/GUIDE.md line 134:
132: builtin C types. 133: 134: The latter import statement imports all the other classes the jextract generates, which
"that jextract generates" doc/GUIDE.md line 135:
133: 134: The latter import statement imports all the other classes the jextract generates, which 135: includes: classes representing structs or unions, function types, and struct or union
includes -> include doc/GUIDE.md line 164:
162: `short,` `int`, `long long`, `float`, `double` `long`, and `long double`. Additionally, 163: there is a `C_POINTER` layout which represents the layout for any C pointer type (such as 164: `T*`). Note that these layouts are platform dependent, depending on the platform that
"platform dependent, depending on the platform" This is somewhat redundant. Just "these layouts depend on" maybe, or some other phrasing. doc/GUIDE.md line 167:
165: jextract runs on. For instance, since these constants were generated on Windows, the 166: `long` type has the same layout as the Java `int` type, indicating a 32-bit value, and the 167: `long double` type has the same layout as the Java `double` type. (note that the latter is
note -> Note doc/GUIDE.md line 181:
179: ``` 180: 181: Jextract will generate the following set of methods for this function, in the main header
function, -> function doc/GUIDE.md line 185:
183: 184: ```java 185: // mylib_h.java
Assuming the class name options wasn't specified (if you want to mention that, though not important). doc/GUIDE.md line 197:
195: call the C function (1). Besides that, there are also several accessors that return 196: additional meta-data for the method: the function's address (2), the function descriptor 197: (3), and the method handle returned by the FFM linker (4), which is used to implement the
I would add inline links for convenience, like: `[function's address](MemorySegment)`, `[function descriptor](FunctionDescriptor)` and `(method handle)[MethodHandle]` doc/GUIDE.md line 200:
198: static wrapper method (1). 199: 200: The parameter types and return type of this method depend on the carrier types of the
Is the reader supposed to know what a "carrier type" is? Can a link be given to an explanation if one exists in FFM maybe? doc/GUIDE.md line 211:
209: // mylib.h 210: 211: int bar;
Maybe mention what happens if the definition includes an assignment, `int bar = 4;`, if it matters. doc/GUIDE.md line 269:
267: not supported by jextract. For function-like macros, alternatives include re-writing the 268: code inside the macro in Java, using the FFM API, or writing a small C library which wraps 269: the function-like macro in a proper exported C function, that can then be linked against
"function," -> "function" doc/GUIDE.md line 348:
346: 347: For working with arrays of structs, we can use the `allocateArray` method which accepts an 348: additional element count, indicating the length of the array:
Comma before "which" instead of after "count". doc/GUIDE.md line 358:
356: 357: for (int i = 0; i < arrLen; i++) { 358: MemorySegment element = Point.asSlice(point, i);
Never used this method, but I assume it should be `asSlice(points, i)`. doc/GUIDE.md line 369:
367: In the above example, the `asSlice` method is used to _slice_ out a section of 368: the array, which corresponds to a single `Point` struct element. This method 369: can be used to access individual elements of the `points` array, when given
"array," -> "array" doc/GUIDE.md line 438:
436: we received from native code. 437: 438: For instance, let's say we have a function that accepts an instance of the `callback_t`
For clarity, I would say "have a native function". doc/GUIDE.md line 456:
454: try (Arena arena = Arena.ofConfined()) { 455: MemorySegment cb = callback_t.allocate((a, b) -> a * b, arena); 456: int result = call_me_back(cb);
Where is `call_me_back` defined? doc/GUIDE.md line 468:
466: can no longer be called). 467: 468: Additionally, we can using the `callback_t::invoke` method invoke an instance of
using -> use doc/GUIDE.md line 485:
483: 484: The `get_callback` function returns an instance of `callback_t`, which is a function pointer 485: pointing to the native `mult` function. We can call `callback_t` instance that `get_callback()`
"call **the** `callback_t` instance" doc/GUIDE.md line 486:
484: The `get_callback` function returns an instance of `callback_t`, which is a function pointer 485: pointing to the native `mult` function. We can call `callback_t` instance that `get_callback()` 486: return in Java using the `invoke` method in the `callback_t` class that jextract generates
return -> returns doc/GUIDE.md line 534:
532: ``` 533: 534: Jextract doesn't generates a regular method, but a _class_, which represents the invoker:
generates -> generate doc/GUIDE.md line 576:
574: ### Typedefs 575: 576: As mentioned before: typedefs are either translated as a `static final` memory layout fields
before: -> before, doc/GUIDE.md line 603:
601: ``` 602: 603: The `MyPoint` `typedef` on the other hand is a typedef for a struct, so it is translated
"`typedef` on the other hand" -> "`typedef`, on the other hand," doc/GUIDE.md line 618:
616: 617: C allows variable declarations to have an inline anonymous type. Jextract handles in 618: particular cases where a struct's field has an inline type specially. For instance, if we
"Jextract handles in particular cases where a struct's field has an inline type specially." I don't understand this sentence. Does Jextract handle nested types only when a struct's field has an inline type? doc/GUIDE.md line 634:
632: 633: Jextract generates a _nested_ struct and function pointer class for the `bar` and `cb` 634: fields, _inside of_ the class it generates for the `Foo` struct itself:
fields, -> fields doc/GUIDE.md line 713:
711: 712: The include options in this file can then be edited down to a set of symbols that is 713: desired, for instance using other command line tools such as `grep` or `Select-String`,
instance -> instance, doc/GUIDE.md line 800:
798: 799: The value of these macros also affects the behavior of jextract. Therefore, jextract 800: supports setting macro values on the command line using the `-D` or
Perhaps mentioning the distinctions between these macros and the ones described in the Constants section more specifically will be helpful? ------------- PR Review: https://git.openjdk.org/jextract/pull/231#pullrequestreview-1989727538 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562492438 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562494228 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562499511 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562495661 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562498454 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562500829 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562503617 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1558074831 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562505421 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562506125 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562510865 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562511595 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562515695 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562517992 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562519931 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562520377 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562532950 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562534017 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562536552 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562538150 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562544444 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562548168 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562583132 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562620372 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562631106 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562634105 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1562635428 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1563001201 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1563006011 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1563008874 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1563038152 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1563038500 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1563049288 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1563054342 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1563069603 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1563074084 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1563075034 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1563083141 PR Review Comment: https://git.openjdk.org/jextract/pull/231#discussion_r1563096318