This CMakeLists.txt: > cmake_minimum_required(VERSION 3.15) > find_package(Java 11 REQUIRED COMPONENTS Runtime) fails to find Java 11: > CMake Error at /usr/local/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:230 (message): > Could NOT find Java: Found unsuitable version "1.8.0.342", but required is > at least "11" (found /usr/local/bin/java, found components: Runtime) > Call Stack (most recent call first): > /usr/local/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:592 (_FPHSA_FAILURE_MESSAGE) > /usr/local/share/cmake/Modules/FindJava.cmake:309 (find_package_handle_standard_args) > CMakeLists.txt:4 (find_package) when several Java versions are installed: > $ pkg info | grep -i openjdk > bootstrap-openjdk17-17.0.1.12.1 Java Development Kit 17 > openjdk11-11.0.16+8.1 Java Development Kit 11 > openjdk17-17.0.4+8.1 Java Development Kit 17 > openjdk8-8.342.07.1 Java Development Kit 8 cmake-3.23.3 FreeBSD 13.1
I discovered this problem while working on update of cad/surelog.
When only openjdk11 is installed it is discovered fine by the above cmake script.
Moin moin Could you provide your WIP update to cad/surelog, so that we have something to reproduce against? mfg Tobias
(In reply to Tobias C. Berner from comment #3) Hi Tobias, The cad/surelog update is committed but its build fails when Java versions other than the one required there (Java 17) are present. It might also depend on the order in which Java versions were installed, I'm not sure. Yuri
(In reply to Yuri Victorovich from comment #4) OK, I'll take a look :) Have you already tried, whether just BINARY_ALIAS=java=${JAVA} does the trick? mfg Tobias
(In reply to Tobias C. Berner from comment #5) No, BINARY_ALIAS=java=${JAVA} doesn't help. It always looks for /usr/local/bin/java. Yuri
(In reply to Yuri Victorovich from comment #6) Did you ever tried to force JAVA_PORT variable in port Makefile? e.g. JAVA_PORT=java/openjdk17
(In reply to Dima Panov from comment #7) JAVA_PORT=java/openjdk17 doesn't help either. Yuri
From FindJava.cmake: 10 This module finds if Java is installed and determines where the 11 include files and libraries are. The caller may set variable ``JAVA_HOME`` 12 to specify a Java installation prefix explicitly. Apparently, setting the CMAKE_ARGS+=-DJAVA_HOME=${JAVA_HOME} does not work. But if you check /usr/local/share/cmake/Modules/CMakeFindJavaCommon.cmake you also see that it can source it from the environment variable JAVA_HOME. If you set CONFIGURE_ENV+= JAVA_HOME=${JAVA_HOME} then at least the configure stage passes without any issues. Note: the CMakeLists contains some direct 'java' calls in custom_commands, so there are likely other issues :) mfg Tobias
It seems that cmake script should use ${JAVA_HOME}/bin/java instead of just "java". And if JAVA_HOME isn't set it can either try just "java", or fail.
(In reply to Yuri Victorovich from comment #10) It should generally use ${JAVA_HOME}/bin/java [1] -- what I meant is, that the custom-commands in surelog don't use ${Java_JAVA_EXECUTABLE} but 'java' -- so even if cmake were able to find the one you want, the target would still execute the one in path :) [1] https://github.com/Kitware/CMake/blob/master/Modules/FindJava.cmake#L89
(In reply to Tobias C. Berner from comment #11) Ah, I see. Then there are 2 problems, one in cmake, and the other one in surelog. :-) I first thought that both were in cmake. I'll let them know. Yuri
After `find_package(Java)` you should be using `${Java_JAVA_EXECUTABLE}` or `${Java_JAVAC_EXECUTABLE}`, which will be the full path of the relevant executable: do not assume that they are in bin/ under the JAVA_HOME. Well, you can, and it'd be right most of the time, but there is a specific, explicit, variable for you to use. The CMake code suggests that it does obey the CMake variable JAVA_HOME (if set) and also the environment variable, so there's some experimentation to be done between running-cmake-from-command-line and running-cmake-in-ports.
CMake-time arguments -- how to get ports to do this is left as an exercise for the reader -- work. With a modified (to produce less output) CMakeLists.txt, with jdk 11, 17 and 8 installed, in that order, the following happens: ``` $ rm -rf build/ ; cmake -B build -S . CMake Error at /usr/local/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:230 (message): Could NOT find Java: Found unsuitable version "1.8.0.352", but required is at least "11" (found /usr/local/bin/java, found components: Runtime) ``` but I can set a version: ``` $ rm -rf build/ ; cmake -B build -S . -DJAVA_HOME=/usr/local/openjdk11/ -- Found Java: /usr/local/openjdk11/bin/java (found suitable version "11.0.17", minimum required is "11") found components: Runtime -- Configuring done -- Generating done -- Build files have been written to: /tmp/derp/build ``` or even a newer version: ``` $ rm -rf build/ ; cmake -B build -S . -DJAVA_HOME=/usr/local/openjdk17/ -- Found Java: /usr/local/openjdk17/bin/java (found suitable version "17.0.5", minimum required is "11") found components: Runtime -- Configuring done -- Generating done -- Build files have been written to: /tmp/derp/build ``` **do** ensure that that command-line argument gets to the CMake invocation. Note that the executable /usr/local/bin/java is a symlink to a shellscript that does all *kinds* of stuff, which eventually runs one of the registered java executables. It doesn't offer an easy (except for the environment variable JAVA_HOME) way to select a particular Java VM.