Skip to content

Commit f8361d5

Browse files
authored
feat: deffile options (#4405)
1 parent d2fb6e0 commit f8361d5

File tree

7 files changed

+307
-211
lines changed

7 files changed

+307
-211
lines changed

docs/images/gradle/gradle-sync.png

29.5 KB
Loading

docs/kr.tree

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@
207207
<toc-element accepts-web-file-names="basic-kotlin-native-app.html,kotlin-native-with-clion.html,targeting-multiple-platforms.html" topic="native-get-started.md"/>
208208
<toc-element topic="native-gradle.md"/>
209209
<toc-element topic="native-command-line-compiler.md"/>
210+
<toc-element topic="native-definition-file.md"/>
210211
<toc-element toc-title="C interop">
211212
<toc-element topic="native-c-interop.md"/>
212213
<toc-element topic="mapping-primitive-data-types-from-c.md"/>
@@ -431,4 +432,4 @@
431432
<toc-element toc-title="Press kit" href="https://kotlinlang.org/assets/kotlin-media-kit.pdf"/>
432433
<toc-element hidden="true" topic="test-page.md"/>
433434
</toc-element>
434-
</instance-profile>
435+
</instance-profile>

docs/topics/multiplatform/multiplatform-configure-compilations.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -316,14 +316,15 @@ The publication of this target is handled by the Kotlin plugin and doesn't requi
316316
Kotlin provides [interoperability with native languages](native-c-interop.md) and DSL to configure this for a specific
317317
compilation.
318318

319-
| Native language | Supported platforms | Comments |
320-
|-----------------|---------------------|----------|
321-
| C | All platforms, except for WebAssembly | |
322-
| Objective-C | Apple platforms (macOS, iOS, watchOS, tvOS) | |
319+
| Native language | Supported platforms | Comments |
320+
|-----------------------|---------------------------------------------|---------------------------------------------------------------------------|
321+
| C | All platforms, except for WebAssembly | |
322+
| Objective-C | Apple platforms (macOS, iOS, watchOS, tvOS) | |
323323
| Swift via Objective-C | Apple platforms (macOS, iOS, watchOS, tvOS) | Kotlin can use only Swift declarations marked with the `@objc` attribute. |
324324

325-
A compilation can interact with several native libraries. Configure interoperability in the `cinterops` block of the
326-
compilation with [available parameters](multiplatform-dsl-reference.md#cinterops).
325+
A compilation can interact with several native libraries. Configure interoperability with available properties in the
326+
[definition file](native-definition-file.md) or in the [`cinterops` block](multiplatform-dsl-reference.md#cinterops) of
327+
your build file:
327328

328329
<tabs group="build-script">
329330
<tab title="Kotlin" group-key="kotlin">

docs/topics/multiplatform/multiplatform-dsl-reference.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,12 +370,12 @@ To provide an interop with a library, add an entry to `cinterops` and define its
370370

371371
| **Name** | **Description** |
372372
|------------------|-------------------------------------------------------|
373-
| `definitionFile` | The `.def` file describing the native API. |
373+
| `definitionFile` | The `.def` file describing the native API. |
374374
| `packageName` | Package prefix for the generated Kotlin API. |
375375
| `compilerOpts` | Options to pass to the compiler by the cinterop tool. |
376376
| `includeDirs` | Directories to look for headers. |
377-
378-
Learn more how to [configure interop with native languages](multiplatform-configure-compilations.md#configure-interop-with-native-languages).
377+
| `header` | Header to be included in the bindings. |
378+
| `headers` | The list of headers to be included in the bindings. |
379379

380380
<tabs group="build-script">
381381
<tab title="Kotlin" group-key="kotlin">
@@ -400,6 +400,10 @@ kotlin {
400400

401401
// A shortcut for includeDirs.allHeaders.
402402
includeDirs("include/directory", "another/directory")
403+
404+
// Header files to be included in the bindings.
405+
header("path/to/header.h")
406+
headers("path/to/header1.h", "path/to/header2.h")
403407
}
404408

405409
val anotherInterop by cinterops.creating { /* ... */ }
@@ -432,6 +436,10 @@ kotlin {
432436
433437
// A shortcut for includeDirs.allHeaders.
434438
includeDirs("include/directory", "another/directory")
439+
440+
// Header files to be included in the bindings.
441+
header("path/to/header.h")
442+
headers("path/to/header1.h", "path/to/header2.h")
435443
}
436444
437445
anotherInterop { /* ... */ }
@@ -444,6 +452,8 @@ kotlin {
444452
</tab>
445453
</tabs>
446454

455+
For more cinterop properties, see [Definition file](native-definition-file.md#properties).
456+
447457
### Android targets
448458

449459
The Kotlin Multiplatform plugin contains two specific functions for android targets.

docs/topics/native/native-c-interop.md

Lines changed: 6 additions & 194 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[//]: # (title: Interoperability with C)
22

33
> The C libraries import is [Experimental](components-stability.md#stability-levels-explained).
4-
> All Kotlin declarations generated by the `cinterop` tool from C libraries
4+
> All Kotlin declarations generated by the cinterop tool from C libraries
55
> should have the `@ExperimentalForeignApi` annotation.
66
>
77
> Native platform libraries shipped with Kotlin/Native (like Foundation, UIKit, and POSIX),
@@ -12,12 +12,12 @@
1212
Kotlin/Native follows the general tradition of Kotlin to provide excellent
1313
existing platform software interoperability. In the case of a native platform,
1414
the most important interoperability target is a C library. So Kotlin/Native
15-
comes with a `cinterop` tool, which can be used to quickly generate
15+
comes with a cinterop tool, which can be used to quickly generate
1616
everything needed to interact with an external library.
1717

1818
The following workflow is expected when interacting with the native library:
1919
1. Create a `.def` file describing what to include into bindings.
20-
2. Use the `cinterop` tool to produce Kotlin bindings.
20+
2. Use the cinterop tool to produce Kotlin bindings.
2121
3. Run the Kotlin/Native compiler on an application to produce the final executable.
2222

2323
The interoperability tool analyses C headers and produces a "natural" mapping of
@@ -58,177 +58,7 @@ Run the client:
5858

5959
## Create bindings for a new library
6060

61-
To create bindings for a new library, start from creating a `.def` file.
62-
Structurally it's a simple property file, which looks like this:
63-
64-
```c
65-
headers = png.h
66-
headerFilter = png.h
67-
package = png
68-
```
69-
70-
Then run the `cinterop` tool with something like this (note that for host libraries that are not included
71-
in the sysroot search paths, headers may be needed):
72-
73-
```bash
74-
cinterop -def png.def -compiler-option -I/usr/local/include -o png
75-
```
76-
77-
This command will produce a `png.klib` compiled library and
78-
`png-build/kotlin` directory containing Kotlin source code for the library.
79-
80-
If the behavior for a certain platform needs to be modified, you can use a format like
81-
`compilerOpts.osx` or `compilerOpts.linux` to provide platform-specific values
82-
to the options.
83-
84-
Note that the generated bindings are generally platform-specific, so if you are developing for
85-
multiple targets, the bindings need to be regenerated.
86-
87-
After the generation of bindings, they can be used by the IDE as a proxy view of the
88-
native library.
89-
90-
For a typical Unix library with a config script, the `compilerOpts` will likely contain
91-
the output of a config script with the `--cflags` flag (maybe without exact paths).
92-
93-
The output of a config script with `--libs` will be passed as a `-linkedArgs` `kotlinc`
94-
flag value (quoted) when compiling.
95-
96-
### Select library headers
97-
98-
When library headers are imported to a C program with the `#include` directive,
99-
all of the headers included by these headers are also included in the program.
100-
So all header dependencies are included in generated stubs as well.
101-
102-
This behavior is correct but it can be very inconvenient for some libraries. So
103-
it is possible to specify in the `.def` file which of the included headers are to
104-
be imported. The separate declarations from other headers can also be imported
105-
in case of direct dependencies.
106-
107-
#### Filter headers by globs
108-
109-
It is possible to filter headers by globs using filter properties from the `.def` file.
110-
They are treated as a space-separated list of globs.
111-
112-
* To include declarations from headers, use the `headerFilter` property. If the included header matches any of the globs,
113-
the declarations are included in the bindings.
114-
115-
The globs are applied to the header paths relative to the appropriate include path elements,
116-
for example, `time.h` or `curl/curl.h`. So if the library is usually included with `#include <SomeLibrary/Header.h>`,
117-
it would probably be correct to filter headers with the following filter:
118-
119-
```none
120-
headerFilter = SomeLibrary/**
121-
```
122-
123-
If `headerFilter` is not provided, all the headers are included. However, we encourage you to use `headerFilter`
124-
and specify the glob as precisely as possible. In this case, the generated library contains only the necessary
125-
declarations. It can help avoid various issues when upgrading Kotlin or tools in your development environment.
126-
127-
* To exclude specific headers, use the `excludeFilter` property.
128-
129-
It can be helpful to remove redundant or problematic headers and optimize compilation,
130-
as declarations from the specified headers are not included into the bindings.
131-
132-
```none
133-
excludeFilter = SomeLibrary/time.h
134-
```
135-
136-
> If the same header is both included with `headerFilter`, and excluded with `excludeFilter`, the latter will have a higher
137-
> priority. The specified header will not be included into the bindings.
138-
>
139-
{style="note"}
140-
141-
#### Filter headers by module maps
142-
143-
Some libraries have proper `module.modulemap` or `module.map` files in their
144-
headers. For example, macOS and iOS system libraries and frameworks do.
145-
The [module map file](https://clang.llvm.org/docs/Modules.html#module-map-language)
146-
describes the correspondence between header files and modules. When the module
147-
maps are available, the headers from the modules that are not included directly
148-
can be filtered out using the experimental `excludeDependentModules` option of the
149-
`.def` file:
150-
151-
```c
152-
headers = OpenGL/gl.h OpenGL/glu.h GLUT/glut.h
153-
compilerOpts = -framework OpenGL -framework GLUT
154-
excludeDependentModules = true
155-
```
156-
157-
When both `excludeDependentModules` and `headerFilter` are used, they are
158-
applied as an intersection.
159-
160-
### C compiler and linker options
161-
162-
Options passed to the C compiler (used to analyze headers, such as preprocessor definitions) and the linker
163-
(used to link final executables) can be passed in the definition file as `compilerOpts` and `linkerOpts`
164-
respectively. For example:
165-
166-
```c
167-
compilerOpts = -DFOO=bar
168-
linkerOpts = -lpng
169-
```
170-
171-
Target-specific options only applicable to the certain target can be specified as well:
172-
173-
```c
174-
compilerOpts = -DBAR=bar
175-
compilerOpts.linux_x64 = -DFOO=foo1
176-
compilerOpts.macos_x64 = -DFOO=foo2
177-
```
178-
179-
With such a configuration, C headers will be analyzed with `-DBAR=bar -DFOO=foo1` on Linux and
180-
with `-DBAR=bar -DFOO=foo2` on macOS .
181-
Note that any definition file option can have both common and the platform-specific part.
182-
183-
#### Linker errors
184-
185-
Linker errors might occur when a Kotlin library depends on C or Objective-C libraries, for example, using the [CocoaPods integration](native-cocoapods.md).
186-
If dependent libraries aren't installed locally on the machine or configured explicitly in the project build script,
187-
the "Framework not found" error occurs.
188-
189-
If you're a library author, you can help your users resolve linker errors with custom messages.
190-
To do that, add a `userSetupHint=message` property to your `.def` file or pass the `-Xuser-setup-hint` compiler option to `cinterop`.
191-
192-
### Add custom declarations
193-
194-
Sometimes it is required to add custom C declarations to the library before
195-
generating bindings (e.g., for [macros](#macros)). Instead of creating an
196-
additional header file with these declarations, you can include them directly
197-
to the end of the `.def` file, after a separating line, containing only the
198-
separator sequence `---`:
199-
200-
```c
201-
headers = errno.h
202-
203-
---
204-
205-
static inline int getErrno() {
206-
return errno;
207-
}
208-
```
209-
210-
Note that this part of the `.def` file is treated as part of the header file, so
211-
functions with the body should be declared as `static`.
212-
The declarations are parsed after including the files from the `headers` list.
213-
214-
### Include a static library in your klib
215-
216-
Sometimes it is more convenient to ship a static library with your product,
217-
rather than assume it is available within the user's environment.
218-
To include a static library into `.klib` use `staticLibrary` and `libraryPaths`
219-
clauses. For example:
220-
221-
```c
222-
headers = foo.h
223-
staticLibraries = libfoo.a
224-
libraryPaths = /opt/local/lib /usr/local/opt/curl/lib
225-
```
226-
227-
When given the above snippet the `cinterop` tool will search `libfoo.a` in
228-
`/opt/local/lib` and `/usr/local/opt/curl/lib`, and if it is found include the
229-
library binary into `klib`.
230-
231-
When using such `klib` in your program, the library is linked automatically.
61+
To create bindings for a new library, first create and configure a [definition file](native-definition-file.md).
23262

23363
## Bindings
23464

@@ -240,7 +70,7 @@ All the supported C types have corresponding representations in Kotlin:
24070
Kotlin counterpart with the same width.
24171
* Pointers and arrays are mapped to `CPointer<T>?`.
24272
* Enums can be mapped to either Kotlin enum or integral values, depending on
243-
heuristics and the [definition file hints](#definition-file-hints).
73+
heuristics and the [definition file settings](native-definition-file.md#configure-enums-generation).
24474
* Structs and unions are mapped to types having fields available via the dot notation,
24575
i.e. `someStructInstance.field1`.
24676
* `typedef` are represented as `typealias`.
@@ -556,7 +386,7 @@ Every C macro that expands to a constant is represented as a Kotlin property.
556386
Other macros are not supported. However, they can be exposed manually by
557387
wrapping them with supported declarations. E.g. function-like macro `FOO` can be
558388
exposed as function `foo` by
559-
[adding the custom declaration](#add-custom-declarations) to the library:
389+
[adding the custom declaration](native-definition-file.md#add-custom-declarations) to the library:
560390

561391
```c
562392
headers = library/base.h
@@ -568,24 +398,6 @@ static inline int foo(int arg) {
568398
}
569399
```
570400

571-
### Definition file hints
572-
573-
The `.def` file supports several options for adjusting the generated bindings.
574-
575-
* `excludedFunctions` property value specifies a space-separated list of the names
576-
of functions that should be ignored. This may be required because a function
577-
declared in the C header is not generally guaranteed to be really callable, and
578-
it is often hard or impossible to figure this out automatically. This option
579-
can also be used to workaround a bug in the interop itself.
580-
581-
* `strictEnums` and `nonStrictEnums` properties values are space-separated
582-
lists of the enums that should be generated as a Kotlin enum or as integral
583-
values correspondingly. If the enum is not included into any of these lists,
584-
then it is generated according to the heuristics.
585-
586-
* `noStringConversion` property value is space-separated lists of the functions whose
587-
`const char*` parameters shall not be auto-converted as Kotlin string
588-
589401
### Portability
590402

591403
Sometimes the C libraries have function parameters or struct fields of a

0 commit comments

Comments
 (0)