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

[native-image] Cross compilation support? #407

Open
sureshg opened this issue May 6, 2018 · 72 comments
Open

[native-image] Cross compilation support? #407

sureshg opened this issue May 6, 2018 · 72 comments
Assignees
Labels

Comments

@sureshg
Copy link

sureshg commented May 6, 2018

Any plans to add cross-compilation feature to native-image? I know it's too early to ask for these kind of requirements since we don't even have a working Windows build. IMHO, this would be a nice feature (golang has nice support for it) to have especially if we want to build binaries for all platforms from a CI (Jenkins) machine.

https://medium.com/@chrisgseaton/i-dont-think-we-have-any-immediate-plans-for-cross-compilation-but-it-s-not-a-major-problem-to-bf789384beaa

@thomaswue thomaswue self-assigned this May 6, 2018
@plombardi89
Copy link

Definitely would love to see this feature! This would make it so much nicer to use Java for CLI apps and servers that need to be distributed to users on Linux, Mac and Windows.

@alza-bitz
Copy link

It would be amazing to have cross-compilation support. Is this still not planned for yet, or is it dependent on the Windows build? It would still be useful to have cross-compilation available to create Mac binaries on a (Linux) CI server, and then add support for Windows cross-compilation later?

@alza-bitz
Copy link

@thomaswue @chrisseaton I was just wondering if this is on the roadmap for 2019, or has any ETA etc? I think it would be a game-changer!

@alza-bitz
Copy link

@thomaswue @chrisseaton I was just wondering if this is on the roadmap for 2019, or has any ETA etc? I think it would be a game-changer!

Hi @thomaswue @chrisseaton since we're halfway through the year, I just thought I'd check in on this one..

Has there been any development on this issue, or any news/progress to report?

Thanks in advance! 🙂

sgammon added a commit to sgammon/elide-archive that referenced this issue Feb 6, 2020
- Support building via `native-image`
- Support pushing to container repo for native image
- No cross-platform build support yet (oracle/graal#407)
sgammon added a commit to sgammon/elide-archive that referenced this issue Feb 6, 2020
* Feature: Packaging

This changeset introduces initial packaging for Gust, and for apps
that use Gust. Changes so far:

- [x] Fixup package for eventual publish to `npm`
- [x] Add support for GitHub packages
- [x] Add support for `rules_docker` targets
- [x] Add support for tarball targets

* Update Micronaut -> 1.3.0

* Upgrade Yarn dependencies

* Upgrade Bazel dependencies

* Fixes and functionality for crosslib builds

- Fix defs when used in a cross-lib context
- Fix DOM test
- Tighten up DualStackTest

* Initial support for container targets

- Add Java container target
- Add example push command (currently blocked on
  bazelbuild/rules_docker#1413)

* Re-enable container tag via BUILD_SCM_VERSION

* Fix workspace status command file

* Working container build-and-run flow

- Ability to build Java app containers, and push them to GCR
- Tested containers locally (manually for now)

* Update fork of rules_closure

* Remove forced JDK8 build flags

* Update J2CL with static bootclasspath

* Update rules_graal with new attrs for debugging

* Initial build flow for Graal native binary targets

- Setup build lib
- Attach to Graal image
- Override default compiler path (workaround for Bazel bug)

* Re-enable disk caching in CI

* Native binary support, with container image

- Support building via `native-image`
- Support pushing to container repo for native image
- No cross-platform build support yet (oracle/graal#407)

* Fix injected testdeps

* Don't enable native targets without a flag

* Add CI routine for baking samples

* Cleaner CI flow

* Attempt GCR auth fix, flush keys

* Another credentials fix

* Fix Bazel label in regular CI job

* Try auth via gcloud

* Explicitly activate gcloud key

* Apply new auth to sample image build

* Fixup key paths in CI

* Move GCP install step up in CI flow

* Cleanup CI configs

* Use relative access to service key from env

* Unify image bake, restore Docker index pull

* Add base container build file

* Use new base container
@sureshg
Copy link
Author

sureshg commented Feb 28, 2020

@thomaswue Now we have java 11 and windows support ready, are there any plans to consider cross-compilation support in the near future?

@thomaswue
Copy link
Member

Adding the support is quite tricky. The issue is that there are parts of the JDK initialized during the native image generation process that could be platform dependent and then end up in the image. One of the alternatives could be to offer a service for creating native images. Also, maybe one could use maybe a system like GitHub actions to build images for different platforms without the need to maintain/setup those machines. Would this help for your use cases or is true cross compilation a requirement?

@xiaodong-xie
Copy link

I do think people should have mentioned this workaround elsewhere.

I am using this https://hub.docker.com/r/oracle/graalvm-ce/ docker image, to build the native-image running on Linux, on my MacBook laptop.

@sureshg
Copy link
Author

sureshg commented Feb 29, 2020

Would this help for your use cases

@thomaswue Thanks. Yeah, GitHub action would work for OSS projects. The issue is, our build system is mostly on Linux and wants to build native-images for windows and mac (mostly for CLI apps). So the cross-compilation would have definitely helped in this scenario.

@nhoughto
Copy link

Yeah it’s not really cross compilation if you need the target platform to build it, that’s just regular old compilation. If Cross compilation is a feature being targeted all the jvm weirdness will need to be solved, I guess the question is, is/when is it a priority?

@sureshg
Copy link
Author

sureshg commented Mar 1, 2020

Here is some discussion on the current limitations - https://graalvm.slack.com/archives/CN9KSFB40/p1582755160011700

@truh
Copy link

truh commented Mar 3, 2020

Here is some discussion on the current limitations - https://graalvm.slack.com/archives/CN9KSFB40/p1582755160011700

Would it be possible to share a summary of the discussion? The slack archive can only be accessed by people that are member to the workspace.

@sureshg
Copy link
Author

sureshg commented Mar 8, 2020

@truh

Christian Wimmer : 
No, cross compilation between different OS is more or less impossible in
 the current approach because OS specific JDK classes need to be loaded 
in the image generator

The biggest problem is, e.g., the file system and network stack. The JDK code
 for that is very different for Linux, MacOS, and Windows. You cannot load the 
code from two platforms at the same time, but you need to load the code from 
the platform that the image generator runs on.

@CircuitRCAY
Copy link

Anything on cross compiling between architectures? (x86_64 -> arm64, for example)

@8Keep
Copy link

8Keep commented Nov 5, 2020

This is pretty huge for me. Is there any future plan at all to find a way to do this?

@SaraDark
Copy link

+1000 to Cross compilation support

@tuhuynh27
Copy link

+10000 to Cross compilation support

loicrouchon added a commit to loicrouchon/symly that referenced this issue Nov 17, 2021
The complexity of setting a build pipeline for GraalVM native image
and having access to both macOs/linux for both x64 and ARM architecture
is too much of an overhead for a small opensource project.

This might be reconsidered in the future when availability on those
OS/arch will be more widely spread or that GraalVM will offer
cross compilation support.

See oracle/graal#407
@mikehearn
Copy link
Contributor

Yes, but that may not arrive any time soon and wouldn't solve the signing or packaging aspects, you'd still need other tools for that. I mention it here as an answer to your second part, so people who want to distribute CLI or GUI tools to desktops with local signing can know where to look.

@thomaswue
Copy link
Member

@brainchild0 The state is specific to the application being translated.

In addition to this, we are depending on the local C developer tool chain a lot, so whatever cross-compilation combination we should support also needs to be available from that tool chain.

There is also the option to build within a docker container.

So, when looking at the existing workarounds such as Docker, GitHub Actions, Conveyor and the complexity of supporting all source/target platform combinations (with 5 supported platforms that would be 25), it seems like it would not be the best prioritization of engineering effort for the project at the moment. We will look more into build server setups that we can make available. Such a scenario can have additional advantages such as faster builds.

@rmannibucau
Copy link

All the mentionned solutions are at least as bad as requiring a local stack and most are more impacting like requiring to oss the project, to pay or just to not be able to run locally. All that are blockers to a solution to this issue so please invest in cross chains more than platforms which are just the current workaround.

@brainchild0
Copy link

In addition to this, we are depending on the local C developer tool chain a lot, so whatever cross-compilation combination we should support also needs to be available from that tool chain.

Such a constraint by itself is not particularly limiting. Cross-compilation solutions have evolved quite substantially in the past decade, and the dissociation between build environment and build target is now rather common, and available without penalty.

it seems like it would not be the best prioritization of engineering effort for the project at the moment.

As previously stated, it is a matter of context and perspective . For some projects, remote builds would be a tremendous help. For others, it has no value. I think it is not completely accurate that CI is a reasonable substitute for local availability of cross-building operations, in the general case.

@NCLnclNCL
Copy link

.

@chenzhiguo
Copy link

I wonder, is there any support for cross-compilation?

@hohwille
Copy link

hohwille commented Jan 6, 2025

Also, maybe one could use maybe a system like GitHub actions to build images for different platforms without the need to maintain/setup those machines. Would this help for your use cases or is true cross compilation a requirement?

I have set this up and can build native image releases for

  • MacOS x64
  • MacOS arm64
  • Windows x64
  • Linux x64

https://github.com/devonfw/IDEasy/blob/ca658ef82ab4f49e92223109f0b6ba0dd5831388/.github/workflows/release.yml#L15C60-L15C68

However, there is no support for free runners for linux or windows on arm64 on github yet.
We already have users that want to use our OSS product on Windows@ARM laptops.
For Linux@ARM releases, we could somehow try to run another build on MacOS arm64 and there build using docker ubuntu-arm64 image if github supports such deep docker nesting...

@sgammon
Copy link

sgammon commented Jan 6, 2025

#8350 would also solve this

@hohwille
Copy link

hohwille commented Jan 7, 2025

#8350 would also solve this

Thanks for the issue link and pointing this out. That sounds awesome. We would still need different native images for different architectures (x64, amd64) but not per OS anymore. That would also mean more simplification (users cannot download a release for the wrong OS and if they are using Ubuntu via Docker in Windows the same binary could still work) and sustainability (each binary for each release must be build, uploaded, stored, downloaded, etc. with less binary release file variants you also have less waste). So 👍 for that feature request!!!

@sgammon
Copy link

sgammon commented Jan 7, 2025

@hohwille > We would still need different native images for different architectures (x64, amd64) but not per OS anymore

Using Blink, APE and Cosmo allows for fat multi-arch binaries as well as binary targeting across operating systems.

@d9j
Copy link

d9j commented Jan 8, 2025

does it still take 30 min to compile simple hello world java app?

@sureshg
Copy link
Author

sureshg commented Jan 8, 2025

@d9j The compilation is slow due to closed world analysis, but it never took anywhere close to 30 minutes for a 'hello world' program. I know you are exaggerating. Here is the latest number from the GraalVM CE dev release. - 21.9s.

❯  java --version
openjdk 25 2025-09-16
OpenJDK Runtime Environment GraalVM CE 25-dev+3.1 (build 25+3-jvmci-b01)
OpenJDK 64-Bit Server VM GraalVM CE 25-dev+3.1 (build 25+3-jvmci-b01, mixed mode, sharing)

❯  cat App.java
void main() {
 println("Hello GraalVM");
}

❯  native-image --enable-preview App
========================================================================================================================
GraalVM Native Image: Generating 'app' (executable)...
========================================================================================================================
[1/8] Initializing...                                                                                    (5.5s @ 0.18GB)
 Java version: 25+3, vendor version: GraalVM CE 25-dev+3.1
 Graal compiler: optimization level: 2, target machine: armv8.1-a
 C compiler: cc (apple, arm64, 16.0.0)
 Garbage collector: Serial GC (max heap size: 80% of RAM)
 1 user-specific feature(s):
 - com.oracle.svm.thirdparty.gson.GsonFeature
------------------------------------------------------------------------------------------------------------------------
Build resources:
 - 24.18GB of memory (75.6% of 32.00GB system memory, determined at start)
 - 10 thread(s) (100.0% of 10 available processor(s), determined at start)
[2/8] Performing analysis...  [******]                                                                   (5.1s @ 0.37GB)
    3,179 reachable types   (68.8% of    4,622 total)
    3,603 reachable fields  (42.3% of    8,520 total)
   14,711 reachable methods (42.4% of   34,733 total)
    1,013 types,     6 fields, and   120 methods registered for reflection
       57 types,    57 fields, and    52 methods registered for JNI access
        4 native libraries: -framework Foundation, dl, pthread, z
[3/8] Building universe...                                                                               (1.0s @ 0.40GB)
[4/8] Parsing methods...      [*]                                                                        (0.6s @ 0.42GB)
[5/8] Inlining methods...     [***]                                                                      (0.5s @ 0.46GB)
[6/8] Compiling methods...    [***]                                                                      (5.7s @ 0.42GB)
[7/8] Laying out methods...   [*]                                                                        (1.4s @ 0.40GB)
[8/8] Creating image...       [*]                                                                        (1.4s @ 0.47GB)
   4.77MB (38.67%) for code area:     8,461 compilation units
   7.19MB (58.27%) for image heap:   93,595 objects and 55 resources
 386.25kB ( 3.06%) for other data
  12.33MB in total
------------------------------------------------------------------------------------------------------------------------
Top 10 origins of code area:                                Top 10 object types in image heap:
   3.53MB java.base                                            1.30MB byte[] for code metadata
 909.82kB svm.jar (Native Image)                               1.24MB byte[] for java.lang.String
 100.06kB java.logging                                       912.63kB java.lang.String
  65.23kB org.graalvm.nativeimage.base                       755.23kB java.lang.Class
  46.41kB jdk.proxy2                                         276.45kB byte[] for general heap data
  33.64kB jdk.proxy1                                         276.14kB java.util.HashMap$Node
  20.41kB org.graalvm.collections                            248.36kB com.oracle.svm.core.hub.DynamicHubCompanion
  18.48kB jdk.internal.vm.ci                                 209.63kB java.lang.Object[]
  11.38kB jdk.proxy3                                         207.28kB heap alignment
   9.38kB jdk.graal.compiler                                 180.85kB java.lang.String[]
   1.87kB for 3 more packages                                  1.66MB for 922 more object types
------------------------------------------------------------------------------------------------------------------------
Recommendations:
 HEAP: Set max heap for improved and more predictable memory usage.
 CPU:  Enable more CPU features with '-march=native' for improved performance.
------------------------------------------------------------------------------------------------------------------------
                        1.0s (4.6% of total time) in 261 GCs | Peak RSS: 1.02GB | CPU load: 5.86
------------------------------------------------------------------------------------------------------------------------
Build artifacts:
 /Users/sgopal1/code/native-image-playground/app (executable)
========================================================================================================================
Finished generating 'app' in 21.9s.

❯ ./app
Hello GraalVM

@d9j
Copy link

d9j commented Jan 8, 2025

@d9j The compilation is slow due to closed world analysis, but it never took anywhere close to 30 minutes for a 'hello world' program. I know you are exaggerating. Here is the last number from the GraalVM CE dev release. - 21.9s.

❯  java --version
openjdk 25 2025-09-16
OpenJDK Runtime Environment GraalVM CE 25-dev+3.1 (build 25+3-jvmci-b01)
OpenJDK 64-Bit Server VM GraalVM CE 25-dev+3.1 (build 25+3-jvmci-b01, mixed mode, sharing)

❯  cat App.java
void main() {
 println("Hello GraalVM");
}

❯  native-image --enable-preview App
========================================================================================================================
GraalVM Native Image: Generating 'app' (executable)...
========================================================================================================================
[1/8] Initializing...                                                                                    (5.5s @ 0.18GB)
 Java version: 25+3, vendor version: GraalVM CE 25-dev+3.1
 Graal compiler: optimization level: 2, target machine: armv8.1-a
 C compiler: cc (apple, arm64, 16.0.0)
 Garbage collector: Serial GC (max heap size: 80% of RAM)
 1 user-specific feature(s):
 - com.oracle.svm.thirdparty.gson.GsonFeature
------------------------------------------------------------------------------------------------------------------------
Build resources:
 - 24.18GB of memory (75.6% of 32.00GB system memory, determined at start)
 - 10 thread(s) (100.0% of 10 available processor(s), determined at start)
[2/8] Performing analysis...  [******]                                                                   (5.1s @ 0.37GB)
    3,179 reachable types   (68.8% of    4,622 total)
    3,603 reachable fields  (42.3% of    8,520 total)
   14,711 reachable methods (42.4% of   34,733 total)
    1,013 types,     6 fields, and   120 methods registered for reflection
       57 types,    57 fields, and    52 methods registered for JNI access
        4 native libraries: -framework Foundation, dl, pthread, z
[3/8] Building universe...                                                                               (1.0s @ 0.40GB)
[4/8] Parsing methods...      [*]                                                                        (0.6s @ 0.42GB)
[5/8] Inlining methods...     [***]                                                                      (0.5s @ 0.46GB)
[6/8] Compiling methods...    [***]                                                                      (5.7s @ 0.42GB)
[7/8] Laying out methods...   [*]                                                                        (1.4s @ 0.40GB)
[8/8] Creating image...       [*]                                                                        (1.4s @ 0.47GB)
   4.77MB (38.67%) for code area:     8,461 compilation units
   7.19MB (58.27%) for image heap:   93,595 objects and 55 resources
 386.25kB ( 3.06%) for other data
  12.33MB in total
------------------------------------------------------------------------------------------------------------------------
Top 10 origins of code area:                                Top 10 object types in image heap:
   3.53MB java.base                                            1.30MB byte[] for code metadata
 909.82kB svm.jar (Native Image)                               1.24MB byte[] for java.lang.String
 100.06kB java.logging                                       912.63kB java.lang.String
  65.23kB org.graalvm.nativeimage.base                       755.23kB java.lang.Class
  46.41kB jdk.proxy2                                         276.45kB byte[] for general heap data
  33.64kB jdk.proxy1                                         276.14kB java.util.HashMap$Node
  20.41kB org.graalvm.collections                            248.36kB com.oracle.svm.core.hub.DynamicHubCompanion
  18.48kB jdk.internal.vm.ci                                 209.63kB java.lang.Object[]
  11.38kB jdk.proxy3                                         207.28kB heap alignment
   9.38kB jdk.graal.compiler                                 180.85kB java.lang.String[]
   1.87kB for 3 more packages                                  1.66MB for 922 more object types
------------------------------------------------------------------------------------------------------------------------
Recommendations:
 HEAP: Set max heap for improved and more predictable memory usage.
 CPU:  Enable more CPU features with '-march=native' for improved performance.
------------------------------------------------------------------------------------------------------------------------
                        1.0s (4.6% of total time) in 261 GCs | Peak RSS: 1.02GB | CPU load: 5.86
------------------------------------------------------------------------------------------------------------------------
Build artifacts:
 /Users/sgopal1/code/native-image-playground/app (executable)
========================================================================================================================
Finished generating 'app' in 21.9s.

❯ ./app Hello GraalVM

Thanks a lot for taking time to reply with benchmarks. I will give graal a try again . around a year ago i had quite disappointing compile times on simple app

@sgammon
Copy link

sgammon commented Jan 8, 2025

@d9j Native Image is much faster now, yeah. Size issues have also improved with the introduction of -Os.

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

No branches or pull requests