Skip to content

Commit

Permalink
Add a script to help test dynamic library loading with Java
Browse files Browse the repository at this point in the history
  • Loading branch information
starseeker committed Sep 11, 2024
1 parent b116cfb commit cf70529
Showing 1 changed file with 134 additions and 0 deletions.
134 changes: 134 additions & 0 deletions CMake/JavaCheck.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# J A V A C H E C K . C M A K E
# BRL-CAD
#
# Copyright (c) 2024 United States Government as represented by
# the U.S. Army Research Laboratory.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
#
# 3. The name of the author may not be used to endorse or promote
# products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
###
# Utility function to check that dlls can be loaded by the Java
# System.loadLibrary mechanism. Parameters (all are mandatory):
#
# JCEXEC = path to javac compiler
# JAREXEC = path to jar archive creater
# JEXEC = path to java executable
# DLLSUFFIX = platform specific shared library suffix (.so, .dll, etc.)
# DLL_DIR = directory holding shared library files to check

function(JavaCheck JC_EXEC JAR_EXEC J_EXEC DLL_SUFFIX dlldir)

if (NOT EXISTS "${dlldir}")
message(FATAL_ERROR "Dll directory ${dlldir} not found\n")
endif ()
if (NOT EXISTS "${JC_EXEC}")
message(FATAL_ERROR "Java compiler executable ${JC_EXEC} not found\n")
endif ()
if (NOT EXISTS "${JAR_EXEC}")
message(FATAL_ERROR "Java archive creation executable ${JAR_EXEC} not found\n")
endif ()
if (NOT EXISTS "${J_EXEC}")
message(FATAL_ERROR "Java executable ${J_EXEC} not found\n")
endif ()

file(WRITE ${dlldir}/LoadLib.java "class LoadLib
{
public static void main(String []args)
{
if (args.length < 1) {
System.out.println(\"No DLL specified\");
System.exit(1);
}
System.out.println(\"Loading \" + args[0]);
System.loadLibrary(args[0]);
System.out.println(\"Done\");
}
}
"
)

# Help make sure Java finds the dynamically linked libraries in question
if (WIN32)
set(ENV{PATH} "${dlldir};$ENV{PATH}")
else (WIN32)
set(ENV{LD_LIBRARY_PATH} "${dlldir}")
endif (WIN32)

# Compile the file and create the jar archive
execute_process(COMMAND ${JC_EXEC} LoadLib.java
RESULT_VARIABLE LSTATUS OUTPUT_VARIABLE LOUT ERROR_VARIABLE LOUT
WORKING_DIRECTORY ${dlldir}
)
if (LSTATUS)
file(REMOVE ${dlldir}/LoadLib.java)
message(FATAL_ERROR "Failed to compile LoadLib.class: ${LOUT}")
endif (LSTATUS)
execute_process(COMMAND ${JAR_EXEC} -cf LoadLib.jar LoadLib.class
RESULT_VARIABLE LSTATUS OUTPUT_VARIABLE LOUT ERROR_VARIABLE LOUT
WORKING_DIRECTORY ${dlldir}
)
if (LSTATUS)
file(REMOVE ${dlldir}/LoadLib.java)
file(REMOVE ${dlldir}/LoadLib.class)
message(FATAL_ERROR "Failed to create JAR file LoadLib.jar: ${LOUT}")
endif (LSTATUS)

file(GLOB dll_files RELATIVE "${dlldir}" "${dlldir}/*${DLL_SUFFIX}")
set(load_fail 0)
foreach(dlf ${dll_files})
string(REGEX REPLACE "^lib" "" dlf "${dlf}")
string(REGEX REPLACE "${DLL_SUFFIX}$" "" dlf "${dlf}")
message("Dll LoadLibrary check: ${J_EXEC} -cp LoadLib.jar LoadLib ${dlf}")
execute_process(COMMAND ${J_EXEC} -cp LoadLib.jar LoadLib ${dlf}
RESULT_VARIABLE LSTATUS OUTPUT_VARIABLE LOUT ERROR_VARIABLE LOUT
WORKING_DIRECTORY ${dlldir}
)
if (LSTATUS)
message("LoadLibrary call with dll file ${dlf} did not succeed: ${LOUT}")
set(load_fail 1)
endif (LSTATUS)
endforeach(dlf ${dll_files})
file(REMOVE ${dlldir}/LoadLib.java)
file(REMOVE ${dlldir}/LoadLib.class)
file(REMOVE ${dlldir}/LoadLib.jar)
if (load_fail)
message(FATAL_ERROR "Dll files present that failed to load with LoadLibrary.")
endif (load_fail)
endfunction(JavaCheck)

if (JCEXEC AND JAREXEC AND JEXEC AND DLLSUFFIX AND DLL_DIR)
JavaCheck(${JCEXEC} ${JAREXEC} ${JEXEC} ${DLLSUFFIX} ${DLL_DIR})
endif ()

# Local Variables:
# tab-width: 8
# mode: cmake
# indent-tabs-mode: t
# End:
# ex: shiftwidth=2 tabstop=8

0 comments on commit cf70529

Please sign in to comment.