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

Help with kotlin-js #28

Open
ericvergnaud opened this issue Feb 8, 2024 · 17 comments
Open

Help with kotlin-js #28

ericvergnaud opened this issue Feb 8, 2024 · 17 comments

Comments

@ericvergnaud
Copy link
Contributor

ericvergnaud commented Feb 8, 2024

Hi @KvanTTT @bashor

I'm experimenting with Kotlin/Wasm and facing an issue you might be able to help with...

I've downloaded kotlinc 2.0.0-Beta3, and kotlinc-js -version shows the correct version.

When I run:

kotlinc-js src/main/kotlin/Test.kt -Xwasm -Xwasm-target=wasm -ir-output-name test.js -ir-output-dir out/wasm -kotlin-home /Users/ericvergnaud/Development/kotlinc

I get:

exception: java.lang.IllegalStateException: Class not found: kotlin/Float

How do I tell kotlin-js where to find builtins (I thought -kotlin-home was about that) ?
Btw where are they actually located ?

@lppedd
Copy link
Collaborator

lppedd commented Feb 8, 2024

IIRC you also need to provide the compiler the stdlib, e.g.:

-libraries={path-to}/kotlin-stdlib-wasm-js-{version}.jar (or .klib)

@bashor
Copy link

bashor commented Feb 8, 2024

@lppedd is right, -libraries should be what you need.

@lppedd
Copy link
Collaborator

lppedd commented Feb 8, 2024

This is the command that will work:

kotlinc-js -ir-output-dir C:\Users\edoardo.luppi\wasm\out -ir-output-name test -Xir-produce-js -libraries kotlin-stdlib-wasm-js-2.0.0-Beta3.klib -Xwasm -Xwasm-target=wasm-js Test.kt

It's not mentioned anywhere and it's what made me rethink my life in the last hour (joking, almost), but -ir-output-dir must be absolute. God's know where my hundreds of attempts had their files outputted.

@ericvergnaud
Copy link
Contributor Author

I can't seem to find that kotlin-stdlib-wasm-js-2.0.0-Beta3.klib file anywhere...

@lppedd
Copy link
Collaborator

lppedd commented Feb 8, 2024

@ericvergnaud Maven Central is the quickest solution, or locally under Gradle's cached files.

@ericvergnaud
Copy link
Contributor Author

Aaahhh... I had to import it using:

        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-stdlib-wasm-js</artifactId>
            <type>klib</type>
            <version>${kotlin.version}</version>
        </dependency>

@ericvergnaud
Copy link
Contributor Author

That resolves the cmd line errors, that said, despite using full paths, it doesn't seem to be generating anything...
Here is my cmd line:
kotlinc-js src/main/kotlin/Test.kt -Xwasm -Xwasm-target=wasm-js -ir-output-name stupid-name -ir-output-dir /Users/ericvergnaud/Development/out/wasm -kotlin-home /Users/ericvergnaud/Development/kotlinc -libraries /Users/ericvergnaud/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-wasm-js/2.0.0-Beta3/kotlin-stdlib-wasm-js-2.0.0-Beta3.klib

@lppedd
Copy link
Collaborator

lppedd commented Feb 8, 2024

@ericvergnaud try to use the same option positioning as mine. And you don't need -kotlin-home.

@KvanTTT
Copy link
Member

KvanTTT commented Feb 8, 2024

I've also tried a first attempt but got the following exception:

exception: kotlin.UninitializedPropertyAccessException: lateinit property jsFrontEndResult has not been initialized
        at org.jetbrains.kotlin.ir.backend.js.ModulesStructure.getJsFrontEndResult(klib.kt:503)
        at org.jetbrains.kotlin.ir.backend.js.KlibKt.preparePsi2Ir(klib.kt:380)
        at org.jetbrains.kotlin.ir.backend.js.KlibKt.loadIr(klib.kt:199)
        at org.jetbrains.kotlin.ir.backend.js.KlibKt.loadIr$default(klib.kt:178)
        at org.jetbrains.kotlin.backend.wasm.CompilerKt.compileToLoweredIr(compiler.kt:61)
        at org.jetbrains.kotlin.cli.js.K2JsIrCompiler.doExecute(K2JsIrCompiler.kt:356)
        at org.jetbrains.kotlin.cli.js.K2JSCompiler.doExecute(K2JSCompiler.java:181)
        at org.jetbrains.kotlin.cli.js.K2JSCompiler.doExecute(K2JSCompiler.java:72)
        at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:104)
        at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:48)
        at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:101)
        at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:79)
        at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:43)
        at org.jetbrains.kotlin.cli.common.CLITool$Companion.doMainNoExit(CLITool.kt:180)
        at org.jetbrains.kotlin.cli.common.CLITool$Companion.doMainNoExit$default(CLITool.kt:173)
        at org.jetbrains.kotlin.cli.common.CLITool$Companion.doMain(CLITool.kt:167)
        at org.jetbrains.kotlin.cli.common.CLITool.doMain(CLITool.kt)
        at org.jetbrains.kotlin.cli.js.K2JSCompiler.main(K2JSCompiler.java:101)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:568)
        at org.jetbrains.kotlin.preloading.Preloader.run(Preloader.java:87)
        at org.jetbrains.kotlin.preloading.Preloader.main(Preloader.java:44)

I'm trying to figure out what the problem is.

@bashor
Copy link

bashor commented Feb 8, 2024

It's not mentioned anywhere and it's what made me rethink my life in the last hour (joking, almost), but -ir-output-dir must be absolute. God's know where my hundreds of attempts had their files outputted.

🫣 Sorry for that. It's really wasn't intended/designed to be used from CLI, so no shortcuts and no user documentation.

@bashor
Copy link

bashor commented Feb 8, 2024

It looks like a one-step compilation for K/Wasm is broken in K2.

You can for compiler work as K1 like below and it should work:

kotlinc-js -language-version 1.9 -Xir-produce-js -Xwasm -Xwasm-target=wasm-js -no-stdlib -libraries kotlin-stdlib-wasm-js-2.0.0-Beta3.klib -ir-output-dir out -ir-output-name=mymodule Simple.kt

@bashor
Copy link

bashor commented Feb 8, 2024

For K2 you need to do two steps:

1: Produce a klib for sources

kotlinc-js -Xwasm -Xwasm-target=wasm-js -Xir-produce-klib-dir -no-stdlib -libraries kotlin-stdlib-wasm-js-2.0.0-Beta3.klib -ir-output-name mymodule -ir-output-dir mymodule-klib -Xir-per-module-output-name=mymodule Simple.kt

2: Generate an executable

kotlinc-js -Xwasm -Xwasm-target=wasm-js -Xir-produce-js -no-stdlib -libraries kotlin-stdlib-wasm-js-2.0.0-Beta3.klib -Xinclude=mymodule-klib -ir-output-dir out -ir-output-name=mymodule

@KvanTTT
Copy link
Member

KvanTTT commented Feb 8, 2024

You can for compiler work as K1 like below and it should work:

Thanks, it really works with -language-version 1.9.

For K2 you need to do two steps:

It also works on my side.

@ericvergnaud
Copy link
Contributor Author

ericvergnaud commented Feb 9, 2024

Thanks @bashor ! Works here too !

The intermediate output is somewhat puzzling...:

image

Notice there is no test-klib and no test-module being generated by the first pass...

Also note that I had to specify full paths for -libraries and -ir-output-dir.

After changing suffixes to .ts and a few tweaks, I was able to run the generated wasm in Deno (attaching the file that works for me): test-module.uninstantiated.ts.zip

Leads me to a few questions:

  • is the plan for K2 to generate a wasm in 1 pass ?
  • will this be supported by kotlin-maven-plugin ? (we need this not for us but for our users)
  • any plan (or interest) for generating typescript instead of javascript (or .d.ts files on top of the js) ?
  • any plan (or interest) for supporting Deno (see working example attached) ?

@bashor
Copy link

bashor commented Feb 9, 2024

Notice there is no test-klib and no test-module being generated by the first pass...

What is test-klib and test-module?
That you see on the picture is an unpacked klib file.

Also note that I had to specify full paths for -libraries and -ir-output-dir.

Might be OS specific bug, please file an issue.

After changing suffixes to .ts and a few tweaks, I was able to run the generated wasm in Deno

What kind of tweaks?
I think Deno should be able to run js, no need to rename.

is the plan for K2 to generate a wasm in 1 pass ?

No specific plan so far about CLI in general. Could you please provide more about your case.
Also, here is a related issue, feel free to vote and follow.

will this be supported by kotlin-maven-plugin ? (we need this not for us but for our users)

Do you ask about Kotlin Multiplatform or Kotlin/Wasm specifically? Anyway, feel free to file an issue.

any plan (or interest) for generating typescript instead of javascript (or .d.ts files on top of the js) ?

No plan for generating TS, but recently we added d.ts generation for exported declarations. It will be available in the upcoming 2.0.0-Beta4
What kind of benefit do you expect from TS instead of JS?

any plan (or interest) for supporting Deno (see working example attached)?

No specific plans for Deno support in Gradle plugin as we have for Node.js now, but if there is any issue with running generated code inside Deno we would happy to look into it. Please file an issue.

BTW, we have adhoc Deno setup in https://github.com/Kotlin/kotlin-wasm-examples/tree/main/wasi-example

@ericvergnaud
Copy link
Contributor Author

ericvergnaud commented Feb 9, 2024

Notice there is no test-klib and no test-module being generated by the first pass...

What is test-klib and test-module? That you see on the picture is an unpacked klib file.

Sorry I should have mentioned these are the names used for -ir-output-name and -Xir-per-module-output-name

Also note that I had to specify full paths for -libraries and -ir-output-dir.

Might be OS specific bug, please file an issue.

Issue filed https://youtrack.jetbrains.com/issue/KT-65711/kotlinc-js-requires-absolute-paths-on-MacOS-X

After changing suffixes to .ts and a few tweaks, I was able to run the generated wasm in Deno

What kind of tweaks? I think Deno should be able to run js, no need to rename.

Deno is able to run .js, but the generated files have an .mjs suffix. Deno related tools such as he WebStorm Deno plugin do not recognize .mjs as Deno files.

Re weaks, they were required because the xxx.uninstantiated.mjs file detects Node, and in its absence falls back to browser, using fetch to load the Wasm bytes, which fails with a local file. See the example attached in my previous post, and in https://youtrack.jetbrains.com/issue/KT-65713/kotlinc-js-for-wasm-generates-a-wrapper-that-cannot-run-in-Deno

is the plan for K2 to generate a wasm in 1 pass ?

No specific plan so far about CLI in general. Could you please provide more about your case. Also, here is a related issue, feel free to vote and follow.

Seems I am not allowed to access this issue...

will this be supported by kotlin-maven-plugin ? (we need this not for us but for our users)

Do you ask about Kotlin Multiplatform or Kotlin/Wasm specifically? Anyway, feel free to file an issue.

I'm asking about Kotlin/Wasm specifically.
I filed an issue here: https://youtrack.jetbrains.com/issue/KT-65717/Missing-support-for-Kotlin-Wasm-in-kotlin-maven-plugin

any plan (or interest) for generating typescript instead of javascript (or .d.ts files on top of the js) ?

No plan for generating TS, but recently we added d.ts generation for exported declarations. It will be available in the upcoming 2.0.0-Beta4 What kind of benefit do you expect from TS instead of JS?

The benefit is static typing. Noted re 2.0.0-Beta4, thanks.

any plan (or interest) for supporting Deno (see working example attached)?

No specific plans for Deno support in Gradle plugin as we have for Node.js now, but if there is any issue with running generated code inside Deno we would happy to look into it. Please file an issue.

Done. See https://youtrack.jetbrains.com/issue/KT-65713/kotlinc-js-for-wasm-generates-a-wrapper-that-cannot-run-in-Deno

This is not about the Gradle plugin, but about kotlinc-js. The generated code does not work with Deno.

BTW, we have adhoc Deno setup in https://github.com/Kotlin/kotlin-wasm-examples/tree/main/wasi-example

Thanks. To your knowledge, does it work with 2.0.0-Beta4 ?

@ericvergnaud
Copy link
Contributor Author

For tracking purpose, working cmd lines are:

kotlinc-js -Xwasm -Xwasm-target=wasm-js -Xir-produce-klib-dir -no-stdlib -libraries /Users/ericvergnaud/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-wasm-js/2.0.0-Beta3/kotlin-stdlib-wasm-js-2.0.0-Beta3.klib -ir-output-name test-klib -ir-output-dir /Users/ericvergnaud/Development/wasm/klib -Xir-per-module-output-name=test-module src/main/kotlin/Test.kt

followed by:

kotlinc-js -Xwasm -Xwasm-target=wasm-js -Xir-produce-js -no-stdlib -libraries /Users/ericvergnaud/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-wasm-js/2.0.0-Beta3/kotlin-stdlib-wasm-js-2.0.0-Beta3.klib -Xinclude=/Users/ericvergnaud/Development/wasm/klib -ir-output-dir /Users/ericvergnaud/Development/wasm/wasm -ir-output-name=test-module

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

4 participants