Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add example to configure linker args #833

Open
bric3 opened this issue Apr 3, 2023 · 4 comments
Open

Add example to configure linker args #833

bric3 opened this issue Apr 3, 2023 · 4 comments

Comments

@bric3
Copy link

bric3 commented Apr 3, 2023

For example in Kotlin DSL

import dev.nokee.platform.nativebase.ExecutableBinary

/*
 * sandbox
 *
 * Copyright (c) 2021,today - Brice Dutheil <[email protected]>
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */
plugins {
    id("dev.nokee.c-application")
}

application {
    binaries.configureEach(ExecutableBinary::class.java) {
        baseName.set("test-dlopen")
        linkTask {
            linkerArgs.add("-ldl")
        }
    }
}

Also I wonder if the API could be make more kotlin friendly, so one could write

binaries.configureEach<ExecutableBinary> {
  ...
}
@bric3
Copy link
Author

bric3 commented Apr 3, 2023

Oh actually there's one with the objective c plugin. But stil it would be nice to have in the C plugins.

@lacasseio
Copy link
Member

You are right; we should expand the samples. As for making the DSL more friendly to Kotlin, we aren't Kotlin experts. If you could help us by pointing out the Kotlin concept for these types of Kotlin-friendly methods, we can look into adding them.

@bric3
Copy link
Author

bric3 commented Apr 19, 2023

Mhh about kotlin friendly API, this might require writing kotlin code. For example the method withType on the task container have this Java API,

DomainObjectCollection {
  // ...
  <S extends T> DomainObjectCollection<S> withType(Class<S> type, Action<? super S> configureAction);
}

and usable in Groovy DSL or Kotlin DSL

tasks.withType(JavaExec) {
    
}
tasks.withType(JavaExec::class.java) {
    
}

However to improve the friendliness of the kotlin DSL API

tasks.withType<JavaExec>() {
    
}

There are extension function

inline fun <reified S : Any> DomainObjectCollection<in S>.withType(noinline configuration: S.() -> Unit) =
    withType(S::class.java, configuration)

This function declaration might be daunting at first as there are 6 different concepts there

  1. inline, in Kotlin an inline function tells the compiler to put the bytecode instructions where the method is referenced. This function is like a C/C++ macro.

    https://kotlinlang.org/docs/inline-functions.html

  2. <reified S : Any> this is a generic declaration, equivalent to <S extends Object> (Any in kotlin is an alias to Object) ; the reified keyword means the generic information is not erased as in Java, however this require the function to be inline.

    DomainObjectCollection<in S> is the reference to the generic variable, and is somewhat equivalent to DomainObjectCollection<? super S> in Java

    https://kotlinlang.org/docs/generics.html

  3. noinline configuration: S.() -> Unit, the no inline simply indicates the compiler to not inline the body of the lambda. The lambda has the type S.() -> Unit. There's no type between the parenthesis (), so there's no args and Unit is like void in Java, so this is equivalent to a Java Runnable ; the interesting bit here is S.(), it means S is the receiver type meaning that this within the lambda is of type S. The receiver type are really powerful to write convenient DSLs.

    https://kotlinlang.org/docs/lambdas.html
    https://kotlinlang.org/docs/lambdas.html#function-literals-with-receiver

  4. ... fun ... .withType(...) = withType(S::class.java, configuration) means this function has a single statement, and as such kotlin offer a short hand = instead of writing { return withType(S::class.java, configuration) } ; also note the return type can be omitted in this declaration just like var s = "Hello" can be omitted in Java.

    https://kotlinlang.org/docs/functions.html#single-expression-functions

  5. S::class.java Like in groovy kotlin has it's own class reference and in order here to link to the right java API, it is necessary to access the Java Class. In this function this notation works because S is reified.

    https://kotlinlang.org/docs/reflection.html#class-references

  6. Additionally there's a 6th concept on the "callsite", in kotlin if the last parameter is a lambda it can be written outside the method ; this should be similar to Groovy. Both notation ate the same

    tasks.withType<JavaExec>({ })
    tasks.withType<JavaExec>() {
        
    }

@lacasseio
Copy link
Member

Thanks a lot for the information. I will see what I can do about that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants