diff --git a/CMakeLists.txt b/CMakeLists.txt index ebffc0d85..0bf2df504 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,37 @@ # dependent libraries. cmake_minimum_required(VERSION 2.8.11) +function(download_bundled_external remote_path lib_name prefix_var) + set(prefix "${CMAKE_BINARY_DIR}/externals/${lib_name}") + if (NOT EXISTS "${prefix}") + message(STATUS "Downloading binaries for ${lib_name}...") + file(DOWNLOAD + https://github.com/citra-emu/ext-windows-bin/raw/master/${remote_path}${lib_name}.7z + "${CMAKE_BINARY_DIR}/externals/${lib_name}.7z" SHOW_PROGRESS) + execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf "${CMAKE_BINARY_DIR}/externals/${lib_name}.7z" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/externals") + endif() + message(STATUS "Using bundled binaries at ${prefix}") + set(${prefix_var} "${prefix}" PARENT_SCOPE) +endfunction() + +include(CheckSymbolExists) +function(detect_architecture symbol arch) + if (NOT DEFINED ARCHITECTURE) + set(CMAKE_REQUIRED_QUIET 1) + check_symbol_exists("${symbol}" "" ARCHITECTURE_${arch}) + unset(CMAKE_REQUIRED_QUIET) + + # The output variable needs to be unique across invocations otherwise + # CMake's crazy scope rules will keep it defined + if (ARCHITECTURE_${arch}) + set(ARCHITECTURE "${arch}" PARENT_SCOPE) + set(ARCHITECTURE_${arch} 1 PARENT_SCOPE) + add_definitions(-DARCHITECTURE_${arch}=1) + endif() + endif() +endfunction() + project(citra) if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git/hooks/pre-commit) @@ -10,12 +41,21 @@ if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git/hooks/pre-commit) DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/.git/hooks) endif() -# Platform-agnostic definition to check if we are on x86_64 -if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "[xX]86_64" OR - ${CMAKE_SYSTEM_PROCESSOR} MATCHES "[aA][mM][dD]64") - set(ARCHITECTURE_x86_64 1) - add_definitions(-DARCHITECTURE_x86_64=1) +if (MSVC) + detect_architecture("_M_AMD64" x86_64) + detect_architecture("_M_IX86" x86) + detect_architecture("_M_ARM" ARM) +else() + detect_architecture("__x86_64__" x86_64) + detect_architecture("__i386__" x86) + detect_architecture("__arm__" ARM) endif() +if (NOT DEFINED ARCHITECTURE) + set(ARCHITECTURE "GENERIC") + set(ARCHITECTURE_GENERIC 1) + add_definitions(-DARCHITECTURE_GENERIC=1) +endif() +message(STATUS "Target architecture: ${ARCHITECTURE}") if (NOT MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-attributes -pthread") @@ -75,7 +115,7 @@ else() message(STATUS "libpng not found. Some debugging features have been disabled.") endif() -find_package(Boost 1.57.0) +find_package(Boost 1.57.0 QUIET) if (Boost_FOUND) include_directories(${Boost_INCLUDE_DIRS}) else() @@ -90,59 +130,29 @@ find_package(OpenGL REQUIRED) include_directories(${OPENGL_INCLUDE_DIR}) option(ENABLE_GLFW "Enable the GLFW frontend" ON) +option(CITRA_USE_BUNDLED_GLFW "Download bundled GLFW binaries" OFF) if (ENABLE_GLFW) - if (WIN32) + if (CITRA_USE_BUNDLED_GLFW) # Detect toolchain and platform - if (MSVC) - if (CMAKE_SIZEOF_VOID_P EQUAL 8) - set(TMP_ARCH "x64") - elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) - set(TMP_ARCH "Win32") - else() - set(TMP_ARCH "UNKNOWN") - message(SEND_ERROR "Couldn't detect your compiler's architecture, you'll have to manually specify the GLFW library to use. (Try checking CMakeOutput.log to find out why.)") - endif() - - if (MSVC11) # Visual C++ 2012 - set(TMP_TOOLSET "v110") - elseif (MSVC12) # Visual C++ 2013 - set(TMP_TOOLSET "v120") - else() - set(TMP_TOOLSET "UNSUPPORTED") - message(SEND_ERROR "We don't supply GLFW binaries for your version of MSVC, you might have to provide them yourself.") - endif() - - set(TMP_TOOLSET "msvc_${TMP_TOOLSET}-${TMP_ARCH}") + if (MSVC14 AND ARCHITECTURE_x86_64) + set(GLFW_VER "glfw-3.1.1-msvc2015_64") + elseif (MSVC12 AND ARCHITECTURE_x86_64) + set(GLFW_VER "glfw-3.1.1-msvc2013_64") else() - # Assume mingw - if (CMAKE_SIZEOF_VOID_P EQUAL 8) - set(TMP_ARCH "x86_64") - elseif (CMAKE_SIZEOF_VOID_P EQUAL 4) - set(TMP_ARCH "i686") - else() - set(TMP_ARCH "UNKNOWN") - message(SEND_ERROR "Couldn't detect your compiler's architecture, you'll have to manually specify the GLFW library to use.") - endif() - - set(TMP_TOOLSET "mingw-${TMP_ARCH}") + message(FATAL_ERROR "No bundled GLFW binaries for your toolchain. Disable CITRA_USE_BUNDLED_GLFW and provide your own.") + endif() + + if (DEFINED GLFW_VER) + download_bundled_external("glfw/" ${GLFW_VER} GLFW_PREFIX) endif() - set(GLFW_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/externals/glfw-3.1.1.bin") set(GLFW_INCLUDE_DIRS "${GLFW_PREFIX}/include" CACHE PATH "Path to GLFW3 headers") - set(GLFW_LIBRARY_DIRS "${GLFW_PREFIX}/lib-${TMP_TOOLSET}" CACHE PATH "Path to GLFW3 libraries") - - # Clean up after ourselves - unset(TMP_TOOLSET) - unset(TMP_ARCH) - + set(GLFW_LIBRARY_DIRS "${GLFW_PREFIX}/lib" CACHE PATH "Path to GLFW3 libraries") set(GLFW_LIBRARIES glfw3) else() find_package(PkgConfig REQUIRED) pkg_search_module(GLFW REQUIRED glfw3) endif() - - include_directories(${GLFW_INCLUDE_DIRS}) - link_directories(${GLFW_LIBRARY_DIRS}) endif() IF (APPLE) @@ -167,22 +177,35 @@ ELSE() ENDIF (APPLE) option(ENABLE_QT "Enable the Qt frontend" ON) +option(CITRA_USE_BUNDLED_QT "Download bundled Qt binaries" OFF) option(CITRA_FORCE_QT4 "Use Qt4 even if Qt5 is available." OFF) if (ENABLE_QT) - # Set CMAKE_PREFIX_PATH if QTDIR is defined in the environment This allows CMake to - # automatically find the Qt packages on Windows - if (DEFINED ENV{QTDIR}) - list(APPEND CMAKE_PREFIX_PATH "$ENV{QTDIR}") + if (CITRA_USE_BUNDLED_QT) + if (MSVC14 AND ARCHITECTURE_x86_64) + set(QT_VER qt-5.5-msvc2015_64) + else() + message(FATAL_ERROR "No bundled Qt binaries for your toolchain. Disable CITRA_USE_BUNDLED_QT and provide your own.") + endif() + + if (DEFINED QT_VER) + download_bundled_external("qt/" ${QT_VER} QT_PREFIX) + endif() + + set(QT_PREFIX_HINT HINTS "${QT_PREFIX}") + else() + # Passing an empty HINTS seems to cause default system paths to get ignored in CMake 2.8 so + # make sure to not pass anything if we don't have one. + set(QT_PREFIX_HINT) endif() if (NOT CITRA_FORCE_QT4) - find_package(Qt5 COMPONENTS Widgets OpenGL) + find_package(Qt5 COMPONENTS Widgets OpenGL ${QT_PREFIX_HINT}) set(CITRA_QT_LIBS Qt5::Widgets Qt5::OpenGL) endif() if (CITRA_FORCE_QT4 OR NOT Qt5_FOUND) # Try to fallback to Qt4 - find_package(Qt4 REQUIRED COMPONENTS QtGui QtOpenGL) + find_package(Qt4 REQUIRED COMPONENTS QtGui QtOpenGL ${QT_PREFIX_HINT}) set(CITRA_QT_LIBS Qt4::QtGui Qt4::QtOpenGL) endif() endif() diff --git a/appveyor.yml b/appveyor.yml index 5dc147639..6e073ece7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -18,7 +18,7 @@ install: before_build: - mkdir build - cd build - - cmake -G "Visual Studio 12 Win64" .. + - cmake -G "Visual Studio 12 Win64" -DCITRA_USE_BUNDLED_GLFW=1 -DQt5_DIR=%QTDIR%/lib/cmake/Qt5 .. - cd .. after_build: diff --git a/src/citra/CMakeLists.txt b/src/citra/CMakeLists.txt index beb96bd30..e7f8a17f9 100644 --- a/src/citra/CMakeLists.txt +++ b/src/citra/CMakeLists.txt @@ -13,6 +13,9 @@ set(HEADERS create_directory_groups(${SRCS} ${HEADERS}) +include_directories(${GLFW_INCLUDE_DIRS}) +link_directories(${GLFW_LIBRARY_DIRS}) + add_executable(citra ${SRCS} ${HEADERS}) target_link_libraries(citra core video_core common) target_link_libraries(citra ${GLFW_LIBRARIES} ${OPENGL_gl_LIBRARY} inih glad)