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 <noel.eck@intel.com>
This commit is contained in:
Noel Eck 2017-07-10 15:34:48 -07:00
parent e190bb9d60
commit f4da94a06e

View File

@ -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