From c3d0dc58888a6f9cfcf07a58bbb14b8fa76bb12f Mon Sep 17 00:00:00 2001 From: Lukas W Date: Sun, 26 Nov 2017 20:54:32 +0100 Subject: [PATCH] Fix Linux VST compilation --- cmake/modules/CheckCXXPreprocessor.cmake | 33 +++++++ plugins/vst_base/CMakeLists.txt | 86 +++++++------------ .../vst_base/RemoteVstPlugin/CMakeLists.txt | 15 +++- plugins/vst_base/RemoteVstPlugin/winegcc | 49 +++++++++++ plugins/vst_base/VstPlugin.cpp | 4 +- 5 files changed, 124 insertions(+), 63 deletions(-) create mode 100644 cmake/modules/CheckCXXPreprocessor.cmake create mode 100755 plugins/vst_base/RemoteVstPlugin/winegcc diff --git a/cmake/modules/CheckCXXPreprocessor.cmake b/cmake/modules/CheckCXXPreprocessor.cmake new file mode 100644 index 000000000..f841f52d1 --- /dev/null +++ b/cmake/modules/CheckCXXPreprocessor.cmake @@ -0,0 +1,33 @@ + +macro(CHECK_CXX_PREPROCESSOR VAR DIRECTIVE) + string(RANDOM DEFINED_KEY) + string(RANDOM UNDEFINED_KEY) + + set(TMP_FILENAME "${CMAKE_CURRENT_BINARY_DIR}/CxxTmp/src.cpp") + SET(SRC " + #if ${DIRECTIVE} + #error ${DEFINED_KEY} + #else + #error ${UNDEFINED_KEY} + #endif + ") + file(WRITE ${TMP_FILENAME} "${SRC}") + try_compile(RESULT_VAR + ${CMAKE_CURRENT_BINARY_DIR} + ${TMP_FILENAME} + OUTPUT_VARIABLE OUTPUT_VAR + ) + + if(OUTPUT_VAR MATCHES ${DEFINED_KEY}) + set(${VAR} ON) + elseif(OUTPUT_VAR MATCHES ${UNDEFINED_KEY}) + set(${VAR} OFF) + else() + message(FATAL_ERROR "Can't determine if \"${DIRECTIVE}\" is true.") + endif() +endmacro() + + +macro(CHECK_CXX_DEFINE VAR DEFINE) + CHECK_CXX_PREPROCESSOR(${VAR} "defined(${DEFINE})") +endmacro() diff --git a/plugins/vst_base/CMakeLists.txt b/plugins/vst_base/CMakeLists.txt index eccfb4246..4a5ec890f 100644 --- a/plugins/vst_base/CMakeLists.txt +++ b/plugins/vst_base/CMakeLists.txt @@ -3,6 +3,9 @@ IF(NOT LMMS_SUPPORT_VST) ENDIF() INCLUDE(BuildPlugin) +INCLUDE(ExternalProject) + +ADD_SUBDIRECTORY(vstbase) SET(LMMS_BINARY_DIR ${CMAKE_BINARY_DIR}) SET(LMMS_SOURCE_DIR ${CMAKE_SOURCE_DIR}) @@ -10,7 +13,6 @@ SET(EXTERNALPROJECT_ARGS "") # build 32 bit version of RemoteVstPlugin IF(LMMS_BUILD_WIN64 AND MSVC) - INCLUDE(ExternalProject) SET(MSVC_VER ${CMAKE_CXX_COMPILER_VERSION}) @@ -45,66 +47,36 @@ IF(LMMS_BUILD_WIN64 AND MSVC) ELSEIF(LMMS_BUILD_WIN32) ADD_SUBDIRECTORY(RemoteVstPlugin) ELSEIF(LMMS_BUILD_LINUX AND NOT WANT_VST_NOWINE) - IF(LMMS_HOST_X86_64) - SET(EXTRA_FLAGS -m32) - IF(WINE_LIBRARY_FIX) - SET(EXTRA_FLAGS ${EXTRA_FLAGS} -nodefaultlibs ${WINE_LIBRARY_FIX}wine/libwinecrt0.a -L${WINE_LIBRARY_FIX}wine/ -luser32 -lkernel32 -lgdi32) - ENDIF() - ENDIF(LMMS_HOST_X86_64) - - SET(WINE_CXX_FLAGS "" CACHE STRING "Extra flags passed to wineg++") - - STRING(REPLACE "include/wine" "include" WINE_INCLUDE_BASE_DIR ${WINE_INCLUDE_DIR}) - STRING(REPLACE "lib/libwine.so" "lib" WINE_LIBRARY_DIR ${WINE_LIBRARY}) - STRING(REPLACE " " ";" WINE_BUILD_FLAGS ${CMAKE_CXX_FLAGS} " " ${CMAKE_EXE_LINKER_FLAGS} " " ${WINE_CXX_FLAGS}) - - SET(WINE_CXX_ARGS - -I${CMAKE_BINARY_DIR} - -I${CMAKE_SOURCE_DIR}/include - -I${WINE_INCLUDE_BASE_DIR} - -I${WINE_INCLUDE_DIR}/windows - -L${WINE_LIBRARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/RemoteVstPlugin.cpp - -std=c++0x - -mwindows -lpthread ${EXTRA_FLAGS} -fno-omit-frame-pointer - ${WINE_BUILD_FLAGS} - -o ../RemoteVstPlugin + ExternalProject_Add(RemoteVstPlugin32 + SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin" + INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/../" + CMAKE_ARGS + -DCMAKE_CXX_COMPILER=${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin/winegcc + -DLMMS_SOURCE_DIR=${CMAKE_SOURCE_DIR} + -DLMMS_BINARY_DIR=${CMAKE_BINARY_DIR} + -DCMAKE_CXX_FLAGS="-m32" + -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + -DCMAKE_MODULE_PATH=${CMAKE_MODULE_PATH} + INSTALL_COMMAND "" + BUILD_ALWAYS ON ) - - # winegcc fails if winebuild is not in path - GET_FILENAME_COMPONENT(WINE_BINDIR ${WINE_CXX} PATH) - FIND_PROGRAM(WINEBUILD winebuild NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) - IF(NOT WINEBUILD) - IF(CMAKE_VERSION VERSION_LESS 3.1) - MESSAGE(WARNING "winebuild is not in PATH. Building RemoteVstPlugin may fail.") - ELSE() - SET(WINE_CXX_ARGS -E env PATH=$ENV{PATH}:${WINE_BINDIR} ${WINE_CXX} ${WINE_CXX_ARGS}) - SET(WINE_CXX "${CMAKE_COMMAND}") - ENDIF() - ENDIF() - - set(ENV{PATH} "$ENV{PATH}:${WINE_BINDIR}") - - ADD_CUSTOM_COMMAND( - SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/RemoteVstPlugin.cpp" - COMMAND export - ARGS "PATH=$PATH:${WINE_BINDIR}" - COMMAND ${WINE_CXX} - ARGS ${WINE_CXX_ARGS} - # Ensure correct file extension - COMMAND sh -c "mv ../RemoteVstPlugin.exe ../RemoteVstPlugin || true" - TARGET vstbase - OUTPUTS ../RemoteVstPlugin - VERBATIM - ) - - SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ../RemoteVstPlugin32.exe.so) - INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32" "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe.so" DESTINATION "${PLUGIN_DIR}") ENDIF() # build 64 bit version of RemoteVstPlugin IF(LMMS_BUILD_WIN64) ADD_SUBDIRECTORY(RemoteVstPlugin) +ELSEIF(LMMS_BUILD_LINUX AND NOT WANT_VST_NOWINE) + ExternalProject_Add(RemoteVstPlugin64 + SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin" + INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/../" + CMAKE_ARGS + -DCMAKE_C_COMPILER=${WINE_CXX} + -DCMAKE_CXX_COMPILER=${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin/winegcc + -DLMMS_SOURCE_DIR=${CMAKE_SOURCE_DIR} + -DLMMS_BINARY_DIR=${CMAKE_BINARY_DIR} + -DCMAKE_RUNTIME_OUTPUT_DIRECTORY=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + -DCMAKE_MODULE_PATH=${CMAKE_MODULE_PATH} + INSTALL_COMMAND "" + BUILD_ALWAYS ON + ) ENDIF() - -ADD_SUBDIRECTORY(vstbase) diff --git a/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt b/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt index d077a80c0..9d3dd9a32 100644 --- a/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt +++ b/plugins/vst_base/RemoteVstPlugin/CMakeLists.txt @@ -1,17 +1,24 @@ cmake_minimum_required(VERSION 3.0.0) project(RemoteVstPlugin LANGUAGES CXX) - set(CMAKE_CXX_STANDARD 11) -if(CMAKE_SIZEOF_VOID_P EQUAL 8) +include(CheckCXXPreprocessor) + +CHECK_CXX_DEFINE(IS_WIN "__WIN32__") +CHECK_CXX_DEFINE(IS_WIN64 "__WIN64__") + +if(NOT IS_WIN) + message(FATAL_ERROR "Toolchain used does not target windows.") +ENDIF() + +if(IS_WIN64 OR CMAKE_SIZEOF_VOID_P EQUAL 8) set(BITNESS 64) else() set(BITNESS 32) endif() set(EXE_NAME RemoteVstPlugin${BITNESS}) - add_executable(${EXE_NAME} ../RemoteVstPlugin.cpp ) @@ -24,7 +31,7 @@ target_include_directories(${EXE_NAME} ) if(WIN32) - find_package(Qt5 REQUIRED COMPONENTS Core) + find_package(Qt5Core REQUIRED) target_link_libraries(${EXE_NAME} Qt5::Core) endif() diff --git a/plugins/vst_base/RemoteVstPlugin/winegcc b/plugins/vst_base/RemoteVstPlugin/winegcc new file mode 100755 index 000000000..018fb5ff7 --- /dev/null +++ b/plugins/vst_base/RemoteVstPlugin/winegcc @@ -0,0 +1,49 @@ +#!/bin/sh +# Wrapper script for winegcc to remove .exe file ending automatically +# appended by winebuild. +# Usage: winegcc + +set -e + +args="$@" + +# Find output name +POSITIONAL=() +while [ $# -gt 0 ]; do + key="$1" + + case $key in + -o) + output=$2 + shift + ;; + -c) + no_link=true + ;; + *) + + ;; + esac + + shift +done + +if [ -z "$output" ]; then + if [ "$no_link" != true ]; then + output="a.out" + no_move=true + fi +# echo "Fatal error in winegcc wrapper: Can't find output file name in args." +# exit 1 +fi + +wineg++ $args + +if [ -z "$no_link" ] && [ "$no_move" != true ]; then + if [ ! -e "$output.exe" ]; then + echo "Fatal error in winegcc wrapper: No output file \"$output.exe\" found." + exit 1 + fi + + mv $output.exe $output +fi diff --git a/plugins/vst_base/VstPlugin.cpp b/plugins/vst_base/VstPlugin.cpp index e629041ca..4428a3019 100644 --- a/plugins/vst_base/VstPlugin.cpp +++ b/plugins/vst_base/VstPlugin.cpp @@ -99,14 +99,14 @@ VstPlugin::VstPlugin( const QString & _plugin ) : { setSplittedChannels( true ); -#ifdef LMMS_BUILD_WIN64 +#ifdef LMMS_HOST_X86_64 tryLoad( "RemoteVstPlugin64" ); if( m_badDllFormat ) { m_badDllFormat = false; #endif tryLoad( "RemoteVstPlugin32" ); -#ifdef LMMS_BUILD_WIN64 +#ifdef LMMS_HOST_X86_64 } #endif