Commit dbeaf709 authored by Wieland Morgenstern's avatar Wieland Morgenstern

restore symlink fixing actions for Mac

In a refactoring of the DELAY_LOAD stuff of Windows it seems the
Mac version was broken. On Mac there is a link to libvideostitch,
which is just a symlink to either _cuda or _opencl versions.

If the the symlink is currently pointing at the wrong one (i.e.
not the one matching our GPU), the symlink is changed and the app
is quit, user asked to launch again.

There seems to have been a refactoring done on Windows which de-
activated DELAY_LOAD completely on Mac, which made some of the
symlink changing code not compile.

Adding a new C Macro for Mac symlinks and allowing for USE_DELAY_LOAD
on Mac as well, in CMake, to restore previous behavior.
parent beb4a73e
......@@ -34,6 +34,17 @@ option(GPU_BACKEND_OPENCL "Build with OpenCL backend" OFF)
message(STATUS "GPU_BACKEND_CUDA='${GPU_BACKEND_CUDA}'")
message(STATUS "GPU_BACKEND_OPENCL='${GPU_BACKEND_OPENCL}'")
# Windows: actually delays loading to runtime
# Mac: create symlink to either libvideostitch_cuda/libvideostitch_opencl,
# change symlink at runtime and restart if necessary
# Linux: not implemented
option(USE_DELAY_LOAD "Delay loading of GPU backend to runtime" OFF)
if(${GPU_BACKEND_CUDA} AND ${GPU_BACKEND_OPENCL})
set(USE_DELAY_LOAD "ON" CACHE BOOL "Defaulting to USE_DELAY_LOAD=ON as both GPU backends are built" FORCE)
endif()
message(STATUS "USE_DELAY_LOAD=${USE_DELAY_LOAD}")
set(GPU_BACKEND_DEFAULT "CUDA" CACHE STRING "Default GPU backend")
set_property(CACHE GPU_BACKEND_DEFAULT PROPERTY STRINGS OPENCL CUDA)
......@@ -393,13 +404,7 @@ endif(GPU_BACKEND_CUDA)
# ----------------------------------------------------------------------------
# Delay load on Windows
# ----------------------------------------------------------------------------
set(USE_DELAY_LOAD "OFF")
if(GPU_BACKEND_CUDA AND GPU_BACKEND_OPENCL AND MSVC)
set(USE_DELAY_LOAD "ON")
endif()
message(STATUS "USE_DELAY_LOAD = ${USE_DELAY_LOAD}")
if(USE_DELAY_LOAD)
if(USE_DELAY_LOAD AND MSVC)
find_library(DELAY_LOAD_LIB NAMES "DelayImp.lib")
endif()
......@@ -415,7 +420,7 @@ if(CMAKE_BUILD_TYPE)
-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
-P ${CMAKE_SOURCE_DIR}/lib/generateFakeLibvideostitch.cmake
DEPENDS ${VS_LIB_DEFAULT})
if(USE_DELAY_LOAD)
if(USE_DELAY_LOAD AND MSVC)
add_dependencies(generateFakeLibvideostitch ${VS_LIB_FAKE})
endif()
else()
......@@ -435,6 +440,7 @@ endif()
# This function should be use by every dll/exe that links on libvideostitch
function(link_target_to_libvideostitch TARGET_NAME)
if(WINDOWS)
if(CMAKE_BUILD_TYPE)
add_dependencies(${TARGET_NAME} generateFakeLibvideostitch)
......@@ -444,17 +450,18 @@ function(link_target_to_libvideostitch TARGET_NAME)
add_dependencies(${TARGET_NAME} generateFakeLibvideostitch_${OUTPUTCONFIG_UP})
endforeach()
endif(CMAKE_BUILD_TYPE)
endif(WINDOWS)
if(USE_DELAY_LOAD)
target_link_libraries(${TARGET_NAME} PRIVATE ${DELAY_LOAD_LIB})
target_link_libraries(${TARGET_NAME} PRIVATE ${VS_LIB_FAKE})
target_compile_definitions(${TARGET_NAME} PRIVATE DELAY_LOAD_ENABLED=1)
set(new_link_flags "/DELAYLOAD:${VS_LIB_FAKE}.dll")
get_target_property(existing_link_flags ${TARGET_NAME} LINK_FLAGS)
if(existing_link_flags)
set(new_link_flags "${existing_link_flags} ${new_link_flags}")
if(USE_DELAY_LOAD)
target_link_libraries(${TARGET_NAME} PRIVATE ${DELAY_LOAD_LIB})
target_link_libraries(${TARGET_NAME} PRIVATE ${VS_LIB_FAKE})
target_compile_definitions(${TARGET_NAME} PRIVATE DELAY_LOAD_ENABLED=1)
set(new_link_flags "/DELAYLOAD:${VS_LIB_FAKE}.dll")
get_target_property(existing_link_flags ${TARGET_NAME} LINK_FLAGS)
if(existing_link_flags)
set(new_link_flags "${existing_link_flags} ${new_link_flags}")
endif()
set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS ${new_link_flags})
endif()
set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS ${new_link_flags})
elseif(APPLE)
target_link_libraries(${TARGET_NAME} PRIVATE ${VS_LIB_FAKE})
# ensure the non-fake backend libs are built
......@@ -466,10 +473,9 @@ function(link_target_to_libvideostitch TARGET_NAME)
endif()
else()
target_link_libraries(${TARGET_NAME} PUBLIC ${VS_LIB_DEFAULT})
endif(USE_DELAY_LOAD)
endif()
endfunction()
# ----------------------------------------------------------------------------
# Android specific after android.toolchain.cmake
# ----------------------------------------------------------------------------
......
......@@ -109,9 +109,16 @@ set (DISCOVERY_SRC_INCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/src/include)
include_discovery_vs_headers(${VS_DISCOVERY})
if(USE_DELAY_LOAD)
target_compile_definitions(${VS_DISCOVERY} PRIVATE DELAY_LOAD_ENABLED=1)
if(MSVC)
target_compile_definitions(${VS_DISCOVERY} PRIVATE DELAY_LOAD_ENABLED=1)
elseif(APPLE)
target_compile_definitions(${VS_DISCOVERY} PRIVATE SYMLINK_UPDATE_ENABLED=1)
endif()
endif()
# ----------------------------------------------------------------------------
# Unit tests
# ----------------------------------------------------------------------------
......
......@@ -95,7 +95,7 @@ bool readVsSymLink(std::string& targetLib) {
}
bool BackendLibLoader::updateVsSymlink() {
#ifdef DELAY_LOAD_ENABLED
#ifdef SYMLINK_UPDATE_ENABLED
std::string pathToLibs;
if (!getPathToLibs(pathToLibs)) {
return false;
......@@ -119,7 +119,7 @@ bool BackendLibLoader::updateVsSymlink() {
std::cerr << "Error creating symlink to " << pathToSymlink << std::endl;
return false;
}
#endif // DELAY_LOAD_ENABLED
#endif // SYMLINK_UPDATE_ENABLED
return true;
}
#endif // __APPLE__
......@@ -182,10 +182,8 @@ bool BackendLibLoader::selectBackend(const Discovery::Framework& framework, bool
if (needToRestart) {
*needToRestart = false;
}
#ifndef DELAY_LOAD_ENABLED
(void)framework;
return true;
#else
#if defined(SYMLINK_UPDATE_ENABLED) || defined(DELAY_LOAD_ENABLED)
if (framework == Discovery::Framework::Unknown) {
return false;
}
......@@ -193,6 +191,7 @@ bool BackendLibLoader::selectBackend(const Discovery::Framework& framework, bool
return true;
}
currentVsFramework = framework;
#if _MSC_VER
if (getBackendHandler() != NULL) {
if (needToRestart) {
......@@ -210,7 +209,10 @@ bool BackendLibLoader::selectBackend(const Discovery::Framework& framework, bool
#else
return true;
#endif // _MSC_VER
#endif // DELAY_LOAD_ENABLED
#else
(void)framework;
return true;
#endif // defined(SYMLINK_UPDATE_ENABLED) || defined(DELAY_LOAD_ENABLED)
}
#ifdef __APPLE__
......
......@@ -815,31 +815,31 @@ endif()
# To be sure, the generated dll on Windows will be replaced by an empty one in generateFakeLibvideostitch,
# while VS_LIB will be loaded using the delay load function
# ----------------------------------------------------------------------------
if(USE_DELAY_LOAD OR APPLE)
if(USE_DELAY_LOAD)
# Use any backend, we don't care, we just want the .lib with the common exported symbols
configure_lib_main_target(${VS_LIB_FAKE} ${GPU_BACKEND_DEFAULT} "SHARED")
endif(USE_DELAY_LOAD OR APPLE)
if(USE_DELAY_LOAD)
function(generate_lib_symbols BACKEND_NAME LIB_DIR)
add_custom_command(TARGET ${VS_LIB_${BACKEND_NAME}}
POST_BUILD
COMMAND dumpbin /EXPORTS /OUT:lib_symbols_${BACKEND_NAME}.txt ${LIB_DIR}/${VS_LIB_${BACKEND_NAME}}.lib
COMMAND cat lib_symbols_${BACKEND_NAME}.txt | grep ? > lib_symbols_only_${BACKEND_NAME}.txt)
endfunction()
# Check that VS_LIB_CUDA and VS_LIB_OPENCL have the same symbols
if(CMAKE_BUILD_TYPE)
generate_lib_symbols("CUDA" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
generate_lib_symbols("OPENCL" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
else()
generate_lib_symbols("CUDA" ${VS_OUT_DIR}/${CMAKE_CFG_INTDIR})
generate_lib_symbols("OPENCL" ${VS_OUT_DIR}/${CMAKE_CFG_INTDIR})
endif(CMAKE_BUILD_TYPE)
add_custom_target(compareLibsSymbols ALL
COMMAND ${CMAKE_COMMAND} -E compare_files lib_symbols_only_CUDA.txt lib_symbols_only_OPENCL.txt
DEPENDS ${VS_LIB_CUDA} ${VS_LIB_OPENCL})
endif(USE_DELAY_LOAD)
if(MSVC)
function(generate_lib_symbols BACKEND_NAME LIB_DIR)
add_custom_command(TARGET ${VS_LIB_${BACKEND_NAME}}
POST_BUILD
COMMAND dumpbin /EXPORTS /OUT:lib_symbols_${BACKEND_NAME}.txt ${LIB_DIR}/${VS_LIB_${BACKEND_NAME}}.lib
COMMAND cat lib_symbols_${BACKEND_NAME}.txt | grep ? > lib_symbols_only_${BACKEND_NAME}.txt)
endfunction()
# Check that VS_LIB_CUDA and VS_LIB_OPENCL have the same symbols
if(CMAKE_BUILD_TYPE)
generate_lib_symbols("CUDA" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
generate_lib_symbols("OPENCL" ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
else()
generate_lib_symbols("CUDA" ${VS_OUT_DIR}/${CMAKE_CFG_INTDIR})
generate_lib_symbols("OPENCL" ${VS_OUT_DIR}/${CMAKE_CFG_INTDIR})
endif(CMAKE_BUILD_TYPE)
add_custom_target(compareLibsSymbols ALL
COMMAND ${CMAKE_COMMAND} -E compare_files lib_symbols_only_CUDA.txt lib_symbols_only_OPENCL.txt
DEPENDS ${VS_LIB_CUDA} ${VS_LIB_OPENCL})
endif()
endif()
# ----------------------------------------------------------------------------
# static lib
......
......@@ -120,9 +120,8 @@ bool loadGPUBackend(const int deviceId, int& returnCode) {
PfnDliHook oldFailureHook = __pfnDliFailureHook2;
__pfnDliFailureHook2 = &delayFailureHook;
try {
#endif
// call any lib function
Status::OK();
#ifdef DELAY_LOAD_ENABLED
} catch (std::exception& e) {
std::cerr << "Error using backend library: " << e.what() << std::endl;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment