From f4da94a06e74cd5897275fe81a1dd6f392f779e3 Mon Sep 17 00:00:00 2001 From: Noel Eck Date: Mon, 10 Jul 2017 15:34:48 -0700 Subject: [PATCH] cmake: Fix race condition to missing upm_interfaces.jar The custom command used to create a per-library jar can hit a race condition where upm_interfaces.jar is in the process of building when the javac command runs for a target. This is because the javac command was provided a full path to the upm_interfaces.jar file for ALL java targets (even targets which do NOT use the interfaces). Example: javac -cp path/to/upm_interfaces.jar If upm_interfaces.jar does not exist, javac is fine. if upm_interfaces.jar exists and is a valid file, javac is fine. If upm_interfaces.jar exists and is empty, javac throws an error. For the targets which do not have a dependency on the interfaces, it's possible one will run javac when the upm_interfaces.jar file is building in parallel and will fail since the file is open/incomplete/empty. The fix is to only provide the full path to the upm_interfaces.jar file for targets which depend on the interfaces. These will pass since they depend on the java interfaces target. Signed-off-by: Noel Eck --- src/CMakeLists.txt | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e70f85ff..4660315a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -436,6 +436,9 @@ macro(upm_swig_java) # depend on the JAVA interfaces if ("${_c_cxx_dependency_list}" MATCHES interfaces) add_dependencies(javaupm_${libname} javaupm_interfaces) + # If this target depends on interfaces, include the java interfaces + # target .jar file in the classpath, otherwise this variable will be empty + set (INTERFACES_JAR_FILE ${CMAKE_BINARY_DIR}/src/interfaces/upm_interfaces.jar) endif () swig_link_libraries (javaupm_${libname} ${MRAAJAVA_LIBRARY} ${JAVA_LIBRARIES} ${libname}) target_include_directories ( ${SWIG_MODULE_javaupm_${libname}_REAL_NAME} @@ -473,14 +476,16 @@ macro(upm_swig_java) set (JAR $ENV{JAVA_HOME_NATIVE}/bin/jar) endif () + # Only include the upm_interfaces.jar in the classpath for targets which + # depend on the interfaces target. This fixes an issue where javac + # complains about an empty upm_interfaces.jar when trying to build a target + # which does not depend on javaupm_interfaces. If not previously set, + # INTERFACES_JAR_FILE will be empty, and javac *should* not complain. add_custom_command (TARGET javaupm_${libname} POST_BUILD - COMMAND cmake -E echo "Compiling java.." COMMAND cmake -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/upm_${libname} - COMMAND ${JAVAC} *.java -d ${CMAKE_CURRENT_BINARY_DIR} -cp ${CMAKE_BINARY_DIR}/src/interfaces/upm_interfaces.jar:. - - COMMAND cmake -E echo "Creating jar" - COMMAND ${JAR} cvf upm_${libname}.jar upm_${libname} + COMMAND ${JAVAC} *.java -d ${CMAKE_CURRENT_BINARY_DIR} -cp ${INTERFACES_JAR_FILE}:. + COMMAND ${JAR} cf upm_${libname}.jar upm_${libname} ) # Keep track of all JAVA targets