Windows: install shared libraries in blender.shared

Instead of the the same folder as the Blender executable, generate a manifest
that lets us move the libraries out of the way of users and into a separate
folder.

Ref T99618
This commit is contained in:
Ray molenkamp 2022-12-05 23:42:49 +01:00 committed by Brecht Van Lommel
parent 20883841c7
commit 6d27a2ff76
Notes: blender-bot 2023-02-13 14:58:24 +01:00
Referenced by issue #99618, Library changes for Blender 3.5
5 changed files with 176 additions and 115 deletions

View File

@ -1277,3 +1277,70 @@ macro(add_bundled_libraries library_dir)
unset(_library_dir)
endif()
endmacro()
macro(windows_install_shared_manifest)
set(options OPTIONAL DEBUG RELEASE ALL)
set(oneValueArgs)
set(multiValueArgs FILES)
cmake_parse_arguments(WINDOWS_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
# If none of the options are set assume ALL.
unset(WINDOWS_CONFIGURATIONS)
if(NOT WINDOWS_INSTALL_ALL AND
NOT WINDOWS_INSTALL_DEBUG AND
NOT WINDOWS_INSTALL_RELEASE)
set(WINDOWS_INSTALL_ALL TRUE)
endif()
# If all is set, turn both DEBUG and RELEASE on.
if(WINDOWS_INSTALL_ALL)
set(WINDOWS_INSTALL_DEBUG TRUE)
set(WINDOWS_INSTALL_RELEASE TRUE)
endif()
if(WINDOWS_INSTALL_DEBUG)
set(WINDOWS_CONFIGURATIONS "${WINDOWS_CONFIGURATIONS};Debug")
list(APPEND WINDOWS_SHARED_MANIFEST_DEBUG ${WINDOWS_INSTALL_FILES})
endif()
if(WINDOWS_INSTALL_RELEASE)
list(APPEND WINDOWS_SHARED_MANIFEST_RELEASE ${WINDOWS_INSTALL_FILES})
set(WINDOWS_CONFIGURATIONS "${WINDOWS_CONFIGURATIONS};Release;RelWithDebInfo;MinSizeRel")
endif()
install(FILES ${WINDOWS_INSTALL_FILES}
CONFIGURATIONS ${WINDOWS_CONFIGURATIONS}
DESTINATION "./blender.shared"
)
endmacro()
macro(windows_generate_manifest)
set(options)
set(oneValueArgs OUTPUT NAME)
set(multiValueArgs FILES)
cmake_parse_arguments(WINDOWS_MANIFEST "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
set(MANIFEST_LIBS "")
foreach(lib ${WINDOWS_MANIFEST_FILES})
get_filename_component(filename ${lib} NAME)
set(MANIFEST_LIBS "${MANIFEST_LIBS} <file name=\"${filename}\"/>\n")
endforeach()
configure_file(${CMAKE_SOURCE_DIR}/release/windows/manifest/blender.manifest.in ${WINDOWS_MANIFEST_OUTPUT} @ONLY)
endmacro()
macro(windows_generate_shared_manifest)
windows_generate_manifest(
FILES "${WINDOWS_SHARED_MANIFEST_DEBUG}"
OUTPUT "${CMAKE_BINARY_DIR}/Debug/blender.shared.manifest"
NAME "blender.shared"
)
windows_generate_manifest(
FILES "${WINDOWS_SHARED_MANIFEST_RELEASE}"
OUTPUT "${CMAKE_BINARY_DIR}/Release/blender.shared.manifest"
NAME "blender.shared"
)
install(
FILES ${CMAKE_BINARY_DIR}/Release/blender.shared.manifest
DESTINATION "./blender.shared"
CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel
)
install(
FILES ${CMAKE_BINARY_DIR}/Debug/blender.shared.manifest
DESTINATION "./blender.shared"
CONFIGURATIONS Debug
)
endmacro()

View File

@ -110,7 +110,41 @@ remove_cc_flag("/GR")
# Make the Windows 8.1 API available for use.
add_definitions(-D_WIN32_WINNT=0x603)
include(build_files/cmake/platform/platform_win32_bundle_crt.cmake)
# First generate the manifest for tests since it will not need the dependency on the CRT.
configure_file(${CMAKE_SOURCE_DIR}/release/windows/manifest/blender.exe.manifest.in ${CMAKE_CURRENT_BINARY_DIR}/tests.exe.manifest @ONLY)
if(WITH_WINDOWS_BUNDLE_CRT)
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE)
set(CMAKE_INSTALL_OPENMP_LIBRARIES ${WITH_OPENMP})
include(InstallRequiredSystemLibraries)
# ucrtbase(d).dll cannot be in the manifest, due to the way windows 10 handles
# redirects for this dll, for details see T88813.
foreach(lib ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS})
string(FIND ${lib} "ucrtbase" pos)
if(NOT pos EQUAL -1)
list(REMOVE_ITEM CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS ${lib})
install(FILES ${lib} DESTINATION . COMPONENT Libraries)
endif()
endforeach()
# Install the CRT to the blender.crt Sub folder.
install(FILES ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} DESTINATION ./blender.crt COMPONENT Libraries)
windows_generate_manifest(
FILES "${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS}"
OUTPUT "${CMAKE_BINARY_DIR}/blender.crt.manifest"
NAME "blender.crt"
)
install(FILES ${CMAKE_BINARY_DIR}/blender.crt.manifest DESTINATION ./blender.crt)
set(BUNDLECRT "<dependency><dependentAssembly><assemblyIdentity type=\"win32\" name=\"blender.crt\" version=\"1.0.0.0\" /></dependentAssembly></dependency>")
set(BUNDLECRT "${BUNDLECRT}<dependency><dependentAssembly><assemblyIdentity type=\"win32\" name=\"blender.shared\" version=\"1.0.0.0\" /></dependentAssembly></dependency>")
endif()
configure_file(${CMAKE_SOURCE_DIR}/release/windows/manifest/blender.exe.manifest.in ${CMAKE_CURRENT_BINARY_DIR}/blender.exe.manifest @ONLY)
remove_cc_flag("/MDd" "/MD" "/Zi")
if(MSVC_CLANG) # Clangs version of cl doesn't support all flags

View File

@ -1,56 +0,0 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# First generate the manifest for tests since it will not need the dependency on the CRT.
configure_file(${CMAKE_SOURCE_DIR}/release/windows/manifest/blender.exe.manifest.in ${CMAKE_CURRENT_BINARY_DIR}/tests.exe.manifest @ONLY)
# Always detect system libraries, since they are also used by oneAPI.
# But don't always install them, only for WITH_WINDOWS_BUNDLE_CRT=ON.
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE)
set(CMAKE_INSTALL_OPENMP_LIBRARIES ${WITH_OPENMP})
# This sometimes can change when updates are installed and the compiler version
# changes, so test if it exists and if not, give InstallRequiredSystemLibraries
# another chance to figure out the path.
if(MSVC_REDIST_DIR AND NOT EXISTS "${MSVC_REDIST_DIR}")
unset(MSVC_REDIST_DIR CACHE)
endif()
include(InstallRequiredSystemLibraries)
if(WITH_WINDOWS_BUNDLE_CRT)
# ucrtbase(d).dll cannot be in the manifest, due to the way windows 10 handles
# redirects for this dll, for details see T88813.
foreach(lib ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS})
string(FIND ${lib} "ucrtbase" pos)
if(NOT pos EQUAL -1)
list(REMOVE_ITEM CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS ${lib})
install(FILES ${lib} DESTINATION . COMPONENT Libraries)
endif()
endforeach()
# Install the CRT to the blender.crt Sub folder.
install(FILES ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} DESTINATION ./blender.crt COMPONENT Libraries)
# Generating the manifest is a relatively expensive operation since
# it is collecting an sha1 hash for every file required. so only do
# this work when the libs have either changed or the manifest does
# not exist yet.
string(SHA1 libshash "${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS}")
set(manifest_trigger_file "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/crt_${libshash}")
if(NOT EXISTS ${manifest_trigger_file})
set(CRTLIBS "")
foreach(lib ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS})
get_filename_component(filename ${lib} NAME)
file(SHA1 "${lib}" sha1_file)
string(APPEND CRTLIBS " <file name=\"${filename}\" hash=\"${sha1_file}\" hashalg=\"SHA1\" />\n")
endforeach()
configure_file(${CMAKE_SOURCE_DIR}/release/windows/manifest/blender.crt.manifest.in ${CMAKE_CURRENT_BINARY_DIR}/blender.crt.manifest @ONLY)
file(TOUCH ${manifest_trigger_file})
endif()
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/blender.crt.manifest DESTINATION ./blender.crt)
set(BUNDLECRT "<dependency><dependentAssembly><assemblyIdentity type=\"win32\" name=\"blender.crt\" version=\"1.0.0.0\" /></dependentAssembly></dependency>")
endif()
configure_file(${CMAKE_SOURCE_DIR}/release/windows/manifest/blender.exe.manifest.in ${CMAKE_CURRENT_BINARY_DIR}/blender.exe.manifest @ONLY)

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="@WINDOWS_MANIFEST_NAME@" version="1.0.0.0" />
@MANIFEST_LIBS@</assembly>

View File

@ -763,7 +763,6 @@ if(UNIX AND NOT APPLE)
unset(_suffix)
endif()
unset(_target_LIB)
endif()
endif()
@ -774,22 +773,22 @@ if(UNIX AND NOT APPLE)
)
endif()
elseif(WIN32)
install(
windows_install_shared_manifest(
FILES ${LIBDIR}/epoxy/bin/epoxy-0.dll
DESTINATION ${TARGETDIR_LIB}
ALL
)
if(WITH_OPENMP AND MSVC_CLANG)
install(
windows_install_shared_manifest(
FILES ${CLANG_OPENMP_DLL}
DESTINATION ${TARGETDIR_LIB}
ALL
)
endif()
if(WITH_FFTW3)
install(
windows_install_shared_manifest(
FILES ${LIBDIR}/fftw3/lib/libfftw3-3.dll
DESTINATION ${TARGETDIR_LIB}
ALL
)
endif()
if(MSVC_ASAN)
@ -804,34 +803,29 @@ elseif(WIN32)
"this is an optional component during the MSVC install, please install it"
)
endif()
install(
windows_install_shared_manifest(
FILES ${ASAN_DLL}
DESTINATION ${TARGETDIR_LIB}
CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel
RELEASE
)
install(
windows_install_shared_manifest(
FILES ${ASAN_DEBUG_DLL}
DESTINATION ${TARGETDIR_LIB}
CONFIGURATIONS Debug
DEBUG
)
unset(ASAN_DLL)
unset(ASAN_DEBUG_DLL)
endif()
if(WITH_GMP)
install(
windows_install_shared_manifest(
FILES ${LIBDIR}/gmp/lib/libgmp-10.dll
DESTINATION ${TARGETDIR_LIB}
ALL
)
install(
windows_install_shared_manifest(
FILES ${LIBDIR}/gmp/lib/libgmpxx.dll
DESTINATION ${TARGETDIR_LIB}
CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel
RELEASE
)
install(
windows_install_shared_manifest(
FILES ${LIBDIR}/gmp/lib/libgmpxx_d.dll
DESTINATION ${TARGETDIR_LIB}
CONFIGURATIONS Debug
DEBUG
)
endif()
@ -851,16 +845,14 @@ elseif(WIN32)
endif()
if(WITH_OPENVDB)
install(
FILES ${LIBDIR}/openvdb/bin/openvdb.dll
DESTINATION ${TARGETDIR_LIB}
CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel
)
install(
FILES ${LIBDIR}/openvdb/bin/openvdb_d.dll
DESTINATION ${TARGETDIR_LIB}
CONFIGURATIONS Debug
)
windows_install_shared_manifest(
FILES ${LIBDIR}/openvdb/bin/openvdb.dll
RELEASE
)
windows_install_shared_manifest(
FILES ${LIBDIR}/openvdb/bin/openvdb_d.dll
DEBUG
)
endif()
if(WITH_PYTHON)
@ -947,27 +939,26 @@ elseif(WIN32)
install(
FILES
${LIBDIR}/python/${_PYTHON_VERSION_NO_DOTS}/libs/python${_PYTHON_VERSION_NO_DOTS}.pdb
DESTINATION ${TARGETDIR_LIB}
DESTINATION "."
CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel
)
install(
FILES
${LIBDIR}/python/${_PYTHON_VERSION_NO_DOTS}/libs/python${_PYTHON_VERSION_NO_DOTS}_d.pdb
DESTINATION ${TARGETDIR_LIB}
DESTINATION "."
CONFIGURATIONS Debug
)
endif()
endif()
unset(_PYTHON_VERSION_NO_DOTS)
endif()
if(WITH_CODEC_FFMPEG)
# Filenames change slightly between FFMPEG versions check both 5.0 and fallback to 4.4
# to ease the transition between versions.
if(EXISTS "${LIBDIR}/ffmpeg/lib/avcodec-59.dll")
install(
windows_install_shared_manifest(
FILES
${LIBDIR}/ffmpeg/lib/avcodec-59.dll
${LIBDIR}/ffmpeg/lib/avformat-59.dll
@ -975,10 +966,10 @@ elseif(WIN32)
${LIBDIR}/ffmpeg/lib/avutil-57.dll
${LIBDIR}/ffmpeg/lib/swscale-6.dll
${LIBDIR}/ffmpeg/lib/swresample-4.dll
DESTINATION ${TARGETDIR_LIB}
ALL
)
else()
install(
windows_install_shared_manifest(
FILES
${LIBDIR}/ffmpeg/lib/avcodec-58.dll
${LIBDIR}/ffmpeg/lib/avformat-58.dll
@ -986,61 +977,57 @@ elseif(WIN32)
${LIBDIR}/ffmpeg/lib/avutil-56.dll
${LIBDIR}/ffmpeg/lib/swscale-5.dll
${LIBDIR}/ffmpeg/lib/swresample-3.dll
DESTINATION ${TARGETDIR_LIB}
ALL
)
endif()
endif()
if(WITH_TBB)
install(
windows_install_shared_manifest(
FILES
${LIBDIR}/tbb/bin/tbb.dll
DESTINATION ${TARGETDIR_LIB}
CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel
RELEASE
)
install(
windows_install_shared_manifest(
FILES
${LIBDIR}/tbb/bin/tbb_debug.dll
DESTINATION ${TARGETDIR_LIB}
CONFIGURATIONS Debug
DEBUG
)
endif()
if(WITH_TBB_MALLOC_PROXY)
install(
windows_install_shared_manifest(
FILES
${LIBDIR}/tbb/bin/tbbmalloc.dll
${LIBDIR}/tbb/bin/tbbmalloc_proxy.dll
DESTINATION ${TARGETDIR_LIB}
CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel
RELEASE
)
install(
windows_install_shared_manifest(
FILES
${LIBDIR}/tbb/bin/tbbmalloc_debug.dll
${LIBDIR}/tbb/bin/tbbmalloc_proxy_debug.dll
DESTINATION ${TARGETDIR_LIB}
CONFIGURATIONS Debug
DEBUG
)
list(APPEND LIB ${TBB_MALLOC_LIBRARIES})
endif()
if(WITH_CODEC_SNDFILE)
install(
windows_install_shared_manifest(
FILES ${LIBDIR}/sndfile/lib/libsndfile-1.dll
DESTINATION ${TARGETDIR_LIB}
ALL
)
endif()
if(WITH_OPENAL)
install(
windows_install_shared_manifest(
FILES
${LIBDIR}/openal/lib/OpenAL32.dll
DESTINATION ${TARGETDIR_LIB}
ALL
)
endif()
if(WITH_SDL)
install(
windows_install_shared_manifest(
FILES ${LIBDIR}/sdl/lib/SDL2.dll
DESTINATION ${TARGETDIR_LIB}
ALL
)
endif()
@ -1050,7 +1037,7 @@ elseif(WIN32)
${LIBDIR}/audaspace/lib/audaspace.dll
${LIBDIR}/audaspace/lib/audaspace-c.dll
${LIBDIR}/audaspace/lib/audaspace-py.dll
DESTINATION ${TARGETDIR_LIB}
DESTINATION "."
)
endif()
@ -1341,6 +1328,25 @@ if(WITH_USD)
endif()
endif()
if(WIN32 AND WITH_BOOST)
set(BOOST_COMPONENTS atomic chrono date_time filesystem
iostreams locale program_options regex
serialization system thread wave wserialization
python${_PYTHON_VERSION_NO_DOTS} numpy${_PYTHON_VERSION_NO_DOTS}
)
foreach(component ${BOOST_COMPONENTS})
if(EXISTS ${BOOST_LIBPATH}/${BOOST_PREFIX}boost_${component}-${BOOST_POSTFIX}.dll)
windows_install_shared_manifest(
FILES ${BOOST_LIBPATH}/${BOOST_PREFIX}boost_${component}-${BOOST_POSTFIX}.dll
RELEASE
)
windows_install_shared_manifest(
FILES ${BOOST_LIBPATH}/${BOOST_PREFIX}boost_${component}-${BOOST_DEBUG_POSTFIX}.dll
DEBUG
)
endif()
endforeach()
endif()
# `vcpkg` substitutes our libraries with theirs, which will cause issues when you you run
# these builds on other systems due to missing DLL's. So we opt out the use of `vcpkg`.
@ -1385,6 +1391,12 @@ if(WIN32 AND NOT WITH_PYTHON_MODULE)
)
endif()
# -----------------------------------------------------------------------------
# Windows shared library manifest
if(WIN32)
windows_generate_shared_manifest()
endif()
# -----------------------------------------------------------------------------
# Post-install script