lucimber / meta-openjdk-temurin

This is a software layer for Java VMs, for use with OpenEmbedded and Yocto Project build systems. The binaries are provided by the Eclipse Temurin Project.
GNU General Public License v2.0
5 stars 3 forks source link

The prebuilt x86_64 binaries are not using the correct linker path #23

Closed zboszor closed 2 months ago

zboszor commented 5 months ago

The openjdk recipes pull prebuilt packages which definitely makes the build faster.

However, the x86_64 binaries are built for regular multilib distros, i.e. the binaries in /usr/lib/jvm/openjdk-11-jre/bin are using /lib64/ld-linux-x86-64.so.2.

However, a Yocto build may omit the DISTRO_FEATURES = multilib setting. In this case, the correct path would be /lib/ld-linux-x86-64.so.2.

I will submit a PR fixing this.

sebveit commented 5 months ago

Thanks for your participation! I wasn't aware of this. Is the multilib feature new?

zboszor commented 5 months ago

Thanks for your participation! I wasn't aware of this. Is the multilib feature new?

Not quite new. The first mention of it is from 2009 in openembedded-core.

sebveit commented 5 months ago

Ahhh, ok, with multilib flag you're thinking of https://docs.yoctoproject.org/dev/dev-manual/libraries.html#combining-multiple-versions-of-library-files-into-one-image ? But there is no such flag in DISTRO_FEATURES ... see https://docs.yoctoproject.org/dev/ref-manual/features.html Can it be, that the only flag relevant to this issue is usrmerge and maybe multiarch?

usrmerge: Merges the /bin, /sbin, /lib, and /lib64 directories into their respective counterparts in the /usr directory to provide better package and application compatibility.

multiarch: Enable building applications with multiple architecture support.

But I don't see how multiarch fits in here.. I have no clue what that really does, because the description isn't giving much information.

So what your PR does, is that it uses patchelf-native to "motivate" the binaries of the JRE to use the correct ELF interpreter. I think that's clever, but is that really necessary?

I'm going to reproduce this situation... might take a while.

zboszor commented 5 months ago

Yes, I mean exactly that. The subsections under the docs link you quoted talk about "multilib" but the flag is "multiarch". Quite confusing...

The patchelf command is indeed needed because you can't know whether path of the runtime linker for pre-built binaries are good for your embedded build because:

FWIW, the same method is in e.g. meta-mono here: https://github.com/DynamicDevices/meta-mono/blob/master/recipes-mono/dotnet/dotnet_7.0.404.bb#L75

Since the arm, aarch64 and x64 runtime linker paths are different, i.e. aarch64 is .so.1 while for x64 it's .so.2, I went a little further in this patch to detect the filename of ld-linux* and use that.

On our x64 Yocto builds usrmerge is used but multiarch is not. Therefore, the way the openjdk package is built currently, executing java is not possible.

An alternative (we used this a long time ago) which is not generic is to add the /lib -> /lib64 symlink but it's not good for any recipe because changing distro features can conflict with it.

The best way is really to use patchelf for pre-built binaries.

FWIW, that still doesn't guarantee that the pre-built binary would run on a specific Yocto build, due to library incompatibilities, if the pre-built binary uses features from a newer version of library and those symbols are not in the version Yocto ships. You have dealt with this with e.g. freetype in the kirkstone branch.

sebveit commented 5 months ago

Very nice explanation for what is going on, when usrmerge and/or multiarch is set. I've never stumbled upon this situation because my setup is rather vanilla... As soon as my build is done, I'm going to rebase and merge your changes! Thank you very much!

michaelbaisch commented 4 months ago

Hello,

I've encountered an issue with the solution to this fix. The error message I receive is:

 ls: cannot access '…/tmp/work/i686-poky-linux/openjdk-17-jre/17.0.9+11-r0/recipe-sysroot/lib/ld-linux-*': No such file or directory

Given my unique setup, where I am installing a 32-bit x86 version from bell-sw.com, in the recipe-sysroot/lib/ directory, there is only a ld-linux.so.2 file.

Therefore, I am suggesting a modification to this line from:

LDLINUX=$(basename $(ls -1 ${RECIPE_SYSROOT}${base_libdir}/ld-linux-* | sort | head -n1))

to

LDLINUX=$(basename $(ls -1 ${RECIPE_SYSROOT}${base_libdir}/ld-linux* | sort | head -n1))

Note the removal of the dash -.

sebveit commented 4 months ago

Thanks for reporting the issue. Looks like an easy fix. I will take care of it next week.

sebveit commented 2 months ago

Sorry for the delay! I've modified the recipes accordingly. It should work and I'm closing the issue now. Feel free to open a new issue if you encounter another problem.