Skip to content

Commit 88f3846

Browse files
committed
macOS: jextract without import cleanup
1 parent b88b267 commit 88f3846

14 files changed

+96
-55
lines changed

java-does-usb/jextract/README.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
# Code Generation with *jextract*
22

3-
Some of the binding code for accessing native functions and data structures is generated with [jextract](https://jdk.java.net/jextract/). The tool is still under construction and has its limitations.
3+
A major part of the binding code for accessing native functions and data structures is generated with [jextract](https://jdk.java.net/jextract/). *jextract* is not bundled with the JDK. The binaries can be downloaded from [jdk.java.net/jextract](https://jdk.java.net/jextract/)
44

5-
In order to generate the code, the scripts in the subdirectories have to be run (`linux/gen_linux.sh`, `macos/gen_macos.sh` and `/windowsgen_win.cmd`). Each script has to be run on the particular operating system.
5+
In order to generate the code, the scripts in the subdirectories have to be run (`linux/gen_linux.sh`, `macos/gen_macos.sh` and `windows/gen_win.cmd`). Each script has to be run on the particular operating system. The scripts expect the *jextract* binary to be in a *jextract* directory at the same parent directory as the *Java Does USB* project. If that is not the case, the *jextract* path can be modified at the top of the scripts.
66

7-
The code is generated in directories below `gen`, i.e. `main/java/net/codecrete/usb/linux/gen` and similar for the other operating systems. For each library (`xxx.so` or `xxx.dll`) and each macOS framework, a separate package is created.
7+
The code is generated in directories below `gen`, i.e. `main/java/net/codecrete/usb/linux/gen` and similarly for the other operating systems. For each library (`xxx.so` or `xxx.dll`) and each macOS framework, a separate package is created.
88

9-
The scripts explicitly specify the functions, structs etc. to include as generating code for entire operating system header files can result in an excessive amount of Java source files and classes.
9+
The scripts explicitly specify the functions, structs etc. to include as generating code for entire operating system header files will result in an excessive amount of Java source files and classes.
1010

11-
The resulting code is then committed to the source code repository. Before the commit, imports are cleaned up to get rid of superfluous imports. Most IDEs provide a convenient command to execute this on entire directories.
11+
The resulting code is then committed to the source code repository.
1212

1313

1414
## General limitations
1515

1616
- According to the jextract mailing list, it would be required to create separate code for Intel x64 and ARM64 architecture. And jextract would need to be run on each architecture separately (no cross-compilation). Fortunately, this doesn't seem to be the case. Linux code generated on Intel x64 also runs on ARM64 without change. The same holds for macOS. However, jextract needs to be run on each operating system separately.
1717

18-
- JDK 20 introduced a new feature for saving the thread-specific error values (`GetLastError()` on Windows, `errno` on Linux). To use it, an additional parameter must be added to function calls. Unfortunately, this is not yet supported by jextract. So a good number of function bindings have to be written manually.
18+
- The *Foreign Function And Memory* API has the abilitiy to save the thread-specific error values (`GetLastError()` on Windows, `errno` on Linux). This is required as the JVM calls operation system functions as well, which overwrite the result values. To save the values, an additional parameter must be added to function calls. Unfortunately, this is not supported by jextract. So a good number of function bindings have to be written manually.
1919

2020
- *jextract* is not really transparent about what it does. It often skips elements without providing any information. In particular, it will silently skip a requested element in these cases:
2121

@@ -26,7 +26,7 @@ The resulting code is then committed to the source code repository. Before the c
2626
- `--include-typedef mystruct` if `mystruct` is actually a `struct`.
2727
- `--include-typedef mytypedef` if `mytypedef` is a `typedef` for a primitive type.
2828

29-
- *jextract* resolves all _typedef_s to their actual types. So this library does not use any _--include-typedef_ option. And there does not seem any obvious use for it.
29+
- *jextract* resolves all _typedef_s to their actual types. So this library does not use any _--include-typedef_ option. And there does not seem any obvious use for it beyond cosmetics.
3030

3131

3232
## Linux
@@ -70,6 +70,7 @@ The known limitations are:
7070
- *jextract* turns off *echo mode*. So the first call will behave differently than the following calls.
7171

7272

73+
7374
## Code Size
7475

7576
*jextract* generates a comprehensive set of methods for each function, struct, struct member etc. Most of it will not be used as a typical application just uses a subset of struct members, might only read or write them etc. So a considerable amount of code is generated. For some types, it's a bit excessive.
@@ -78,13 +79,13 @@ The worst example is [`IOUSBInterfaceStruct190`](https://github.com/manuelbl/Jav
7879

7980
The table below shows class file size statistics for version 1.0.0 of the library:
8081

81-
| Operating Systems | Manually Created | % | Generated | % | Total | % |
82+
| Operating Systems | Manually Written | % | Generated | % | Total | % |
8283
|-------------------|-----------------:|------:|----------:|------:|----------:|--------:|
8384
| Linux | 54,022 | 4.3% | 162,099 | 12.8% | 216,121 | 17.1% |
8485
| macOS | 77,149 | 6.1% | 529,347 | 41.8% | 606,496 | 47.9% |
8586
| Windows | 106,358 | 8.4% | 232,395 | 18.3% | 338,753 | 26.7% |
8687
| Common | 105,423 | 8.3% | | | 105,423 | 8.3% |
87-
| Grand Total | 342,952 | 27.1% | 923,841 | 72.9% | 1,266,793 | 100.00% |
88+
| Grand Total | 342,952 | 27.1% | 923,841 | 72.9% | 1,266,793 | 100.0% |
8889

8990

9091
*Class File Size (compiled), in bytes and percentage of total size*

java-does-usb/jextract/macos/gen_macos.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/bin/sh
22

3-
JEXTRACT=../../../../jextract/build/jextract/bin/jextract
3+
JEXTRACT=../../../../jextract/bin/jextract
44
# If SDK_DIR is changed, it needs to be changed in compile_flags.txt as well.
55
SDK_DIR=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
66

java-does-usb/src/main/java/net/codecrete/usb/macos/gen/corefoundation/CFRange.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@
22

33
package net.codecrete.usb.macos.gen.corefoundation;
44

5+
import java.lang.invoke.*;
56
import java.lang.foreign.*;
6-
import java.util.function.Consumer;
7+
import java.nio.ByteOrder;
8+
import java.util.*;
9+
import java.util.function.*;
10+
import java.util.stream.*;
711

8-
import static java.lang.foreign.MemoryLayout.PathElement.groupElement;
9-
import static java.lang.foreign.ValueLayout.OfLong;
12+
import static java.lang.foreign.ValueLayout.*;
13+
import static java.lang.foreign.MemoryLayout.PathElement.*;
1014

1115
/**
1216
* {@snippet lang=c :

java-does-usb/src/main/java/net/codecrete/usb/macos/gen/corefoundation/CFUUIDBytes.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@
22

33
package net.codecrete.usb.macos.gen.corefoundation;
44

5+
import java.lang.invoke.*;
56
import java.lang.foreign.*;
6-
import java.util.function.Consumer;
7+
import java.nio.ByteOrder;
8+
import java.util.*;
9+
import java.util.function.*;
10+
import java.util.stream.*;
711

8-
import static java.lang.foreign.MemoryLayout.PathElement.groupElement;
9-
import static java.lang.foreign.ValueLayout.OfByte;
12+
import static java.lang.foreign.ValueLayout.*;
13+
import static java.lang.foreign.MemoryLayout.PathElement.*;
1014

1115
/**
1216
* {@snippet lang=c :

java-does-usb/src/main/java/net/codecrete/usb/macos/gen/corefoundation/CoreFoundation.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22

33
package net.codecrete.usb.macos.gen.corefoundation;
44

5+
import java.lang.invoke.*;
56
import java.lang.foreign.*;
6-
import java.lang.invoke.MethodHandle;
7-
import java.lang.invoke.MethodHandles;
8-
import java.util.Arrays;
9-
import java.util.stream.Collectors;
7+
import java.nio.ByteOrder;
8+
import java.util.*;
9+
import java.util.function.*;
10+
import java.util.stream.*;
1011

11-
import static java.lang.foreign.ValueLayout.JAVA_BYTE;
12+
import static java.lang.foreign.ValueLayout.*;
13+
import static java.lang.foreign.MemoryLayout.PathElement.*;
1214

1315
public class CoreFoundation {
1416

java-does-usb/src/main/java/net/codecrete/usb/macos/gen/iokit/CFUUIDBytes.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@
22

33
package net.codecrete.usb.macos.gen.iokit;
44

5+
import java.lang.invoke.*;
56
import java.lang.foreign.*;
6-
import java.util.function.Consumer;
7+
import java.nio.ByteOrder;
8+
import java.util.*;
9+
import java.util.function.*;
10+
import java.util.stream.*;
711

8-
import static java.lang.foreign.MemoryLayout.PathElement.groupElement;
9-
import static java.lang.foreign.ValueLayout.OfByte;
12+
import static java.lang.foreign.ValueLayout.*;
13+
import static java.lang.foreign.MemoryLayout.PathElement.*;
1014

1115
/**
1216
* {@snippet lang=c :

java-does-usb/src/main/java/net/codecrete/usb/macos/gen/iokit/IOCFPlugInInterfaceStruct.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22

33
package net.codecrete.usb.macos.gen.iokit;
44

5+
import java.lang.invoke.*;
56
import java.lang.foreign.*;
6-
import java.lang.invoke.MethodHandle;
7-
import java.util.function.Consumer;
7+
import java.nio.ByteOrder;
8+
import java.util.*;
9+
import java.util.function.*;
10+
import java.util.stream.*;
811

9-
import static java.lang.foreign.MemoryLayout.PathElement.groupElement;
10-
import static java.lang.foreign.ValueLayout.OfShort;
12+
import static java.lang.foreign.ValueLayout.*;
13+
import static java.lang.foreign.MemoryLayout.PathElement.*;
1114

1215
/**
1316
* {@snippet lang=c :

java-does-usb/src/main/java/net/codecrete/usb/macos/gen/iokit/IOKit.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22

33
package net.codecrete.usb.macos.gen.iokit;
44

5+
import java.lang.invoke.*;
56
import java.lang.foreign.*;
6-
import java.lang.invoke.MethodHandle;
7-
import java.lang.invoke.MethodHandles;
8-
import java.util.Arrays;
9-
import java.util.stream.Collectors;
7+
import java.nio.ByteOrder;
8+
import java.util.*;
9+
import java.util.function.*;
10+
import java.util.stream.*;
1011

11-
import static java.lang.foreign.ValueLayout.JAVA_BYTE;
12-
import static java.lang.foreign.ValueLayout.OfInt;
12+
import static java.lang.foreign.ValueLayout.*;
13+
import static java.lang.foreign.MemoryLayout.PathElement.*;
1314

1415
public class IOKit {
1516

java-does-usb/src/main/java/net/codecrete/usb/macos/gen/iokit/IOServiceAddMatchingNotification$callback.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@
22

33
package net.codecrete.usb.macos.gen.iokit;
44

5-
import java.lang.foreign.Arena;
6-
import java.lang.foreign.FunctionDescriptor;
7-
import java.lang.foreign.Linker;
8-
import java.lang.foreign.MemorySegment;
9-
import java.lang.invoke.MethodHandle;
5+
import java.lang.invoke.*;
6+
import java.lang.foreign.*;
7+
import java.nio.ByteOrder;
8+
import java.util.*;
9+
import java.util.function.*;
10+
import java.util.stream.*;
11+
12+
import static java.lang.foreign.ValueLayout.*;
13+
import static java.lang.foreign.MemoryLayout.PathElement.*;
1014

1115
/**
1216
* {@snippet lang=c :

java-does-usb/src/main/java/net/codecrete/usb/macos/gen/iokit/IOUSBDevRequest.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@
22

33
package net.codecrete.usb.macos.gen.iokit;
44

5+
import java.lang.invoke.*;
56
import java.lang.foreign.*;
6-
import java.util.function.Consumer;
7+
import java.nio.ByteOrder;
8+
import java.util.*;
9+
import java.util.function.*;
10+
import java.util.stream.*;
711

8-
import static java.lang.foreign.MemoryLayout.PathElement.groupElement;
912
import static java.lang.foreign.ValueLayout.*;
13+
import static java.lang.foreign.MemoryLayout.PathElement.*;
1014

1115
/**
1216
* {@snippet lang=c :

java-does-usb/src/main/java/net/codecrete/usb/macos/gen/iokit/IOUSBDeviceStruct187.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@
22

33
package net.codecrete.usb.macos.gen.iokit;
44

5+
import java.lang.invoke.*;
56
import java.lang.foreign.*;
6-
import java.lang.invoke.MethodHandle;
7-
import java.util.function.Consumer;
7+
import java.nio.ByteOrder;
8+
import java.util.*;
9+
import java.util.function.*;
10+
import java.util.stream.*;
811

9-
import static java.lang.foreign.MemoryLayout.PathElement.groupElement;
12+
import static java.lang.foreign.ValueLayout.*;
13+
import static java.lang.foreign.MemoryLayout.PathElement.*;
1014

1115
/**
1216
* {@snippet lang=c :

java-does-usb/src/main/java/net/codecrete/usb/macos/gen/iokit/IOUSBFindInterfaceRequest.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@
22

33
package net.codecrete.usb.macos.gen.iokit;
44

5+
import java.lang.invoke.*;
56
import java.lang.foreign.*;
6-
import java.util.function.Consumer;
7+
import java.nio.ByteOrder;
8+
import java.util.*;
9+
import java.util.function.*;
10+
import java.util.stream.*;
711

8-
import static java.lang.foreign.MemoryLayout.PathElement.groupElement;
9-
import static java.lang.foreign.ValueLayout.OfShort;
12+
import static java.lang.foreign.ValueLayout.*;
13+
import static java.lang.foreign.MemoryLayout.PathElement.*;
1014

1115
/**
1216
* {@snippet lang=c :

java-does-usb/src/main/java/net/codecrete/usb/macos/gen/iokit/IOUSBInterfaceStruct190.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@
22

33
package net.codecrete.usb.macos.gen.iokit;
44

5+
import java.lang.invoke.*;
56
import java.lang.foreign.*;
6-
import java.lang.invoke.MethodHandle;
7-
import java.util.function.Consumer;
7+
import java.nio.ByteOrder;
8+
import java.util.*;
9+
import java.util.function.*;
10+
import java.util.stream.*;
811

9-
import static java.lang.foreign.MemoryLayout.PathElement.groupElement;
12+
import static java.lang.foreign.ValueLayout.*;
13+
import static java.lang.foreign.MemoryLayout.PathElement.*;
1014

1115
/**
1216
* {@snippet lang=c :

java-does-usb/src/main/java/net/codecrete/usb/macos/gen/mach/mach.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22

33
package net.codecrete.usb.macos.gen.mach;
44

5+
import java.lang.invoke.*;
56
import java.lang.foreign.*;
6-
import java.lang.invoke.MethodHandle;
7-
import java.lang.invoke.MethodHandles;
8-
import java.util.Arrays;
9-
import java.util.stream.Collectors;
7+
import java.nio.ByteOrder;
8+
import java.util.*;
9+
import java.util.function.*;
10+
import java.util.stream.*;
1011

11-
import static java.lang.foreign.ValueLayout.JAVA_BYTE;
12+
import static java.lang.foreign.ValueLayout.*;
13+
import static java.lang.foreign.MemoryLayout.PathElement.*;
1214

1315
public class mach {
1416

0 commit comments

Comments
 (0)