Skip to content

Commit

Permalink
First cut at logic to check LoadLibrary behavior with output dlls.
Browse files Browse the repository at this point in the history
  • Loading branch information
starseeker committed Sep 9, 2024
1 parent 05c22d7 commit 288e25e
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 2 deletions.
2 changes: 1 addition & 1 deletion CMake/DllTypeCheck.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
70 changes: 70 additions & 0 deletions CMake/LoadLibraryCheck.cmake
Original file line number Diff line number Diff line change
@@ -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
43 changes: 43 additions & 0 deletions CMake/LoadLibraryTest.cpp
Original file line number Diff line number Diff line change
@@ -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 <windows.h>
#include <stdio.h>

int main(int argc, const char **argv)
{
if (argc < 2) {
printf("lltest <dllfile>\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
13 changes: 12 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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=\"$<CONFIG>\" -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=\"$<CONFIG>\" -DLEXEC=\"$<TARGET_FILE>: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
###############################################################################
Expand Down

0 comments on commit 288e25e

Please sign in to comment.