node-gradle / gradle-node-plugin

Gradle plugin for integrating NodeJS in your build. :rocket:
Apache License 2.0
601 stars 117 forks source link

Feature request: Provide option/configuration for used architecture #234

Open giftkugel opened 2 years ago

giftkugel commented 2 years ago

Right now the plugin tries to resolve the current system and the used architecture on its own. That's okay for most use cases.

With the new Apple M1 silicon it is not that easy to determinate the correct architecture which should be used. e.g. the plugin may choose the wrong one.

For example, I want to use darwin-x64 for node<16 and darwin-arm64 for node>=16. But the Plugin will try to load darwin-arm64 even for node<16 as long as I don't use the workaround described here: https://github.com/node-gradle/gradle-node-plugin/issues/154#issuecomment-873478814

The workaround with an extra terminal started with Rosetta2 does not work for terminals inside IDEs, or Gradle executed outside of a terminal.

I would love to have an expert option/configuration to provide the architecture which should be used on my own.

Examples

node {
    version = "12.22.7"
    arch = "x64"
}
node {
    version = "16.14.2"
    arch = "x64"
}

Of course a configuration for node=12 and arm64 would fail again, because there is no NodeJS 12.x for ARM architecture available.

node {
    version = "12.22.7"
    arch = "arm64"
}

The arch option/configuration should be optional and if used it should prevent the architecture to be detected by the plugin

deepy commented 2 years ago

If you set your JAVA_HOME to a x86_64 Java the plugin will pick a x64 node for you, IntelliJ lets you set a JVM on a project-basis (and also a separate one for Gradle)

But with Node 12 being end of life you really should consider upgrading the node version being used

And the section of the code that'd need to change to support this is... messy. I have a branch where I'm doing some exploratory development to introduce something similar to the Toolchains for JVM projects offered by Gradle which if finished would give you an additional workaround (or at least make it easier to create workarounds)

Although if someone were to make a sneaky PR that adds a property to support something like: -Pcom.github.gradle.node.aarch.forcearch=x64 (provided it doesn't break the configuration-cache support) it could probably be merged and be a workaround until I've had a chance to rework the gnarly bits

giftkugel commented 2 years ago

Thank you for the answer

If you set your JAVA_HOME to a x86_64 Java the plugin will pick a x64 node for you, IntelliJ lets you set a JVM on a project-basis (and also a separate one for Gradle)

Hmm, may work. But I want to keep Java as arm64 because it is significantly faster without emulation over Rosetta 2.
So I only want NodeJS to work and because I am somehow pinned to version 12 in that project, I would need to use it as x86_64 (because there is no arm64 for version 12).
For NodeJS I can live without arm64, because performance in that case is not important.

But with Node 12 being end of life you really should consider upgrading the node version being used

I know, but sometimes it is not up to me to decide about that. 😆

Although if someone were to make a sneaky PR that adds a property to support something like: -Pcom.github.gradle.node.aarch.forcearch=x64

Have to find out what that means 😁

thouseef commented 2 years ago

In my project, we are at Node 10, and I'm not sure they would let me upgrade at all.

@giftkugel , Thanks for raising this! I am also of the same opinion. Don't want to change my JVM, but only get node running.

Did you manage to find out what the below means?

Although if someone were to make a sneaky PR that adds a property to support something like: -Pcom.github.gradle.node.aarch.forcearch=x64

deepy commented 2 years ago

In Gradle 6+ it's ProviderFactory.gradleProperty(String) and in Gradle 5 it's Project.property(String)

giftkugel commented 2 years ago

@thouseef I was able to force an Intel version of Node on my M1 Mac by using the os.arch system property. Because it is used in the code to determinate the architecture

https://github.com/node-gradle/gradle-node-plugin/blob/9364519c99049e3eea0a69a07843ed5189ad23cd/src/main/kotlin/com/github/gradle/node/util/PlatformHelper.kt#L19

For example:./gradlew build -Dos.arch='x86_64'

But this system property is also. used by Gradle ... so Gradle then also treats my System as x86_64

./gradlew --no-daemon --version -Dos.arch='x86_64'

------------------------------------------------------------
Gradle 7.2
------------------------------------------------------------

Build time:   2021-08-17 09:59:03 UTC
Revision:     a773786b58bb28710e3dc96c4d1a7063628952ad

Kotlin:       1.5.21
Groovy:       3.0.8
Ant:          Apache Ant(TM) version 1.10.9 compiled on September 27 2020
JVM:          11.0.15 (Azul Systems, Inc. 11.0.15+10-LTS)
OS:           Mac OS X 12.4 x86_64

Without that system property

./gradlew --no-daemon --version

------------------------------------------------------------
Gradle 7.2
------------------------------------------------------------

Build time:   2021-08-17 09:59:03 UTC
Revision:     a773786b58bb28710e3dc96c4d1a7063628952ad

Kotlin:       1.5.21
Groovy:       3.0.8
Ant:          Apache Ant(TM) version 1.10.9 compiled on September 27 2020
JVM:          11.0.15 (Azul Systems, Inc. 11.0.15+10-LTS)
OS:           Mac OS X 12.4 aarch64