ref: 1600818848fc99eb53e0de240670b598ac490fdc
parent: b56c994b721f7cb5c5bcf09c5d695d4ae07d3052
author: Simon Tatham <anakin@pobox.com>
date: Thu Jan 6 04:03:28 EST 2022
Try to fix flakiness in the NestedVM build. I've had a lot of Puzzles nightly builds fail recently in the NestedVM stage, with a 'jar' command producing a message along these lines: java.util.zip.ZipException: attempt to write past end of STORED entry at java.base/java.util.zip.ZipOutputStream.write(ZipOutputStream.java:337) at jdk.jartool/sun.tools.jar.Main.copy(Main.java:1250) at jdk.jartool/sun.tools.jar.Main.copy(Main.java:1263) at jdk.jartool/sun.tools.jar.Main.addFile(Main.java:1211) at jdk.jartool/sun.tools.jar.Main.create(Main.java:879) at jdk.jartool/sun.tools.jar.Main.run(Main.java:319) at jdk.jartool/sun.tools.jar.Main.main(Main.java:1681) Suppressed: java.util.zip.ZipException: invalid entry size (expected 0 but got 786 bytes) at java.base/java.util.zip.ZipOutputStream.closeEntry(ZipOutputStream.java:288) at java.base/java.util.zip.ZipOutputStream.finish(ZipOutputStream.java:361) at java.base/java.util.zip.DeflaterOutputStream.close(DeflaterOutputStream.java:238) at java.base/java.util.zip.ZipOutputStream.close(ZipOutputStream.java:378) at jdk.jartool/sun.tools.jar.Main.create(Main.java:854) ... 2 more It's hard to work out exactly what this error dump means, and web-searching for the error message isn't much help because the same exception can occur in application code using java.util.zip, and most mentions on the web are about that, and not about what I want to know, which is why it might happen in the 'jar' program in particular. However, the clues visible in that message suggest that 'jar' had somehow got confused about the size of one of the files it was adding to the jar archive, in that it initially decided it was 0 bytes long and later found it was longer. That suggests a problem of excessive parallelism between the build steps, perhaps due to a missing dependency in the makefile, which might plausibly cause the 'jar' step to be running already while some file it needs to read is still being written. (Which would also explain why it doesn't happen every time.) An eyeball review of cmake/platforms/nestedvm.cmake didn't find any obvious missing dependencies. But I vaguely remembered that in some other context I'd had trouble with cmake 'add_custom_command'. So in this commit I replace all those custom commands with custom _targets_, listing the previous OUTPUT files as BYPRODUCTS. And then the dependencies are written using the target names, instead of the file names. I don't fully understand why this should make a difference. But it seems more reliable in a soak test, and still builds the right things, so I'll commit it and see if it makes the flakiness in the actual nightly builds stop happening.
--- a/cmake/platforms/nestedvm.cmake
+++ b/cmake/platforms/nestedvm.cmake
@@ -5,7 +5,8 @@
"Main-Class: PuzzleApplet\n")
include(FindJava)
-add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/PuzzleApplet.class
+add_custom_target(nvm-puzzle-applet
+ BYPRODUCTS ${CMAKE_BINARY_DIR}/PuzzleApplet.class
COMMAND ${Java_JAVAC_EXECUTABLE}
-source 1.7 -target 1.7 -d . -cp ${NESTEDVM}/build
${CMAKE_SOURCE_DIR}/PuzzleApplet.java
@@ -18,9 +19,12 @@
function(set_platform_gui_target_properties TARGET)
set(build_subdir ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}-tmp)
- add_custom_command(OUTPUT ${build_subdir}
+ add_custom_target(${TARGET}-nvm-build-subdir
+ BYPRODUCTS ${build_subdir}
COMMAND ${CMAKE_COMMAND} -E make_directory ${build_subdir})
- add_custom_command(OUTPUT ${build_subdir}/PuzzleApplet.class
+
+ add_custom_target(${TARGET}-nvm-symlinks
+ BYPRODUCTS ${build_subdir}/PuzzleApplet.class
COMMAND ${CMAKE_SOURCE_DIR}/cmake/glob-symlinks.py
${CMAKE_BINARY_DIR} applet.manifest
${CMAKE_BINARY_DIR} PuzzleApplet\\*.class
@@ -31,17 +35,18 @@
${NESTEDVM}/build org/ibex/nestedvm/util/Seekable\\*.class
WORKING_DIRECTORY ${build_subdir}
DEPENDS
- ${build_subdir}
- ${CMAKE_BINARY_DIR}/PuzzleApplet.class
+ ${TARGET}-nvm-build-subdir
+ nvm-puzzle-applet
${CMAKE_SOURCE_DIR}/cmake/glob-symlinks.py)
- add_custom_command(OUTPUT ${build_subdir}/PuzzleEngine.class
+ add_custom_target(${TARGET}-nvm-engine
+ BYPRODUCTS ${build_subdir}/PuzzleEngine.class
COMMAND ${Java_JAVA_EXECUTABLE}
-cp ${NESTEDVM}/build:${NESTEDVM}/upstream/build/classgen/build
org.ibex.nestedvm.Compiler -outformat class -d .
PuzzleEngine ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}
DEPENDS
- ${build_subdir}
+ ${TARGET}-nvm-build-subdir
${CMAKE_CURRENT_BINARY_DIR}/${TARGET}
WORKING_DIRECTORY ${build_subdir})
@@ -51,9 +56,10 @@
applet.manifest PuzzleEngine.class PuzzleApplet*.class org
WORKING_DIRECTORY ${build_subdir}
DEPENDS
- ${CMAKE_BINARY_DIR}/PuzzleApplet.class
- ${build_subdir}/PuzzleApplet.class
- ${build_subdir}/PuzzleEngine.class)
+ nvm-puzzle-applet
+ ${TARGET}-nvm-build-subdir
+ ${TARGET}-nvm-symlinks
+ ${TARGET}-nvm-engine)
endfunction()
function(set_platform_puzzle_target_properties NAME TARGET)