diff --git a/CMakeLists.txt b/CMakeLists.txt index 590a20c98..36e35bf4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,8 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.3) PROJECT(lmms) SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules" ${CMAKE_MODULE_PATH}) +SET(LMMS_BINARY_DIR ${CMAKE_BINARY_DIR}) +SET(LMMS_SOURCE_DIR ${CMAKE_SOURCE_DIR}) IF(COMMAND CMAKE_POLICY) CMAKE_POLICY(SET CMP0005 NEW) diff --git a/cmake/install/CMakeLists.txt b/cmake/install/CMakeLists.txt index 3e37fa00e..a3a81beeb 100644 --- a/cmake/install/CMakeLists.txt +++ b/cmake/install/CMakeLists.txt @@ -1,95 +1,17 @@ - -FUNCTION(GET_COMPILER_SEARCH_DIR VAR) - SET(results "") - IF(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang|AppleClang)") - EXECUTE_PROCESS( - COMMAND ${CMAKE_CXX_COMPILER} --print-search-dirs - OUTPUT_VARIABLE out - ) - STRING(REPLACE "\n" ";" out "${out}") - FOREACH(line ${out}) - IF(line MATCHES "^.+:") - STRING(REPLACE " " ";" line "${line}") - LIST(GET line 1 paths) - # Remove "=" prefix - STRING(REGEX REPLACE "^=" "" paths "${paths}") - STRING(REPLACE ":" ";" paths "${paths}") - FOREACH(path ${paths}) - LIST(APPEND results ${path}) - ENDFOREACH() - ENDIF() - ENDFOREACH() - ENDIF() - - SET(paths "") - FOREACH(result ${results}) - GET_FILENAME_COMPONENT(result ${result} REALPATH) - IF(IS_DIRECTORY "${result}") - LIST(APPEND paths ${result}) - ENDIF() - ENDFOREACH() - LIST(REMOVE_DUPLICATES paths) - - SET(${VAR} ${paths} PARENT_SCOPE) -ENDFUNCTION() - SET(PLUGIN_FILES "") IF(LMMS_BUILD_WIN32) INSTALL(FILES $ DESTINATION platforms) ENDIF() IF(LMMS_BUILD_WIN32 OR LMMS_INSTALL_DEPENDENCIES) + include(InstallTargetDependencies) + # Collect directories to search for DLLs GET_FILENAME_COMPONENT(QTBIN_DIR "${QT_QMAKE_EXECUTABLE}" PATH) set(LIB_DIRS "${QTBIN_DIR}") GET_PROPERTY(PLUGINS_BUILT GLOBAL PROPERTY PLUGINS_BUILT) - foreach(target lmms ${PLUGINS_BUILT}) - get_target_property(target_libs ${target} LINK_LIBRARIES) - - foreach(lib ${target_libs}) - if(TARGET ${lib} OR NOT IS_ABSOLUTE ${lib}) - continue() - endif() - - get_filename_component(lib_dir ${lib} PATH) - list(APPEND LIB_DIRS ${lib_dir}) - if(lib MATCHES ".(lib|dll.a)$") - if(IS_DIRECTORY ${lib_dir}/../bin) - list(APPEND LIB_DIRS ${lib_dir}/../bin) - endif() - if(IS_DIRECTORY ${lib_dir}/bin) - list(APPEND LIB_DIRS ${lib_dir}/bin) - endif() - endif() - endforeach() - endforeach() - - GET_COMPILER_SEARCH_DIR(COMPILER_SEARCH_DIRS) - LIST(APPEND LIB_DIRS ${COMPILER_SEARCH_DIRS}) - - LIST(REMOVE_DUPLICATES LIB_DIRS) - - # Collect plugin files to inspect - FOREACH(PLUGIN ${PLUGINS_BUILT}) - LIST(APPEND DEPLOY_TARGETS "$") - ENDFOREACH() - # Create the list of files using file(GENERATE) - SET(DEPLOY_LIST_FILE "${CMAKE_CURRENT_BINARY_DIR}/filelist.txt") - FILE(GENERATE OUTPUT "${DEPLOY_LIST_FILE}" CONTENT "${DEPLOY_TARGETS}") - - IF(LMMS_BUILD_LINUX) - FILE(DOWNLOAD "https://raw.githubusercontent.com/AppImage/AppImages/master/excludelist" - "${CMAKE_BINARY_DIR}/excludelist") - SET(additional_args INCLUDE_SYSTEM IGNORE_LIBS_FILE ${CMAKE_BINARY_DIR}/excludelist) - ELSEIF(LMMS_BUILD_WIN32) - SET(additional_args IGNORE_CASE IGNORE_LIBS_FILE ${CMAKE_CURRENT_LIST_DIR}/excludelist-win) - IF(CMAKE_CROSSCOMPILING) - SET(additional_args "${additional_args}" GP_TOOL objdump) - ENDIF() - ENDIF() - IF(LMMS_BUILD_WIN32) SET(LMMS_DEP_DESTINATION ${BIN_DIR}) SET(PLUGIN_DEP_DESTINATION ${BIN_DIR}) @@ -98,25 +20,19 @@ IF(LMMS_BUILD_WIN32 OR LMMS_INSTALL_DEPENDENCIES) SET(PLUGIN_DEP_DESTINATION ${LIB_DIR}) ENDIF() - INSTALL(CODE " - INCLUDE(\"${CMAKE_SOURCE_DIR}/cmake/modules/InstallDependencies.cmake\") - # Install dependencies of lmms - INSTALL_DEPENDENCIES( - FILES ${BIN_DIR}/lmms${CMAKE_EXECUTABLE_SUFFIX} - DESTINATION ${LMMS_DEP_DESTINATION} - LIB_DIRS ${LIB_DIRS} - ${additional_args} - ) - # Install dependencies of plugins - FILE(READ \"${DEPLOY_LIST_FILE}\" DEPLOY_FILES) - INSTALL_DEPENDENCIES( - FILES \"\${DEPLOY_FILES}\" - DESTINATION \"${PLUGIN_DEP_DESTINATION}\" - LIB_DIRS ${LIB_DIRS} \"${BIN_DIR}\" \"${PLUGIN_DIR}\" - SEARCH_PATHS \"${BIN_DIR}\" \"${PLUGIN_DIR}\" - ${additional_args} - ) - ") + INSTALL_TARGET_DEPENDENCIES( + NAME "main_binary" + TARGETS lmms + DESTINATION "${LMMS_DEP_DESTINATION}" + LIB_DIRS ${LIB_DIRS} + ) + + INSTALL_TARGET_DEPENDENCIES( + NAME "plugins" + TARGETS ${PLUGINS_BUILT} + DESTINATION ${PLUGIN_DEP_DESTINATION} + LIB_DIRS ${LIB_DIRS} "${PLUGIN_DIR}" + ) ENDIF() IF(LMMS_BUILD_APPLE) diff --git a/cmake/modules/InstallTargetDependencies.cmake b/cmake/modules/InstallTargetDependencies.cmake new file mode 100644 index 000000000..9665a0b87 --- /dev/null +++ b/cmake/modules/InstallTargetDependencies.cmake @@ -0,0 +1,89 @@ +include(DefineInstallVar) + +SET(DEFAULT_SEARCH_DIRECTORIES "${BIN_DIR}" "${LIB_DIR}" "${CMAKE_FIND_ROOT_PATH}" "${CMAKE_PREFIX_PATH}") +SET(DEFAULT_SEARCH_SUFFIXES "bin" "lib" "../bin") + +# Like INSTALL_DEPENDENCIES but can be called from regular cmake code +# (instead of install(CODE)), takes targets instead of files, +# takes care of configuring search paths, and other platform-specific tweaks. +# Arguments: +# TARGETS: list of cmake targets to install. +# NAME: unique string for this install. +# DESTINATION: directory path to install the binaries to. +# LIB_DIRS: list of paths for looking up dependencies. +# LIB_DIRS_SUFFIXES: list of possible suffixes for LIB_DIRS entries. +# NO_DEFAULT_PATHS: supply this value to avoid adding DEFAULT_SEARCH_DIRECTORIES +# to LIB_DIRS and DEFAULT_SEARCH_SUFFIXES to LIB_DIRS_SUFFIXES. +FUNCTION(INSTALL_TARGET_DEPENDENCIES) + set(options NO_DEFAULT_PATHS) + set(oneValueArgs NAME) + set(multiValueArgs TARGETS DESTINATION LIB_DIRS_SUFFIXES LIB_DIRS) + cmake_parse_arguments(DEPS "${options}" "${oneValueArgs}" + "${multiValueArgs}" ${ARGN} ) + + if(NOT DEPS_LIB_DIRS) + set(DEPS_LIB_DIRS "") + endif() + + # Set default values. + if(NOT DEPS_NO_DEFAULT_PATHS) + list(APPEND DEPS_LIB_DIRS ${DEFAULT_SEARCH_DIRECTORIES}) + set(DEPS_LIB_DIRS_SUFFIXES "${DEPS_LIB_DIRS_SUFFIXES}" ${DEFAULT_SEARCH_SUFFIXES}) + endif() + + FOREACH(TARGET ${DEPS_TARGETS}) + IF(NOT TARGET ${TARGET}) + message(FATAL_ERROR "Not a target: ${TARGET}") + ENDIF() + + # Collect target output files. + LIST(APPEND DEPLOY_TARGETS "$") + + # Collect target link directories + get_target_property(target_libs ${TARGET} LINK_LIBRARIES) + + foreach(lib ${target_libs}) + if(TARGET ${lib} OR NOT IS_ABSOLUTE ${lib}) + continue() + endif() + + get_filename_component(lib_dir ${lib} PATH) + list(APPEND DEPS_LIB_DIRS ${lib_dir}) + endforeach() + ENDFOREACH() + + LIST(APPEND DEPS_LIB_DIRS ${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES}) + + FOREACH(LIB_PATH ${DEPS_LIB_DIRS}) + FOREACH(suffix ${DEPS_LIB_DIRS_SUFFIXES}) + list(APPEND DEPS_LIB_DIRS "${LIB_PATH}/${suffix}") + ENDFOREACH() + ENDFOREACH() + + DEFINE_INSTALL_VAR(NAME "DEPLOY_FILES" CONTENT "${DEPLOY_TARGETS}" GENERATOR_EXPRESSION) + + LIST(REMOVE_DUPLICATES DEPS_LIB_DIRS) + + IF(LMMS_BUILD_LINUX) + FILE(DOWNLOAD "https://raw.githubusercontent.com/AppImage/AppImages/master/excludelist" + "${CMAKE_BINARY_DIR}/excludelist") + SET(additional_args INCLUDE_SYSTEM IGNORE_LIBS_FILE ${CMAKE_BINARY_DIR}/excludelist) + ELSEIF(LMMS_BUILD_WIN32) + SET(additional_args IGNORE_CASE IGNORE_LIBS_FILE "${LMMS_SOURCE_DIR}/cmake/install/excludelist-win") + IF(CMAKE_CROSSCOMPILING) + SET(additional_args "${additional_args}" GP_TOOL objdump) + ENDIF() + ENDIF() + + INSTALL(CODE " + INCLUDE(\"${LMMS_SOURCE_DIR}/cmake/modules/InstallDependencies.cmake\") + + INSTALL_DEPENDENCIES( + FILES \"\${DEPLOY_FILES}\" + DESTINATION \"${DEPS_DESTINATION}\" + LIB_DIRS \"${DEPS_LIB_DIRS}\" + SEARCH_PATHS \"${DEPS_SEARCH_PATHS}\" + ${additional_args} + ) + ") +ENDFUNCTION()