diff --git a/CMake/DllTypeCheck.cmake b/CMake/DllTypeCheck.cmake index e07708ac..badf8e9c 100644 --- a/CMake/DllTypeCheck.cmake +++ b/CMake/DllTypeCheck.cmake @@ -48,7 +48,7 @@ function(DllTypeCheck btype dlldir) file(GLOB dll_files RELATIVE "${dlldir}" "${dlldir}/*.dll") set(non_match 0) foreach(dlf ${dll_files}) - message("Checking ${dlf}") + message("Dll Type check: ${dlf}") # dumpbin doesn't like CMake style paths file(TO_NATIVE_PATH "${dlf}" TBFN) # https://stackoverflow.com/a/28304716/2037687 diff --git a/CMake/LoadLibraryCheck.cmake b/CMake/LoadLibraryCheck.cmake new file mode 100644 index 00000000..a4dce448 --- /dev/null +++ b/CMake/LoadLibraryCheck.cmake @@ -0,0 +1,70 @@ +# L O A D L I B R A R Y 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 a dll can be loaded by the LoadLibrary +# function on Windows. + +function(LoadLibraryCheck LLTEST_EXEC dlldir) + if (NOT EXISTS "${dlldir}") + return() + endif (NOT EXISTS "${dlldir}") + if (NOT EXISTS "${LLTEST_EXEC}") + return() + endif (NOT EXISTS "${LLTEST_EXEC}") + file(GLOB dll_files RELATIVE "${dlldir}" "${dlldir}/*.dll") + set(load_fail 0) + foreach(dlf ${dll_files}) + message("Dll LoadLibrary check: ${dlf}") + execute_process(COMMAND ${LLTEST_EXEC} ${dlf} RESULT_VARIABLE LSTATUS OUTPUT_VARIABLE LOUT) + if (LSTATUS) + message("LoadLibrary call with dll file ${dllfile} did not succeed.") + set(load_fail 1) + endif (LSTATUS) + endforeach(dlf ${dll_files}) + if (load_fail) + message(FATAL_ERROR "Dll files present that failed to load with LoadLibrary.") + endif (load_fail) +endfunction(LoadLibraryCheck) + +if (CMAKE_BUILD_TYPE AND LEXEC AND DLL_DIR) + LoadLibraryCheck(${CMAKE_BUILD_TYPE} ${LEXEC} ${DLL_DIR}) +endif (CMAKE_BUILD_TYPE AND LEXEC AND DLL_DIR) + +# Local Variables: +# tab-width: 8 +# mode: cmake +# indent-tabs-mode: t +# End: +# ex: shiftwidth=2 tabstop=8 diff --git a/CMake/LoadLibraryTest.cpp b/CMake/LoadLibraryTest.cpp new file mode 100644 index 00000000..c6599ac3 --- /dev/null +++ b/CMake/LoadLibraryTest.cpp @@ -0,0 +1,43 @@ +/* L O A D L I B R A R Y T E S T . C P P + * + * Published in 2024 by the United States Government. + * This work is in the public domain. + * + */ +/** @file LoadLibraryTest.cpp + * + * File to test if a Dll file can be successfully loaded + * by the Windows LoadLibrary call. + */ + +#include +#include + +int main(int argc, const char **argv) +{ + if (argc < 2) { + printf("lltest \n"); + return -1; + } + HINSTANCE linst = LoadLibrary(TEXT(argv[1])); + if (linst == NULL) { + printf("LoadLibrary of %s failed\n", argv[1]); + return 1; + } + Bool flr = FreeLibrary(linst); + if (!flr) { + printf("FreeLibrary failed for %s\n", argv[1]); + return 1; + } + printf("Success\n"); + return 0; +} + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 diff --git a/CMakeLists.txt b/CMakeLists.txt index 6dafd4a6..3421d8ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -491,9 +491,20 @@ endif (EXISTS "${CMAKE_BUNDLE_INSTALL_PREFIX}" AND STALE_INSTALL_WARN) # On Windows, if we get dlls built for the wrong configuration it can cause # problems. Define a utility target to check ############################################################################### -add_custom_target(dllcheck +add_custom_target(dll_typecheck COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=\"$\" -DDLL_DIR=\"${CMAKE_INSTALL_PREFIX}/bext_output/install/bin\" -P ${CMAKE_SOURCE_DIR}/CMake/DllTypeCheck.cmake) +############################################################################### +# Check that Windows LoadLibrary call can succeed with our dll outputs +############################################################################### +if (WIN32) + add_executable(lltest ${CMAKE_CURRENT_SOURCE_DIR}/LoadLibraryTest.cpp) + add_custom_target(dll_loadcheck + COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=\"$\" -DLEXEC=\"$:lltest\" -DDLL_DIR=\"${CMAKE_INSTALL_PREFIX}/bext_output/install/bin\" -P ${CMAKE_SOURCE_DIR}/CMake/LoadLibraryCheck.cmake + DEPENDS lltest + ) +endif (WIN32) + ############################################################################### # Report where we will be putting our output ###############################################################################