Skip to content

Commit

Permalink
Improve Gradle DSL in docs (JetBrains#3481)
Browse files Browse the repository at this point in the history
  • Loading branch information
ilmat192 authored Oct 25, 2019
1 parent b8df05e commit 61702a6
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 24 deletions.
75 changes: 55 additions & 20 deletions FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,19 @@ garbage.
### Q: How do I create a shared library?

A: Use the `-produce dynamic` compiler switch, or `binaries.sharedLib()` in Gradle, i.e.
```groovy
targets {
fromPreset(presets.iosArm64, 'mylib') {

<div class="sample" markdown="1" theme="idea" mode="kotlin" data-highlight-only>

```kotlin
kotlin {
iosArm64("mylib") {
binaries.sharedLib()
}
}
```

</div>

It will produce a platform-specific shared object (.so on Linux, .dylib on macOS, and .dll on Windows targets) and a
C language header, allowing the use of all public APIs available in your Kotlin/Native program from C/C++ code.
See `samples/python_extension` for an example of using such a shared object to provide a bridge between Python and
Expand All @@ -32,13 +38,19 @@ Kotlin/Native.
### Q: How do I create a static library or an object file?

A: Use the `-produce static` compiler switch, or `binaries.staticLib()` in Gradle, i.e.
```groovy
targets {
fromPreset(presets.iosArm64, 'mylib') {

<div class="sample" markdown="1" theme="idea" mode="kotlin" data-highlight-only>

```kotlin
kotlin {
iosArm64("mylib") {
binaries.staticLib()
}
}
```

</div>

It will produce a platform-specific static object (.a library format) and a C language header, allowing you to
use all the public APIs available in your Kotlin/Native program from C/C++ code.

Expand All @@ -54,26 +66,47 @@ or set it via the `JAVA_OPTS` environment variable.

A: Use the `-module-name` compiler option or matching Gradle DSL statement, i.e.

<div class="multi-language-sample" data-lang="kotlin">
<div class="sample" markdown="1" theme="idea" mode="kotlin" data-highlight-only>

```kotlin
kotlin {
iosArm64("myapp") {
binaries.framework {
freeCompilerArgs += listOf("-module-name", "TheName")
}
}
}
```

</div>
</div>

<div class="multi-language-sample" data-lang="groovy">
<div class="sample" markdown="1" theme="idea" mode="groovy">

```groovy
targets {
fromPreset(presets.iosArm64, 'myapp') {
binaries.framework()
compilations.main.extraOpts '-module-name', 'TheName'
kotlin {
iosArm64("myapp") {
binaries.framework {
freeCompilerArgs += ["-module-name", "TheName"]
}
}
}
```

</div>
</div>

### Q: How do I rename the iOS framework? (default name is _\<project name\>_.framework)

A: Use the `baseName` option. This will also set the module name.

```groovy
targets {
fromPreset(presets.iosArm64, 'myapp') {
<div class="sample" markdown="1" theme="idea" mode="kotlin" data-highlight-only>

```kotlin
kotlin {
iosArm64("myapp") {
binaries {
framework {
baseName = "TheName"
Expand All @@ -83,6 +116,8 @@ targets {
}
```

</div>

### Q: How do I enable bitcode for my Kotlin framework?

A: By default gradle plugin adds it on iOS target.
Expand All @@ -92,27 +127,27 @@ A: By default gradle plugin adds it on iOS target.
Or commandline arguments: `-Xembed-bitcode` (for release) and `-Xembed-bitcode-marker` (debug)

Setting this in a Gradle DSL:
<div class="sample" markdown="1" theme="idea" mode="groovy">
<div class="sample" markdown="1" theme="idea" mode="kotlin" data-highlight-only>

```groovy
targets {
fromPreset(presets.iosArm64, 'myapp') {
```kotlin
kotlin {
iosArm64("myapp") {
binaries {
framework {
// Use "marker" to embed the bitcode marker (for debug builds).
// Use "disable" to disable embedding.
embedBitcode "bitcode" // for release binaries.
embedBitcode("bitcode") // for release binaries.
}
}
}
}
```

</div>

These options have nearly the same effect as clang's `-fembed-bitcode`/`-fembed-bitcode-marker`
and swiftc's `-embed-bitcode`/`-embed-bitcode-marker`.

</div>

### Q: Why do I see `InvalidMutabilityException`?

A: It likely happens, because you are trying to mutate a frozen object. An object can transfer to the
Expand Down
31 changes: 27 additions & 4 deletions OBJC_INTEROP.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,13 +237,16 @@ but the features supported retain meaningful information.
Generics are currently not enabled by default. To have the framework header written with generics, add an experimental
flag to the compiler config:

```
compilations.main {
outputKinds("framework")
extraOpts "-Xobjc-generics"
<div class="sample" markdown="1" theme="idea" data-highlight-only>

```kotlin
binaries.framework {
freeCompilerArgs += "-Xobjc-generics"
}
```

</div>

#### Limitations

Objective-C generics do not support all features of either Kotlin or Swift, so there will be some information lost
Expand All @@ -256,48 +259,68 @@ Generics can only be defined on classes, not on interfaces (protocols in Objc an
Kotlin and Swift both define nullability as part of the type specification, while Objc defines nullability on methods
and properties of a type. As such, the following:

<div class="sample" markdown="1" theme="idea" data-highlight-only>

```kotlin
class Sample<T>(){
fun myVal():T
}
```

</div>

will (logically) look like this:

<div class="sample" markdown="1" theme="idea" mode="swift">

```swift
class Sample<T>(){
fun myVal():T?
}
```

</div>

In order to support a potentially nullable type, the Objc header needs to define `myVal` with a nullable return value.

To mitigate this, when defining your generic classes, if the generic type should *never* be null, provide a non-null
type constraint:

<div class="sample" markdown="1" theme="idea" data-highlight-only>

```kotlin
class Sample<T:Any>(){
fun myVal():T
}
```

</div>

That will force the Objc header to mark `myVal` as non-null.

#### Variance

Objective-C allows generics to be declared covariant or contravariant. Swift has no support for variance. Generic classes coming
from Objective-C can be force-cast as needed.

<div class="sample" markdown="1" theme="idea" data-highlight-only>

```kotlin
data class SomeData(val num:Int = 42):BaseData()
class GenVarOut<out T:Any>(val arg:T)
```

</div>

<div class="sample" markdown="1" theme="idea" mode="swift">

```swift
let variOut = GenVarOut<SomeData>(arg: sd)
let variOutAny : GenVarOut<BaseData> = variOut as! GenVarOut<BaseData>
```

</div>

#### Constraints

In Kotlin you can provide upper bounds for a generic type. Objective-C also supports this, but that support is unavailable
Expand Down

0 comments on commit 61702a6

Please sign in to comment.