From 55dd027115e72ca2ffc6a0bbf8f131d380c73faa Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Thu, 3 Jun 2021 02:49:53 -0400 Subject: [PATCH 1/4] cmake: Use autotools to build libusb generally for GNU Building libusb was also broken on GCC (and maybe Clang) on our CMakeLists after upgrading to 1.0.24, but it was not being checked because our 18.04 container had libusb installed on it. This builds on the MinGW work from earlier and extends it to the rest of the GNU toolchains. In addition we make use of pkg-config when present to find libusb. pkg-config is preferrable because we can specify a minimum required version. --- CMakeLists.txt | 12 ++++++--- externals/libusb/CMakeLists.txt | 44 +++++++++++++++++++++------------ 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ba207dfd13..c07be6f579 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,8 @@ option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON) option(YUZU_USE_BUNDLED_BOOST "Download bundled Boost" OFF) +option(YUZU_USE_BUNDLED_LIBUSB "Compile bundled libusb" OFF) + CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_FFMPEG "Download/Build bundled FFmpeg" ON "WIN32" OFF) option(YUZU_USE_QT_WEB_ENGINE "Use QtWebEngine for web applet implementation" OFF) @@ -422,11 +424,15 @@ endif() # Ensure libusb is properly configured (based on dolphin libusb include) if(NOT APPLE) include(FindPkgConfig) - find_package(LibUSB) + if (PKG_CONFIG_FOUND) + pkg_check_modules(LIBUSB QUIET libusb-1.0>=1.0.24) + else() + find_package(LibUSB) + endif() endif() -if (NOT LIBUSB_FOUND) +if (NOT LIBUSB_FOUND OR YUZU_USE_BUNDLED_LIBUSB) add_subdirectory(externals/libusb) - set(LIBUSB_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/externals/libusb/libusb/libusb") + set(LIBUSB_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/libusb/libusb/libusb") set(LIBUSB_LIBRARIES usb) endif() diff --git a/externals/libusb/CMakeLists.txt b/externals/libusb/CMakeLists.txt index 3ef007b40f..da6d686841 100644 --- a/externals/libusb/CMakeLists.txt +++ b/externals/libusb/CMakeLists.txt @@ -1,10 +1,10 @@ -if (MINGW) - # The MinGW toolchain for some reason doesn't work with this CMakeLists file after updating to - # 1.0.24, so we do it the old-fashioned way for now. We may want to move native Linux toolchains - # to here, too (TODO lat9nq?). +if (MINGW OR NOT WIN32) + # GNU toolchains for some reason doesn't work with the later half of this CMakeLists after + # updating to 1.0.24, so we do it the old-fashioned way for now. set(LIBUSB_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/libusb") set(LIBUSB_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libusb") + # Workarounds for MSYS/MinGW if (MSYS) # CMake on Windows passes `C:/`, but we need `/C/` or `/c/` to use `configure` @@ -19,9 +19,18 @@ if (MINGW) set(LIBUSB_CONFIGURE "${LIBUSB_SRC_DIR}/configure") set(LIBUSB_MAKEFILE "${LIBUSB_PREFIX}/Makefile") - set(LIBUSB_LIBRARY "${LIBUSB_PREFIX}/libusb/.libs/libusb-1.0.dll.a") - set(LIBUSB_SHARED_LIBRARY "${LIBUSB_PREFIX}/libusb/.libs/libusb-1.0.dll") - set(LIBUSB_SHARED_LIBRARY_DEST "${CMAKE_BINARY_DIR}/bin/libusb-1.0.dll") + + if (MINGW) + set(LIBUSB_LIBRARY "${LIBUSB_PREFIX}/libusb/.libs/libusb-1.0.dll.a") + set(LIBUSB_SHARED_LIBRARY "${LIBUSB_PREFIX}/libusb/.libs/libusb-1.0.dll") + set(LIBUSB_SHARED_LIBRARY_DEST "${CMAKE_BINARY_DIR}/bin/libusb-1.0.dll") + + set(LIBUSB_CONFIGURE_ARGS --host=x86_64-w64-mingw32 --build=x86_64-windows) + else() + set(LIBUSB_LIBRARY "${LIBUSB_PREFIX}/libusb/.libs/libusb-1.0.so") + set(LIBUSB_SHARED_LIBRARY "${LIBUSB_LIBRARY}") + set(LIBUSB_SHARED_LIBRARY_DEST "${CMAKE_BINARY_DIR}/bin/libusb-1.0.so") + endif() # Causes "externals/libusb/libusb/libusb/os/windows_winusb.c:1427:2: error: conversion to non-scalar type requested", so cannot statically link it for now. # set(LIBUSB_CFLAGS "-DGUID_DEVINTERFACE_USB_DEVICE=\\(GUID\\){0xA5DCBF10,0x6530,0x11D2,{0x90,0x1F,0x00,0xC0,0x4F,0xB9,0x51,0xED}}") @@ -37,11 +46,6 @@ if (MINGW) "${LIBUSB_PREFIX}" ) - # We may use this path for other GNU toolchains, so put all of the MinGW-specific stuff here - if (MINGW) - set(LIBUSB_CONFIGURE_ARGS --host=x86_64-w64-mingw32 --build=x86_64-windows) - endif() - add_custom_command( OUTPUT "${LIBUSB_MAKEFILE}" @@ -71,16 +75,24 @@ if (MINGW) /bin/cp "${LIBUSB_SHARED_LIBRARY}" "${LIBUSB_SHARED_LIBRARY_DEST}" ) - add_custom_target(usb-bootstrap ALL DEPENDS "${LIBUSB_CONFIGURE}") - add_custom_target(usb-configure ALL DEPENDS "${LIBUSB_MAKEFILE}" usb-bootstrap) + add_custom_target(usb-bootstrap DEPENDS "${LIBUSB_CONFIGURE}") + add_custom_target(usb-configure DEPENDS "${LIBUSB_MAKEFILE}" usb-bootstrap) add_custom_target(usb-build ALL DEPENDS "${LIBUSB_LIBRARY}" usb-configure) # Workaround since static linking didn't work out -- We need to copy the DLL to the bin directory add_custom_target(usb-copy ALL DEPENDS "${LIBUSB_SHARED_LIBRARY_DEST}" usb-build) - # Make `usb` alias to LIBUSB_LIBRARY add_library(usb INTERFACE) + add_dependencies(usb usb-copy) target_link_libraries(usb INTERFACE "${LIBUSB_LIBRARY}") -else() # MINGW + + if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") + find_package(Libudev QUIET) + if(LIBUDEV_FOUND) + target_link_libraries(usb INTERFACE "${LIBUDEV_LIBRARIES}") + target_include_directories(usb INTERFACE "${LIBUDEV_INCLUDE_DIR}") + endif() + endif() +else() # MINGW OR NOT WIN32 # Ensure libusb compiles with UTF-8 encoding on MSVC if(MSVC) add_compile_options(/utf-8) From ddc47e6df8cd9e06d799933f67e75ba6f8952acd Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Thu, 3 Jun 2021 03:49:35 -0400 Subject: [PATCH 2/4] cmake: General improvements to libusb linking Delegates libusb external communication to externals/CMakeLists.txt Ensures an interface library `usb` for every pathway input_common just links to the `usb` library now externals/libusb/CMakeLists.txt sets variables to override SDL2's libusb finding Other minor cleanup --- CMakeLists.txt | 16 ++++++++++------ externals/CMakeLists.txt | 5 +++++ externals/libusb/CMakeLists.txt | 24 +++++++++++++++--------- src/input_common/CMakeLists.txt | 3 +-- 4 files changed, 31 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c07be6f579..68d9e5f9db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -422,18 +422,22 @@ elseif (TARGET Boost::boost) endif() # Ensure libusb is properly configured (based on dolphin libusb include) -if(NOT APPLE) +if(NOT APPLE AND NOT YUZU_USE_BUNDLED_LIBUSB) include(FindPkgConfig) if (PKG_CONFIG_FOUND) pkg_check_modules(LIBUSB QUIET libusb-1.0>=1.0.24) else() find_package(LibUSB) endif() -endif() -if (NOT LIBUSB_FOUND OR YUZU_USE_BUNDLED_LIBUSB) - add_subdirectory(externals/libusb) - set(LIBUSB_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/libusb/libusb/libusb") - set(LIBUSB_LIBRARIES usb) + + if (NOT LIBUSB_FOUND) + message(WARNING "libusb not found, falling back to externals") + set(YUZU_USE_BUNDLED_LIBUSB ON) + else() + add_library(usb INTERFACE) + target_include_directories(usb INTERFACE "${LIBUSB_INCLUDE_DIRS}") + target_link_libraries(usb INTERFACE "${LIBUSB_LIBRARIES}") + endif() endif() # List of all FFmpeg components required diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index aae0baa0bb..5402a532fb 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -45,6 +45,11 @@ target_include_directories(microprofile INTERFACE ./microprofile) add_library(unicorn-headers INTERFACE) target_include_directories(unicorn-headers INTERFACE ./unicorn/include) +# libusb +if (NOT LIBUSB_FOUND OR YUZU_USE_BUNDLED_LIBUSB) + add_subdirectory(libusb) +endif() + # SDL2 if (NOT SDL2_FOUND AND ENABLE_SDL2) if (NOT WIN32) diff --git a/externals/libusb/CMakeLists.txt b/externals/libusb/CMakeLists.txt index da6d686841..b2b36261cf 100644 --- a/externals/libusb/CMakeLists.txt +++ b/externals/libusb/CMakeLists.txt @@ -1,4 +1,7 @@ -if (MINGW OR NOT WIN32) +set(LIBUSB_FOUND ON CACHE BOOL "libusb is present" FORCE) +set(LIBUSB_VERSION "1.0.24" CACHE STRING "libusb version string" FORCE) + +if (MINGW OR (${CMAKE_SYSTEM_NAME} MATCHES "Linux")) # GNU toolchains for some reason doesn't work with the later half of this CMakeLists after # updating to 1.0.24, so we do it the old-fashioned way for now. @@ -21,17 +24,19 @@ if (MINGW OR NOT WIN32) set(LIBUSB_MAKEFILE "${LIBUSB_PREFIX}/Makefile") if (MINGW) - set(LIBUSB_LIBRARY "${LIBUSB_PREFIX}/libusb/.libs/libusb-1.0.dll.a") + set(LIBUSB_LIBRARIES "${LIBUSB_PREFIX}/libusb/.libs/libusb-1.0.dll.a" CACHE PATH "libusb library path" FORCE) set(LIBUSB_SHARED_LIBRARY "${LIBUSB_PREFIX}/libusb/.libs/libusb-1.0.dll") set(LIBUSB_SHARED_LIBRARY_DEST "${CMAKE_BINARY_DIR}/bin/libusb-1.0.dll") set(LIBUSB_CONFIGURE_ARGS --host=x86_64-w64-mingw32 --build=x86_64-windows) else() - set(LIBUSB_LIBRARY "${LIBUSB_PREFIX}/libusb/.libs/libusb-1.0.so") - set(LIBUSB_SHARED_LIBRARY "${LIBUSB_LIBRARY}") + set(LIBUSB_LIBRARIES "${LIBUSB_PREFIX}/libusb/.libs/libusb-1.0.so" CACHE PATH "libusb library path" FORCE) + set(LIBUSB_SHARED_LIBRARY "${LIBUSB_LIBRARIES}") set(LIBUSB_SHARED_LIBRARY_DEST "${CMAKE_BINARY_DIR}/bin/libusb-1.0.so") endif() + set(LIBUSB_INCLUDE_DIRS "${LIBUSB_SRC_DIR}/libusb" CACHE PATH "libusb headers path" FORCE) + # Causes "externals/libusb/libusb/libusb/os/windows_winusb.c:1427:2: error: conversion to non-scalar type requested", so cannot statically link it for now. # set(LIBUSB_CFLAGS "-DGUID_DEVINTERFACE_USB_DEVICE=\\(GUID\\){0xA5DCBF10,0x6530,0x11D2,{0x90,0x1F,0x00,0xC0,0x4F,0xB9,0x51,0xED}}") @@ -39,7 +44,7 @@ if (MINGW OR NOT WIN32) add_custom_command( OUTPUT - "${LIBUSB_LIBRARY}" + "${LIBUSB_LIBRARIES}" COMMAND make WORKING_DIRECTORY @@ -77,13 +82,14 @@ if (MINGW OR NOT WIN32) add_custom_target(usb-bootstrap DEPENDS "${LIBUSB_CONFIGURE}") add_custom_target(usb-configure DEPENDS "${LIBUSB_MAKEFILE}" usb-bootstrap) - add_custom_target(usb-build ALL DEPENDS "${LIBUSB_LIBRARY}" usb-configure) + add_custom_target(usb-build ALL DEPENDS "${LIBUSB_LIBRARIES}" usb-configure) # Workaround since static linking didn't work out -- We need to copy the DLL to the bin directory add_custom_target(usb-copy ALL DEPENDS "${LIBUSB_SHARED_LIBRARY_DEST}" usb-build) add_library(usb INTERFACE) add_dependencies(usb usb-copy) - target_link_libraries(usb INTERFACE "${LIBUSB_LIBRARY}") + target_link_libraries(usb INTERFACE "${LIBUSB_LIBRARIES}") + target_include_directories(usb INTERFACE "${LIBUSB_INCLUDE_DIRS}") if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") find_package(Libudev QUIET) @@ -92,7 +98,7 @@ if (MINGW OR NOT WIN32) target_include_directories(usb INTERFACE "${LIBUDEV_INCLUDE_DIR}") endif() endif() -else() # MINGW OR NOT WIN32 +else() # MINGW OR (${CMAKE_SYSTEM_NAME} MATCHES "Linux") # Ensure libusb compiles with UTF-8 encoding on MSVC if(MSVC) add_compile_options(/utf-8) @@ -248,4 +254,4 @@ else() # MINGW OR NOT WIN32 configure_file(config.h.in config.h) -endif() # MINGW +endif() # MINGW OR (${CMAKE_SYSTEM_NAME} MATCHES "Linux") diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt index de53e1fda1..7c5763f9c1 100644 --- a/src/input_common/CMakeLists.txt +++ b/src/input_common/CMakeLists.txt @@ -71,8 +71,7 @@ if (ENABLE_SDL2) target_compile_definitions(input_common PRIVATE HAVE_SDL2) endif() -target_include_directories(input_common SYSTEM PRIVATE ${LIBUSB_INCLUDE_DIR}) -target_link_libraries(input_common PRIVATE ${LIBUSB_LIBRARIES}) +target_link_libraries(input_common PRIVATE usb) create_target_directory_groups(input_common) target_link_libraries(input_common PUBLIC core PRIVATE common Boost::boost) From 890acfa2c001a034e0a837404118b3670305e0df Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Thu, 3 Jun 2021 04:38:29 -0400 Subject: [PATCH 3/4] externals: libusb: Link libusb statically on Linux Turns out that this is possible. Also addresses my own review comment. --- CMakeLists.txt | 8 ++++---- externals/libusb/CMakeLists.txt | 24 +++++++++++++----------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 68d9e5f9db..97afaf1a91 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -430,13 +430,13 @@ if(NOT APPLE AND NOT YUZU_USE_BUNDLED_LIBUSB) find_package(LibUSB) endif() - if (NOT LIBUSB_FOUND) - message(WARNING "libusb not found, falling back to externals") - set(YUZU_USE_BUNDLED_LIBUSB ON) - else() + if (LIBUSB_FOUND) add_library(usb INTERFACE) target_include_directories(usb INTERFACE "${LIBUSB_INCLUDE_DIRS}") target_link_libraries(usb INTERFACE "${LIBUSB_LIBRARIES}") + else() + message(WARNING "libusb not found, falling back to externals") + set(YUZU_USE_BUNDLED_LIBUSB ON) endif() endif() diff --git a/externals/libusb/CMakeLists.txt b/externals/libusb/CMakeLists.txt index b2b36261cf..20a1050878 100644 --- a/externals/libusb/CMakeLists.txt +++ b/externals/libusb/CMakeLists.txt @@ -30,15 +30,15 @@ if (MINGW OR (${CMAKE_SYSTEM_NAME} MATCHES "Linux")) set(LIBUSB_CONFIGURE_ARGS --host=x86_64-w64-mingw32 --build=x86_64-windows) else() - set(LIBUSB_LIBRARIES "${LIBUSB_PREFIX}/libusb/.libs/libusb-1.0.so" CACHE PATH "libusb library path" FORCE) - set(LIBUSB_SHARED_LIBRARY "${LIBUSB_LIBRARIES}") - set(LIBUSB_SHARED_LIBRARY_DEST "${CMAKE_BINARY_DIR}/bin/libusb-1.0.so") + set(LIBUSB_LIBRARIES "${LIBUSB_PREFIX}/libusb/.libs/libusb-1.0.a" CACHE PATH "libusb library path" FORCE) endif() set(LIBUSB_INCLUDE_DIRS "${LIBUSB_SRC_DIR}/libusb" CACHE PATH "libusb headers path" FORCE) - # Causes "externals/libusb/libusb/libusb/os/windows_winusb.c:1427:2: error: conversion to non-scalar type requested", so cannot statically link it for now. - # set(LIBUSB_CFLAGS "-DGUID_DEVINTERFACE_USB_DEVICE=\\(GUID\\){0xA5DCBF10,0x6530,0x11D2,{0x90,0x1F,0x00,0xC0,0x4F,0xB9,0x51,0xED}}") + # MINGW: causes "externals/libusb/libusb/libusb/os/windows_winusb.c:1427:2: error: conversion to non-scalar type requested", so cannot statically link it for now. + if (NOT MINGW) + set(LIBUSB_CFLAGS "-DGUID_DEVINTERFACE_USB_DEVICE=\\(GUID\\){0xA5DCBF10,0x6530,0x11D2,{0x90,0x1F,0x00,0xC0,0x4F,0xB9,0x51,0xED}}") + endif() make_directory("${LIBUSB_PREFIX}") @@ -55,8 +55,8 @@ if (MINGW OR (${CMAKE_SYSTEM_NAME} MATCHES "Linux")) OUTPUT "${LIBUSB_MAKEFILE}" COMMAND - # /bin/env - # CFLAGS="${LIBUSB_CFLAGS}" + /bin/env + CFLAGS="${LIBUSB_CFLAGS}" /bin/sh "${LIBUSB_CONFIGURE}" ${LIBUSB_CONFIGURE_ARGS} --srcdir="${LIBUSB_SRC_DIR}" @@ -92,10 +92,12 @@ if (MINGW OR (${CMAKE_SYSTEM_NAME} MATCHES "Linux")) target_include_directories(usb INTERFACE "${LIBUSB_INCLUDE_DIRS}") if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - find_package(Libudev QUIET) - if(LIBUDEV_FOUND) - target_link_libraries(usb INTERFACE "${LIBUDEV_LIBRARIES}") - target_include_directories(usb INTERFACE "${LIBUDEV_INCLUDE_DIR}") + Include(FindPkgConfig) + pkg_check_modules(LIBUDEV REQUIRED libudev) + + if (LIBUDEV_FOUND) + target_include_directories(usb INTERFACE "${LIBUDEV_INCLUDE_DIRS}") + target_link_libraries(usb INTERFACE "${LIBUDEV_STATIC_LIBRARIES}") endif() endif() else() # MINGW OR (${CMAKE_SYSTEM_NAME} MATCHES "Linux") From 7395cd312412116377920509b2cda485db384f46 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Thu, 3 Jun 2021 04:53:01 -0400 Subject: [PATCH 4/4] externals: libusb: Call program names not full paths --- externals/libusb/CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/externals/libusb/CMakeLists.txt b/externals/libusb/CMakeLists.txt index 20a1050878..06ce0fba78 100644 --- a/externals/libusb/CMakeLists.txt +++ b/externals/libusb/CMakeLists.txt @@ -55,9 +55,9 @@ if (MINGW OR (${CMAKE_SYSTEM_NAME} MATCHES "Linux")) OUTPUT "${LIBUSB_MAKEFILE}" COMMAND - /bin/env + env CFLAGS="${LIBUSB_CFLAGS}" - /bin/sh "${LIBUSB_CONFIGURE}" + sh "${LIBUSB_CONFIGURE}" ${LIBUSB_CONFIGURE_ARGS} --srcdir="${LIBUSB_SRC_DIR}" WORKING_DIRECTORY @@ -68,7 +68,7 @@ if (MINGW OR (${CMAKE_SYSTEM_NAME} MATCHES "Linux")) OUTPUT "${LIBUSB_CONFIGURE}" COMMAND - /bin/sh "${LIBUSB_SRC_DIR}/bootstrap.sh" + sh "${LIBUSB_SRC_DIR}/bootstrap.sh" WORKING_DIRECTORY "${LIBUSB_SRC_DIR}" ) @@ -77,7 +77,7 @@ if (MINGW OR (${CMAKE_SYSTEM_NAME} MATCHES "Linux")) OUTPUT "${LIBUSB_SHARED_LIBRARY_DEST}" COMMAND - /bin/cp "${LIBUSB_SHARED_LIBRARY}" "${LIBUSB_SHARED_LIBRARY_DEST}" + cp "${LIBUSB_SHARED_LIBRARY}" "${LIBUSB_SHARED_LIBRARY_DEST}" ) add_custom_target(usb-bootstrap DEPENDS "${LIBUSB_CONFIGURE}")