From af40c764efbf0d29e2d6df1c38f19bb325ee509c Mon Sep 17 00:00:00 2001 From: Hyunjin Song Date: Mon, 11 Mar 2019 16:20:42 +0900 Subject: [PATCH] Better Wine detection and support * Support more Wine packagings * Allow building 64-bit RemoteVstPlugin using 32-bit Wine tools if possible * Provide suitable library paths for creating AppImages --- cmake/linux/package_linux.sh.in | 4 +- cmake/modules/FindWine.cmake | 117 +++++++++++++++++++++++-------- cmake/modules/winegcc_wrapper.in | 8 +++ 3 files changed, 98 insertions(+), 31 deletions(-) diff --git a/cmake/linux/package_linux.sh.in b/cmake/linux/package_linux.sh.in index 2eff0f264..bd164bd6a 100644 --- a/cmake/linux/package_linux.sh.in +++ b/cmake/linux/package_linux.sh.in @@ -134,10 +134,10 @@ export LD_LIBRARY_PATH="${APPDIR}usr/lib/lmms/":$LD_LIBRARY_PATH # Handle wine linking if [ -d "@WINE_32_LIBRARY_DIR@" ]; then - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LD_LIBRARY_PATH/wine/:@WINE_32_LIBRARY_DIR@:@WINE_32_LIBRARY_DIR@wine/ + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:@WINE_32_LIBRARY_DIRS@ fi if [ -d "@WINE_64_LIBRARY_DIR@" ]; then - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LD_LIBRARY_PATH/wine/:@WINE_64_LIBRARY_DIR@:@WINE_64_LIBRARY_DIR@wine/ + export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:@WINE_64_LIBRARY_DIRS@ fi # Move executables so linuxdeployqt can find them diff --git a/cmake/modules/FindWine.cmake b/cmake/modules/FindWine.cmake index 225d6a824..50bf54edb 100644 --- a/cmake/modules/FindWine.cmake +++ b/cmake/modules/FindWine.cmake @@ -7,46 +7,89 @@ # WINE_DEFINITIONS - Compiler switches required for using wine # +MACRO(_findwine_find_flags output expression result) + STRING(REPLACE " " ";" WINEBUILD_FLAGS "${output}") + FOREACH(FLAG ${WINEBUILD_FLAGS}) + IF("${FLAG}" MATCHES "${expression}") + SET(${result} "${FLAG}") + ENDIF() + ENDFOREACH() +ENDMACRO() + LIST(APPEND CMAKE_PREFIX_PATH /opt/wine-stable /opt/wine-devel /opt/wine-staging /usr/lib/wine/) - -FIND_PATH(WINE_INCLUDE_DIR wine/exception.h PATH_SUFFIXES wine) FIND_PROGRAM(WINE_CXX NAMES wineg++ winegcc winegcc64 winegcc32 winegcc-stable - PATHS /usr/lib/wine) + PATHS /usr/lib/wine +) FIND_PROGRAM(WINE_BUILD NAMES winebuild) +# Detect wine paths and handle linking problems +IF(WINE_CXX) + EXEC_PROGRAM(${WINE_CXX} ARGS "-m32 -v /dev/zero" OUTPUT_VARIABLE WINEBUILD_OUTPUT_32) + EXEC_PROGRAM(${WINE_CXX} ARGS "-m64 -v /dev/zero" OUTPUT_VARIABLE WINEBUILD_OUTPUT_64) + _findwine_find_flags("${WINEBUILD_OUTPUT_32}" "^-isystem/usr/include$" BUGGED_WINEGCC) + _findwine_find_flags("${WINEBUILD_OUTPUT_32}" "^-isystem" WINEGCC_INCLUDE_DIR) + _findwine_find_flags("${WINEBUILD_OUTPUT_32}" "libwinecrt0\\.a.*" WINECRT_32) + _findwine_find_flags("${WINEBUILD_OUTPUT_64}" "libwinecrt0\\.a.*" WINECRT_64) + STRING(REGEX REPLACE "^-isystem" "" WINE_INCLUDE_HINT "${WINEGCC_INCLUDE_DIR}") + STRING(REGEX REPLACE "/wine/windows$" "" WINE_INCLUDE_HINT "${WINE_INCLUDE_HINT}") + STRING(REGEX REPLACE "libwinecrt0\\.a.*" "" WINE_32_LIBRARY_DIR "${WINECRT_32}") + STRING(REGEX REPLACE "libwinecrt0\\.a.*" "" WINE_64_LIBRARY_DIR "${WINECRT_64}") + + IF(BUGGED_WINEGCC) + MESSAGE(WARNING "Your winegcc is unusable due to https://bugs.winehq.org/show_bug.cgi?id=46293,\n + Consider either upgrading or downgrading wine.") + RETURN() + ENDIF() + IF(WINE_32_LIBRARY_DIR STREQUAL WINE_64_LIBRARY_DIR) + MESSAGE(STATUS "Old winegcc detected, trying to use workaround linking") + # Fix library search directory according to the target bitness + IF(WINE_32_LIBRARY_DIR MATCHES "/lib/(x86_64|i386)-") + # Debian systems + STRING(REPLACE "/lib/x86_64-" "/lib/i386-" WINE_32_LIBRARY_DIR "${WINE_32_LIBRARY_DIR}") + STRING(REPLACE "/lib/i386-" "/lib/x86_64-" WINE_64_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}") + ELSEIF(WINE_32_LIBRARY_DIR MATCHES "/(lib|lib64)/wine/$") + # WineHQ (/opt/wine-stable, /opt/wine-devel, /opt/wine-staging) + STRING(REGEX REPLACE "/lib64/wine/$" "/lib/wine/" WINE_32_LIBRARY_DIR "${WINE_32_LIBRARY_DIR}") + STRING(REGEX REPLACE "/lib/wine/$" "/lib64/wine/" WINE_64_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}") + ELSEIF(WINE_32_LIBRARY_DIR MATCHES "/lib32/.*/wine/") + # Systems with old multilib layout + STRING(REPLACE "/lib32/" "/lib/" WINE_64_LIBRARY_DIR "${WINE_32_LIBRARY_DIR}") + ELSEIF(WINE_32_LIBRARY_DIR MATCHES "/lib64/.*/wine/") + # We need to test if the corresponding 64bit library directory is lib or lib32 + STRING(REPLACE "/lib64/" "/lib32/" WINE_32_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}") + IF(NOT EXISTS "${WINE_32_LIBRARY_DIR}") + STRING(REPLACE "/lib64/" "/lib/" WINE_32_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}") + ENDIF() + ELSEIF(WINE_32_LIBRARY_DIR MATCHES "/lib/.*/wine/") + # Test if this directory is for 32bit or 64bit + STRING(REPLACE "/lib/" "/lib32/" WINE_32_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}") + IF(NOT EXISTS "${WINE_32_LIBRARY_DIR}") + SET(WINE_32_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}") + STRING(REPLACE "/lib/" "/lib64/" WINE_64_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}") + ENDIF() + ELSE() + MESSAGE(WARNING "Can't detect wine installation layout. You may get some build errors.") + ENDIF() + SET(WINE_LIBRARY_FIX "${WINE_32_LIBRARY_DIR} and ${WINE_64_LIBRARY_DIR}") + ENDIF() +ENDIF() + +FIND_PATH(WINE_INCLUDE_DIR wine/exception.h + HINTS "${WINE_INCLUDE_HINT}" +) SET(_ARCHITECTURE ${CMAKE_LIBRARY_ARCHITECTURE}) -FIND_LIBRARY(WINE_LIBRARY NAMES wine PATH_SUFFIXES wine i386-linux-gnu/wine) +FIND_LIBRARY(WINE_LIBRARY NAMES wine + PATH_SUFFIXES wine i386-linux-gnu/wine + HINTS "${WINE_32_LIBRARY_DIR}" "${WINE_64_LIBRARY_DIR}" +) SET(CMAKE_LIBRARY_ARCHITECTURE ${_ARCHITECTURE}) SET(WINE_INCLUDE_DIRS ${WINE_INCLUDE_DIR} ) -SET(WINE_LIBRARIES ${WINE_LIBRARY} ) - -# Handle wine linking problems -EXEC_PROGRAM(${WINE_CXX} ARGS "-v -m32 /dev/zero" OUTPUT_VARIABLE WINEBUILD_OUTPUT) -STRING(REPLACE " " ";" WINEBUILD_FLAGS "${WINEBUILD_OUTPUT}") - -FOREACH(FLAG ${WINEBUILD_FLAGS}) - IF("${FLAG}" MATCHES "libwinecrt0.a.*") - STRING(REGEX REPLACE "/wine/libwinecrt0.a.*" "" FLAG "${FLAG}") - - SET(WINE_64_LIBRARY_DIR "${FLAG}/") - - # Debian systems - STRING(REPLACE "/lib/x86_64-" "/lib/i386-" FLAG "${FLAG}") - # Fedora systems - STRING(REPLACE "/lib/lib64" "/lib/i386" FLAG "${FLAG}") - # Gentoo systems - STRING(REPLACE "/lib/wine-" "/lib32/wine-" FLAG "${FLAG}") - # WineHQ (/opt/wine-stable, /opt/wine-devel, /opt/wine-staging) - STRING(REGEX REPLACE "/lib64$" "/lib" FLAG "${FLAG}") - - SET(WINE_32_LIBRARY_DIR "${FLAG}/") - ENDIF() -ENDFOREACH() +SET(WINE_LIBRARIES ${WINE_LIBRARY}) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(Wine DEFAULT_MSG WINE_CXX WINE_LIBRARIES WINE_INCLUDE_DIRS) @@ -54,7 +97,23 @@ find_package_handle_standard_args(Wine DEFAULT_MSG WINE_CXX WINE_LIBRARIES WINE_ mark_as_advanced(WINE_INCLUDE_DIR WINE_LIBRARY WINE_CXX WINE_BUILD) IF(WINE_32_LIBRARY_DIR) - SET(WINE_32_FLAGS "-L${WINE_32_LIBRARY_DIR}wine/ -L${WINE_32_LIBRARY_DIR}") + IF(WINE_32_LIBRARY_DIR MATCHES "wine*/lib") + SET(WINE_32_FLAGS "-L${WINE_32_LIBRARY_DIR} -L${WINE_32_LIBRARY_DIR}../") + SET(WINE_32_LIBRARY_DIRS "${WINE_32_LIBRARY_DIR}:${WINE_32_LIBRARY_DIR}/..") + ELSE() + SET(WINE_32_FLAGS "-L${WINE_32_LIBRARY_DIR}") + SET(WINE_32_LIBRARY_DIRS "${WINE_32_LIBRARY_DIR}") + ENDIF() +ENDIF() + +IF(WINE_64_LIBRARY_DIR) + IF(WINE_64_LIBRARY_DIR MATCHES "wine*/lib") + SET(WINE_64_FLAGS "-L${WINE_64_LIBRARY_DIR} -L${WINE_64_LIBRARY_DIR}../") + SET(WINE_64_LIBRARY_DIRS "${WINE_64_LIBRARY_DIR}:${WINE_64_LIBRARY_DIR}/..") + ELSE() + SET(WINE_64_FLAGS "-L${WINE_64_LIBRARY_DIR}") + SET(WINE_64_LIBRARY_DIRS "${WINE_64_LIBRARY_DIR}") + ENDIF() ENDIF() # Create winegcc wrapper diff --git a/cmake/modules/winegcc_wrapper.in b/cmake/modules/winegcc_wrapper.in index d7d680be2..32d65dd68 100755 --- a/cmake/modules/winegcc_wrapper.in +++ b/cmake/modules/winegcc_wrapper.in @@ -22,6 +22,9 @@ while [ $# -gt 0 ]; do -m32) win32=true ;; + -m64) + win64=true + ;; *) ;; @@ -47,6 +50,11 @@ if [ "$win32" = true ] && [ "$no_link" != true ]; then extra_args="$extra_args @WINE_32_FLAGS@" fi +# Apply -m64 library fix if necessary +if [ "$win64" = true ] && [ "$no_link" != true ]; then + extra_args="$extra_args @WINE_64_FLAGS@" +fi + # Run winegcc export WINEBUILD=@WINE_BUILD@ @WINE_CXX@ $extra_args $args