First Commit

This commit is contained in:
2025-11-18 14:18:26 -07:00
parent 33eb6e3707
commit 27277ec342
6106 changed files with 3571167 additions and 0 deletions

302
cmake/BuildParameters.cmake Normal file
View File

@@ -0,0 +1,302 @@
# Extra preprocessor definitions that will be added to all pcsx2 builds
set(PCSX2_DEFS "")
include(GNUInstallDirs)
#-------------------------------------------------------------------------------
# Misc option
#-------------------------------------------------------------------------------
option(ENABLE_TESTS "Enables building the unit tests" ON)
option(ENABLE_GSRUNNER "Enables building the GSRunner by default. It can still be built with `make pcsx2-gsrunner` otherwise." OFF)
option(LTO_PCSX2_CORE "Enable LTO/IPO/LTCG on the subset of pcsx2 that benefits most from it but not anything else")
option(USE_VTUNE "Plug VTUNE to profile GS JIT.")
option(PACKAGE_MODE "Use this option to ease packaging of PCSX2 (developer/distribution option)")
#-------------------------------------------------------------------------------
# Graphical option
#-------------------------------------------------------------------------------
if(NOT APPLE)
option(USE_OPENGL "Enable OpenGL GS renderer" ON)
endif()
option(USE_VULKAN "Enable Vulkan GS renderer" ON)
#-------------------------------------------------------------------------------
# Path and lib option
#-------------------------------------------------------------------------------
if(UNIX AND NOT APPLE)
option(ENABLE_SETCAP "Enable networking capability for DEV9" OFF)
option(X11_API "Enable X11 support" ON)
option(WAYLAND_API "Enable Wayland support" ON)
option(USE_BACKTRACE "Enable libbacktrace support" ON)
endif()
if(UNIX)
option(USE_LINKED_FFMPEG "Links with ffmpeg instead of using dynamic loading" OFF)
endif()
if(APPLE)
option(OSX_USE_DEFAULT_SEARCH_PATH "Don't prioritize system library paths" OFF)
option(SKIP_POSTPROCESS_BUNDLE "Skip postprocessing bundle for redistributability" OFF)
endif()
#-------------------------------------------------------------------------------
# Compiler extra
#-------------------------------------------------------------------------------
option(USE_ASAN "Enable address sanitizer")
#-------------------------------------------------------------------------------
# if no build type is set, use Devel as default
# Note without the CMAKE_BUILD_TYPE options the value is still defined to ""
# Ensure that the value set by the User is correct to avoid some bad behavior later
#-------------------------------------------------------------------------------
if(NOT CMAKE_BUILD_TYPE MATCHES "Debug|Devel|MinSizeRel|RelWithDebInfo|Release")
set(CMAKE_BUILD_TYPE Devel)
message(STATUS "BuildType set to ${CMAKE_BUILD_TYPE} by default")
endif()
# Add Devel build type
set(CMAKE_C_FLAGS_DEVEL "${CMAKE_C_FLAGS_RELWITHDEBINFO}"
CACHE STRING "Flags used by the C compiler during development builds" FORCE)
set(CMAKE_CXX_FLAGS_DEVEL "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}"
CACHE STRING "Flags used by the C++ compiler during development builds" FORCE)
set(CMAKE_LINKER_FLAGS_DEVEL "${CMAKE_LINKER_FLAGS_RELWITHDEBINFO}"
CACHE STRING "Flags used for linking binaries during development builds" FORCE)
set(CMAKE_SHARED_LINKER_FLAGS_DEVEL "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}"
CACHE STRING "Flags used for linking shared libraries during development builds" FORCE)
set(CMAKE_EXE_LINKER_FLAGS_DEVEL "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}"
CACHE STRING "Flags used for linking executables during development builds" FORCE)
# Exclude Debug from the configurations we can import from
set(CMAKE_MAP_IMPORTED_CONFIG_DEVEL "RelWithDebInfo" "Release" "MinSizeRel" "None" "NoConfig" ""
CACHE STRING "Configurations used when importing packages for development builds" FORCE)
if(CMAKE_CONFIGURATION_TYPES)
list(INSERT CMAKE_CONFIGURATION_TYPES 0 Devel)
endif()
mark_as_advanced(CMAKE_C_FLAGS_DEVEL CMAKE_CXX_FLAGS_DEVEL CMAKE_LINKER_FLAGS_DEVEL CMAKE_SHARED_LINKER_FLAGS_DEVEL CMAKE_EXE_LINKER_FLAGS_DEVEL CMAKE_MAP_IMPORTED_CONFIG_DEVEL)
#-------------------------------------------------------------------------------
# Select the architecture
#-------------------------------------------------------------------------------
if("${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "x86_64" OR "${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "amd64" OR
"${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "AMD64" OR "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "x86_64")
# Multi-ISA only exists on x86.
option(DISABLE_ADVANCE_SIMD "Disable advance use of SIMD (SSE2+ & AVX)" OFF)
list(APPEND PCSX2_DEFS _M_X86=1)
set(_M_X86 TRUE)
if(DISABLE_ADVANCE_SIMD)
message(STATUS "Building for x86-64 (Multi-ISA).")
else()
message(STATUS "Building for x86-64.")
endif()
if(MSVC)
# SSE4.1 is not set by MSVC, it uses _M_SSE instead.
list(APPEND PCSX2_DEFS __SSE4_1__=1)
if(USE_CLANG_CL)
# clang-cl => need to explicitly enable SSE4.1.
add_compile_options("-msse4.1")
endif()
else()
# Multi-ISA => SSE4, otherwise native.
if (DISABLE_ADVANCE_SIMD)
add_compile_options("-msse" "-msse2" "-msse4.1" "-mfxsr")
else()
# Can't use march=native on Apple Silicon.
if(NOT APPLE OR "${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "x86_64")
add_compile_options("-march=native")
endif()
endif()
endif()
elseif("${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "arm64" OR "${CMAKE_HOST_SYSTEM_PROCESSOR}" STREQUAL "aarch64" OR
"${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64")
message(STATUS "Building for Apple Silicon (ARM64).")
list(APPEND PCSX2_DEFS _M_ARM64=1)
set(_M_ARM64 TRUE)
add_compile_options("-march=armv8.4-a" "-mcpu=apple-m1")
# If we're running on Linux, we need to detect the page/cache line size.
# It could be a virtual machine with 4K pages, or 16K with Asahi.
if(LINUX)
detect_page_size()
list(APPEND PCSX2_DEFS OVERRIDE_HOST_PAGE_SIZE=${HOST_PAGE_SIZE})
detect_cache_line_size()
list(APPEND PCSX2_DEFS OVERRIDE_HOST_CACHE_LINE_SIZE=${HOST_CACHE_LINE_SIZE})
endif()
# Windows page/cache line size seems to match x68-64
if(WIN32)
list(APPEND PCSX2_DEFS OVERRIDE_HOST_PAGE_SIZE=0x1000)
# Value of std::hardware_destructive_interference_size for ARM64 on MSVC toolset 14.40.33807
list(APPEND PCSX2_DEFS OVERRIDE_HOST_CACHE_LINE_SIZE=64)
endif()
else()
message(FATAL_ERROR "Unsupported architecture: ${CMAKE_HOST_SYSTEM_PROCESSOR}")
endif()
# Require C++20.
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(MSVC AND NOT USE_CLANG_CL)
add_compile_options(
"$<$<COMPILE_LANGUAGE:CXX>:/Zc:externConstexpr>"
"$<$<COMPILE_LANGUAGE:CXX>:/Zc:__cplusplus>"
"$<$<COMPILE_LANGUAGE:CXX>:/permissive->"
"$<$<COMPILE_LANGUAGE:CXX>:/Zc:preprocessor>"
"/Zo"
"/utf-8"
)
endif()
if(MSVC)
# Disable Exceptions
string(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
else()
add_compile_options(-pipe -fvisibility=hidden -pthread)
add_compile_options(
"$<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions>"
)
endif()
set(CONFIG_REL_NO_DEB $<OR:$<CONFIG:Release>,$<CONFIG:MinSizeRel>>)
set(CONFIG_ANY_REL $<OR:$<CONFIG:Release>,$<CONFIG:MinSizeRel>,$<CONFIG:RelWithDebInfo>>)
if(WIN32)
add_compile_definitions(
$<$<CONFIG:Debug>:_ITERATOR_DEBUG_LEVEL=2>
$<$<CONFIG:Devel>:_ITERATOR_DEBUG_LEVEL=1>
$<${CONFIG_ANY_REL}:_ITERATOR_DEBUG_LEVEL=0>
_HAS_EXCEPTIONS=0
)
list(APPEND PCSX2_DEFS
_CRT_NONSTDC_NO_WARNINGS
_CRT_SECURE_NO_WARNINGS
CRT_SECURE_NO_DEPRECATE
_SCL_SECURE_NO_WARNINGS
_UNICODE
UNICODE
)
else()
# Assume everything else is POSIX.
list(APPEND PCSX2_DEFS
__POSIX__
)
endif()
# Enable debug information in release builds for Linux.
# Makes the backtrace actually meaningful.
if(LINUX)
add_compile_options($<$<CONFIG:Release>:-g1>)
endif()
if(MSVC)
# Enable PDB generation in release builds
add_compile_options(
$<${CONFIG_REL_NO_DEB}:/Zi>
)
add_link_options(
$<${CONFIG_REL_NO_DEB}:/DEBUG>
$<${CONFIG_REL_NO_DEB}:/OPT:REF>
$<${CONFIG_REL_NO_DEB}:/OPT:ICF>
)
endif()
if(PACKAGE_MODE)
file(RELATIVE_PATH relative_datadir ${CMAKE_INSTALL_FULL_BINDIR} ${CMAKE_INSTALL_FULL_DATADIR}/PCSX2)
# Compile all source codes with those defines
list(APPEND PCSX2_DEFS
PCSX2_APP_DATADIR="${relative_datadir}")
endif()
if(USE_VTUNE)
list(APPEND PCSX2_DEFS ENABLE_VTUNE)
endif()
if(USE_OPENGL)
list(APPEND PCSX2_DEFS ENABLE_OPENGL)
endif()
if(USE_VULKAN)
list(APPEND PCSX2_DEFS ENABLE_VULKAN)
endif()
if(X11_API)
list(APPEND PCSX2_DEFS X11_API)
endif()
if(WAYLAND_API)
list(APPEND PCSX2_DEFS WAYLAND_API)
endif()
# -Wno-attributes: "always_inline function might not be inlinable" <= real spam (thousand of warnings!!!)
# -Wno-missing-field-initializers: standard allow to init only the begin of struct/array in static init. Just a silly warning.
# -Wno-unused-function: warn for function not used in release build
if (MSVC)
set(DEFAULT_WARNINGS)
else()
set(DEFAULT_WARNINGS -Wall -Wextra -Wno-unused-function -Wno-unused-parameter -Wno-missing-field-initializers)
endif()
if (USE_PGO_GENERATE OR USE_PGO_OPTIMIZE)
add_compile_options("-fprofile-dir=${CMAKE_SOURCE_DIR}/profile")
endif()
if (USE_PGO_GENERATE)
add_compile_options(-fprofile-generate)
endif()
if(USE_PGO_OPTIMIZE)
add_compile_options(-fprofile-use)
endif()
list(APPEND PCSX2_DEFS
"$<$<CONFIG:Debug>:PCSX2_DEVBUILD;PCSX2_DEBUG;_DEBUG>"
"$<$<CONFIG:Devel>:PCSX2_DEVBUILD;_DEVEL>")
if (USE_ASAN)
add_compile_options(-fsanitize=address)
add_link_options(-fsanitize=address)
list(APPEND PCSX2_DEFS ASAN_WORKAROUND)
endif()
if(USE_CLANG AND TIMETRACE)
add_compile_options(-ftime-trace)
endif()
set(PCSX2_WARNINGS ${DEFAULT_WARNINGS})
#-------------------------------------------------------------------------------
# MacOS-specific things
#-------------------------------------------------------------------------------
if(NOT CMAKE_GENERATOR MATCHES "Xcode")
# Assume Xcode builds aren't being used for distribution
# Helpful because Xcode builds don't build multiple metallibs for different macOS versions
# Also helpful because Xcode's interactive shader debugger requires apps be built for the latest macOS
set(CMAKE_OSX_DEPLOYMENT_TARGET 11.0)
endif()
# CMake defaults the suffix for modules to .so on macOS but wx tells us that the
# extension is .dylib (so that's what we search for)
if(APPLE)
set(CMAKE_SHARED_MODULE_SUFFIX ".dylib")
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
if(NOT OSX_USE_DEFAULT_SEARCH_PATH)
# Hack up the path to prioritize the path to built-in OS libraries to
# increase the chance of not depending on a bunch of copies of them
# installed by MacPorts, Fink, Homebrew, etc, and ending up copying
# them into the bundle. Since we depend on libraries which are not
# part of OS X (wx, etc.), however, don't remove the default path
# entirely. This is still kinda evil, since it defeats the user's
# path settings...
# See http://www.cmake.org/cmake/help/v3.0/command/find_program.html
list(APPEND CMAKE_PREFIX_PATH "/usr")
endif()
add_link_options(-Wl,-dead_strip,-dead_strip_dylibs)
endif()

43
cmake/CheckLib.cmake Normal file
View File

@@ -0,0 +1,43 @@
include(FindPkgConfig OPTIONAL)
macro(_internal_message msg)
message("${msg}")
endmacro()
macro(check_lib var lib)
set(_arg_list ${ARGN})
if(PKG_CONFIG_FOUND AND NOT DEFINED pcsx2_manually_found_${var})
string(TOLOWER ${lib} lower_lib)
pkg_search_module(${var} QUIET IMPORTED_TARGET ${lower_lib})
endif()
if(TARGET PkgConfig::${var})
_internal_message("-- ${var} found pkg")
else()
find_library(${var}_LIBRARIES ${lib})
if(_arg_list)
find_path(${var}_INCLUDE ${_arg_list})
else()
set(${var}_INCLUDE FALSE)
endif()
if(${var}_LIBRARIES AND ${var}_INCLUDE)
add_library(PkgConfig::${var} UNKNOWN IMPORTED GLOBAL)
# Imitate what pkg-config would have found
set_target_properties(PkgConfig::${var} PROPERTIES
IMPORTED_LOCATION "${${var}_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${${var}_INCLUDE}"
)
_internal_message("-- ${var} found")
set(${var}_FOUND 1 CACHE INTERNAL "")
set(pcsx2_manually_found_${var} 1 CACHE INTERNAL "")
elseif(${var}_LIBRARIES)
_internal_message("-- ${var} not found (miss include)")
elseif(${var}_INCLUDE)
_internal_message("-- ${var} not found (miss lib)")
else()
_internal_message("-- ${var} not found")
endif()
endif()
endmacro()

View File

@@ -0,0 +1,52 @@
function(copy_base_translations target)
get_target_property(LCONVERT_EXE Qt6::lconvert IMPORTED_LOCATION)
get_filename_component(QT_BINARY_DIRECTORY "${LCONVERT_EXE}" DIRECTORY)
set(BASE_TRANSLATIONS_DIR "${QT_BINARY_DIRECTORY}/../translations")
if(NOT APPLE)
add_custom_command(TARGET ${target} POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E make_directory "$<TARGET_FILE_DIR:${target}>/translations")
endif()
file(GLOB qmFiles "${BASE_TRANSLATIONS_DIR}/qt_*.qm")
foreach(path IN LISTS qmFiles)
get_filename_component(file ${path} NAME)
# qt_help_<lang> just has to ruin everything.
if(file MATCHES "qt_help_" OR NOT file MATCHES "qt_([^.]+).qm")
continue()
endif()
# If qtbase_<lang>.qm exists, merge all qms for that language into a single qm.
set(lang "${CMAKE_MATCH_1}")
set(baseQmPath "${BASE_TRANSLATIONS_DIR}/qtbase_${lang}.qm")
if(EXISTS "${baseQmPath}")
set(outPath "${CMAKE_CURRENT_BINARY_DIR}/qt_${lang}.qm")
set(srcQmFiles)
file(GLOB langQmFiles "${BASE_TRANSLATIONS_DIR}/qt*${lang}.qm")
foreach(qmFile IN LISTS langQmFiles)
get_filename_component(file ${qmFile} NAME)
if(file STREQUAL "qt_${lang}.qm")
continue()
endif()
LIST(APPEND srcQmFiles "${qmFile}")
endforeach()
add_custom_command(OUTPUT ${outPath}
COMMAND Qt6::lconvert -verbose -of qm -o "${outPath}" ${srcQmFiles}
DEPENDS ${srcQmFiles}
)
set(path "${outPath}")
endif()
target_sources(${target} PRIVATE ${path})
if(APPLE)
set_source_files_properties(${path} PROPERTIES MACOSX_PACKAGE_LOCATION Resources/translations)
elseif(WIN32)
# TODO: Set the correct binary instead of relying on make install on Windows...
install(FILES "${path}" DESTINATION "${CMAKE_SOURCE_DIR}/bin/translations")
else()
add_custom_command(TARGET ${target} POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${path}" "$<TARGET_FILE_DIR:${target}>/translations")
endif()
endforeach()
endfunction()

195
cmake/FindFFMPEG.cmake Normal file
View File

@@ -0,0 +1,195 @@
#[==[
Provides the following variables:
* `FFMPEG_INCLUDE_DIRS`: Include directories necessary to use FFMPEG.
* `FFMPEG_LIBRARIES`: Libraries necessary to use FFMPEG. Note that this only
includes libraries for the components requested.
* `FFMPEG_VERSION`: The version of FFMPEG found.
The following components are supported:
* `avcodec`
* `avdevice`
* `avfilter`
* `avformat`
* `avresample`
* `avutil`
* `swresample`
* `swscale`
For each component, the following are provided:
* `FFMPEG_<component>_FOUND`: Libraries for the component.
* `FFMPEG_<component>_INCLUDE_DIRS`: Include directories for
the component.
* `FFMPEG_<component>_LIBRARIES`: Libraries for the component.
* `FFMPEG::<component>`: A target to use with `target_link_libraries`.
Note that only components requested with `COMPONENTS` or `OPTIONAL_COMPONENTS`
are guaranteed to set these variables or provide targets.
#]==]
function (_ffmpeg_find component headername)
find_path("FFMPEG_${component}_INCLUDE_DIR"
NAMES
"lib${component}/${headername}"
PATHS
"${FFMPEG_ROOT}/include"
~/Library/Frameworks
/Library/Frameworks
/usr/local/include
/usr/include
/sw/include # Fink
/opt/local/include # DarwinPorts
/opt/csw/include # Blastwave
/opt/include
/usr/freeware/include
PATH_SUFFIXES
ffmpeg
DOC "FFMPEG's ${component} include directory")
mark_as_advanced("FFMPEG_${component}_INCLUDE_DIR")
# On Windows, static FFMPEG is sometimes built as `lib<name>.a`.
if (WIN32)
list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES ".a" ".lib")
list(APPEND CMAKE_FIND_LIBRARY_PREFIXES "" "lib")
endif ()
find_library("FFMPEG_${component}_LIBRARY"
NAMES
"${component}"
PATHS
"${FFMPEG_ROOT}/lib"
~/Library/Frameworks
/Library/Frameworks
/usr/local/lib
/usr/local/lib64
/usr/lib
/usr/lib64
/sw/lib
/opt/local/lib
/opt/csw/lib
/opt/lib
/usr/freeware/lib64
"${FFMPEG_ROOT}/bin"
DOC "FFMPEG's ${component} library")
mark_as_advanced("FFMPEG_${component}_LIBRARY")
if (FFMPEG_${component}_LIBRARY AND FFMPEG_${component}_INCLUDE_DIR)
set(_deps_found TRUE)
set(_deps_link)
foreach (_ffmpeg_dep IN LISTS ARGN)
if (TARGET "FFMPEG::${_ffmpeg_dep}")
list(APPEND _deps_link "FFMPEG::${_ffmpeg_dep}")
else ()
set(_deps_found FALSE)
endif ()
endforeach ()
if (_deps_found)
if (NOT TARGET "FFMPEG::${component}")
add_library("FFMPEG::${component}" UNKNOWN IMPORTED)
set_target_properties("FFMPEG::${component}" PROPERTIES
IMPORTED_LOCATION "${FFMPEG_${component}_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${FFMPEG_${component}_INCLUDE_DIR}"
IMPORTED_LINK_INTERFACE_LIBRARIES "${_deps_link}")
endif ()
set("FFMPEG_${component}_FOUND" 1
PARENT_SCOPE)
set(version_header_path "${FFMPEG_${component}_INCLUDE_DIR}/lib${component}/version.h")
if (EXISTS "${version_header_path}")
string(TOUPPER "${component}" component_upper)
file(STRINGS "${version_header_path}" version
REGEX "#define *LIB${component_upper}_VERSION_(MAJOR|MINOR|MICRO) ")
string(REGEX REPLACE ".*_MAJOR *\([0-9]*\).*" "\\1" major "${version}")
string(REGEX REPLACE ".*_MINOR *\([0-9]*\).*" "\\1" minor "${version}")
string(REGEX REPLACE ".*_MICRO *\([0-9]*\).*" "\\1" micro "${version}")
if (NOT major STREQUAL "" AND
NOT minor STREQUAL "" AND
NOT micro STREQUAL "")
set("FFMPEG_${component}_VERSION" "${major}.${minor}.${micro}"
PARENT_SCOPE)
endif ()
endif ()
else ()
set("FFMPEG_${component}_FOUND" 0
PARENT_SCOPE)
set(what)
if (NOT FFMPEG_${component}_LIBRARY)
set(what "library")
endif ()
if (NOT FFMPEG_${component}_INCLUDE_DIR)
if (what)
string(APPEND what " or headers")
else ()
set(what "headers")
endif ()
endif ()
set("FFMPEG_${component}_NOT_FOUND_MESSAGE"
"Could not find the ${what} for ${component}."
PARENT_SCOPE)
endif ()
endif ()
endfunction ()
_ffmpeg_find(avutil avutil.h)
_ffmpeg_find(avresample avresample.h
avutil)
_ffmpeg_find(swresample swresample.h
avutil)
_ffmpeg_find(swscale swscale.h
avutil)
_ffmpeg_find(avcodec avcodec.h
avutil)
_ffmpeg_find(avformat avformat.h
avcodec avutil)
_ffmpeg_find(avfilter avfilter.h
avutil)
_ffmpeg_find(avdevice avdevice.h
avformat avutil)
if (TARGET FFMPEG::avutil)
set(_ffmpeg_version_header_path "${FFMPEG_avutil_INCLUDE_DIR}/libavutil/ffversion.h")
if (EXISTS "${_ffmpeg_version_header_path}")
file(STRINGS "${_ffmpeg_version_header_path}" _ffmpeg_version
REGEX "FFMPEG_VERSION")
string(REGEX REPLACE ".*\"n?\(.*\)\"" "\\1" FFMPEG_VERSION "${_ffmpeg_version}")
unset(_ffmpeg_version)
else ()
set(FFMPEG_VERSION FFMPEG_VERSION-NOTFOUND)
endif ()
unset(_ffmpeg_version_header_path)
endif ()
set(FFMPEG_INCLUDE_DIRS)
set(FFMPEG_LIBRARIES)
set(_ffmpeg_required_vars)
foreach (_ffmpeg_component IN LISTS FFMPEG_FIND_COMPONENTS)
if (TARGET "FFMPEG::${_ffmpeg_component}")
set(FFMPEG_${_ffmpeg_component}_INCLUDE_DIRS
"${FFMPEG_${_ffmpeg_component}_INCLUDE_DIR}")
set(FFMPEG_${_ffmpeg_component}_LIBRARIES
"${FFMPEG_${_ffmpeg_component}_LIBRARY}")
list(APPEND FFMPEG_INCLUDE_DIRS
"${FFMPEG_${_ffmpeg_component}_INCLUDE_DIRS}")
list(APPEND FFMPEG_LIBRARIES
"${FFMPEG_${_ffmpeg_component}_LIBRARIES}")
if (FFMEG_FIND_REQUIRED_${_ffmpeg_component})
list(APPEND _ffmpeg_required_vars
"FFMPEG_${_ffmpeg_required_vars}_INCLUDE_DIRS"
"FFMPEG_${_ffmpeg_required_vars}_LIBRARIES")
endif ()
endif ()
endforeach ()
unset(_ffmpeg_component)
if (FFMPEG_INCLUDE_DIRS)
list(REMOVE_DUPLICATES FFMPEG_INCLUDE_DIRS)
endif ()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(FFMPEG
REQUIRED_VARS FFMPEG_INCLUDE_DIRS FFMPEG_LIBRARIES ${_ffmpeg_required_vars}
VERSION_VAR FFMPEG_VERSION
HANDLE_COMPONENTS)
unset(_ffmpeg_required_vars)

45
cmake/FindLZ4.cmake Normal file
View File

@@ -0,0 +1,45 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Finds liblz4.
#
# This module defines:
# LZ4_FOUND
# LZ4_INCLUDE_DIR
# LZ4_LIBRARY
#
find_path(LZ4_INCLUDE_DIR NAMES lz4.h)
find_library(LZ4_LIBRARY_DEBUG NAMES lz4d)
find_library(LZ4_LIBRARY_RELEASE NAMES lz4)
include(SelectLibraryConfigurations)
SELECT_LIBRARY_CONFIGURATIONS(LZ4)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(
LZ4 DEFAULT_MSG
LZ4_LIBRARY LZ4_INCLUDE_DIR
)
mark_as_advanced(LZ4_INCLUDE_DIR LZ4_LIBRARY)
if(LZ4_FOUND AND NOT (TARGET LZ4::LZ4))
add_library (LZ4::LZ4 UNKNOWN IMPORTED)
set_target_properties(LZ4::LZ4
PROPERTIES
IMPORTED_LOCATION ${LZ4_LIBRARY}
INTERFACE_INCLUDE_DIRECTORIES ${LZ4_INCLUDE_DIR})
endif()

View File

@@ -0,0 +1,31 @@
# - Try to find libbacktrace
# Once done this will define
# LIBBACKTRACE_FOUND - System has libbacktrace
# LIBBACKTRACE_INCLUDE_DIRS - The libbacktrace include directories
# LIBBACKTRACE_LIBRARIES - The libraries needed to use libbacktrace
FIND_PATH(
LIBBACKTRACE_INCLUDE_DIR backtrace.h
HINTS /usr/include /usr/local/include
${LIBBACKTRACE_PATH_INCLUDES}
)
FIND_LIBRARY(
LIBBACKTRACE_LIBRARY
NAMES backtrace
PATHS ${ADDITIONAL_LIBRARY_PATHS} ${LIBBACKTRACE_PATH_LIB}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Libbacktrace DEFAULT_MSG
LIBBACKTRACE_LIBRARY LIBBACKTRACE_INCLUDE_DIR)
if(LIBBACKTRACE_FOUND)
add_library(libbacktrace::libbacktrace UNKNOWN IMPORTED)
set_target_properties(libbacktrace::libbacktrace PROPERTIES
IMPORTED_LOCATION ${LIBBACKTRACE_LIBRARY}
INTERFACE_INCLUDE_DIRECTORIES ${LIBBACKTRACE_INCLUDE_DIR}
)
endif()
mark_as_advanced(LIBBACKTRACE_INCLUDE_DIR LIBBACKTRACE_LIBRARY)

84
cmake/FindPCAP.cmake Normal file
View File

@@ -0,0 +1,84 @@
# - Try to find libpcap include dirs and libraries
#
# Usage of this module as follows:
#
# find_package(PCAP)
#
# Variables used by this module, they can change the default behaviour and need
# to be set before calling find_package:
#
# PCAP_ROOT_DIR Set this variable to the root installation of
# libpcap if the module has problems finding the
# proper installation path.
#
# Imported Targets:
# PCAP::PCAP The libpcap library, if found
#
# Variables defined by this module:
#
# PCAP_FOUND System has libpcap, include and library dirs found
# PCAP_INCLUDE_DIR The libpcap include directories.
# PCAP_LIBRARY The libpcap library (possibly includes a thread
# library e.g. required by pf_ring's libpcap)
# HAVE_PF_RING If a found version of libpcap supports PF_RING
find_path(PCAP_ROOT_DIR
NAMES include/pcap.h
)
find_path(PCAP_INCLUDE_DIR
NAMES pcap.h
HINTS ${PCAP_ROOT_DIR}/include
)
find_library(PCAP_LIBRARY
NAMES pcap
HINTS ${PCAP_ROOT_DIR}/lib
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(PCAP DEFAULT_MSG
PCAP_LIBRARY
PCAP_INCLUDE_DIR
)
include(CheckCSourceCompiles)
set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARY})
check_c_source_compiles("int main() { return 0; }" PCAP_LINKS_SOLO)
set(CMAKE_REQUIRED_LIBRARIES)
# check if linking against libpcap also needs to link against a thread library
if (NOT PCAP_LINKS_SOLO)
find_package(Threads)
if (THREADS_FOUND)
set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARY} ${CMAKE_THREAD_LIBS_INIT})
check_c_source_compiles("int main() { return 0; }" PCAP_NEEDS_THREADS)
set(CMAKE_REQUIRED_LIBRARIES)
endif ()
if (THREADS_FOUND AND PCAP_NEEDS_THREADS)
set(_tmp ${PCAP_LIBRARY} ${CMAKE_THREAD_LIBS_INIT})
list(REMOVE_DUPLICATES _tmp)
set(PCAP_LIBRARY ${_tmp}
CACHE STRING "Libraries needed to link against libpcap" FORCE)
else ()
message(FATAL_ERROR "Couldn't determine how to link against libpcap")
endif ()
endif ()
include(CheckFunctionExists)
set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARY})
check_function_exists(pcap_get_pfring_id HAVE_PF_RING)
set(CMAKE_REQUIRED_LIBRARIES)
if(PCAP_LIBRARY AND NOT TARGET PCAP::PCAP)
add_library(PCAP::PCAP UNKNOWN IMPORTED GLOBAL)
set_target_properties(PCAP::PCAP PROPERTIES
IMPORTED_LOCATION "${PCAP_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${PCAP_INCLUDE_DIR}")
endif()
mark_as_advanced(
PCAP_ROOT_DIR
PCAP_INCLUDE_DIR
PCAP_LIBRARY
)

31
cmake/FindShaderc.cmake Normal file
View File

@@ -0,0 +1,31 @@
# - Try to find SHADERC
# Once done this will define
# SHADERC_FOUND - System has SHADERC
# SHADERC_INCLUDE_DIRS - The SHADERC include directories
# SHADERC_LIBRARIES - The libraries needed to use SHADERC
find_path(
SHADERC_INCLUDE_DIR shaderc/shaderc.h
${SHADERC_PATH_INCLUDES}
)
find_library(
SHADERC_LIBRARY
NAMES shaderc_shared.1 shaderc_shared shaderc
PATHS ${ADDITIONAL_LIBRARY_PATHS} ${SHADERC_PATH_LIB}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Shaderc DEFAULT_MSG
SHADERC_LIBRARY SHADERC_INCLUDE_DIR)
if(SHADERC_FOUND)
add_library(Shaderc::shaderc_shared UNKNOWN IMPORTED)
set_target_properties(Shaderc::shaderc_shared PROPERTIES
IMPORTED_LOCATION ${SHADERC_LIBRARY}
INTERFACE_INCLUDE_DIRECTORIES ${SHADERC_INCLUDE_DIR}
INTERFACE_COMPILE_DEFINITIONS "SHADERC_SHAREDLIB"
)
endif()
mark_as_advanced(SHADERC_INCLUDE_DIR SHADERC_LIBRARY)

36
cmake/FindVtune.cmake Normal file
View File

@@ -0,0 +1,36 @@
# Find Intel's VTUNE tool
# VTUNE_FOUND found Vtune
# Vtune::Vtune Imported target, if found
# VTUNE_INCLUDE_DIRS include path to jitprofiling.h
# VTUNE_LIBRARIES path to vtune libs
set(VTUNE_PATHS
/opt/intel/oneapi/vtune/latest
/opt/intel/vtune_amplifier_xe_2018
/opt/intel/vtune_amplifier_xe_2017
/opt/intel/vtune_amplifier_xe_2016
"C:\\Program Files (x86)\\Intel\\oneAPI\\vtune\\latest"
)
find_path(VTUNE_INCLUDE_DIRS NAMES jitprofiling.h PATHS ${VTUNE_PATHS} PATH_SUFFIXES include)
find_library(VTUNE_LIBRARIES
NAMES ${CMAKE_STATIC_LIBRARY_PREFIX}jitprofiling${CMAKE_STATIC_LIBRARY_SUFFIX}
PATHS ${VTUNE_PATHS}
PATH_SUFFIXES lib64
)
# handle the QUIETLY and REQUIRED arguments and set VTUNE_FOUND to TRUE if
# all listed variables are TRUE
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Vtune DEFAULT_MSG VTUNE_LIBRARIES VTUNE_INCLUDE_DIRS)
if(VTUNE_LIBRARIES AND NOT TARGET Vtune::Vtune)
add_library(Vtune::Vtune UNKNOWN IMPORTED GLOBAL)
set_target_properties(Vtune::Vtune PROPERTIES
IMPORTED_LOCATION "${VTUNE_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${VTUNE_INCLUDE_DIRS}")
endif()
mark_as_advanced(VTUNE_FOUND VTUNE_INCLUDE_DIRS VTUNE_LIBRARIES)

166
cmake/FindWebP.cmake Normal file
View File

@@ -0,0 +1,166 @@
# Copyright (C) 2020 Sony Interactive Entertainment Inc.
# Copyright (C) 2012 Raphael Kubo da Costa <rakuco@webkit.org>
# Copyright (C) 2013 Igalia S.L.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND ITS CONTRIBUTORS ``AS
# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ITS
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#[=======================================================================[.rst:
FindWebP
--------------
Find WebP headers and libraries.
Imported Targets
^^^^^^^^^^^^^^^^
``WebP::libwebp``
The WebP library, if found.
``WebP::demux``
The WebP demux library, if found.
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables in your project:
``WebP_FOUND``
true if (the requested version of) WebP is available.
``WebP_VERSION``
the version of WebP.
``WebP_LIBRARIES``
the libraries to link against to use WebP.
``WebP_INCLUDE_DIRS``
where to find the WebP headers.
``WebP_COMPILE_OPTIONS``
this should be passed to target_compile_options(), if the
target is not used for linking
#]=======================================================================]
find_package(PkgConfig QUIET)
pkg_check_modules(PC_WEBP QUIET libwebp)
set(WebP_COMPILE_OPTIONS ${PC_WEBP_CFLAGS_OTHER})
set(WebP_VERSION ${PC_WEBP_CFLAGS_VERSION})
find_path(WebP_INCLUDE_DIR
NAMES webp/decode.h
HINTS ${PC_WEBP_INCLUDEDIR} ${PC_WEBP_INCLUDE_DIRS}
)
find_library(WebP_LIBRARY
NAMES ${WebP_NAMES} webp libwebp
HINTS ${PC_WEBP_LIBDIR} ${PC_WEBP_LIBRARY_DIRS}
)
# There's nothing in the WebP headers that could be used to detect the exact
# WebP version being used so don't attempt to do so. A version can only be found
# through pkg-config
if ("${WebP_FIND_VERSION}" VERSION_GREATER "${WebP_VERSION}")
if (WebP_VERSION)
message(FATAL_ERROR "Required version (" ${WebP_FIND_VERSION} ") is higher than found version (" ${WebP_VERSION} ")")
else ()
message(WARNING "Cannot determine WebP version without pkg-config")
endif ()
endif ()
# Find components
if (WebP_INCLUDE_DIR AND WebP_LIBRARY)
set(_WebP_REQUIRED_LIBS_FOUND ON)
set(WebP_LIBS_FOUND "WebP (required): ${WebP_LIBRARY}")
else ()
set(_WebP_REQUIRED_LIBS_FOUND OFF)
set(WebP_LIBS_NOT_FOUND "WebP (required)")
endif ()
if ("demux" IN_LIST WebP_FIND_COMPONENTS)
find_library(WebP_DEMUX_LIBRARY
NAMES ${WebP_DEMUX_NAMES} webpdemux libwebpdemux
HINTS ${PC_WEBP_LIBDIR} ${PC_WEBP_LIBRARY_DIRS}
)
if (WebP_DEMUX_LIBRARY)
if (WebP_FIND_REQUIRED_demux)
list(APPEND WebP_LIBS_FOUND "demux (required): ${WebP_DEMUX_LIBRARY}")
else ()
list(APPEND WebP_LIBS_FOUND "demux (optional): ${WebP_DEMUX_LIBRARY}")
endif ()
else ()
if (WebP_FIND_REQUIRED_demux)
set(_WebP_REQUIRED_LIBS_FOUND OFF)
list(APPEND WebP_LIBS_NOT_FOUND "demux (required)")
else ()
list(APPEND WebP_LIBS_NOT_FOUND "demux (optional)")
endif ()
endif ()
endif ()
if (NOT WebP_FIND_QUIETLY)
if (WebP_LIBS_FOUND)
message(STATUS "Found the following WebP libraries:")
foreach (found ${WebP_LIBS_FOUND})
message(STATUS " ${found}")
endforeach ()
endif ()
if (WebP_LIBS_NOT_FOUND)
message(STATUS "The following WebP libraries were not found:")
foreach (found ${WebP_LIBS_NOT_FOUND})
message(STATUS " ${found}")
endforeach ()
endif ()
endif ()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(WebP
FOUND_VAR WebP_FOUND
REQUIRED_VARS WebP_INCLUDE_DIR WebP_LIBRARY _WebP_REQUIRED_LIBS_FOUND
VERSION_VAR WebP_VERSION
)
if (WebP_LIBRARY AND NOT TARGET WebP::libwebp)
add_library(WebP::libwebp UNKNOWN IMPORTED GLOBAL)
set_target_properties(WebP::libwebp PROPERTIES
IMPORTED_LOCATION "${WebP_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${WebP_COMPILE_OPTIONS}"
INTERFACE_INCLUDE_DIRECTORIES "${WebP_INCLUDE_DIR}"
)
endif ()
if (WebP_DEMUX_LIBRARY AND NOT TARGET WebP::demux)
add_library(WebP::demux UNKNOWN IMPORTED GLOBAL)
set_target_properties(WebP::demux PROPERTIES
IMPORTED_LOCATION "${WebP_DEMUX_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${WebP_COMPILE_OPTIONS}"
INTERFACE_INCLUDE_DIRECTORIES "${WebP_INCLUDE_DIR}"
)
endif ()
mark_as_advanced(
WebP_INCLUDE_DIR
WebP_LIBRARY
WebP_DEMUX_LIBRARY
)
if (WebP_FOUND)
set(WebP_LIBRARIES ${WebP_LIBRARY} ${WebP_DEMUX_LIBRARY})
set(WebP_INCLUDE_DIRS ${WebP_INCLUDE_DIR})
endif ()

45
cmake/FindZstd.cmake Normal file
View File

@@ -0,0 +1,45 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# - Try to find Facebook zstd library
# This will define
# Zstd_FOUND
# Zstd_INCLUDE_DIR
# Zstd_LIBRARY
#
find_path(Zstd_INCLUDE_DIR NAMES zstd.h)
find_library(Zstd_LIBRARY_DEBUG NAMES zstdd zstd_staticd)
find_library(Zstd_LIBRARY_RELEASE NAMES zstd zstd_static)
include(SelectLibraryConfigurations)
SELECT_LIBRARY_CONFIGURATIONS(Zstd)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(
Zstd DEFAULT_MSG
Zstd_LIBRARY Zstd_INCLUDE_DIR
)
mark_as_advanced(Zstd_INCLUDE_DIR Zstd_LIBRARY)
if(Zstd_FOUND AND NOT (TARGET Zstd::Zstd))
add_library (Zstd::Zstd UNKNOWN IMPORTED)
set_target_properties(Zstd::Zstd
PROPERTIES
IMPORTED_LOCATION ${Zstd_LIBRARY}
INTERFACE_INCLUDE_DIRECTORIES ${Zstd_INCLUDE_DIR})
endif()

347
cmake/Pcsx2Utils.cmake Normal file
View File

@@ -0,0 +1,347 @@
function(detect_operating_system)
message(STATUS "CMake Version: ${CMAKE_VERSION}")
message(STATUS "CMake System Name: ${CMAKE_SYSTEM_NAME}")
# LINUX wasn't added until CMake 3.25.
if (CMAKE_VERSION VERSION_LESS 3.25.0 AND CMAKE_SYSTEM_NAME MATCHES "Linux")
# Have to make it visible in this scope as well for below.
set(LINUX TRUE PARENT_SCOPE)
set(LINUX TRUE)
endif()
if(WIN32)
message(STATUS "Building for Windows.")
elseif(APPLE AND NOT IOS)
message(STATUS "Building for MacOS.")
elseif(LINUX)
message(STATUS "Building for Linux.")
elseif(BSD)
message(STATUS "Building for *BSD.")
else()
message(FATAL_ERROR "Unsupported platform.")
endif()
endfunction()
function(detect_compiler)
if(MSVC AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(USE_CLANG_CL TRUE PARENT_SCOPE)
set(IS_SUPPORTED_COMPILER TRUE PARENT_SCOPE)
message(STATUS "Building with Clang-CL.")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
set(USE_CLANG TRUE PARENT_SCOPE)
set(IS_SUPPORTED_COMPILER TRUE PARENT_SCOPE)
message(STATUS "Building with Clang/LLVM.")
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(USE_GCC TRUE PARENT_SCOPE)
set(IS_SUPPORTED_COMPILER FALSE PARENT_SCOPE)
message(STATUS "Building with GNU GCC.")
elseif(MSVC)
set(IS_SUPPORTED_COMPILER TRUE PARENT_SCOPE)
message(STATUS "Building with MSVC.")
else()
message(FATAL_ERROR "Unknown compiler: ${CMAKE_CXX_COMPILER_ID}")
endif()
endfunction()
function(get_git_version_info)
set(PCSX2_GIT_REV "")
set(PCSX2_GIT_TAG "")
set(PCSX2_GIT_HASH "")
if (GIT_FOUND AND EXISTS ${PROJECT_SOURCE_DIR}/.git)
EXECUTE_PROCESS(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} describe --tags
OUTPUT_VARIABLE PCSX2_GIT_REV
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
EXECUTE_PROCESS(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} tag --points-at HEAD --sort=version:refname
OUTPUT_VARIABLE PCSX2_GIT_TAG_LIST
RESULT_VARIABLE TAG_RESULT
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
# CAUTION: There is a race here, this solves the problem of a commit being tagged multiple times (take the last tag)
# however, if simultaneous builds are pushing tags to the same commit you might get inconsistent results (it's a race)
#
# The easy solution is, don't do that, but just something to be aware of.
if(PCSX2_GIT_TAG_LIST AND TAG_RESULT EQUAL 0)
string(REPLACE "\n" ";" PCSX2_GIT_TAG_LIST "${PCSX2_GIT_TAG_LIST}")
if (PCSX2_GIT_TAG_LIST)
list(GET PCSX2_GIT_TAG_LIST -1 PCSX2_GIT_TAG)
message("Using tag: ${PCSX2_GIT_TAG}")
endif()
endif()
EXECUTE_PROCESS(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
OUTPUT_VARIABLE PCSX2_GIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
EXECUTE_PROCESS(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} log -1 --format=%cd --date=local
OUTPUT_VARIABLE PCSX2_GIT_DATE
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
endif()
if (NOT PCSX2_GIT_REV)
EXECUTE_PROCESS(WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
OUTPUT_VARIABLE PCSX2_GIT_REV
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
if (NOT PCSX2_GIT_REV)
set(PCSX2_GIT_REV "Unknown")
endif()
endif()
if(DEFINED PCSX2_GIT_REV_OVERRIDE)
set(PCSX2_GIT_REV "${PCSX2_GIT_REV_OVERRIDE}")
endif()
set(PCSX2_GIT_REV "${PCSX2_GIT_REV}" PARENT_SCOPE)
set(PCSX2_GIT_TAG "${PCSX2_GIT_TAG}" PARENT_SCOPE)
set(PCSX2_GIT_HASH "${PCSX2_GIT_HASH}" PARENT_SCOPE)
set(PCSX2_GIT_DATE "${PCSX2_GIT_DATE}" PARENT_SCOPE)
endfunction()
function(write_svnrev_h)
if ("${PCSX2_GIT_TAG}" MATCHES "^v([0-9]+)\\.([0-9]+)\\.([0-9]+)$")
file(WRITE ${CMAKE_BINARY_DIR}/common/include/svnrev.h
"#define GIT_TAG \"${PCSX2_GIT_TAG}\"\n"
"#define GIT_TAGGED_COMMIT 1\n"
"#define GIT_TAG_HI ${CMAKE_MATCH_1}\n"
"#define GIT_TAG_MID ${CMAKE_MATCH_2}\n"
"#define GIT_TAG_LO ${CMAKE_MATCH_3}\n"
"#define GIT_REV \"${PCSX2_GIT_TAG}\"\n"
"#define GIT_HASH \"${PCSX2_GIT_HASH}\"\n"
"#define GIT_DATE \"${PCSX2_GIT_DATE}\"\n"
)
elseif ("${PCSX2_GIT_REV}" MATCHES "^v([0-9]+)\\.([0-9]+)\\.([0-9]+)")
file(WRITE ${CMAKE_BINARY_DIR}/common/include/svnrev.h
"#define GIT_TAG \"${PCSX2_GIT_TAG}\"\n"
"#define GIT_TAGGED_COMMIT 0\n"
"#define GIT_TAG_HI ${CMAKE_MATCH_1}\n"
"#define GIT_TAG_MID ${CMAKE_MATCH_2}\n"
"#define GIT_TAG_LO ${CMAKE_MATCH_3}\n"
"#define GIT_REV \"${PCSX2_GIT_REV}\"\n"
"#define GIT_HASH \"${PCSX2_GIT_HASH}\"\n"
"#define GIT_DATE \"${PCSX2_GIT_DATE}\"\n"
)
else()
file(WRITE ${CMAKE_BINARY_DIR}/common/include/svnrev.h
"#define GIT_TAG \"${PCSX2_GIT_TAG}\"\n"
"#define GIT_TAGGED_COMMIT 0\n"
"#define GIT_TAG_HI 0\n"
"#define GIT_TAG_MID 0\n"
"#define GIT_TAG_LO 0\n"
"#define GIT_REV \"${PCSX2_GIT_REV}\"\n"
"#define GIT_HASH \"${PCSX2_GIT_HASH}\"\n"
"#define GIT_DATE \"${PCSX2_GIT_DATE}\"\n"
)
endif()
endfunction()
function(check_no_parenthesis_in_path)
if ("${CMAKE_BINARY_DIR}" MATCHES "[()]" OR "${CMAKE_SOURCE_DIR}" MATCHES "[()]")
message(FATAL_ERROR "Your path contains some parenthesis. Unfortunately Cmake doesn't support them correctly.\nPlease rename your directory to avoid '(' and ')' characters\n")
endif()
endfunction()
# like add_library(new ALIAS old) but avoids add_library cannot create ALIAS target "new" because target "old" is imported but not globally visible. on older cmake
function(alias_library new old)
string(REPLACE "::" "" library_no_namespace ${old})
if (NOT TARGET _alias_${library_no_namespace})
add_library(_alias_${library_no_namespace} INTERFACE)
target_link_libraries(_alias_${library_no_namespace} INTERFACE ${old})
endif()
add_library(${new} ALIAS _alias_${library_no_namespace})
endfunction()
function(source_groups_from_vcxproj_filters file)
file(READ "${file}" filecontent)
get_filename_component(parent "${file}" DIRECTORY)
if (parent STREQUAL "")
set(parent ".")
endif()
set(regex "<[^ ]+ Include=\"([^\"]+)\">[ \t\r\n]+<Filter>([^<]+)<\\/Filter>[ \t\r\n]+<\\/[^ >]+>")
string(REGEX MATCHALL "${regex}" filterstrings "${filecontent}")
foreach(filterstring IN LISTS filterstrings)
string(REGEX REPLACE "${regex}" "\\1" path "${filterstring}")
string(REGEX REPLACE "${regex}" "\\2" group "${filterstring}")
source_group("${group}" FILES "${parent}/${path}")
endforeach()
endfunction()
# Extracts a translation with the given type ("source" or "translation") from the given category of the given ts file
# (If there's multiple strings under the same category, which one it extracts is implementation defined. Just don't do it.)
function(extract_translation_from_ts file type category output)
file(READ "${file}" filecontent)
# Don't you love it when the best parser your language has to offer is regex?
set(regex_search "(<[^\\/>]+>[^<>]+<\\/[^>\\/]+>|<\\/?context>)")
set(regex_extract "<[^\\/>]+>([^<>]+)<\\/([^>\\/]+)>")
string(REGEX MATCHALL "${regex_search}" pieces "${filecontent}")
foreach(piece IN LISTS pieces)
if (piece STREQUAL "<context>")
set(found "")
set(name_match FALSE)
elseif (piece STREQUAL "</context>")
if (name_match)
set(${output} "${found}" PARENT_SCOPE)
break()
endif()
else()
string(REGEX REPLACE "${regex_extract}" "\\1" content "${piece}")
string(REGEX REPLACE "${regex_extract}" "\\2" tag "${piece}")
if (tag STREQUAL "name" AND content STREQUAL "${category}")
set(name_match TRUE)
endif()
if (tag STREQUAL "${type}")
set(found "${content}")
endif()
endif()
endforeach()
endfunction()
function(fixup_file_properties target)
get_target_property(SOURCES ${target} SOURCES)
if(APPLE)
foreach(source IN LISTS SOURCES)
# Set the right file types for .inl files in Xcode
if("${source}" MATCHES "\\.(inl|h)$")
set_source_files_properties("${source}" PROPERTIES XCODE_EXPLICIT_FILE_TYPE sourcecode.cpp.h)
endif()
if("${source}" MATCHES "\\.(qm)$")
set_source_files_properties("${source}" PROPERTIES XCODE_EXPLICIT_FILE_TYPE compiled)
endif()
# CMake makefile and ninja generators will attempt to share one PCH for both cpp and mm files
# That's not actually OK
if("${source}" MATCHES "\\.mm$")
set_source_files_properties("${source}" PROPERTIES SKIP_PRECOMPILE_HEADERS ON)
endif()
endforeach()
endif()
endfunction()
function(disable_compiler_warnings_for_target target)
if(MSVC)
target_compile_options(${target} PRIVATE "/W0")
else()
target_compile_options(${target} PRIVATE "-w")
endif()
endfunction()
function(detect_page_size)
message(STATUS "Determining host page size")
set(detect_page_size_file ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c)
file(WRITE ${detect_page_size_file} "
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
int res = sysconf(_SC_PAGESIZE);
printf(\"%d\", res);
return (res > 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}")
try_run(
detect_page_size_run_result
detect_page_size_compile_result
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}
${detect_page_size_file}
RUN_OUTPUT_VARIABLE detect_page_size_output)
if(NOT detect_page_size_compile_result OR NOT detect_page_size_run_result EQUAL 0 OR CMAKE_CROSSCOMPILING)
message(FATAL_ERROR "Could not determine host page size.")
else()
message(STATUS "Host page size: ${detect_page_size_output}")
set(HOST_PAGE_SIZE ${detect_page_size_output} CACHE STRING "Reported host page size")
endif()
endfunction()
function(detect_cache_line_size)
message(STATUS "Determining host cache line size")
set(detect_cache_line_size_file ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.c)
file(WRITE ${detect_cache_line_size_file} "
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main() {
int l1i = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
int l1d = sysconf(_SC_LEVEL1_ICACHE_LINESIZE);
int res = (l1i > l1d) ? l1i : l1d;
for (int index = 0; index < 16; index++) {
char buf[128];
snprintf(buf, sizeof(buf), \"/sys/devices/system/cpu/cpu0/cache/index%d/coherency_line_size\", index);
FILE* fp = fopen(buf, \"rb\");
if (!fp)
break;
fread(buf, sizeof(buf), 1, fp);
fclose(fp);
int val = atoi(buf);
res = (val > res) ? val : res;
}
printf(\"%d\", res);
return (res > 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}")
try_run(
detect_cache_line_size_run_result
detect_cache_line_size_compile_result
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}
${detect_cache_line_size_file}
RUN_OUTPUT_VARIABLE detect_cache_line_size_output)
if(NOT detect_cache_line_size_compile_result OR NOT detect_cache_line_size_run_result EQUAL 0 OR CMAKE_CROSSCOMPILING)
message(FATAL_ERROR "Could not determine host cache line size.")
else()
message(STATUS "Host cache line size: ${detect_cache_line_size_output}")
set(HOST_CACHE_LINE_SIZE ${detect_cache_line_size_output} CACHE STRING "Reported host cache line size")
endif()
endfunction()
function(get_recursive_include_directories output target inc_prop link_prop)
get_target_property(dirs ${target} ${inc_prop})
if(NOT dirs)
set(dirs)
endif()
get_target_property(deps ${target} ${link_prop})
if(deps)
foreach(dep IN LISTS deps)
if(TARGET ${dep})
get_recursive_include_directories(depdirs ${dep} INTERFACE_INCLUDE_DIRECTORIES INTERFACE_LINK_LIBRARIES)
foreach(depdir IN LISTS depdirs)
# Only match absolute paths
# We'll hope any non-absolute paths will not get set as system directories
if(depdir MATCHES "^/")
list(APPEND dirs ${depdir})
endif()
endforeach()
endif()
endforeach()
list(REMOVE_DUPLICATES dirs)
endif()
set(${output} "${dirs}" PARENT_SCOPE)
endfunction()
function(force_include_last_impl target include inc_prop link_prop)
get_recursive_include_directories(dirs ${target} ${inc_prop} ${link_prop})
set(remove)
foreach(dir IN LISTS dirs)
if("${dir}" MATCHES "${include}")
list(APPEND remove ${dir})
endif()
endforeach()
if(NOT "${remove}" STREQUAL "")
get_target_property(sysdirs ${target} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES)
if(NOT sysdirs)
set(sysdirs)
endif()
# Move matching items to the end
list(REMOVE_ITEM dirs ${remove})
list(APPEND dirs ${remove})
# Set them as system include directories
list(APPEND sysdirs ${remove})
list(REMOVE_DUPLICATES sysdirs)
set_target_properties(${target} PROPERTIES
${inc_prop} "${dirs}"
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${sysdirs}"
)
endif()
endfunction()
function(force_include_last target include)
force_include_last_impl(${target} "${include}" INTERFACE_INCLUDE_DIRECTORIES INTERFACE_LINK_LIBRARIES)
force_include_last_impl(${target} "${include}" INCLUDE_DIRECTORIES LINK_LIBRARIES)
endfunction()

162
cmake/SearchForStuff.cmake Normal file
View File

@@ -0,0 +1,162 @@
#-------------------------------------------------------------------------------
# Search all libraries on the system
#-------------------------------------------------------------------------------
find_package(Git)
# Require threads on all OSes.
find_package(Threads REQUIRED)
# Dependency libraries.
# On macOS, Mono.framework contains an ancient version of libpng. We don't want that.
# Avoid it by telling cmake to avoid finding frameworks while we search for libpng.
set(FIND_FRAMEWORK_BACKUP ${CMAKE_FIND_FRAMEWORK})
set(CMAKE_FIND_FRAMEWORK NEVER)
find_package(PNG 1.6.37 REQUIRED)
find_package(JPEG REQUIRED) # No version because flatpak uses libjpeg-turbo.
find_package(ZLIB REQUIRED) # v1.3, but Mac uses the SDK version.
find_package(Zstd 1.5.5 REQUIRED)
find_package(LZ4 REQUIRED)
find_package(WebP REQUIRED) # v1.3.2, spews an error on Linux because no pkg-config.
find_package(SDL3 3.2.6)
if (TARGET SDL3::SDL3)
add_library(SDL3::SDL3-use ALIAS SDL3::SDL3-shared)
else()
add_subdirectory(3rdparty/sdl EXCLUDE_FROM_ALL)
add_library(SDL3::SDL3-use ALIAS SDL3-static)
endif()
find_package(Freetype 2.11.1 REQUIRED)
find_package(plutovg QUIET) # v0.0.13 is needed for building plutosvg, but we can support v1.0.0
find_package(plutosvg 0.0.6 QUIET)
if (NOT TARGET plutosvg::plutosvg)
add_subdirectory(3rdparty/plutosvg EXCLUDE_FROM_ALL)
endif()
if(USE_VULKAN)
find_package(Shaderc)
if (NOT TARGET Shaderc::shaderc_shared)
set(SHADERC_SKIP_TESTS ON)
set(SHADERC_SKIP_EXAMPLES ON)
set(SHADERC_SKIP_COPYRIGHT_CHECK ON)
add_subdirectory(3rdparty/shaderc EXCLUDE_FROM_ALL)
add_library(Shaderc::shaderc_shared ALIAS shaderc)
endif()
endif()
# Platform-specific dependencies.
if (WIN32)
add_subdirectory(3rdparty/D3D12MemAlloc EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/winpixeventruntime EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/winwil EXCLUDE_FROM_ALL)
set(FFMPEG_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/3rdparty/ffmpeg/include")
find_package(Vtune)
else()
find_package(CURL REQUIRED)
find_package(PCAP REQUIRED)
find_package(Vtune)
# Use bundled ffmpeg v4.x.x headers if we can't locate it in the system.
# We'll try to load it dynamically at runtime.
find_package(FFMPEG COMPONENTS avcodec avformat avutil swresample swscale)
if(NOT FFMPEG_FOUND)
message(WARNING "FFmpeg not found, using bundled headers.")
set(FFMPEG_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/3rdparty/ffmpeg/include")
endif()
## Use CheckLib package to find module
include(CheckLib)
if(UNIX AND NOT APPLE)
if(LINUX)
check_lib(LIBUDEV libudev libudev.h)
endif()
if(X11_API)
find_package(X11 REQUIRED)
if (NOT X11_Xrandr_FOUND)
message(FATAL_ERROR "XRandR extension is required")
endif()
endif()
if(WAYLAND_API)
find_package(ECM REQUIRED NO_MODULE)
list(APPEND CMAKE_MODULE_PATH "${ECM_MODULE_PATH}")
find_package(Wayland REQUIRED Egl)
endif()
if(USE_BACKTRACE)
find_package(Libbacktrace REQUIRED)
endif()
find_package(PkgConfig REQUIRED)
pkg_check_modules(DBUS REQUIRED dbus-1)
endif()
endif()
set(CMAKE_FIND_FRAMEWORK ${FIND_FRAMEWORK_BACKUP})
add_subdirectory(3rdparty/fast_float EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/rapidyaml EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/lzma EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/libchdr EXCLUDE_FROM_ALL)
disable_compiler_warnings_for_target(libchdr)
add_subdirectory(3rdparty/soundtouch EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/simpleini EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/imgui EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/cpuinfo EXCLUDE_FROM_ALL)
disable_compiler_warnings_for_target(cpuinfo)
add_subdirectory(3rdparty/libzip EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/rcheevos EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/rapidjson EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/discord-rpc EXCLUDE_FROM_ALL)
add_subdirectory(3rdparty/freesurround EXCLUDE_FROM_ALL)
if(USE_OPENGL)
add_subdirectory(3rdparty/glad EXCLUDE_FROM_ALL)
endif()
if(USE_VULKAN)
add_subdirectory(3rdparty/vulkan EXCLUDE_FROM_ALL)
endif()
add_subdirectory(3rdparty/cubeb EXCLUDE_FROM_ALL)
disable_compiler_warnings_for_target(cubeb)
disable_compiler_warnings_for_target(speex)
# Find the Qt components that we need.
find_package(Qt6 6.2.4 COMPONENTS CoreTools Core GuiTools Gui WidgetsTools Widgets LinguistTools REQUIRED)
if(WIN32)
add_subdirectory(3rdparty/rainterface EXCLUDE_FROM_ALL)
endif()
# Demangler for the debugger.
add_subdirectory(3rdparty/demangler EXCLUDE_FROM_ALL)
# Symbol table parser.
add_subdirectory(3rdparty/ccc EXCLUDE_FROM_ALL)
# The docking system for the debugger.
find_package(KDDockWidgets-qt6 2.0.0 REQUIRED)
# Add an extra include path to work around a broken include directive.
# TODO: Remove this the next time we update KDDockWidgets.
get_target_property(KDDOCKWIDGETS_INCLUDE_DIRECTORY KDAB::kddockwidgets INTERFACE_INCLUDE_DIRECTORIES)
target_include_directories(KDAB::kddockwidgets INTERFACE
${KDDOCKWIDGETS_INCLUDE_DIRECTORY}/kddockwidgets
)
# Architecture-specific.
if(_M_X86)
add_subdirectory(3rdparty/zydis EXCLUDE_FROM_ALL)
elseif(_M_ARM64)
add_subdirectory(3rdparty/vixl EXCLUDE_FROM_ALL)
endif()
# Prevent fmt from being built with exceptions, or being thrown at call sites.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DFMT_USE_EXCEPTIONS=0 -DFMT_USE_RTTI=0")
add_subdirectory(3rdparty/fmt EXCLUDE_FROM_ALL)
# Deliberately at the end. We don't want to set the flag on third-party projects.
if(MSVC)
# Don't warn about "deprecated" POSIX functions.
add_definitions("-D_CRT_NONSTDC_NO_WARNINGS" "-D_CRT_SECURE_NO_WARNINGS" "-DCRT_SECURE_NO_DEPRECATE")
endif()