From 1cae50b7a3b30f67a9c41acdeac7079765eae8da Mon Sep 17 00:00:00 2001 From: jcm <6864788+jcm93@users.noreply.github.com> Date: Thu, 31 Oct 2024 18:24:12 -0500 Subject: [PATCH] CMake: add infrastructure, macOS, Windows, Linux builds --- .gitignore | 42 +- CMakeLists.txt | 96 +--- CMakePresets.json | 82 ++++ LICENSE | 2 +- Legacy Build System.md | 120 +++++ README.md | 238 +++++---- ares/CMakeLists.txt | 260 ++++++++-- ares/a26/CMakeLists.txt | 83 +++- ares/cmake/os-freebsd.cmake | 4 + ares/cmake/os-linux.cmake | 4 + ares/cmake/os-macos.cmake | 1 + ares/cmake/os-windows.cmake | 12 + ares/cv/CMakeLists.txt | 84 +++- ares/fc/CMakeLists.txt | 191 +++++++- ares/gb/CMakeLists.txt | 84 +++- ares/gba/CMakeLists.txt | 97 +++- ares/md/CMakeLists.txt | 178 ++++++- ares/ms/CMakeLists.txt | 156 +++++- ares/msx/CMakeLists.txt | 116 ++++- ares/msx/rtc/rtc.cpp | 2 +- ares/myvision/CMakeLists.txt | 64 ++- ares/n64/CMakeLists.txt | 342 ++++++++++--- ares/n64/cmake/os-linux.cmake | 0 ares/n64/cmake/os-macos.cmake | 12 + ares/n64/cmake/os-windows.cmake | 0 ares/n64/cpu/recompiler.cpp | 3 + ares/ng/CMakeLists.txt | 104 +++- ares/ngp/CMakeLists.txt | 87 +++- ares/pce/CMakeLists.txt | 134 +++++- ares/ps1/CMakeLists.txt | 162 ++++++- ares/saturn/CMakeLists.txt | 11 +- ares/sfc/CMakeLists.txt | 264 +++++++++- ares/sfc/coprocessor/superfx/core.cpp | 4 +- ares/sg/CMakeLists.txt | 94 +++- ares/spec/CMakeLists.txt | 74 ++- ares/ws/CMakeLists.txt | 107 ++++- buildspec.json | 16 + cmake/CMakeLists.txt | 37 ++ cmake/Dependencies.md | 67 +++ cmake/README.md | 12 + cmake/common/bootstrap.cmake | 52 ++ cmake/common/ccache.cmake | 24 + cmake/common/compiler_common.cmake | 85 ++++ cmake/common/dependencies_common.cmake | 90 ++++ cmake/common/helpers_common.cmake | 269 +++++++++++ cmake/common/osconfig.cmake | 19 + cmake/common/versionconfig.cmake | 24 + cmake/finders/FindAO.cmake | 89 ++++ cmake/finders/FindGTK.cmake | 93 ++++ cmake/finders/FindMoltenVK.cmake | 138 ++++++ cmake/finders/FindOSS.cmake | 64 +++ cmake/finders/FindSDL.cmake | 147 ++++++ cmake/finders/Findlibrashader.cmake | 162 +++++++ cmake/linux/compilerconfig.cmake | 7 + cmake/linux/defaults.cmake | 11 + cmake/linux/dependencies.cmake | 21 + cmake/linux/helpers.cmake | 24 + cmake/macos/compilerconfig.cmake | 53 ++ cmake/macos/defaults.cmake | 29 ++ cmake/macos/dependencies.cmake | 28 ++ cmake/macos/helpers.cmake | 164 +++++++ cmake/macos/resources/ccache-launcher-c.in | 14 + cmake/macos/resources/ccache-launcher-cxx.in | 14 + cmake/macos/xcode.cmake | 168 +++++++ cmake/windows/compilerconfig.cmake | 118 +++++ cmake/windows/defaults.cmake | 15 + cmake/windows/dependencies.cmake | 16 + cmake/windows/helpers.cmake | 211 ++++++++ desktop-ui/CMakeLists.txt | 60 ++- desktop-ui/cmake/macos/Info.plist.in | 39 ++ desktop-ui/cmake/macos/entitlements.plist | 10 + desktop-ui/cmake/macos/exportOptions.plist.in | 14 + desktop-ui/cmake/os-linux.cmake | 61 +++ desktop-ui/cmake/os-macos.cmake | 96 ++++ desktop-ui/cmake/os-windows.cmake | 26 + desktop-ui/cmake/sources.cmake | 98 ++++ .../AppIcon.appiconset/Contents.json | 68 +++ .../AppIcon.appiconset/ares 1.png | Bin 0 -> 11155 bytes .../AppIcon.appiconset/ares.png | Bin 0 -> 11155 bytes .../AppIcon.appiconset/ares@1024x1024.png | Bin 0 -> 168908 bytes .../AppIcon.appiconset/ares@128x128.png | Bin 0 -> 9254 bytes .../AppIcon.appiconset/ares@16x16.png | Bin 0 -> 1231 bytes .../AppIcon.appiconset/ares@32x32 1.png | Bin 0 -> 2157 bytes .../AppIcon.appiconset/ares@32x32.png | Bin 0 -> 2157 bytes .../AppIcon.appiconset/ares@512x512 1.png | Bin 0 -> 54059 bytes .../AppIcon.appiconset/ares@512x512.png | Bin 0 -> 54059 bytes .../AppIcon.appiconset/ares@64x64.png | Bin 0 -> 4105 bytes .../resource/Assets.xcassets/Contents.json | 6 + .../font.imageset/Contents.json | 21 + .../Assets.xcassets/font.imageset/font.png | Bin 0 -> 2909 bytes desktop-ui/resource/ares.entitlements | 6 +- desktop-ui/resource/ares.plist | 74 +-- hiro/CMakeLists.txt | 110 +---- hiro/cmake/os-bsd.cmake | 1 + hiro/cmake/os-linux.cmake | 31 ++ hiro/cmake/os-macos.cmake | 24 + hiro/cmake/os-windows.cmake | 15 + hiro/cmake/sources.cmake | 451 ++++++++++++++++++ hiro/hiro.mm | 1 + libco/CMakeLists.txt | 32 ++ mia/CMakeLists.txt | 150 +++++- mia/CMakeLists.txt.rej | 10 + mia/cmake/macos/entitlements.plist | 10 + mia/cmake/os-macos.cmake | 28 ++ nall/CMakeLists.txt | 319 +++---------- nall/cmake/os-freebsd.cmake | 1 + nall/cmake/os-linux.cmake | 9 + nall/cmake/os-macos.cmake | 8 + nall/cmake/os-windows.cmake | 41 ++ nall/cmake/sources.cmake | 296 ++++++++++++ nall/decode/inflate.hpp | 3 +- nall/intrinsics.hpp | 12 +- nall/macos/guard.hpp | 5 +- nall/sljitAllocator.cpp | 9 + ruby/CMakeLists.txt | 176 ++----- ruby/audio/sdl.cpp | 4 - ruby/cmake/os-freebsd.cmake | 30 ++ ruby/cmake/os-linux.cmake | 90 ++++ ruby/cmake/os-macos.cmake | 64 +++ ruby/cmake/os-windows.cmake | 71 +++ ruby/input/sdl.cpp | 4 - ruby/ruby.mm | 1 + ruby/video/metal/metal.hpp | 4 +- ruby/video/opengl/opengl.hpp | 3 +- ruby/video/opengl/utility.hpp | 2 +- ruby/video/video.cpp | 2 +- tests/i8080/CMakeLists.txt | 6 +- thirdparty/CMakeLists.txt | 89 ++-- .../zlib-1.3.1/{zconf.h => zconf.h.included} | 0 tools/genius/CMakeLists.txt | 21 +- tools/genius/cmake/macos/Info.plist.in | 0 tools/genius/cmake/macos/entitlements.plist | 10 + tools/genius/cmake/os-linux.cmake | 0 tools/genius/cmake/os-macos.cmake | 35 ++ tools/mame2bml/CMakeLists.txt | 7 +- tools/sourcery/CMakeLists.txt | 10 +- 136 files changed, 7260 insertions(+), 1109 deletions(-) create mode 100644 CMakePresets.json create mode 100644 Legacy Build System.md create mode 100644 ares/cmake/os-freebsd.cmake create mode 100644 ares/cmake/os-linux.cmake create mode 100644 ares/cmake/os-macos.cmake create mode 100644 ares/cmake/os-windows.cmake create mode 100644 ares/n64/cmake/os-linux.cmake create mode 100644 ares/n64/cmake/os-macos.cmake create mode 100644 ares/n64/cmake/os-windows.cmake create mode 100644 buildspec.json create mode 100644 cmake/CMakeLists.txt create mode 100644 cmake/Dependencies.md create mode 100644 cmake/README.md create mode 100644 cmake/common/bootstrap.cmake create mode 100644 cmake/common/ccache.cmake create mode 100644 cmake/common/compiler_common.cmake create mode 100644 cmake/common/dependencies_common.cmake create mode 100644 cmake/common/helpers_common.cmake create mode 100644 cmake/common/osconfig.cmake create mode 100644 cmake/common/versionconfig.cmake create mode 100644 cmake/finders/FindAO.cmake create mode 100644 cmake/finders/FindGTK.cmake create mode 100644 cmake/finders/FindMoltenVK.cmake create mode 100644 cmake/finders/FindOSS.cmake create mode 100644 cmake/finders/FindSDL.cmake create mode 100644 cmake/finders/Findlibrashader.cmake create mode 100644 cmake/linux/compilerconfig.cmake create mode 100644 cmake/linux/defaults.cmake create mode 100644 cmake/linux/dependencies.cmake create mode 100644 cmake/linux/helpers.cmake create mode 100644 cmake/macos/compilerconfig.cmake create mode 100644 cmake/macos/defaults.cmake create mode 100644 cmake/macos/dependencies.cmake create mode 100644 cmake/macos/helpers.cmake create mode 100644 cmake/macos/resources/ccache-launcher-c.in create mode 100755 cmake/macos/resources/ccache-launcher-cxx.in create mode 100644 cmake/macos/xcode.cmake create mode 100644 cmake/windows/compilerconfig.cmake create mode 100644 cmake/windows/defaults.cmake create mode 100644 cmake/windows/dependencies.cmake create mode 100644 cmake/windows/helpers.cmake create mode 100644 desktop-ui/cmake/macos/Info.plist.in create mode 100644 desktop-ui/cmake/macos/entitlements.plist create mode 100644 desktop-ui/cmake/macos/exportOptions.plist.in create mode 100644 desktop-ui/cmake/os-linux.cmake create mode 100644 desktop-ui/cmake/os-macos.cmake create mode 100644 desktop-ui/cmake/os-windows.cmake create mode 100644 desktop-ui/cmake/sources.cmake create mode 100644 desktop-ui/resource/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 desktop-ui/resource/Assets.xcassets/AppIcon.appiconset/ares 1.png create mode 100644 desktop-ui/resource/Assets.xcassets/AppIcon.appiconset/ares.png create mode 100644 desktop-ui/resource/Assets.xcassets/AppIcon.appiconset/ares@1024x1024.png create mode 100644 desktop-ui/resource/Assets.xcassets/AppIcon.appiconset/ares@128x128.png create mode 100644 desktop-ui/resource/Assets.xcassets/AppIcon.appiconset/ares@16x16.png create mode 100644 desktop-ui/resource/Assets.xcassets/AppIcon.appiconset/ares@32x32 1.png create mode 100644 desktop-ui/resource/Assets.xcassets/AppIcon.appiconset/ares@32x32.png create mode 100644 desktop-ui/resource/Assets.xcassets/AppIcon.appiconset/ares@512x512 1.png create mode 100644 desktop-ui/resource/Assets.xcassets/AppIcon.appiconset/ares@512x512.png create mode 100644 desktop-ui/resource/Assets.xcassets/AppIcon.appiconset/ares@64x64.png create mode 100644 desktop-ui/resource/Assets.xcassets/Contents.json create mode 100644 desktop-ui/resource/Assets.xcassets/font.imageset/Contents.json create mode 100644 desktop-ui/resource/Assets.xcassets/font.imageset/font.png create mode 100644 hiro/cmake/os-bsd.cmake create mode 100644 hiro/cmake/os-linux.cmake create mode 100644 hiro/cmake/os-macos.cmake create mode 100644 hiro/cmake/os-windows.cmake create mode 100644 hiro/cmake/sources.cmake create mode 100644 hiro/hiro.mm create mode 100644 mia/CMakeLists.txt.rej create mode 100644 mia/cmake/macos/entitlements.plist create mode 100644 mia/cmake/os-macos.cmake create mode 100644 nall/cmake/os-freebsd.cmake create mode 100644 nall/cmake/os-linux.cmake create mode 100644 nall/cmake/os-macos.cmake create mode 100644 nall/cmake/os-windows.cmake create mode 100644 nall/cmake/sources.cmake create mode 100644 nall/sljitAllocator.cpp create mode 100644 ruby/cmake/os-freebsd.cmake create mode 100644 ruby/cmake/os-linux.cmake create mode 100644 ruby/cmake/os-macos.cmake create mode 100644 ruby/cmake/os-windows.cmake create mode 100644 ruby/ruby.mm rename thirdparty/libchdr/deps/zlib-1.3.1/{zconf.h => zconf.h.included} (100%) create mode 100644 tools/genius/cmake/macos/Info.plist.in create mode 100644 tools/genius/cmake/macos/entitlements.plist create mode 100644 tools/genius/cmake/os-linux.cmake create mode 100644 tools/genius/cmake/os-macos.cmake diff --git a/.gitignore b/.gitignore index 377fd52d4f..9afbb21e05 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,33 @@ -*.moc -*.user -*.xcuserdata -.vs/ -.vscode/ -.idea/ -build*/ -cmake-*/ +# Exclude everything +/* + +# Except for default project files +!/.github +!/ares +!/desktop-ui +!/hiro +!/cmake +!/libco +!/mia +!/nall +!/ruby +!/scripts +!/tests/i8080 +!/thirdparty +!/tools +!/GNUMakefile +!/LICENSE +!/README.md +!/Legacy Build System.md +!.cmake-format.json +!.editorconfig +!.gitmodules +!.gitignore +!buildspec.json +!CMakeLists.txt +!CMakePresets.json + +/cmake/.CMakeBuildNumber obj/ out/ obj-amd64/ @@ -14,6 +36,8 @@ out-amd64/ out-arm64/ thirdparty/SDL/SDL thirdparty/SDL/libSDL2-2.0.0.dylib +ruby/video/metal/shaders.metallib +ruby/video/metal/shaders.ir macos-xcode/ .swiftpm -*.xcodeproj +*.xcodeproj \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 0767bfb84b..9b1b43c9c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,96 +1,44 @@ -cmake_minimum_required(VERSION 3.14...3.27) +cmake_minimum_required(VERSION 3.28...3.30) -project( - ares - VERSION 0.134 - DESCRIPTION "ares is a cross-platform, open source, multi-system emulator, focusing on accuracy and preservation." - LANGUAGES C CXX) +include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/common/bootstrap.cmake" NO_POLICY_SCOPE) -if(WIN32 AND NOT MINGW) - add_compile_definitions(EXCLUDE_MANIFEST_FROM_RC) #global -endif() - -function(add_sourcery_command target subdir) - add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/resource.cpp ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/resource.hpp - COMMAND sourcery resource.bml resource.cpp resource.hpp - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${subdir} - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/resource.bml - VERBATIM - ) - add_custom_target(${target}-resource DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/resource.cpp ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/resource.hpp) - add_dependencies(${target} ${target}-resource) -endfunction() - -add_subdirectory(thirdparty) +set(CMAKE_SUPPRESS_REGENERATION true) -set(build optimized) -set(threaded TRUE) -set(openmp FALSE) -set(vulkan TRUE) -set(local TRUE) -set(lto TRUE) -set(console FALSE) +project(ares VERSION ${ARES_VERSION_CANONICAL}) -set(default_build_type "Release") -if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - message(STATUS "Setting build type to '${default_build_type}' as none was specified.") - set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE - STRING "Choose the type of build." FORCE) - # Set the possible values of build type for cmake-gui - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS - "Debug" "Release" "MinSizeRel" "RelWithDebInfo") -endif() +include(compilerconfig) +include(defaults) +include(helpers) -#for now, derive build type from cmake standard build type -set(build $<$:debug>$<$:optimized>$<$:release>$<$:minified>) -#file(GENERATE OUTPUT build_$.txt CONTENT "build = ${build}") +add_subdirectory(cmake) -include_directories(.) #global +add_subdirectory(thirdparty) add_subdirectory(nall) - -if(arch STREQUAL x86 OR arch STREQUAL amd64) - if(NOT MSVC) - if(local) - add_compile_options(-march=native) #global - else() - # For official builds, default to x86-64-v2 (Intel Nehalem, AMD Bulldozer) which supports up to SSE 4.2. - add_compile_options(-march=x86-64-v2) #global - endif() - endif() -endif() - add_subdirectory(libco) add_subdirectory(ruby) - -#hiro.resource := resource/ares.rc add_subdirectory(hiro) -set(profile performance) -set(cores n64 ng spec) -#set(cores a26 fc sfc n64 sg ms md ps1 pce ng msx cv myvision gb gba ws ngp spec) #saturn +# gersemi: off +set( + ARES_CORES + a26 fc sfc sg ms md ps1 pce ng msx cv myvision gb gba ws ngp spec n64 + CACHE INTERNAL LIST +) +# gersemi: on add_subdirectory(ares) add_subdirectory(mia) add_subdirectory(desktop-ui) + add_subdirectory(tests/i8080) -if(NOT WIN32) +if(NOT OS_WINDOWS AND NOT OS_MACOS) add_subdirectory(tools/genius) +else() + target_disable_subproject(genius "genius (database editor)") endif() add_subdirectory(tools/mame2bml) add_subdirectory(tools/sourcery) - -set_target_properties( - ares - hiro - libco - mia - nall - ruby - desktop-ui - libchdr - sljit - tzxfile - ymfm - PROPERTIES VS_GLOBAL_VcpkgEnabled false) +message_configuration() +return() diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000000..6921c3e352 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,82 @@ +{ + "version": 3, + "cmakeMinimumRequired": { + "major": 3, + "minor": 28, + "patch": 0 + }, + "configurePresets": [ + { + "name": "environmentVars", + "hidden": true, + "cacheVariables": { + "ARES_PROFILE_ACCURACY": false, + "ENABLE_VULKAN": true, + "ARES_BUILD_LOCAL": true, + "ENABLE_CCACHE": false + } + }, + { + "name": "macos", + "displayName": "macOS", + "description": "Xcode project (host architecture by default)", + "inherits": ["environmentVars"], + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Darwin" + }, + "generator": "Xcode", + "binaryDir": "${sourceDir}/build_macos", + "cacheVariables": { + "CMAKE_OSX_DEPLOYMENT_TARGET": {"type": "STRING", "value": "10.13"}, + "ARES_CODESIGN_IDENTITY": {"type": "STRING", "value": "$penv{CODESIGN_IDENT}"}, + "ARES_CODESIGN_TEAM": {"type": "STRING", "value": "$penv{CODESIGN_TEAM}"}, + "ENABLE_COMPILER_TRACE": true, + "ENABLE_CCACHE": false + } + }, + { + "name": "windows", + "displayName": "Windows (Visual Studio, ClangCL)", + "description": "Visual Studio project using ClangCL (host architecture)", + "inherits": ["environmentVars"], + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + }, + "binaryDir": "${sourceDir}/build_vsclang", + "generator": "Visual Studio 17 2022", + "toolset": "ClangCL", + "cacheVariables": { + "ENABLE_CCACHE": false + } + }, + { + "name": "windows-msvc", + "displayName": "Windows (Visual Studio, MSVC)", + "description": "Visual Studio project using MSVC (host architecture)", + "inherits": ["environmentVars"], + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + }, + "binaryDir": "${sourceDir}/build_msvc", + "generator": "Visual Studio 17 2022", + "cacheVariables": { + "ENABLE_CCACHE": false + } + } + ], + "buildPresets": [ + { + "name": "windows", + "configurePreset": "windows", + "displayName": "Windows build (host architecture)", + "description": "Windows build (host architecture)", + "configuration": "RelWithDebInfo" + } + ] +} diff --git a/LICENSE b/LICENSE index 0422f916df..6e81bab677 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ ---------------------------------------------------------------------- ares -Copyright (c) 2004-2021 ares team, Near et al +Copyright (c) 2004-2024 ares team, Near et al Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff --git a/Legacy Build System.md b/Legacy Build System.md new file mode 100644 index 0000000000..8474dbf11c --- /dev/null +++ b/Legacy Build System.md @@ -0,0 +1,120 @@ +# Legacy Build System + +### *nix building + +###### Minimum required packages: +``` +g++ make pkg-config libgtk-3-dev libcanberra-gtk-module libgl-dev libasound2-dev +``` +###### Additional Audio Drivers +ares supports additional audio drivers besides the ALSA drivers included above. Installing these additional packages will allow them to be selected in Settings > Drivers: +`libao-dev libopenal-dev` + +###### GTK2 & GTK3 +By default, GTK3 is used, but support for GTK2 is available. You will need to install the additional package `libgtk2.0-dev` as well as specifying the command line option `hiro=gtk2` at compile time. + +###### SDL2 for input +If you would like to use SDL for input (e.g. for using a controller), you will need to install the `libsdl2-dev` and `libsdl2-2.0-0` packages and perform a clean build of ares. +You should then be able to select SDL for input in the Settings > Drivers menu. + +##### Building with clang + +clang++ is now the preferred compiler for ares. If clang is detected on Windows/macOS/BSD, it will be selected by default. On Linux and other platforms, g++ remains the default if present. To build with clang, it is necessary to install both the `clang` and `lld` packages. If you would like to manually specify a compiler, you can use the following option: `compiler=[g++|clang++]` + +##### Librashader Support +If you do not want to include librashader support, you can pass the following option to the `make` command to skip these requirements using: `librashader=false` + +Librashader requires rust in order to build. You can install it with the following command: +``` +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +source ~/.cargo/env +rustup toolchain install nightly +``` + +In order to build librashader, change into the `ares/thirdparty/librashader` directory and run the script `build-librashader.sh` +Note that once the build completes, it will instruct you to run three copy commands to install the library on your system. These paths may be different depending on Linux distribution. + +-------------- + +### Windows building + +To build on Windows, using MSYS2 is recommended which can be download [here](https://www.msys2.org/). Follow the instructions +on this page to install and setup an appropriate MINGW64 environment. Running the command: +``` +pacman -S --needed base-devel mingw-w64-x86_64-toolchain mingw-w64-x86_64-SDL2 +``` +from the MSYS2 MSYS terminal should setup everything you need to compile ares. Note that in order to compile, you will want to be in a MINGW64 terminal window after install and setup is complete. + +##### Building with clang + +clang is available through Visual Studio (or Build Tools for Visual Studio) through its installer and can be used to build ares. You will still need to supply GNU make in this instance. MSYS2 also offers a clang environment. You will want to make sure you select the clangw64 option during installation of MSYS2 which should provide and additional CLANG64 pre-configured environment. Install the clang toolchain package from the MSYS2 terminal: +``` +pacman -S mingw-w64-clang-x86_64-toolchain mingw-w64-clang-x86_64-SDL2 +``` +Once complete, open a CLANG64 terminal window and proceed with building ares. + +###### Debug Symbols +When building with clang, by default symbols will be generated for debug builds using an MSVC compatible format (CodeView) for use with Windows debugging tools. In order to generate GDB compatible symbols, specify the following option: `symformat=gdb` + +###### Librashader Support +ares has introduced support for the [librashader](https://github.com/SnowflakePowered/librashader) library, which is a preprocessor, compiler, and runtime for RetroArch 'slang' shaders. If you are not interested in working with librashaders, you can pass the following option to the `make` command to skip these requirements using: `librashader=false` + +Building the librashader library on Windows requires Rust. Follow these steps to prepare your system and build the librashader library: + +1. Download and execute the rustup-init.exe installer from: https://rustup.rs/ +2. Open a new Windows terminal and run the following commands: + ``` + rustup toolchain install nightly + rustup default nightly + ``` +3. With Rust successfully installed, you will need to update your PATH environment variable within your MSYS2 environment. In an MSYS2 shell, open $HOME/.bash_profile and append something like the following (note you will need to replace both instances of %USER_NAME% with the real user name you used to install Rust): + ``` + if [ -d "/C/Users/%USER_NAME%/.cargo/bin" ] ; then + PATH="/C/Users/%USER_NAME%/.cargo/bin:${PATH}" + fi + ``` +4. Open a new MSYS2 based shell for the compiler you are using (MinGW64|CLANG64|UCRT64), execute `rustup` to validate the path is set properly within your MSYS2 environment. +5. In your MSYS2 compiler shell, `cd` into the `ares/thirdparty/librashader` directory +6. Execute the build script, build should complete successfully: + ``` + ./build-librashader.sh + ``` + +This only needs to be done once, or anytime the librashader library is updated. Once built, ares will build with librashader support by default requiring no additional flags. + +Compilation +----------- + +Check out the source code by running this command: + +``` +git clone https://github.com/ares-emulator/ares.git +``` + +From the root of the project directory run: + +``` +make -j4 +``` + +`-j#` indicates number of parallel build processes, and shouldn't be set higher than N-1 cores on your processor. Specifying this option can significantly decrease the time to build this project. There are multiple build types available and it defaults to an 'optimized' build. Build types can be specified using: `build=[debug|stable|release|minified|optimized]` + +Build options can be found in the following two make files: nall/GNUmakefile desktop-ui/GNUmakefile + +To start compilation from the beginning, run the following prior to compiling: + +``` +make clean +``` + +#### Building specific cores +If you would like to build a subset of cores, you can specify the `cores="core1 core2"` option. Currently available cores: +``` +a26 fc sfc n64 sg ms md ps1 pce ng msx cv myvision gb gba ws ngp spec +``` + +Build Output +------------ + +There is a single binary produced at the end of compilation which can be found in `desktop-ui/out`. On OS's besides Linux, the `Database` & `Shader` directories are copied over here as well. On Linux, running `make install` after compilation will copy these directories and binary into suitable locations (see desktop-ui/GNUmakefile for details). Alternatively, these directories can be copied from `thirdparty/slang-shaders/*` into a `Shader` directory, and by copying `mia/Database/*` + diff --git a/README.md b/README.md index 682348a937..8fe434fba0 100644 --- a/README.md +++ b/README.md @@ -17,127 +17,203 @@ Nightly Builds Automated, untested builds of ares are available for Windows and macOS as a [pre-release](https://github.com/higan-emu/ares/releases/tag/nightly). Only the latest nightly build is kept. -Prerequisites +Building ------------- +> [!IMPORTANT] +> If you are reading this, this build system is still heavily under development. Documentation is incomplete, and it is possible that commands listed here will change or temporarily not function. Thank you for testing! Please feel free to tag @yam on the [ares Discord](https://discord.com/invite/gz2quhk2kv) with any issues. -### *nix building +Building ares requires [CMake](https://cmake.org/download/) 3.28 or greater. -###### Minimum required packages: -``` -g++ make pkg-config libgtk-3-dev libcanberra-gtk-module libgl-dev libasound2-dev -``` -###### Additional Audio Drivers -ares supports additional audio drivers besides the ALSA drivers included above. Installing these additional packages will allow them to be selected in Settings > Drivers: -`libao-dev libopenal-dev` +### Windows + +ares on Windows can be built either via the default Windows shell, or within an MSYS2/MinGW environment. -###### GTK2 & GTK3 -By default, GTK3 is used, but support for GTK2 is available. You will need to install the additional package `libgtk2.0-dev` as well as specifying the command line option `hiro=gtk2` at compile time. +#### Windows Command Prompt (MSVC/Clang-CL) -###### SDL2 for input -If you would like to use SDL for input (e.g. for using a controller), you will need to install the `libsdl2-dev` and `libsdl2-2.0-0` packages and perform a clean build of ares. -You should then be able to select SDL for input in the Settings > Drivers menu. +###### Prerequisites -##### Building with clang +* Windows 10 or higher +* CMake 3.28 or higher +* Git for Windows +* Visual Studio 17 2022 -clang++ is now the preferred compiler for ares. If clang is detected on Windows/macOS/BSD, it will be selected by default. On Linux and other platforms, g++ remains the default if present. To build with clang, it is necessary to install both the `clang` and `lld` packages. If you would like to manually specify a compiler, you can use the following option: `compiler=[g++|clang++]` +Ensure that the "Desktop Development with C++" package is included in your Visual Studio 2022 installation. Building ares with clang also requires that the "C++ Clang tools for Windows" package is installed. -##### Librashader Support -If you do not want to include librashader support, you can pass the following option to the `make` command to skip these requirements using: `librashader=false` +###### Configuration -Librashader requires rust in order to build. You can install it with the following command: -``` -curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -source ~/.cargo/env -rustup toolchain install nightly +First, clone the ares repository: +``` +git clone https://github.com/ares-emulator/ares +cd ares ``` +A Visual Studio project can be setup by using the `windows` CMake preset: +``` +cmake --preset windows +``` +This preset will generate a Visual Studio project for ares using Clang-CL that will build all targets and package dependencies appropriately. -In order to build librashader, change into the `ares/thirdparty/librashader` directory and run the script `build-librashader.sh` -Note that once the build completes, it will instruct you to run three copy commands to install the library on your system. These paths may be different depending on Linux distribution. - --------------- +If you prefer to use the MSVC compiler, specify the `windows-msvc` preset: +``` +cmake --preset windows-msvc +``` +Visual Studio presets will generate single-architecture configuration with the host architecture will be created; if you would like to compile for a specific architecture, you may specify `-A x64` or `-A arm64` as appropriate. Multi-architecture configuration is not supported. 32-bit `x86` builds are not currently supported (*note 10/14: WIP, may work, just untested*). +#### MSYS2/MinGW + +Under MSYS2/MinGW, the same Visual Studio CMake presets above are also supported. Under MSYS2/MinGW, we may also however build with GNU Clang or GCC. -### Windows building +###### Prerequisites -To build on Windows, using MSYS2 is recommended which can be download [here](https://www.msys2.org/). Follow the instructions -on this page to install and setup an appropriate MINGW64 environment. Running the command: +* MSYS2 +* An appropriate MSYS2 [environment](https://www.msys2.org/docs/environments/), such as CLANG64 +* A suitable MinGW toolchain, for example [mingw-w64-llvm](https://packages.msys2.org/base/mingw-w64-llvm) +* Git (`pacman -S git`) +* CMake 3.28 or higher (`pacman -S cmake`) + +First, clone the ares repository: +``` +git clone https://github.com/ares-emulator/ares +cd ares +``` +Then, invoke CMake as normal with your chosen generator, e.g Ninja: ``` -pacman -S --needed base-devel mingw-w64-x86_64-toolchain mingw-w64-x86_64-SDL2 -``` -from the MSYS2 MSYS terminal should setup everything you need to compile ares. Note that in order to compile, you will want to be in a MINGW64 terminal window after install and setup is complete. +mkdir build && cd build +cmake .. -G "Ninja Multi-Config" +``` +After configuration, build ares: +``` +cmake --build . --config RelWithDebInfo +``` +For further configuration options, see the [Build Options] section. +### macOS -##### Building with clang +###### Prerequisites -clang is available through Visual Studio (or Build Tools for Visual Studio) through its installer and can be used to build ares. You will still need to supply GNU make in this instance. MSYS2 also offers a clang environment. You will want to make sure you select the clangw64 option during installation of MSYS2 which should provide and additional CLANG64 pre-configured environment. Install the clang toolchain package from the MSYS2 terminal: +* macOS 10.15 or higher +* Xcode 12.4 or higher +* CMake 3.28 or higher + +###### Configuration + +First, clone the ares repository: +``` +git clone https://github.com/ares-emulator/ares +cd ares +``` +macOS builds can be setup by using the `macos` CMake preset: +``` +cmake --preset macos +``` +This generates an Xcode project in the `build_macos` folder that builds all `ares` targets including subprojects. By default, a single-architecture project with the host architecture is generated. To build universal binaries or cross-compile, the `-DCMAKE_OSX_ARCHITECTURES="x86_64;arm64"` option can be specified in addition to the preset. + +You may also build with other generators such as Make or Ninja. To do this, invoke CMake as normal: +``` +mkdir my_build && cd my_build +cmake .. -G "GNU Makefiles" ``` -pacman -S mingw-w64-clang-x86_64-toolchain mingw-w64-clang-x86_64-SDL2 -``` -Once complete, open a CLANG64 terminal window and proceed with building ares. +After configuration, build ares: +``` +make desktop-ui -j8 +``` +For further configuration options, see the [Build Options] section. + +### Linux + +###### Prerequisites + +* Git +* CMake 3.28 or higher +* A compiler toolchain such as clang or gcc + +ares requires development versions of the following packages in order to build: -###### Debug Symbols -When building with clang, by default symbols will be generated for debug builds using an MSVC compatible format (CodeView) for use with Windows debugging tools. In order to generate GDB compatible symbols, specify the following option: `symformat=gdb` +* X11 +* libGL +* GTK3 (gtk+-3.0) -###### Librashader Support -ares has introduced support for the [librashader](https://github.com/SnowflakePowered/librashader) library, which is a preprocessor, compiler, and runtime for RetroArch 'slang' shaders. If you are not interested in working with librashaders, you can pass the following option to the `make` command to skip these requirements using: `librashader=false` +Recommended development packages include: -Building the librashader library on Windows requires Rust. Follow these steps to prepare your system and build the librashader library: +* [librashader](https://software.opensuse.org//download.html?project=home%3Achyyran%3Alibrashader&package=librashader) +* SDL2 -1. Download and execute the rustup-init.exe installer from: https://rustup.rs/ -2. Open a new Windows terminal and run the following commands: - ``` - rustup toolchain install nightly - rustup default nightly - ``` -3. With Rust successfully installed, you will need to update your PATH environment variable within your MSYS2 environment. In an MSYS2 shell, open $HOME/.bash_profile and append something like the following (note you will need to replace both instances of %USER_NAME% with the real user name you used to install Rust): - ``` - if [ -d "/C/Users/%USER_NAME%/.cargo/bin" ] ; then - PATH="/C/Users/%USER_NAME%/.cargo/bin:${PATH}" - fi - ``` -4. Open a new MSYS2 based shell for the compiler you are using (MinGW64|CLANG64|UCRT64), execute `rustup` to validate the path is set properly within your MSYS2 environment. -5. In your MSYS2 compiler shell, `cd` into the `ares/thirdparty/librashader` directory -6. Execute the build script, build should complete successfully: - ``` - ./build-librashader.sh - ``` +You may also configure with development packages for other audio drivers: -This only needs to be done once, or anytime the librashader library is updated. Once built, ares will build with librashader support by default requiring no additional flags. +* OpenAL +* AO +* ALSA +* PulseAudio -Compilation ------------ +Optional but recommended build tools include: -Check out the source code by running this command: +* Ninja +* clang +* Ccache +###### Configuration + +First, clone the ares repository: +``` +git clone https://github.com/ares-emulator/ares +cd ares +``` +Building ares with `clang` and Ninja is recommended: +``` +mkdir build && cd build +cmake .. -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -G "Ninja Multi-Config" +``` +The generation step will report what features are enabled and disabled according to the libraries found on your system. Next, build ares: +``` +cmake --build . ``` -git clone https://github.com/ares-emulator/ares.git +After building, products can be found in the `rundir` folder. ares can be run from this location, or the rundir can be relocated. ares can also be `install`ed: ``` +cmake --install . --prefix +``` + +### Build Options + +When generating/configuring ares on any platform, a number of configuration options are available. -From the root of the project directory run: +##### ARES_CORES +Default: `"a26;fc;sfc;sg;ms;md;ps1;pce;ng;msx;cv;myvision;gb;gba;ws;ngp;spec;n64"` +By default, ares configures with all emulator cores. To specify that only a subset of cores should be built, use the `-DARES_CORES` option. For example: ``` -make -j4 +cmake .. -G Ninja -DARES_CORES="a26;n64;sg;myvision" ``` - -`-j#` indicates number of parallel build processes, and shouldn't be set higher than N-1 cores on your processor. Specifying this option can significantly decrease the time to build this project. There are multiple build types available and it defaults to an 'optimized' build. Build types can be specified using: `build=[debug|stable|release|minified|optimized]` -Build options can be found in the following two make files: nall/GNUmakefile desktop-ui/GNUmakefile +##### CMAKE_BUILD_TYPE +Default: `RelWithDebInfo` -To start compilation from the beginning, run the following prior to compiling: +Multi-configuration generators (Xcode, Visual Studio, Ninja Multi-Config) will automatically configure with all build configurations available. Single-configuration generators will configure by default using the `RelWithDebInfo` configuration. To specify another configuration, use `-DCMAKE_BUILD_TYPE`: ``` -make clean +cmake .. -G "MinGW Makefiles" -DARES_CORES="a26" -DCMAKE_BUILD_TYPE=Release ``` -#### Building specific cores -If you would like to build a subset of cores, you can specify the `cores="core1 core2"` option. Currently available cores: -``` -a26 fc sfc n64 sg ms md ps1 pce ng msx cv myvision gb gba ws ngp spec -``` +Supported build types are ``. +##### ENABLE_CCACHE +Default: `ON` -Build Output ------------- +ares will try to use CCache by default on all platforms to speed up compilation. You may disable CCache if you are experimenting with compilation options or the build system by building with `-DENABLE_CCACHE=OFF`. + +##### ARES_BUILD_LOCAL +Default: `ON` + +When this option is enabled, certain compiler optimizations are enabled to optimize performance for the host/target system. This option also controls certain entitlements and runtime options on macOS that interfere with may debugging but are necessary for notarization and distribution. + +##### ARES\_ENABLE_LIBRASHADER +Default: `ON` + +This flag may be disabled if you wish to compile without librashader and slang-shaders, producing a slimmer build. Note that the librashader header is still required to build without librashader; however, this header is bundled as a dependency on all platforms and it should not be necessary to install any dependency to build without librashader. + +##### ARES_PROFILE_ACCURACY +Default: `OFF` + +Mostly unused in current versions of ares; acts as a compile-time switch for certain performance-sensitive areas of emulation. -There is a single binary produced at the end of compilation which can be found in `desktop-ui/out`. On OS's besides Linux, the `Database` & `Shader` directories are copied over here as well. On Linux, running `make install` after compilation will copy these directories and binary into suitable locations (see desktop-ui/GNUmakefile for details). Alternatively, these directories can be copied from `thirdparty/slang-shaders/*` into a `Shader` directory, and by copying `mia/Database/*` +# Legacy build system +Legacy build information is available [here](./Legacy%20Build%20System.md) Command-line options -------------------- diff --git a/ares/CMakeLists.txt b/ares/CMakeLists.txt index e04c6b813b..f48b12c5c1 100644 --- a/ares/CMakeLists.txt +++ b/ares/CMakeLists.txt @@ -1,39 +1,101 @@ -add_library(ares STATIC - ares/ares.cpp - ares/memory/fixed-allocator.cpp -) +add_library(ares STATIC ares/ares.cpp ares/memory/fixed-allocator.cpp) -target_include_directories(ares PUBLIC .) +add_library(ares::ares ALIAS ares) -target_link_libraries(ares - PUBLIC libco sljit nall - PRIVATE thirdparty ymfm -) +target_precompile_headers(ares PRIVATE "$<$:${CMAKE_CURRENT_SOURCE_DIR}/ares/ares.hpp>") -if(platform STREQUAL windows) -# target_link_libraries(ares PRIVATE uuid kernel32 user32 gdi32 comctl32 comdlg32 shell32) -elseif(platform STREQUAL macos) -elseif(platform STREQUAL linux OR platform STREQUAL bsd) -# target_link_options(ares PRIVATE LINKER:-export-dynamic) -# target_link_libraries(ares PRIVATE X11 Xext) +target_link_libraries(ares PUBLIC libco sljit nall) + +if(ARES_PROFILE_ACCURACY) + target_compile_definitions(ares PUBLIC PROFILE_ACCURACY) else() - message(FATAL_ERROR "ares is a library and cannot be built directly.") + target_compile_definitions(ares PUBLIC PROFILE_PERFORMANCE) endif() -if(platform STREQUAL macos) -# set(ares.dylibs "") -endif() +target_sources( + ares + PRIVATE ares/ares.cpp ares/ares.hpp ares/inline.hpp ares/platform.hpp ares/random.hpp ares/types.hpp +) -if(vulkan) - target_compile_definitions(ares PUBLIC VULKAN) -endif() +target_sources( + ares + PRIVATE + ares/debug/debug.cpp + ares/debug/debug.hpp + ares/memory/fixed-allocator.cpp + ares/memory/fixed-allocator.hpp + ares/memory/memory.hpp + ares/memory/readable.hpp + ares/memory/writable.hpp +) -if(profile STREQUAL accuracy) - target_compile_definitions(ares PUBLIC PROFILE_ACCURACY) +target_sources( + ares + PRIVATE ares/scheduler/scheduler.cpp ares/scheduler/scheduler.hpp ares/scheduler/thread.cpp ares/scheduler/thread.hpp +) + +target_sources( + ares + PRIVATE + ares/node/attribute.hpp + ares/node/class.hpp + ares/node/node.cpp + ares/node/node.hpp + ares/node/object.hpp + ares/node/peripheral.hpp + ares/node/port.hpp + ares/node/system.hpp +) + +target_sources(ares PRIVATE ares/node/audio/audio.hpp ares/node/audio/stream.cpp ares/node/audio/stream.hpp) + +target_sources(ares PRIVATE ares/node/component/component.hpp ares/node/component/real-time-clock.hpp) + +target_sources( + ares + PRIVATE + ares/node/input/axis.hpp + ares/node/input/button.hpp + ares/node/input/input.hpp + ares/node/input/rumble.hpp + ares/node/input/trigger.hpp +) + +target_sources( + ares + PRIVATE + ares/node/setting/boolean.hpp + ares/node/setting/integer.hpp + ares/node/setting/natural.hpp + ares/node/setting/real.hpp + ares/node/setting/setting.hpp + ares/node/setting/string.hpp +) + +target_sources( + ares + PRIVATE + ares/node/video/screen.cpp + ares/node/video/screen.hpp + ares/node/video/sprite.cpp + ares/node/video/sprite.hpp + ares/node/video/video.hpp +) + +if(OS_WINDOWS) + include(cmake/os-windows.cmake) +elseif(OS_MACOS) + include(cmake/os-macos.cmake) +elseif(OS_LINUX) + include(cmake/os-linux.cmake) +elseif(OS_FREEBSD OR OS_OPENBSD) + include(cmake/os-freebsd.cmake) endif() -if(profile STREQUAL performance) - target_compile_definitions(ares PUBLIC PROFILE_PERFORMANCE) +if(ENABLE_VULKAN) + target_enable_feature(ares "N64 Vulkan rendering with paraLLEl-RDP" VULKAN) + target_compile_definitions(ares PUBLIC ENABLE_VULKAN) + target_compile_definitions(ares PUBLIC VULKAN) endif() macro(ares_components) @@ -41,86 +103,192 @@ macro(ares_components) set(ares.components ${ares.components} PARENT_SCOPE) endmacro() -if(a26 IN_LIST cores) +macro(ares_add_header_sources core) + foreach(arg IN ITEMS ${ARGN}) + list(APPEND ARES_HEADER_SOURCES "${core}/${arg}") + endforeach() + target_sources(ares PRIVATE ${ARGV}) + set(ARES_HEADER_SOURCES ${ARES_HEADER_SOURCES} PARENT_SCOPE) +endmacro() + +if(a26 IN_LIST ARES_CORES) + enable_core("Atari 2600") add_subdirectory(a26) +else() + disable_core("Atari 2600") endif() -if(fc IN_LIST cores) +if(fc IN_LIST ARES_CORES) + enable_core("NES / Famicom") add_subdirectory(fc) +else() + disable_core("NES / Famicom") endif() -if(sfc IN_LIST cores) +if(sfc IN_LIST ARES_CORES) + enable_core("SNES / Super Famicom") add_subdirectory(sfc) +else() + disable_core("SNES / Super Famicom") endif() -if(n64 IN_LIST cores) +if(n64 IN_LIST ARES_CORES) + enable_core("Nintendo 64") add_subdirectory(n64) +else() + disable_core("Nintendo 64") endif() -if(sg IN_LIST cores) +if(sg IN_LIST ARES_CORES) + enable_core("Sega SG-1000") add_subdirectory(sg) +else() + disable_core("Sega SG-1000") endif() -if(ms IN_LIST cores) +if(ms IN_LIST ARES_CORES) + enable_core("Sega Master System / Mark III") add_subdirectory(ms) +else() + disable_core("Sega Master System / Mark III") endif() -if(md IN_LIST cores) +if(md IN_LIST ARES_CORES) + enable_core("Sega Mega Drive / Genesis") add_subdirectory(md) +else() + disable_core("Sega Mega Drive / Genesis") endif() -if(saturn IN_LIST cores) +if(saturn IN_LIST ARES_CORES) + enable_core("Sega Saturn") add_subdirectory(saturn) +else() + disable_core("Sega Saturn") endif() -if(ps1 IN_LIST cores) +if(ps1 IN_LIST ARES_CORES) + enable_core("PlayStation") add_subdirectory(ps1) +else() + disable_core("Playstation") endif() -if(pce IN_LIST cores) +if(pce IN_LIST ARES_CORES) + enable_core("PC-Engine / TurboGrafx") add_subdirectory(pce) +else() + disable_core("PC-Engine / TurboGrafx") endif() -if(msx IN_LIST cores) +if(msx IN_LIST ARES_CORES) + enable_core("Microsoft MSX") add_subdirectory(msx) +else() + disable_core("Microsoft MSX") endif() -if(cv IN_LIST cores) +if(cv IN_LIST ARES_CORES) + enable_core("ColecoVision") add_subdirectory(cv) +else() + disable_core("ColecoVision") endif() -if(myvision IN_LIST cores) +if(myvision IN_LIST ARES_CORES) + enable_core("My Vision") add_subdirectory(myvision) +else() + disable_core("My Vision") endif() -if(gb IN_LIST cores) +if(gb IN_LIST ARES_CORES) + enable_core("Game Boy / Game Boy Color") add_subdirectory(gb) +else() + disable_core("Game Boy / Game Boy Color") endif() -if(gba IN_LIST cores) +if(gba IN_LIST ARES_CORES) + enable_core("Game Boy Advance") add_subdirectory(gba) +else() + disable_core("Game Boy Advance") endif() -if(ws IN_LIST cores) +if(ws IN_LIST ARES_CORES) + enable_core("WonderSwan / WonderSwan Color") add_subdirectory(ws) +else() + disable_core("WonderSwan / WonderSwan Color") endif() -if(ng IN_LIST cores) +if(ng IN_LIST ARES_CORES) + enable_core("Neo Geo (AES/MVS)") add_subdirectory(ng) +else() + disable_core("Neo Geo (AES/MVS)") endif() -if(ngp IN_LIST cores) +if(ngp IN_LIST ARES_CORES) + enable_core("Neo Geo Pocket / Neo Geo Pocket Color") add_subdirectory(ngp) +else() + disable_core("Neo Geo Pocket / Neo Geo Pocket Color") endif() -if(spec IN_LIST cores) +if(spec IN_LIST ARES_CORES) + enable_core("ZX Spectrum") add_subdirectory(spec) +else() + disable_core("ZX Spectrum") endif() add_subdirectory(component) -foreach(c IN LISTS cores) +foreach(c IN LISTS ARES_CORES) + # target_enable_feature(ares "${c} core" CORE_$) target_compile_definitions(ares PUBLIC CORE_$) endforeach() +get_target_property(ares_SOURCES ares SOURCES) + +set_source_files_properties( + ares + ares/debug/debug.cpp + ares/node/audio/stream.cpp + ares/node/node.cpp + ares/node/video/screen.cpp + ares/node/video/sprite.cpp + ares/scheduler/thread.cpp + ares/scheduler/scheduler.cpp + PROPERTIES HEADER_FILE_ONLY TRUE +) + +set_source_files_properties( + n64/vulkan/parallel-rdp/vulkan/shader.cpp + n64/vulkan/parallel-rdp/vulkan/descriptor_set.cpp + n64/vulkan/parallel-rdp/vulkan/device.cpp + n64/vulkan/parallel-rdp/vulkan/command_buffer.cpp + n64/vulkan/parallel-rdp/vulkan/render_pass.cpp + PROPERTIES + SKIP_PRECOMPILE_HEADERS ON +) + +target_sources( + ares + PRIVATE + cmake/os-macos.cmake + cmake/os-windows.cmake + cmake/os-linux.cmake +) + +set_source_files_properties(ares ${ARES_HEADER_SOURCES} PROPERTIES HEADER_FILE_ONLY TRUE) + +set_source_files_properties(ares ares/ares.cpp ares/memory/fixed-allocator.cpp PROPERTIES HEADER_FILE_ONLY FALSE) + +target_include_directories(ares INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) + +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${ares_SOURCES}) + add_sourcery_command(ares ares/resource) diff --git a/ares/a26/CMakeLists.txt b/ares/a26/CMakeLists.txt index 20116383a1..f2e2bb8982 100644 --- a/ares/a26/CMakeLists.txt +++ b/ares/a26/CMakeLists.txt @@ -1,12 +1,77 @@ -ares_components( - mos6502 +ares_components(mos6502) + +target_sources( + ares + PRIVATE + system/system.cpp + controller/controller.cpp + cartridge/cartridge.cpp + cpu/cpu.cpp + tia/tia.cpp + riot/riot.cpp +) + +ares_add_header_sources(a26 a26.hpp CMakeLists.txt) + +ares_add_header_sources( + a26 + cartridge/cartridge.hpp + cartridge/serialization.cpp + cartridge/slot.cpp + cartridge/slot.hpp + cartridge/board/atari16k.cpp + cartridge/board/atari32k.cpp + cartridge/board/atari8k.cpp + cartridge/board/board.cpp + cartridge/board/board.hpp + cartridge/board/commavid.cpp + cartridge/board/linear.cpp + cartridge/board/parker-bros.cpp + cartridge/board/tigervision.cpp +) + +ares_add_header_sources( + a26 + controller/controller.hpp + controller/port.cpp + controller/port.hpp + controller/gamepad/gamepad.cpp + controller/gamepad/gamepad.hpp +) + +ares_add_header_sources( + a26 + cpu/cpu.hpp + cpu/debugger.cpp + cpu/memory.cpp + cpu/serialization.cpp + cpu/timing.cpp +) + +ares_add_header_sources( + a26 + riot/io.cpp + riot/riot.hpp + riot/serialization.cpp +) + +ares_add_header_sources( + a26 + system/controls.cpp + system/serialization.cpp + system/system.hpp ) -target_sources(ares PRIVATE - system/system.cpp - controller/controller.cpp - cartridge/cartridge.cpp - cpu/cpu.cpp - tia/tia.cpp - riot/riot.cpp +ares_add_header_sources( + a26 + tia/audio.cpp + tia/ball.cpp + tia/color.cpp + tia/io.cpp + tia/missile.cpp + tia/player.cpp + tia/playfield.cpp + tia/serialization.cpp + tia/tia.hpp + tia/write-queue.cpp ) diff --git a/ares/cmake/os-freebsd.cmake b/ares/cmake/os-freebsd.cmake new file mode 100644 index 0000000000..7ea10b5cec --- /dev/null +++ b/ares/cmake/os-freebsd.cmake @@ -0,0 +1,4 @@ +target_link_options(ares PRIVATE LINKER:-export-dynamic) +target_link_libraries(ares PRIVATE X11 Xext) + +target_sources(ares PRIVATE cmake/os-freebsd.cmake) diff --git a/ares/cmake/os-linux.cmake b/ares/cmake/os-linux.cmake new file mode 100644 index 0000000000..1fb6d99a0e --- /dev/null +++ b/ares/cmake/os-linux.cmake @@ -0,0 +1,4 @@ +target_link_options(ares PRIVATE LINKER:-export-dynamic) +target_link_libraries(ares PRIVATE X11 Xext) + +target_sources(ares PRIVATE cmake/os-linux.cmake) diff --git a/ares/cmake/os-macos.cmake b/ares/cmake/os-macos.cmake new file mode 100644 index 0000000000..7a9d46e269 --- /dev/null +++ b/ares/cmake/os-macos.cmake @@ -0,0 +1 @@ +target_sources(ares PRIVATE cmake/os-macos.cmake) diff --git a/ares/cmake/os-windows.cmake b/ares/cmake/os-windows.cmake new file mode 100644 index 0000000000..fbcbf9ae5d --- /dev/null +++ b/ares/cmake/os-windows.cmake @@ -0,0 +1,12 @@ +target_link_libraries( + ares + PRIVATE + uuid + kernel32 + user32 + gdi32 + comctl32 + comdlg32 + shell32 +) +target_sources(ares PRIVATE cmake/os-windows.cmake) diff --git a/ares/cv/CMakeLists.txt b/ares/cv/CMakeLists.txt index a32deb3a21..dbcb271aaf 100644 --- a/ares/cv/CMakeLists.txt +++ b/ares/cv/CMakeLists.txt @@ -1,14 +1,72 @@ -ares_components( - z80 - tms9918 - sn76489 -) - -target_sources(ares PRIVATE - cpu/cpu.cpp - vdp/vdp.cpp - psg/psg.cpp - system/system.cpp - cartridge/cartridge.cpp - controller/controller.cpp +ares_components(z80 tms9918 sn76489) + +target_sources( + ares + PRIVATE + cpu/cpu.cpp + vdp/vdp.cpp + psg/psg.cpp + system/system.cpp + cartridge/cartridge.cpp + controller/controller.cpp +) + +ares_add_header_sources(cv cv.hpp CMakeLists.txt) + +ares_add_header_sources( + cv + cartridge/cartridge.hpp + cartridge/serialization.cpp + cartridge/slot.cpp + cartridge/slot.hpp +) + +ares_add_header_sources( + cv + cartridge/board/board.cpp + cartridge/board/board.hpp + cartridge/board/coleco.cpp + cartridge/board/megacart.cpp + cartridge/board/xin1.cpp +) + +ares_add_header_sources( + cv + controller/controller.hpp + controller/port.cpp + controller/port.hpp +) + +ares_add_header_sources( + cv + controller/gamepad/gamepad.cpp + controller/gamepad/gamepad.hpp +) + +ares_add_header_sources( + cv + cpu/cpu.hpp + cpu/debugger.cpp + cpu/memory.cpp + cpu/serialization.cpp +) + +ares_add_header_sources( + cv + psg/psg.hpp + psg/serialization.cpp +) + +ares_add_header_sources( + cv + system/controls.cpp + system/serialization.cpp + system/system.hpp +) + +ares_add_header_sources( + cv + vdp/color.cpp + vdp/serialization.cpp + vdp/vdp.hpp ) diff --git a/ares/fc/CMakeLists.txt b/ares/fc/CMakeLists.txt index 9c16232a30..2ecd4ddd24 100644 --- a/ares/fc/CMakeLists.txt +++ b/ares/fc/CMakeLists.txt @@ -6,13 +6,186 @@ ares_components( sst39sf0x0 ) -target_sources(ares PRIVATE - system/system.cpp - controller/controller.cpp - expansion/expansion.cpp - cartridge/cartridge.cpp - cpu/cpu.cpp - apu/apu.cpp - ppu/ppu.cpp - fds/fds.cpp +target_link_libraries(ares PRIVATE ymfm) + +target_sources( + ares + PRIVATE + system/system.cpp + controller/controller.cpp + expansion/expansion.cpp + cartridge/cartridge.cpp + cpu/cpu.cpp + apu/apu.cpp + ppu/ppu.cpp + fds/fds.cpp +) + +ares_add_header_sources(fc fc.hpp CMakeLists.txt) + +ares_add_header_sources( + fc + apu/apu.hpp + apu/dmc.cpp + apu/envelope.cpp + apu/framecounter.cpp + apu/length.cpp + apu/noise.cpp + apu/pulse.cpp + apu/serialization.cpp + apu/sweep.cpp + apu/triangle.cpp +) + +ares_add_header_sources( + fc + cartridge/cartridge.hpp + cartridge/serialization.cpp + cartridge/slot.cpp + cartridge/slot.hpp +) + +ares_add_header_sources( + fc + cartridge/board/action53.cpp + cartridge/board/ave-nina-001.cpp + cartridge/board/ave-nina-06.cpp + cartridge/board/bandai-74161.cpp + cartridge/board/bandai-fcg.cpp + cartridge/board/bandai-karaoke.cpp + cartridge/board/bandai-lz93d50.cpp + cartridge/board/bandai-oeka.cpp + cartridge/board/board.cpp + cartridge/board/board.hpp + cartridge/board/camerica-bf909x.cpp + cartridge/board/colordreams-74x377.cpp + cartridge/board/gtrom.cpp + cartridge/board/hvc-axrom.cpp + cartridge/board/hvc-bnrom.cpp + cartridge/board/hvc-cnrom.cpp + cartridge/board/hvc-exrom.cpp + cartridge/board/hvc-fmr.cpp + cartridge/board/hvc-fxrom.cpp + cartridge/board/hvc-gxrom.cpp + cartridge/board/hvc-hkrom.cpp + cartridge/board/hvc-nrom.cpp + cartridge/board/hvc-pxrom.cpp + cartridge/board/hvc-sxrom.cpp + cartridge/board/hvc-txrom.cpp + cartridge/board/hvc-uxrom.cpp + cartridge/board/inl-nsf.cpp + cartridge/board/irem-g101.cpp + cartridge/board/irem-h3001.cpp + cartridge/board/irem-lrog017.cpp + cartridge/board/irem-tam-s1.cpp + cartridge/board/jaleco-jf05.cpp + cartridge/board/jaleco-jf11.cpp + cartridge/board/jaleco-jf16.cpp + cartridge/board/jaleco-jf17.cpp + cartridge/board/jaleco-jf23.cpp + cartridge/board/konami-vrc1.cpp + cartridge/board/konami-vrc2.cpp + cartridge/board/konami-vrc3.cpp + cartridge/board/konami-vrc4.cpp + cartridge/board/konami-vrc5.cpp + cartridge/board/konami-vrc6.cpp + cartridge/board/konami-vrc7.cpp + cartridge/board/magicfloor.cpp + cartridge/board/mlt-action52.cpp + cartridge/board/namco-118.cpp + cartridge/board/namco-163.cpp + cartridge/board/namco-340.cpp + cartridge/board/sunsoft-1.cpp + cartridge/board/sunsoft-2.cpp + cartridge/board/sunsoft-3.cpp + cartridge/board/sunsoft-4.cpp + cartridge/board/sunsoft-5b.cpp + cartridge/board/taito-tc0190.cpp + cartridge/board/taito-tc0690.cpp + cartridge/board/taito-x1-005.cpp + cartridge/board/taito-x1-017.cpp + cartridge/board/tengen-80003x.cpp + cartridge/board/unl-bmc.cpp + cartridge/board/unl-sachen-74ls374n.cpp + cartridge/board/unl-sachen-sa0037.cpp + cartridge/board/unl-txc.cpp + cartridge/board/unrom-512.cpp +) + +ares_add_header_sources( + fc + cartridge/board/ic/jv001.hpp + cartridge/board/ic/txc05-00002-010.hpp +) + +ares_add_header_sources( + fc + controller/controller.hpp + controller/port.cpp + controller/port.hpp +) + +ares_add_header_sources( + fc + controller/gamepad/gamepad.cpp + controller/gamepad/gamepad.hpp +) + +ares_add_header_sources( + fc + cpu/cpu.hpp + cpu/debugger.cpp + cpu/memory.cpp + cpu/serialization.cpp + cpu/timing.cpp +) + +ares_add_header_sources( + fc + expansion/expansion.hpp + expansion/port.cpp + expansion/port.hpp +) + +ares_add_header_sources( + fc + expansion/epsm/epsm.cpp + expansion/epsm/epsm.hpp +) + +ares_add_header_sources( + fc + expansion/family-keyboard/family-keyboard.cpp + expansion/family-keyboard/family-keyboard.hpp +) + +ares_add_header_sources( + fc + fds/audio.cpp + fds/audio.hpp + fds/drive.cpp + fds/drive.hpp + fds/fds.hpp + fds/serialization.cpp + fds/timer.cpp + fds/timer.hpp +) + +ares_add_header_sources( + fc + ppu/color.cpp + ppu/debugger.cpp + ppu/memory.cpp + ppu/ppu.hpp + ppu/render.cpp + ppu/scroll.cpp + ppu/serialization.cpp + ppu/sprite.cpp +) + +ares_add_header_sources( + fc + system/controls.cpp + system/serialization.cpp + system/system.hpp ) diff --git a/ares/gb/CMakeLists.txt b/ares/gb/CMakeLists.txt index 4ee4e2ce77..435f235c09 100644 --- a/ares/gb/CMakeLists.txt +++ b/ares/gb/CMakeLists.txt @@ -1,13 +1,73 @@ -ares_components( - sm83 - m93lcx6 -) - -target_sources(ares PRIVATE - system/system.cpp - cartridge/cartridge.cpp - bus/bus.cpp - cpu/cpu.cpp - ppu/ppu.cpp - apu/apu.cpp +ares_components(sm83 m93lcx6) + +target_sources( + ares + PRIVATE + system/system.cpp + cartridge/cartridge.cpp + bus/bus.cpp + cpu/cpu.cpp + ppu/ppu.cpp + apu/apu.cpp +) + +ares_add_header_sources(gb gb.hpp CMakeLists.txt) + +ares_add_header_sources( + gb + apu/apu.hpp + apu/io.cpp + apu/noise.cpp + apu/sequencer.cpp + apu/serialization.cpp + apu/square1.cpp + apu/square2.cpp + apu/wave.cpp +) + +ares_add_header_sources(gb bus/bus.hpp) + +ares_add_header_sources( + gb + cartridge/cartridge.hpp + cartridge/memory.cpp + cartridge/serialization.cpp + cartridge/slot.cpp + cartridge/slot.hpp +) + +ares_add_header_sources( + gb + cartridge/board/board.cpp + cartridge/board/board.hpp + cartridge/board/huc1.cpp + cartridge/board/huc3.cpp + cartridge/board/linear.cpp + cartridge/board/mbc1.cpp + cartridge/board/mbc1m.cpp + cartridge/board/mbc2.cpp + cartridge/board/mbc3.cpp + cartridge/board/mbc5.cpp + cartridge/board/mbc6.cpp + cartridge/board/mbc7.cpp + cartridge/board/mmm01.cpp + cartridge/board/none.cpp + cartridge/board/tama.cpp +) + +ares_add_header_sources( + gb + cpu/cpu.hpp + cpu/debugger.cpp + cpu/io.cpp + cpu/memory.cpp + cpu/serialization.cpp + cpu/timing.cpp +) + +ares_add_header_sources( + gb + system/controls.cpp + system/serialization.cpp + system/system.hpp ) diff --git a/ares/gba/CMakeLists.txt b/ares/gba/CMakeLists.txt index 0214d11e54..bb9f184497 100644 --- a/ares/gba/CMakeLists.txt +++ b/ares/gba/CMakeLists.txt @@ -1,13 +1,86 @@ -ares_components( - arm7tdmi -) - -target_sources(ares PRIVATE - memory/memory.cpp - system/system.cpp - cartridge/cartridge.cpp - player/player.cpp - cpu/cpu.cpp - ppu/ppu.cpp - apu/apu.cpp +ares_components(arm7tdmi) + +target_sources( + ares + PRIVATE + memory/memory.cpp + system/system.cpp + cartridge/cartridge.cpp + player/player.cpp + cpu/cpu.cpp + ppu/ppu.cpp + apu/apu.cpp +) + +ares_add_header_sources(gba gba.hpp CMakeLists.txt) + +ares_add_header_sources( + gba + apu/apu.hpp + apu/fifo.cpp + apu/io.cpp + apu/noise.cpp + apu/sequencer.cpp + apu/serialization.cpp + apu/square.cpp + apu/square1.cpp + apu/square2.cpp + apu/wave.cpp +) + +ares_add_header_sources( + gba + cartridge/cartridge.hpp + cartridge/eeprom.cpp + cartridge/flash.cpp + cartridge/memory.hpp + cartridge/mrom.cpp + cartridge/serialization.cpp + cartridge/slot.cpp + cartridge/slot.hpp + cartridge/sram.cpp +) + +ares_add_header_sources( + gba + cpu/bus.cpp + cpu/cpu.hpp + cpu/debugger.cpp + cpu/dma.cpp + cpu/io.cpp + cpu/keypad.cpp + cpu/memory.cpp + cpu/prefetch.cpp + cpu/serialization.cpp + cpu/timer.cpp +) + +ares_add_header_sources(gba memory/memory.hpp) + +ares_add_header_sources( + gba + player/player.hpp + player/serialization.cpp +) + +ares_add_header_sources( + gba + ppu/background.cpp + ppu/color.cpp + ppu/dac.cpp + ppu/debugger.cpp + ppu/io.cpp + ppu/memory.cpp + ppu/object.cpp + ppu/ppu.hpp + ppu/serialization.cpp + ppu/window.cpp +) + +ares_add_header_sources( + gba + system/bios.cpp + system/controls.cpp + system/serialization.cpp + system/system.hpp ) diff --git a/ares/md/CMakeLists.txt b/ares/md/CMakeLists.txt index c9cd7e28df..6828052cef 100644 --- a/ares/md/CMakeLists.txt +++ b/ares/md/CMakeLists.txt @@ -8,15 +8,171 @@ ares_components( m24c ) -target_sources(ares PRIVATE - bus/bus.cpp - cpu/cpu.cpp - apu/apu.cpp - vdp/vdp.cpp - opn2/opn2.cpp - m32x/m32x.cpp - mcd/mcd.cpp - system/system.cpp - cartridge/cartridge.cpp - controller/controller.cpp +target_sources( + ares + PRIVATE + bus/bus.cpp + cpu/cpu.cpp + apu/apu.cpp + vdp/vdp.cpp + opn2/opn2.cpp + m32x/m32x.cpp + mcd/mcd.cpp + system/system.cpp + cartridge/cartridge.cpp + controller/controller.cpp +) + +ares_add_header_sources(md md.hpp CMakeLists.txt) + +ares_add_header_sources( + md + apu/apu.hpp + apu/bus.cpp + apu/debugger.cpp + apu/serialization.cpp +) + +ares_add_header_sources( + md + bus/bus.hpp + bus/inline.hpp + bus/serialization.cpp +) + +ares_add_header_sources( + md + cartridge/cartridge.hpp + cartridge/serialization.cpp + cartridge/slot.cpp + cartridge/slot.hpp +) + +ares_add_header_sources( + md + cartridge/board/banked.cpp + cartridge/board/board.cpp + cartridge/board/board.hpp + cartridge/board/debugger.cpp + cartridge/board/game-genie.cpp + cartridge/board/j-cart.cpp + cartridge/board/linear.cpp + cartridge/board/mega-32x.cpp + cartridge/board/realtec.cpp + cartridge/board/standard.cpp + cartridge/board/svp.cpp +) + +ares_add_header_sources( + md + controller/controller.hpp + controller/port.cpp + controller/port.hpp +) + +ares_add_header_sources( + md + controller/control-pad/control-pad.cpp + controller/control-pad/control-pad.hpp +) + +ares_add_header_sources( + md + controller/fighting-pad/fighting-pad.cpp + controller/fighting-pad/fighting-pad.hpp +) + +ares_add_header_sources( + md + cpu/bus.cpp + cpu/cpu.hpp + cpu/debugger.cpp + cpu/io.cpp + cpu/serialization.cpp +) + +ares_add_header_sources( + md + m32x/bus-external.cpp + m32x/bus-internal.cpp + m32x/debugger.cpp + m32x/io-external.cpp + m32x/io-internal.cpp + m32x/m32x.hpp + m32x/pwm.cpp + m32x/serialization.cpp + m32x/sh7604.cpp + m32x/vdp.cpp +) + +ares_add_header_sources( + md + mcd/bus-external.cpp + mcd/bus-internal.cpp + mcd/cdc-transfer.cpp + mcd/cdc.cpp + mcd/cdd-dac.cpp + mcd/cdd.cpp + mcd/debugger.cpp + mcd/gpu.cpp + mcd/io-external.cpp + mcd/io-internal.cpp + mcd/irq.cpp + mcd/mcd.hpp + mcd/pcm.cpp + mcd/serialization.cpp + mcd/timer.cpp +) + +ares_add_header_sources( + md + opn2/opn2.hpp + opn2/serialization.cpp +) + +ares_add_header_sources( + md + system/controls.cpp + system/serialization.cpp + system/system.hpp +) + +ares_add_header_sources( + md + vdp/color.cpp + vdp/dac.cpp + vdp/debugger.cpp + vdp/dma.cpp + vdp/fifo.cpp + vdp/io.cpp + vdp/irq.cpp + vdp/layer.cpp + vdp/layers.cpp + vdp/main.cpp + vdp/memory.cpp + vdp/prefetch.cpp + vdp/psg.cpp + vdp/serialization.cpp + vdp/sprite.cpp + vdp/vdp.hpp + vdp/window.cpp +) + +ares_add_header_sources( + md + vdp-performance/background.cpp + vdp-performance/color.cpp + vdp-performance/debugger.cpp + vdp-performance/dma.cpp + vdp-performance/io.cpp + vdp-performance/irq.cpp + vdp-performance/main.cpp + vdp-performance/memory.cpp + vdp-performance/object.cpp + vdp-performance/psg.cpp + vdp-performance/render.cpp + vdp-performance/serialization.cpp + vdp-performance/sprite.cpp + vdp-performance/vdp.cpp + vdp-performance/vdp.hpp ) diff --git a/ares/ms/CMakeLists.txt b/ares/ms/CMakeLists.txt index 1667d33c3d..d91be735db 100644 --- a/ares/ms/CMakeLists.txt +++ b/ares/ms/CMakeLists.txt @@ -1,16 +1,142 @@ -ares_components( - z80 - sn76489 - ym2413 -) - -target_sources(ares PRIVATE - cpu/cpu.cpp - vdp/vdp.cpp - psg/psg.cpp - opll/opll.cpp - system/system.cpp - cartridge/cartridge.cpp - controller/controller.cpp - expansion/expansion.cpp +ares_components(z80 sn76489 ym2413) + +target_sources( + ares + PRIVATE + cpu/cpu.cpp + vdp/vdp.cpp + psg/psg.cpp + opll/opll.cpp + system/system.cpp + cartridge/cartridge.cpp + controller/controller.cpp + expansion/expansion.cpp +) + +ares_add_header_sources(ms ms.hpp CMakeLists.txt) + +ares_add_header_sources( + ms + cartridge/cartridge.hpp + cartridge/serialization.cpp + cartridge/slot.cpp + cartridge/slot.hpp +) + +ares_add_header_sources( + ms + cartridge/board/board.cpp + cartridge/board/board.hpp + cartridge/board/codemasters.cpp + cartridge/board/hap2000.cpp + cartridge/board/hicom.cpp + cartridge/board/janggun.cpp + cartridge/board/k188in1.cpp + cartridge/board/korea.cpp + cartridge/board/pak4.cpp + cartridge/board/sega.cpp + cartridge/board/zemina.cpp +) + +ares_add_header_sources( + ms + controller/controller.hpp + controller/port.cpp + controller/port.hpp +) + +ares_add_header_sources( + ms + controller/gamepad/gamepad.cpp + controller/gamepad/gamepad.hpp +) + +ares_add_header_sources( + ms + controller/light-phaser/light-phaser.cpp + controller/light-phaser/light-phaser.hpp +) + +ares_add_header_sources( + ms + controller/md-control-pad/md-control-pad.cpp + controller/md-control-pad/md-control-pad.hpp +) + +ares_add_header_sources( + ms + controller/md-fighting-pad/md-fighting-pad.cpp + controller/md-fighting-pad/md-fighting-pad.hpp +) + +ares_add_header_sources( + ms + controller/mega-mouse/mega-mouse.cpp + controller/mega-mouse/mega-mouse.hpp +) + +ares_add_header_sources( + ms + controller/paddle/paddle.cpp + controller/paddle/paddle.hpp +) + +ares_add_header_sources( + ms + controller/sports-pad/sports-pad.cpp + controller/sports-pad/sports-pad.hpp +) + +ares_add_header_sources( + ms + cpu/cpu.hpp + cpu/debugger.cpp + cpu/memory.cpp + cpu/serialization.cpp +) + +ares_add_header_sources( + ms + expansion/expansion.hpp + expansion/port.cpp + expansion/port.hpp +) + +ares_add_header_sources( + ms + expansion/fmsound/fmsound.cpp + expansion/fmsound/fmsound.hpp +) + +ares_add_header_sources( + ms + opll/opll.hpp + opll/serialization.cpp +) + +ares_add_header_sources( + ms + psg/psg.hpp + psg/serialization.cpp +) + +ares_add_header_sources( + ms + system/bios.cpp + system/controls.cpp + system/serialization.cpp + system/system.hpp +) + +ares_add_header_sources( + ms + vdp/background.cpp + vdp/color.cpp + vdp/dac.cpp + vdp/debugger.cpp + vdp/io.cpp + vdp/irq.cpp + vdp/serialization.cpp + vdp/sprite.cpp + vdp/vdp.hpp ) diff --git a/ares/msx/CMakeLists.txt b/ares/msx/CMakeLists.txt index e78809e339..b02ff52e01 100644 --- a/ares/msx/CMakeLists.txt +++ b/ares/msx/CMakeLists.txt @@ -6,14 +6,110 @@ ares_components( ym2413 ) -target_sources(ares PRIVATE - system/system.cpp - keyboard/keyboard.cpp - cartridge/cartridge.cpp - controller/controller.cpp - cpu/cpu.cpp - vdp/vdp.cpp - psg/psg.cpp - tape/tape.cpp - rtc/rtc.cpp +target_sources( + ares + PRIVATE + system/system.cpp + keyboard/keyboard.cpp + cartridge/cartridge.cpp + controller/controller.cpp + cpu/cpu.cpp + vdp/vdp.cpp + psg/psg.cpp + tape/tape.cpp + rtc/rtc.cpp +) + +ares_add_header_sources(msx msx.hpp CMakeLists.txt) + +ares_add_header_sources( + msx + cartridge/cartridge.hpp + cartridge/serialization.cpp + cartridge/slot.cpp + cartridge/slot.hpp +) + +ares_add_header_sources( + msx + cartridge/board/asc16.cpp + cartridge/board/asc8.cpp + cartridge/board/board.cpp + cartridge/board/board.hpp + cartridge/board/cross-blaim.cpp + cartridge/board/konami-scc.cpp + cartridge/board/konami.cpp + cartridge/board/linear.cpp + cartridge/board/mirrored.cpp + cartridge/board/super-lode-runner.cpp + cartridge/board/super-pierrot.cpp +) + +ares_add_header_sources( + msx + controller/controller.hpp + controller/mux.cpp + controller/mux.hpp + controller/port.cpp + controller/port.hpp +) + +ares_add_header_sources( + msx + controller/gamepad/gamepad.cpp + controller/gamepad/gamepad.hpp +) + +ares_add_header_sources( + msx + controller/vaus-paddle/vaus-paddle.cpp + controller/vaus-paddle/vaus-paddle.hpp +) + +ares_add_header_sources( + msx + cpu/cpu.hpp + cpu/debugger.cpp + cpu/memory.cpp + cpu/serialization.cpp +) + +ares_add_header_sources( + msx + keyboard/keyboard.hpp + keyboard/serialization.cpp +) + +ares_add_header_sources( + msx + psg/psg.hpp + psg/serialization.cpp +) + +ares_add_header_sources( + msx + rtc/rtc.hpp + rtc/serialization.cpp +) + +ares_add_header_sources( + msx + system/serialization.cpp + system/system.hpp +) + +ares_add_header_sources( + msx + tape/deck.cpp + tape/deck.hpp + tape/tape.hpp + tape/tray.cpp + tape/tray.hpp +) + +ares_add_header_sources( + msx + vdp/color.cpp + vdp/serialization.cpp + vdp/vdp.hpp ) diff --git a/ares/msx/rtc/rtc.cpp b/ares/msx/rtc/rtc.cpp index d43f57182d..7145eee41d 100644 --- a/ares/msx/rtc/rtc.cpp +++ b/ares/msx/rtc/rtc.cpp @@ -65,4 +65,4 @@ auto RTC::write(n4 data) -> void { debug(unimplemented, "[RTC::write] bank: ", io.registerBank, " index: ", io.registerIndex, " = ", data); } -} \ No newline at end of file +} diff --git a/ares/myvision/CMakeLists.txt b/ares/myvision/CMakeLists.txt index 6c0225e474..3adf2cf65b 100644 --- a/ares/myvision/CMakeLists.txt +++ b/ares/myvision/CMakeLists.txt @@ -1,13 +1,53 @@ -ares_components( - z80 - tms9918 - ay38910 -) - -target_sources(ares PRIVATE - cpu/cpu.cpp - vdp/vdp.cpp - psg/psg.cpp - system/system.cpp - cartridge/cartridge.cpp +ares_components(z80 tms9918 ay38910) + +target_sources( + ares + PRIVATE + cpu/cpu.cpp + vdp/vdp.cpp + psg/psg.cpp + system/system.cpp + cartridge/cartridge.cpp +) + +ares_add_header_sources( + myvision + myvision.hpp + CMakeLists.txt +) + +ares_add_header_sources( + myvision + cartridge/cartridge.hpp + cartridge/serialization.cpp + cartridge/slot.cpp + cartridge/slot.hpp +) + +ares_add_header_sources( + myvision + cpu/cpu.hpp + cpu/debugger.cpp + cpu/memory.cpp + cpu/serialization.cpp +) + +ares_add_header_sources( + myvision + psg/psg.hpp + psg/serialization.cpp +) + +ares_add_header_sources( + myvision + system/controls.cpp + system/serialization.cpp + system/system.hpp +) + +ares_add_header_sources( + myvision + vdp/color.cpp + vdp/serialization.cpp + vdp/vdp.hpp ) diff --git a/ares/n64/CMakeLists.txt b/ares/n64/CMakeLists.txt index d154cebd5f..746efe2279 100644 --- a/ares/n64/CMakeLists.txt +++ b/ares/n64/CMakeLists.txt @@ -1,45 +1,231 @@ -ares_components( - sm5k -) - -target_sources(ares PRIVATE - memory/memory.cpp - system/system.cpp - cartridge/cartridge.cpp - cic/cic.cpp - controller/controller.cpp - dd/dd.cpp - mi/mi.cpp - vi/vi.cpp - ai/ai.cpp - pi/pi.cpp - pif/pif.cpp - ri/ri.cpp - si/si.cpp - rdram/rdram.cpp - cpu/cpu.cpp - rsp/rsp.cpp - rdp/rdp.cpp -) - -if(vulkan) - if(platform STREQUAL macos) -# molten = $(ares.path)/../thirdparty/MoltenVK/libMoltenVK.dylib -# ifeq ($(wildcard $(molten)),) -# molten = $(shell brew --prefix molten-vk)/lib/libMoltenVK.dylib -# ifeq ($(wildcard $(molten)),) -# $(error Compiling Ares N64 Vulkan backend requires MoltenVK. Install it via Homebrew, compile it using thirdparty/MoltenVK/build-moltenvk.sh, or disable with vulkan=false") -# endif -# endif -# ares.dylibs += $(molten) - endif() - - target_sources(ares PRIVATE - vulkan/vulkan.cpp - ) - - target_sources(ares PRIVATE -# $(wildcard vulkan/parallel-rdp/parallel-rdp/*.cpp) +ares_components(sm5k) + +target_sources( + ares + PRIVATE + memory/memory.cpp + system/system.cpp + cartridge/cartridge.cpp + cic/cic.cpp + controller/controller.cpp + dd/dd.cpp + mi/mi.cpp + vi/vi.cpp + ai/ai.cpp + pi/pi.cpp + pif/pif.cpp + ri/ri.cpp + si/si.cpp + rdram/rdram.cpp + cpu/cpu.cpp + rsp/rsp.cpp + rdp/rdp.cpp +) + +if(OS_WINDOWS) + include(cmake/os-windows.cmake) +elseif(OS_MACOS) + include(cmake/os-macos.cmake) +elseif(OS_LINUX) + include(cmake/os-linux.cmake) +elseif(OS_FREEBSD OR OS_OPENBSD) + include(cmake/os-freebsd.cmake) +endif() + +ares_add_header_sources(n64 n64.hpp CMakeLists.txt) + +ares_add_header_sources( + n64 + ai/ai.hpp + ai/debugger.cpp + ai/io.cpp + ai/serialization.cpp +) + +ares_add_header_sources( + n64 + cartridge/cartridge.hpp + cartridge/debugger.cpp + cartridge/flash.cpp + cartridge/isviewer.cpp + cartridge/joybus.cpp + cartridge/rtc.cpp + cartridge/serialization.cpp + cartridge/slot.cpp + cartridge/slot.hpp +) + +ares_add_header_sources( + n64 + cic/cic.hpp + cic/commands.cpp + cic/io.cpp + cic/serialization.cpp +) + +ares_add_header_sources( + n64 + controller/controller.hpp + controller/port.cpp + controller/port.hpp +) + +ares_add_header_sources( + n64 + controller/gamepad/gamepad.cpp + controller/gamepad/gamepad.hpp + controller/gamepad/transfer-pak.cpp +) + +ares_add_header_sources( + n64 + controller/mouse/mouse.cpp + controller/mouse/mouse.hpp +) + +ares_add_header_sources( + n64 + cpu/algorithms.cpp + cpu/context.cpp + cpu/cpu.hpp + cpu/dcache.cpp + cpu/debugger.cpp + cpu/disassembler.cpp + cpu/exceptions.cpp + cpu/interpreter-cop2.cpp + cpu/interpreter-fpu.cpp + cpu/interpreter-ipu.cpp + cpu/interpreter-scc.cpp + cpu/interpreter.cpp + cpu/memory.cpp + cpu/recompiler.cpp + cpu/serialization.cpp + cpu/tlb.cpp +) + +ares_add_header_sources( + n64 + dd/controller.cpp + dd/dd.hpp + dd/debugger.cpp + dd/drive.cpp + dd/io.cpp + dd/rtc.cpp + dd/serialization.cpp +) + +ares_add_header_sources( + n64 + memory/bus.hpp + memory/io.hpp + memory/memory.hpp + memory/lsb/readable.hpp + memory/lsb/writable.hpp + memory/msb/readable.hpp + memory/msb/writable.hpp +) + +ares_add_header_sources( + n64 + mi/debugger.cpp + mi/io.cpp + mi/mi.hpp + mi/serialization.cpp +) + +ares_add_header_sources( + n64 + pi/bus.hpp + pi/debugger.cpp + pi/dma.cpp + pi/io.cpp + pi/pi.hpp + pi/serialization.cpp +) + +ares_add_header_sources( + n64 + pif/debugger.cpp + pif/hle.cpp + pif/io.cpp + pif/pif.hpp + pif/serialization.cpp +) + +ares_add_header_sources( + n64 + rdp/debugger.cpp + rdp/io.cpp + rdp/rdp.hpp + rdp/render.cpp + rdp/serialization.cpp +) + +ares_add_header_sources( + n64 + rdram/debugger.cpp + rdram/io.cpp + rdram/rdram.hpp + rdram/serialization.cpp +) + +ares_add_header_sources( + n64 + ri/debugger.cpp + ri/io.cpp + ri/ri.hpp + ri/serialization.cpp +) + +ares_add_header_sources( + n64 + rsp/debugger.cpp + rsp/decoder.cpp + rsp/disassembler.cpp + rsp/dma.cpp + rsp/interpreter-ipu.cpp + rsp/interpreter-scc.cpp + rsp/interpreter-vpu.cpp + rsp/interpreter.cpp + rsp/io.cpp + rsp/recompiler.cpp + rsp/rsp.hpp + rsp/serialization.cpp +) + +ares_add_header_sources( + n64 + si/debugger.cpp + si/dma.cpp + si/io.cpp + si/serialization.cpp + si/si.hpp +) + +ares_add_header_sources( + n64 + system/serialization.cpp + system/system.hpp +) + +ares_add_header_sources( + n64 + vi/debugger.cpp + vi/io.cpp + vi/serialization.cpp + vi/vi.hpp +) + +target_compile_definitions(ares PRIVATE VULKAN) + +target_sources( + ares + PRIVATE vulkan/vulkan.cpp vulkan/vulkan.hpp +) + +target_sources( + ares + PRIVATE vulkan/parallel-rdp/parallel-rdp/command_ring.cpp vulkan/parallel-rdp/parallel-rdp/rdp_device.cpp vulkan/parallel-rdp/parallel-rdp/rdp_dump_write.cpp @@ -74,26 +260,74 @@ if(vulkan) vulkan/parallel-rdp/util/timer.cpp vulkan/parallel-rdp/util/timeline_trace_file.cpp vulkan/parallel-rdp/util/thread_name.cpp - + vulkan/parallel-rdp/util/environment.cpp vulkan/parallel-rdp/volk/volk.c - ) +) +target_sources( + ares + PRIVATE + vulkan/parallel-rdp/parallel-rdp/command_ring.hpp + vulkan/parallel-rdp/parallel-rdp/rdp_device.hpp + vulkan/parallel-rdp/parallel-rdp/rdp_dump_write.hpp + vulkan/parallel-rdp/parallel-rdp/rdp_renderer.hpp + vulkan/parallel-rdp/parallel-rdp/video_interface.hpp + vulkan/parallel-rdp/vulkan/buffer.hpp + vulkan/parallel-rdp/vulkan/buffer_pool.hpp + vulkan/parallel-rdp/vulkan/command_buffer.hpp + vulkan/parallel-rdp/vulkan/command_pool.hpp + vulkan/parallel-rdp/vulkan/context.hpp + vulkan/parallel-rdp/vulkan/cookie.hpp + vulkan/parallel-rdp/vulkan/descriptor_set.hpp + vulkan/parallel-rdp/vulkan/device.hpp + vulkan/parallel-rdp/vulkan/event_manager.hpp + vulkan/parallel-rdp/vulkan/fence.hpp + vulkan/parallel-rdp/vulkan/fence_manager.hpp + vulkan/parallel-rdp/vulkan/image.hpp + vulkan/parallel-rdp/vulkan/indirect_layout.hpp + vulkan/parallel-rdp/vulkan/memory_allocator.hpp + vulkan/parallel-rdp/vulkan/pipeline_event.hpp + vulkan/parallel-rdp/vulkan/query_pool.hpp + vulkan/parallel-rdp/vulkan/render_pass.hpp + vulkan/parallel-rdp/vulkan/sampler.hpp + vulkan/parallel-rdp/vulkan/semaphore.hpp + vulkan/parallel-rdp/vulkan/semaphore_manager.hpp + vulkan/parallel-rdp/vulkan/shader.hpp + vulkan/parallel-rdp/vulkan/texture/texture_format.hpp + vulkan/parallel-rdp/util/arena_allocator.hpp + vulkan/parallel-rdp/util/logging.hpp + vulkan/parallel-rdp/util/thread_id.hpp + vulkan/parallel-rdp/util/aligned_alloc.hpp + vulkan/parallel-rdp/util/timer.hpp + vulkan/parallel-rdp/util/timeline_trace_file.hpp + vulkan/parallel-rdp/util/thread_name.hpp + vulkan/parallel-rdp/util/environment.hpp + vulkan/parallel-rdp/volk/volk.c +) - target_include_directories(ares PRIVATE +target_include_directories( + ares + PRIVATE vulkan/parallel-rdp/parallel-rdp vulkan/parallel-rdp/volk vulkan/parallel-rdp/vulkan vulkan/parallel-rdp/vulkan-headers/include vulkan/parallel-rdp/util - ) +) -# PARALLEL_RDP_LDFLAGS := -pthread - if(platform STREQUAL windows) - target_compile_definitions(ares PRIVATE VK_USE_PLATFORM_WIN32_KHR) -# PARALLEL_RDP_LDFLAGS += -lwinmm - else() -# PARALLEL_RDP_LDFLAGS += -ldl - endif() +target_compile_options(ares PRIVATE + $<$:-Wno-newline-eof> +) + +set(THREADS_PREFER_PTHREAD_FLAG ON) +find_package(Threads REQUIRED) +target_link_libraries(ares PUBLIC Threads::Threads) +if(OS_WINDOWS) + target_compile_definitions( + ares + PRIVATE VK_USE_PLATFORM_WIN32_KHR + ) + target_link_libraries(ares PRIVATE winmm) else() - message(WARNING "Ares n64 core requires Vulkan for RDP emulation, only titles using Software Rendering will function") + target_link_libraries(ares PRIVATE dl) endif() diff --git a/ares/n64/cmake/os-linux.cmake b/ares/n64/cmake/os-linux.cmake new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ares/n64/cmake/os-macos.cmake b/ares/n64/cmake/os-macos.cmake new file mode 100644 index 0000000000..af414eb3d8 --- /dev/null +++ b/ares/n64/cmake/os-macos.cmake @@ -0,0 +1,12 @@ +target_sources(ares PRIVATE cmake/os-macos.cmake) + +find_package(MoltenVK) + +target_link_libraries( + ares + PRIVATE $<$:MoltenVK::MoltenVK> +) + +if(MoltenVK_FOUND) + set(VULKAN_FOUND true) +endif() diff --git a/ares/n64/cmake/os-windows.cmake b/ares/n64/cmake/os-windows.cmake new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ares/n64/cpu/recompiler.cpp b/ares/n64/cpu/recompiler.cpp index 05a66941d8..79d78a9c76 100644 --- a/ares/n64/cpu/recompiler.cpp +++ b/ares/n64/cpu/recompiler.cpp @@ -23,6 +23,8 @@ auto CPU::Recompiler::block(u64 vaddr, u32 address, bool singleInstruction) -> B #define IpuReg(r) sreg(1), offsetof(IPU, r) - IpuBase #define PipelineReg(x) mem(sreg(0), offsetof(CPU, pipeline) + offsetof(Pipeline, x)) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winvalid-offsetof" auto CPU::Recompiler::emit(u64 vaddr, u32 address, bool singleInstruction) -> Block* { if(unlikely(allocator.available() < 1_MiB)) { print("CPU allocator flush\n"); @@ -94,6 +96,7 @@ auto CPU::Recompiler::emit(u64 vaddr, u32 address, bool singleInstruction) -> Bl //print(hex(PC, 8L), " ", instructions, " ", size(), "\n"); return block; } +#pragma clang diagnostic pop #define Sa (instruction >> 6 & 31) #define Rdn (instruction >> 11 & 31) diff --git a/ares/ng/CMakeLists.txt b/ares/ng/CMakeLists.txt index 547a801ee7..821dd91495 100644 --- a/ares/ng/CMakeLists.txt +++ b/ares/ng/CMakeLists.txt @@ -1,15 +1,91 @@ -ares_components( - m68000 - z80 -) - -target_sources(ares PRIVATE - system/system.cpp - cpu/cpu.cpp - apu/apu.cpp - lspc/lspc.cpp - opnb/opnb.cpp - cartridge/cartridge.cpp - controller/controller.cpp - card/card.cpp +ares_components(m68000 z80) + +target_link_libraries(ares PRIVATE ymfm) + +target_sources( + ares + PRIVATE + system/system.cpp + cpu/cpu.cpp + apu/apu.cpp + lspc/lspc.cpp + opnb/opnb.cpp + cartridge/cartridge.cpp + controller/controller.cpp + card/card.cpp +) + +ares_add_header_sources(ng ng.hpp CMakeLists.txt) + +ares_add_header_sources( + ng + apu/apu.hpp + apu/debugger.cpp + apu/memory.cpp + apu/serialization.cpp +) + +ares_add_header_sources( + ng + card/card.hpp + card/debugger.cpp + card/serialization.cpp + card/slot.cpp + card/slot.hpp +) + +ares_add_header_sources( + ng + cartridge/cartridge.hpp + cartridge/serialization.cpp + cartridge/slot.cpp + cartridge/slot.hpp + cartridge/board/board.cpp + cartridge/board/board.hpp + cartridge/board/jockey-gp.cpp + cartridge/board/mslugx.cpp + cartridge/board/rom.cpp +) + +ares_add_header_sources( + ng + controller/controller.hpp + controller/port.cpp + controller/port.hpp +) + +ares_add_header_sources( + ng + controller/arcade-stick/arcade-stick.cpp + controller/arcade-stick/arcade-stick.hpp +) + +ares_add_header_sources( + ng + cpu/cpu.hpp + cpu/debugger.cpp + cpu/memory.cpp + cpu/serialization.cpp +) + +ares_add_header_sources( + ng + lspc/color.cpp + lspc/debugger.cpp + lspc/lspc.hpp + lspc/render.cpp + lspc/serialization.cpp +) + +ares_add_header_sources( + ng + opnb/opnb.hpp + opnb/serialization.cpp +) + +ares_add_header_sources( + ng + system/debugger.cpp + system/serialization.cpp + system/system.hpp ) diff --git a/ares/ngp/CMakeLists.txt b/ares/ngp/CMakeLists.txt index 20891a28d7..7fccb40002 100644 --- a/ares/ngp/CMakeLists.txt +++ b/ares/ngp/CMakeLists.txt @@ -1,14 +1,75 @@ -ares_components( - tlcs900h - z80 - t6w28 -) - -target_sources(ares PRIVATE - system/system.cpp - cartridge/cartridge.cpp - cpu/cpu.cpp - apu/apu.cpp - kge/kge.cpp - psg/psg.cpp +ares_components(tlcs900h z80 t6w28) + +target_sources( + ares + PRIVATE + system/system.cpp + cartridge/cartridge.cpp + cpu/cpu.cpp + apu/apu.cpp + kge/kge.cpp + psg/psg.cpp +) + +ares_add_header_sources(ngp ngp.hpp CMakeLists.txt) + +ares_add_header_sources( + ngp + apu/apu.hpp + apu/debugger.cpp + apu/memory.cpp + apu/serialization.cpp +) + +ares_add_header_sources( + ngp + cartridge/cartridge.hpp + cartridge/debugger.cpp + cartridge/flash.cpp + cartridge/flash.hpp + cartridge/serialization.cpp + cartridge/slot.cpp + cartridge/slot.hpp +) + +ares_add_header_sources( + ngp + cpu/adc.cpp + cpu/cpu.hpp + cpu/debugger.cpp + cpu/interrupts.cpp + cpu/io.cpp + cpu/memory.cpp + cpu/ports.cpp + cpu/rtc.cpp + cpu/serial.cpp + cpu/serialization.cpp + cpu/timers.cpp + cpu/watchdog.cpp +) + +ares_add_header_sources( + ngp + kge/color.cpp + kge/dac.cpp + kge/kge.hpp + kge/memory.cpp + kge/plane.cpp + kge/serialization.cpp + kge/sprite.cpp + kge/window.cpp +) + +ares_add_header_sources( + ngp + psg/psg.hpp + psg/serialization.cpp +) + +ares_add_header_sources( + ngp + system/controls.cpp + system/debugger.cpp + system/serialization.cpp + system/system.hpp ) diff --git a/ares/pce/CMakeLists.txt b/ares/pce/CMakeLists.txt index 92144c768e..0cf10e691c 100644 --- a/ares/pce/CMakeLists.txt +++ b/ares/pce/CMakeLists.txt @@ -1,15 +1,121 @@ -ares_components( - huc6280 - msm5205 -) - -target_sources(ares PRIVATE - cpu/cpu.cpp - vdp/vdp.cpp - vdp-performance/vdp.cpp - psg/psg.cpp - pcd/pcd.cpp - system/system.cpp - cartridge/cartridge.cpp - controller/controller.cpp +ares_components(huc6280 msm5205) + +target_sources( + ares + PRIVATE + cpu/cpu.cpp + vdp/vdp.cpp + vdp-performance/vdp.cpp + psg/psg.cpp + pcd/pcd.cpp + system/system.cpp + cartridge/cartridge.cpp + controller/controller.cpp +) + +ares_add_header_sources(pce pce.hpp CMakeLists.txt) + +ares_add_header_sources( + pce + cartridge/cartridge.hpp + cartridge/serialization.cpp + cartridge/slot.cpp + cartridge/slot.hpp + cartridge/board/arcade-card-duo.cpp + cartridge/board/arcade-card-pro.cpp + cartridge/board/banked.cpp + cartridge/board/board.cpp + cartridge/board/board.hpp + cartridge/board/debugger.cpp + cartridge/board/games-express.cpp + cartridge/board/linear.cpp + cartridge/board/ram.cpp + cartridge/board/split.cpp + cartridge/board/super-system-card.cpp + cartridge/board/system-card.cpp +) + +ares_add_header_sources( + pce + controller/controller.hpp + controller/port.cpp + controller/port.hpp + controller/avenuepad/avenuepad.cpp + controller/avenuepad/avenuepad.hpp + controller/gamepad/gamepad.cpp + controller/gamepad/gamepad.hpp + controller/multitap/multitap.cpp + controller/multitap/multitap.hpp +) + +ares_add_header_sources( + pce + cpu/cpu.hpp + cpu/debugger.cpp + cpu/io.cpp + cpu/irq.cpp + cpu/serialization.cpp +) + +ares_add_header_sources( + pce + pcd/adpcm.cpp + pcd/cdda.cpp + pcd/debugger.cpp + pcd/drive.cpp + pcd/fader.cpp + pcd/io.cpp + pcd/pcd.hpp + pcd/scsi.cpp + pcd/serialization.cpp +) + +ares_add_header_sources( + pce + psg/channel.cpp + psg/io.cpp + psg/psg.hpp + psg/serialization.cpp +) + +ares_add_header_sources( + pce + system/serialization.cpp + system/system.hpp +) + +ares_add_header_sources( + pce + vdp/background.cpp + vdp/color.cpp + vdp/debugger.cpp + vdp/dma.cpp + vdp/irq.cpp + vdp/serialization.cpp + vdp/sprite.cpp + vdp/vce.cpp + vdp/vce.hpp + vdp/vdc.cpp + vdp/vdc.hpp + vdp/vdp.hpp + vdp/vpc.cpp + vdp/vpc.hpp +) + +ares_add_header_sources( + pce + vdp-performance/background.cpp + vdp-performance/color.cpp + vdp-performance/debugger.cpp + vdp-performance/dma.cpp + vdp-performance/irq.cpp + vdp-performance/serialization.cpp + vdp-performance/sprite.cpp + vdp-performance/vce.cpp + vdp-performance/vce.hpp + vdp-performance/vdc.cpp + vdp-performance/vdc.hpp + vdp-performance/vdp.hpp + vdp-performance/vpc.cpp + vdp-performance/vpc.hpp ) diff --git a/ares/ps1/CMakeLists.txt b/ares/ps1/CMakeLists.txt index 741c6b1f73..26bc6f2395 100644 --- a/ares/ps1/CMakeLists.txt +++ b/ares/ps1/CMakeLists.txt @@ -1,17 +1,147 @@ -ares_components( - m68hc05 -) - -target_sources(ares PRIVATE - memory/memory.cpp - system/system.cpp - disc/disc.cpp - cpu/cpu.cpp - gpu/gpu.cpp - spu/spu.cpp - mdec/mdec.cpp - interrupt/interrupt.cpp - peripheral/peripheral.cpp - dma/dma.cpp - timer/timer.cpp +ares_components(m68hc05) + +target_sources( + ares + PRIVATE + memory/memory.cpp + system/system.cpp + disc/disc.cpp + cpu/cpu.cpp + gpu/gpu.cpp + spu/spu.cpp + mdec/mdec.cpp + interrupt/interrupt.cpp + peripheral/peripheral.cpp + dma/dma.cpp + timer/timer.cpp +) + +ares_add_header_sources(ps1 ps1.hpp CMakeLists.txt) + +ares_add_header_sources(ps1 accuracy.hpp) + +ares_add_header_sources( + ps1 + cpu/breakpoints.cpp + cpu/cpu.hpp + cpu/debugger.cpp + cpu/delay-slots.cpp + cpu/disassembler.cpp + cpu/exceptions.cpp + cpu/icache.cpp + cpu/interpreter-gte.cpp + cpu/interpreter-ipu.cpp + cpu/interpreter-scc.cpp + cpu/interpreter.cpp + cpu/memory.cpp + cpu/recompiler.cpp + cpu/serialization.cpp +) + +ares_add_header_sources( + ps1 + disc/cdda.cpp + disc/cdxa.cpp + disc/command.cpp + disc/debugger.cpp + disc/disc.hpp + disc/drive.cpp + disc/io.cpp + disc/irq.cpp + disc/serialization.cpp +) + +ares_add_header_sources( + ps1 + dma/channel.cpp + dma/debugger.cpp + dma/dma.hpp + dma/io.cpp + dma/irq.cpp + dma/serialization.cpp +) + +ares_add_header_sources( + ps1 + gpu/blitter.cpp + gpu/debugger.cpp + gpu/gp0.cpp + gpu/gp1.cpp + gpu/gpu.hpp + gpu/io.cpp + gpu/renderer.cpp + gpu/serialization.cpp +) + +ares_add_header_sources( + ps1 + interrupt/interrupt.hpp + interrupt/io.cpp + interrupt/serialization.cpp +) + +ares_add_header_sources( + ps1 + mdec/decoder.cpp + mdec/io.cpp + mdec/mdec.hpp + mdec/serialization.cpp + mdec/tables.cpp +) + +ares_add_header_sources( + ps1 + memory/bus.hpp + memory/interface.hpp + memory/io.cpp + memory/memory.hpp + memory/readable.hpp + memory/serialization.cpp + memory/unmapped.hpp + memory/writable.hpp +) + +ares_add_header_sources( + ps1 + peripheral/io.cpp + peripheral/peripheral.hpp + peripheral/port.cpp + peripheral/port.hpp + peripheral/serialization.cpp + peripheral/digital-gamepad/digital-gamepad.cpp + peripheral/digital-gamepad/digital-gamepad.hpp + peripheral/dualshock/dualshock.cpp + peripheral/dualshock/dualshock.hpp + peripheral/memory-card/memory-card.cpp + peripheral/memory-card/memory-card.hpp +) + +ares_add_header_sources( + ps1 + spu/adpcm.cpp + spu/adsr.cpp + spu/capture.cpp + spu/debugger.cpp + spu/envelope.cpp + spu/fifo.cpp + spu/gaussian.cpp + spu/io.cpp + spu/noise.cpp + spu/reverb.cpp + spu/serialization.cpp + spu/spu.hpp + spu/voice.cpp +) + +ares_add_header_sources( + ps1 + system/serialization.cpp + system/system.hpp +) + +ares_add_header_sources( + ps1 + timer/io.cpp + timer/serialization.cpp + timer/timer.hpp ) diff --git a/ares/saturn/CMakeLists.txt b/ares/saturn/CMakeLists.txt index 1e6f67a16b..920339c988 100644 --- a/ares/saturn/CMakeLists.txt +++ b/ares/saturn/CMakeLists.txt @@ -1,8 +1,5 @@ -ares_components( - sh2 - m68k -) +ares_components(sh2 m68k) -target_sources(ares PRIVATE - system/system.cpp -) +target_sources(ares PRIVATE system/system.cpp) + +ares_add_header_sources(saturn saturn.hpp CMakeLists.txt) diff --git a/ares/sfc/CMakeLists.txt b/ares/sfc/CMakeLists.txt index 35b2319ce0..f27475ca95 100644 --- a/ares/sfc/CMakeLists.txt +++ b/ares/sfc/CMakeLists.txt @@ -7,19 +7,253 @@ ares_components( upd96050 ) -target_sources(ares PRIVATE - system/system.cpp - controller/controller.cpp - cartridge/cartridge.cpp - memory/memory.cpp - - cpu/cpu.cpp - smp/smp.cpp - dsp/dsp.cpp - ppu/ppu.cpp - ppu-performance/ppu.cpp - - coprocessor/coprocessor.cpp - expansion/expansion.cpp - slot/slot.cpp +target_sources( + ares + PRIVATE + system/system.cpp + controller/controller.cpp + cartridge/cartridge.cpp + memory/memory.cpp + cpu/cpu.cpp + smp/smp.cpp + dsp/dsp.cpp + ppu/ppu.cpp + ppu-performance/ppu.cpp + coprocessor/coprocessor.cpp + expansion/expansion.cpp + slot/slot.cpp +) + +ares_add_header_sources(sfc sfc.hpp CMakeLists.txt) + +ares_add_header_sources( + sfc + cartridge/cartridge.hpp + cartridge/debugger.cpp + cartridge/load.cpp + cartridge/save.cpp + cartridge/serialization.cpp + cartridge/slot.cpp + cartridge/slot.hpp +) + +ares_add_header_sources( + sfc + controller/controller.hpp + controller/port.cpp + controller/port.hpp + controller/gamepad/gamepad.cpp + controller/gamepad/gamepad.hpp + controller/justifier/justifier.cpp + controller/justifier/justifier.hpp + controller/justifiers/justifiers.cpp + controller/justifiers/justifiers.hpp + controller/mouse/mouse.cpp + controller/mouse/mouse.hpp + controller/ntt-data-keypad/ntt-data-keypad.cpp + controller/ntt-data-keypad/ntt-data-keypad.hpp + controller/super-multitap/super-multitap.cpp + controller/super-multitap/super-multitap.hpp + controller/super-scope/super-scope.cpp + controller/super-scope/super-scope.hpp + controller/twin-tap/twin-tap.cpp + controller/twin-tap/twin-tap.hpp +) + +ares_add_header_sources( + sfc + coprocessor/coprocessor.hpp + coprocessor/armdsp/armdsp.cpp + coprocessor/armdsp/armdsp.hpp + coprocessor/armdsp/debugger.cpp + coprocessor/armdsp/io.cpp + coprocessor/armdsp/memory.cpp + coprocessor/armdsp/serialization.cpp + coprocessor/competition/competition.cpp + coprocessor/competition/competition.hpp + coprocessor/competition/serialization.cpp + coprocessor/dip/dip.cpp + coprocessor/dip/dip.hpp + coprocessor/dip/serialization.cpp + coprocessor/epsonrtc/epsonrtc.cpp + coprocessor/epsonrtc/epsonrtc.hpp + coprocessor/epsonrtc/memory.cpp + coprocessor/epsonrtc/serialization.cpp + coprocessor/epsonrtc/time.cpp + coprocessor/hitachidsp/debugger.cpp + coprocessor/hitachidsp/hitachidsp.cpp + coprocessor/hitachidsp/hitachidsp.hpp + coprocessor/hitachidsp/memory.cpp + coprocessor/hitachidsp/serialization.cpp + coprocessor/icd/icd.cpp + coprocessor/icd/icd.hpp + coprocessor/icd/interface.cpp + coprocessor/icd/io.cpp + coprocessor/icd/serialization.cpp + coprocessor/mcc/mcc.cpp + coprocessor/mcc/mcc.hpp + coprocessor/mcc/serialization.cpp + coprocessor/msu1/msu1.cpp + coprocessor/msu1/msu1.hpp + coprocessor/msu1/serialization.cpp + coprocessor/necdsp/debugger.cpp + coprocessor/necdsp/memory.cpp + coprocessor/necdsp/necdsp.cpp + coprocessor/necdsp/necdsp.hpp + coprocessor/necdsp/serialization.cpp + coprocessor/obc1/obc1.cpp + coprocessor/obc1/obc1.hpp + coprocessor/obc1/serialization.cpp + coprocessor/sa1/bwram.cpp + coprocessor/sa1/debugger.cpp + coprocessor/sa1/dma.cpp + coprocessor/sa1/io.cpp + coprocessor/sa1/iram.cpp + coprocessor/sa1/memory.cpp + coprocessor/sa1/rom.cpp + coprocessor/sa1/sa1.cpp + coprocessor/sa1/sa1.hpp + coprocessor/sa1/serialization.cpp + coprocessor/sdd1/decompressor.cpp + coprocessor/sdd1/decompressor.hpp + coprocessor/sdd1/sdd1.cpp + coprocessor/sdd1/sdd1.hpp + coprocessor/sdd1/serialization.cpp + coprocessor/sharprtc/memory.cpp + coprocessor/sharprtc/serialization.cpp + coprocessor/sharprtc/sharprtc.cpp + coprocessor/sharprtc/sharprtc.hpp + coprocessor/sharprtc/time.cpp + coprocessor/spc7110/alu.cpp + coprocessor/spc7110/data.cpp + coprocessor/spc7110/dcu.cpp + coprocessor/spc7110/decompressor.cpp + coprocessor/spc7110/serialization.cpp + coprocessor/spc7110/spc7110.cpp + coprocessor/spc7110/spc7110.hpp + coprocessor/superfx/bus.cpp + coprocessor/superfx/core.cpp + coprocessor/superfx/debugger.cpp + coprocessor/superfx/io.cpp + coprocessor/superfx/memory.cpp + coprocessor/superfx/serialization.cpp + coprocessor/superfx/superfx.cpp + coprocessor/superfx/superfx.hpp + coprocessor/superfx/timing.cpp +) + +ares_add_header_sources( + sfc + cpu/cpu.hpp + cpu/debugger.cpp + cpu/dma.cpp + cpu/io.cpp + cpu/irq.cpp + cpu/memory.cpp + cpu/serialization.cpp + cpu/timing.cpp +) + +ares_add_header_sources( + sfc + dsp/brr.cpp + dsp/counter.cpp + dsp/debugger.cpp + dsp/dsp.hpp + dsp/echo.cpp + dsp/envelope.cpp + dsp/gaussian.cpp + dsp/memory.cpp + dsp/misc.cpp + dsp/serialization.cpp + dsp/voice.cpp +) + +ares_add_header_sources( + sfc + expansion/expansion.hpp + expansion/port.cpp + expansion/port.hpp + expansion/21fx/21fx.cpp + expansion/21fx/21fx.hpp + expansion/satellaview/satellaview.cpp + expansion/satellaview/satellaview.hpp +) + +ares_add_header_sources( + sfc + memory/inline.hpp + memory/memory.hpp + memory/protectable.hpp + memory/readable.hpp + memory/writable.hpp +) + +ares_add_header_sources( + sfc + ppu/background.cpp + ppu/color.cpp + ppu/dac.cpp + ppu/debugger.cpp + ppu/io.cpp + ppu/main.cpp + ppu/mode7.cpp + ppu/mosaic.cpp + ppu/oam.cpp + ppu/object.cpp + ppu/ppu.hpp + ppu/serialization.cpp + ppu/window.cpp + ppu/counter/counter.hpp + ppu/counter/inline.hpp + ppu/counter/serialization.cpp +) + +ares_add_header_sources( + sfc + ppu-performance/background.cpp + ppu-performance/color.cpp + ppu-performance/dac.cpp + ppu-performance/debugger.cpp + ppu-performance/io.cpp + ppu-performance/mode7.cpp + ppu-performance/mosaic.cpp + ppu-performance/oam.cpp + ppu-performance/object.cpp + ppu-performance/ppu.hpp + ppu-performance/serialization.cpp + ppu-performance/window.cpp +) + +ares_add_header_sources( + sfc + slot/slot.hpp + slot/bsmemory/bsmemory.cpp + slot/bsmemory/bsmemory.hpp + slot/bsmemory/serialization.cpp + slot/bsmemory/slot.cpp + slot/bsmemory/slot.hpp + slot/sufamiturbo/memory.cpp + slot/sufamiturbo/serialization.cpp + slot/sufamiturbo/slot.cpp + slot/sufamiturbo/slot.hpp + slot/sufamiturbo/sufamiturbo.cpp + slot/sufamiturbo/sufamiturbo.hpp +) + +ares_add_header_sources( + sfc + smp/debugger.cpp + smp/io.cpp + smp/memory.cpp + smp/serialization.cpp + smp/smp.hpp + smp/timing.cpp +) + +ares_add_header_sources( + sfc + system/controls.cpp + system/serialization.cpp + system/system.hpp ) diff --git a/ares/sfc/coprocessor/superfx/core.cpp b/ares/sfc/coprocessor/superfx/core.cpp index b0766468d0..74895edce9 100644 --- a/ares/sfc/coprocessor/superfx/core.cpp +++ b/ares/sfc/coprocessor/superfx/core.cpp @@ -49,7 +49,7 @@ auto SuperFX::rpix(n8 x, n8 y) -> n8 { flushPixelCache(pixelcache[1]); flushPixelCache(pixelcache[0]); - u32 cn = 0; //character number + u32 cn = 0; //character number switch(regs.por.obj ? 3 : regs.scmr.ht) { case 0: cn = ((x & 0xf8) << 1) + ((y & 0xf8) >> 3); break; case 1: cn = ((x & 0xf8) << 1) + ((x & 0xf8) >> 1) + ((y & 0xf8) >> 3); break; @@ -76,7 +76,7 @@ auto SuperFX::flushPixelCache(PixelCache& cache) -> void { n8 x = cache.offset << 3; n8 y = cache.offset >> 5; - u32 cn = 0; //character number + u32 cn = 0; //character number switch(regs.por.obj ? 3 : regs.scmr.ht) { case 0: cn = ((x & 0xf8) << 1) + ((y & 0xf8) >> 3); break; case 1: cn = ((x & 0xf8) << 1) + ((x & 0xf8) >> 1) + ((y & 0xf8) >> 3); break; diff --git a/ares/sg/CMakeLists.txt b/ares/sg/CMakeLists.txt index 956cc92d59..b6cb37cc6e 100644 --- a/ares/sg/CMakeLists.txt +++ b/ares/sg/CMakeLists.txt @@ -1,16 +1,80 @@ -ares_components( - z80 - tms9918 - sn76489 - i8255 -) - -target_sources(ares PRIVATE - cpu/cpu.cpp - vdp/vdp.cpp - psg/psg.cpp - ppi/ppi.cpp - system/system.cpp - cartridge/cartridge.cpp - controller/controller.cpp +ares_components(z80 tms9918 sn76489 i8255) + +target_sources( + ares + PRIVATE + cpu/cpu.cpp + vdp/vdp.cpp + psg/psg.cpp + ppi/ppi.cpp + system/system.cpp + cartridge/cartridge.cpp + controller/controller.cpp +) + +ares_add_header_sources(sg sg.hpp CMakeLists.txt) + +ares_add_header_sources( + sg + cartridge/cartridge.hpp + cartridge/serialization.cpp + cartridge/slot.cpp + cartridge/slot.hpp +) + +ares_add_header_sources( + sg + cartridge/cartridge.hpp + cartridge/serialization.cpp + cartridge/slot.cpp + cartridge/slot.hpp + cartridge/board/arcade-rom.cpp + cartridge/board/board.cpp + cartridge/board/board.hpp + cartridge/board/linear.cpp + cartridge/board/taiwan-a.cpp + cartridge/board/taiwan-b.cpp +) + +ares_add_header_sources( + sg + controller/controller.hpp + controller/port.cpp + controller/port.hpp + controller/gamepad/gamepad.cpp + controller/gamepad/gamepad.hpp +) + +ares_add_header_sources( + sg + cpu/cpu.hpp + cpu/debugger.cpp + cpu/memory.cpp + cpu/serialization.cpp +) + +ares_add_header_sources( + sg + ppi/ppi.hpp + ppi/serialization.cpp +) + +ares_add_header_sources( + sg + psg/psg.hpp + psg/serialization.cpp +) + +ares_add_header_sources( + sg + system/arcade-controls.cpp + system/serialization.cpp + system/system.hpp +) + +ares_add_header_sources( + sg + vdp/color.cpp + vdp/serialization.cpp + vdp/vdp.hpp ) diff --git a/ares/spec/CMakeLists.txt b/ares/spec/CMakeLists.txt index e683ebccb4..157d7f8c67 100644 --- a/ares/spec/CMakeLists.txt +++ b/ares/spec/CMakeLists.txt @@ -1,14 +1,62 @@ -ares_components( - z80 - ay38910 -) - -target_sources(ares PRIVATE - keyboard/keyboard.cpp - expansion/expansion.cpp - system/system.cpp - cpu/cpu.cpp - ula/ula.cpp - psg/psg.cpp - tape/tape.cpp +ares_components(z80 ay38910) + +target_sources( + ares + PRIVATE + keyboard/keyboard.cpp + expansion/expansion.cpp + system/system.cpp + cpu/cpu.cpp + ula/ula.cpp + psg/psg.cpp + tape/tape.cpp +) + +ares_add_header_sources(spec spec.hpp CMakeLists.txt) + +ares_add_header_sources( + spec + cpu/cpu.hpp + cpu/debugger.cpp + cpu/memory.cpp + cpu/serialization.cpp +) + +ares_add_header_sources( + spec + expansion/expansion.hpp + expansion/port.cpp + expansion/port.hpp + expansion/kempston/kempston.cpp + expansion/kempston/kempston.hpp +) + +ares_add_header_sources(spec keyboard/keyboard.hpp) + +ares_add_header_sources( + spec + psg/psg.hpp + psg/serialization.cpp +) + +ares_add_header_sources( + spec + system/serialization.cpp + system/system.hpp +) + +ares_add_header_sources( + spec + tape/deck.cpp + tape/deck.hpp + tape/tape.hpp + tape/tray.cpp + tape/tray.hpp +) + +ares_add_header_sources( + spec + ula/color.cpp + ula/serialization.cpp + ula/ula.hpp ) diff --git a/ares/ws/CMakeLists.txt b/ares/ws/CMakeLists.txt index 7240d2e476..d08258ec6a 100644 --- a/ares/ws/CMakeLists.txt +++ b/ares/ws/CMakeLists.txt @@ -1,15 +1,94 @@ -ares_components( - v30mz - m93lcx6 -) - -target_sources(ares PRIVATE - system/system.cpp - memory/memory.cpp - eeprom/eeprom.cpp - cartridge/cartridge.cpp - cpu/cpu.cpp - ppu/ppu.cpp - apu/apu.cpp - serial/serial.cpp +ares_components(v30mz m93lcx6) + +target_sources( + ares + PRIVATE + system/system.cpp + memory/memory.cpp + eeprom/eeprom.cpp + cartridge/cartridge.cpp + cpu/cpu.cpp + ppu/ppu.cpp + apu/apu.cpp + serial/serial.cpp +) + +ares_add_header_sources(ws ws.hpp CMakeLists.txt) + +ares_add_header_sources( + ws + apu/apu.hpp + apu/channel1.cpp + apu/channel2.cpp + apu/channel3.cpp + apu/channel4.cpp + apu/channel5.cpp + apu/debugger.cpp + apu/dma.cpp + apu/io.cpp + apu/serialization.cpp +) + +ares_add_header_sources( + ws + cartridge/cartridge.hpp + cartridge/debugger.cpp + cartridge/flash.cpp + cartridge/io.cpp + cartridge/karnak.cpp + cartridge/memory.cpp + cartridge/rtc.cpp + cartridge/serialization.cpp + cartridge/slot.cpp + cartridge/slot.hpp +) + +ares_add_header_sources( + ws + cpu/cpu.hpp + cpu/debugger.cpp + cpu/dma.cpp + cpu/interrupt.cpp + cpu/io.cpp + cpu/keypad.cpp + cpu/serialization.cpp +) + +ares_add_header_sources( + ws + eeprom/eeprom.hpp + eeprom/serialization.cpp +) + +ares_add_header_sources(ws memory/memory.hpp) + +ares_add_header_sources( + ws + ppu/color.cpp + ppu/dac.cpp + ppu/debugger.cpp + ppu/io.cpp + ppu/memory.cpp + ppu/ppu.hpp + ppu/screen.cpp + ppu/serialization.cpp + ppu/sprite.cpp + ppu/timer.cpp + ppu/window.cpp +) + +ares_add_header_sources( + ws + serial/debugger.cpp + serial/serial.hpp + serial/serialization.cpp +) + +ares_add_header_sources( + ws + system/controls.cpp + system/debugger.cpp + system/io.cpp + system/serialization.cpp + system/system.hpp ) diff --git a/buildspec.json b/buildspec.json new file mode 100644 index 0000000000..a7df1f2880 --- /dev/null +++ b/buildspec.json @@ -0,0 +1,16 @@ +{ + "dependencies": { + "prebuilt": { + "version": "main", + "baseUrl": "https://github.com/jcm93/ares-deps/releases/download", + "label": "Pre-Built ares-deps", + "hashes": { + "linux-universal": "bd3c0db29e9a1ecd189a73b1a7cb252a2b6b15adc98a846eb011029206ff7b22", + "macos-universal": "40d06cd73a109ac4110ca715716eb9b769bd9309d39342fa7a2873c175f0a6d3", + "windows-arm64": "c9b1c937d38b3e591230f0c18a0d6b13206afb7cdbc315de6c67ff6bb701c66d", + "windows-x64": "47cb441e7fad25b1e8f893cc6444933fab1a4b11023f05989d62e15c63b8655a" + } + } + }, + "name": "ares" +} diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt new file mode 100644 index 0000000000..586c6c3a2d --- /dev/null +++ b/cmake/CMakeLists.txt @@ -0,0 +1,37 @@ +# dummy cmake target used to enable editing of CMake files within generated IDE projects + +add_library(cmake INTERFACE) + +target_sources( + cmake + PRIVATE + common/bootstrap.cmake + common/dependencies_common.cmake + common/ccache.cmake + common/compiler_common.cmake + common/helpers_common.cmake + common/osconfig.cmake + common/versionconfig.cmake + finders/Findlibrashader.cmake + finders/FindMoltenVK.cmake + finders/FindSDL.cmake + finders/FindGTK.cmake + finders/FindAO.cmake + finders/FindOSS.cmake + macos/dependencies.cmake + macos/compilerconfig.cmake + macos/defaults.cmake + macos/helpers.cmake + macos/xcode.cmake + windows/compilerconfig.cmake + windows/defaults.cmake + windows/dependencies.cmake + windows/helpers.cmake + linux/compilerconfig.cmake + linux/defaults.cmake + linux/helpers.cmake + linux/dependencies.cmake +) + +get_target_property(cmake_SOURCES cmake SOURCES) +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${cmake_SOURCES}) diff --git a/cmake/Dependencies.md b/cmake/Dependencies.md new file mode 100644 index 0000000000..a3e865d8fc --- /dev/null +++ b/cmake/Dependencies.md @@ -0,0 +1,67 @@ +# Dependencies + +This document provides an extensive overview of how dependencies and packaging work in the ares build system with a little bit of overall contextual information about dependencies in CMake in general. + +## The Link Interface + +In modern CMake, each independent component of the build system is meant to be thought of as a target. For ares, this means `hiro`, `nall`, `ruby`, etc. all constitute different CMake targets underneath the `ares` namespace. We might link two targets together like so: +```cmake +target_link_libraries(ares::hiro PRIVATE ares::nall) +``` +By doing this, we have made `nall` a dependency of `hiro` (or in CMake terms, `hiro` is a dependent of `nall`). When we link together these two targets, not only does that mean that when we eventually build `hiro`, the `nall` library file will be passed to the C++ linker, but more generally, `hiro` will also become aware of any `PUBLIC` OR `INTERFACE` properties in nall. For example, we might have the following properties: +```cmake +target_compile_definitions(ares::nall PUBLIC PLATFORM_MACOS) +target_compile_definitions(ares::nall INTERFACE USING_NALL) +``` +If a property on a linked target is declared `PUBLIC` or `INTERFACE`, then any targets that link to it have those properties propagated to them. So `hiro` will have both `PLATFORM_MACOS` and `USING_NALL` defined. The visibility of those properties in `hiro` will be defined by how we link the targets together. In our example above, `PLATFORM_MACOS` and `USING_NALL` will both be `PRIVATE` properties of `hiro`. If we linked using `PUBLIC`, the properties would be public. + +> [!NOTE] +> A property declared as `PRIVATE` under target `our_target` is known only to `our_target`. A property marked `PUBLIC` is known by `our_target` and will be propagated to any target that either directly or transitively links against `our_target`. A property declared `INTERFACE` will be known to all targets that directly or transitively link against `our_target`, but not to `our_target` itself. + +The same logic applies for dependencies outside of the ares tree. Depending on how `ares` is configured, `ruby` and `hiro` may depend on a number of different libraries; some of these may be built-in system libraries, while others such as librashader or SDL may need to come from a package manager or be otherwise supplied by the user. If we treat these dependencies like any other target, we are able to propagate all of the information required to link with them in a logical and structured way. + +In an ideal world, this would be as simple as calling something like `find_package(SDL)` and then, if it's found, calling `target_link_libraries` against `SDL`. However, we do not live in an ideal world! In fact, the world is so un-ideal that we will sometimes find ourselves having to construct a CMake Find Module. + +## FindHelp.cmake + +To link with a dependency, CMake generally needs to know: + +* The library's binary file location (possibly multiple) +* The library's header files locations (possibly in multiple directories) +* Compile options required to compile the library's headers +* Version information + +Our problem is that we need to define logic that can find all of that information, on every platform (macOS, Windows, Linux broadly). Between all of these platforms, for any particular dependency, this information might be found in many different places. + +The `find_package` command is our primary tool for this purpose. This command takes a package name as a single argument, and is intended to provide you in return with a CMake target that contains all of the information you need with appropriate visibility. + +At this point, it gets somewhat complicated. CMake recognizes two distinct modes of operation for locating dependencies with `find_package`; Config and Module mode. In Config mode, the default, CMake will scour the system for a "Config module" for a particular package. A Config module is meant to be provided by the upstream package to your particular platform. If a Config module exists for our package, our job is usually done. Unfortunately, they often do not exist for packages on every platform, and we cannot guarantee their existence. In rare cases, they can even be defined in a way that doesn't conform with our usage requirements (*foreshadowing*). + +The fallback mode is the find module. A CMake find module is a CMake file, provided by the downstream consumer of the package (us), and is meant to supply all logic necessary to determine if a package exists on the system and, if it does, what we need in order to build against it (the four sets of information above). + +On Linux, there is a tool that roughly serves this purpose, `pkg-config`, which may be queried from within our find module to locate compile and linker flags information for a particular library. CMake also provides comands such as `find_path`, `find_library`, and `find_package_handle_standard_args`, that make up a complicated platform-dependent toolset that makes educated guesses about where a library may be found. + +> [!NOTE] +> ares provides certain dependencies pre-built on macOS and Windows, with binaries and headers fetched at configure-time. To ensure that CMake can find these pre-built dependencies, we simply add their directory prefix to the `CMAKE_PREFIX_PATH`, which is searched by these package-finding functions. In other respects, these dependencies are just like ones installed on the system. On Linux, we do not attempt to provide pre-built dependencies. + +The main point is, after locating the information we need for each dependency, we need to create a CMake target for our package. Once we have this target, we can define various `PUBLIC` or `INTERFACE` properties on it in order to propagate include directories, compile definitions and library locations to targets that need them. For CMake code that builds our targets, this makes our job very easy. All we need to do is find the package and link it to our target. + +For our CMake code overall, however, we're not done. While we've done the work required to make ares build, we still need to make it run, which is less trivial than it might sound. In fact, this is the most complicated part of the ares build system, mostly because of the disparate packaging requirements of all the platforms ares runs on. + +## Packaged Suffering + +Canonically, in CMake, the `build` step handles everything we've discussed so far, while the `install` step creates an actual runnable application and installs it; on Windows, that might mean in `C:\Program Files\ares\`, on macOS, `/Applications/ares.app`, while on Linux, libraries, executables, and data may be placed in a number of disparate locations around the system depending on the specific distribution and its packaging philosophy. `install`ing may also fix up runpaths for libraries and executables if we're on Linux or macOS. + +There are a few reasons that we do not properly implement `install` behavior on all platforms: +* On macOS and Windows, dependencies that we need to bundle (such as librashader, SDL, and MoltenVK), cannot be `install`ed because they are `IMPORTED` targets. This restriction exists because `install` originates from Linux, where it does not make sense to install an `IMPORTED` target, and it would indeed not be correct to. Some workarounds exist for this issue, but they are either incomplete or don't apply to macOS. +* Semantically, the notion of `install` overall is somewhat muddy; on Linux, it might be a straightforward concept that something must installed in the appropriate system directories before it can be run, but on macOS and Windows, we generally consider *building* to the primary step, creating an app bundle or app directory, at which time it can be run, and subsequently relocated (or "installed") on the system wherever we wish. Only if a program has exceptional requirements (such as installing drivers or system extensions) would we expect the `install` step to be strictly necessary for running the program. +* On macOS in particular, the `install` flow for creating a bundle properly is meant to be provided by the `BundleUtilities` package, which is a fairly cursed utility that no one should have the displeasure of using. + +Even the step of determining what libraries need to be `install`ed or bundled on macOS and Windows is quite complex. CMake does not trivially differentiate between system libraries and other types of runtime library dependencies. As such, for any executable target, we need to manually traverse the tree of dependencies recursively and determine what libraries are system or provided by us, and be sure to only try to bundle the required dependencies. + +In the end, what we choose to implement is basically the following: +* On macOS and Windows, the build step will create a fully runnable application located in the build directory. The install step will essentially duplicate the same work. +* On Linux, `cmake --build` will compile and link everything and place it in a staging directory, with no further guarantees. `cmake --install` will place libraries, executables and data in standard directories defined by the `GNUInstallDirs` CMake package. + +Dependency copying, runpath fixups and code-signing on macOS are done by simple post-build scripts. + diff --git a/cmake/README.md b/cmake/README.md new file mode 100644 index 0000000000..c31a490658 --- /dev/null +++ b/cmake/README.md @@ -0,0 +1,12 @@ +### *ares* Build System + +This document provides an overview of the general design and structure behind ares's CMake build system generator. + +At a high level, all CMake code directly related to internal build system considerations (compiler/architecture configuration, project generation, dependency management, code signing, app bundling and installation) lives in this `cmake` folder. The tree of files that manage this functionality all branch off of `common/bootstrap.cmake` into various OS-specific and common files. + +CMake code related to the actual generation and building of specific ares components lives in the CMakeLists.txt for each target, as well as auxiliary and OS-specific files for those targets where necessary. + +Broadly, we try to conform to "modern CMake" best practices. There are plentiful resources on this subject; [An Introduction to Modern CMake](https://cliutils.gitlab.io/modern-cmake/README.html) is a good starting point. The primary philosophy behind these resources is that the build system code should be as modular and platform-agnostic as possible. Everything should be implemented as a target, and the build system's job is to describe and structure the relationships between these targets in a sound and logical way. `nall`'s Makefile this is not! + +More in-depth documentation is available in separate documents. The most complicated part of this build system— the definition, resolution, and bundling of dependencies— is described in [Dependencies](./Dependencies.md). + diff --git a/cmake/common/bootstrap.cmake b/cmake/common/bootstrap.cmake new file mode 100644 index 0000000000..3b733ab364 --- /dev/null +++ b/cmake/common/bootstrap.cmake @@ -0,0 +1,52 @@ +include_guard(GLOBAL) + +# gersemi: off +set(CMAKE_MAP_IMPORTED_CONFIG_RELWITHDEBINFO RelWithDebInfo Release MinSizeRel None "") +set(CMAKE_MAP_IMPORTED_CONFIG_MINSIZEREL MinSizeRel Release RelWithDebInfo None "") +set(CMAKE_MAP_IMPORTED_CONFIG_RELEASE Release RelWithDebInfo MinSizeRel None "") +# gersemi: on + +# Prohibit in-source builds +if("${CMAKE_CURRENT_BINARY_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") + message( + FATAL_ERROR + "In-source builds of ares are not supported." + "Specify a build directory via 'cmake -S -B ' instead." + ) + file(REMOVE_RECURSE "${CMAKE_CURRENT_SOURCE_DIR}/CMakeCache.txt" "${CMAKE_CURRENT_SOURCE_DIR}/CMakeFiles") +endif() + +# Set default global project variables +set(ARES_NAME "ares") +set(ARES_WEBSITE "https://ares-emu.net") +set( + ARES_COMMENTS + "ares is a cross-platform, open source, multi-system emulator, focusing on accuracy and preservation." +) +set(ARES_LEGAL_COPYRIGHT "Copyright (c) 2004-${CURRENT_YEAR} ares team, Near et. al.") + +# Add common module directories to default search path +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/common" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/finders") + +include(versionconfig) +include(osconfig) + +# Allow selection of common build types via UI +if(NOT CMAKE_GENERATOR MATCHES "(Xcode|Ninja Multi-Config|Visual Studio .+)") + if(NOT CMAKE_BUILD_TYPE) + set( + CMAKE_BUILD_TYPE + "RelWithDebInfo" + CACHE STRING + "ares build type [Release, RelWithDebInfo, Debug, MinSizeRel]" + FORCE + ) + set_property( + CACHE CMAKE_BUILD_TYPE + PROPERTY STRINGS Release RelWithDebInfo Debug MinSizeRel + ) + endif() +endif() + +# Enable default inclusion of targets' source and binary directory +set(CMAKE_INCLUDE_CURRENT_DIR TRUE) diff --git a/cmake/common/ccache.cmake b/cmake/common/ccache.cmake new file mode 100644 index 0000000000..aa0c6f3147 --- /dev/null +++ b/cmake/common/ccache.cmake @@ -0,0 +1,24 @@ +# ares CMake ccache module + +include_guard(GLOBAL) + +if(NOT DEFINED CCACHE_PROGRAM) + message(DEBUG "Trying to find ccache on build host") + find_program(CCACHE_PROGRAM "ccache") + mark_as_advanced(CCACHE_PROGRAM) +endif() + +if(CCACHE_PROGRAM) + message(DEBUG "Trying to find ccache on build host - done") + message(DEBUG "Ccache found as ${CCACHE_PROGRAM}") + option(ENABLE_CCACHE "Enable compiler acceleration with ccache" ON) + + if(ENABLE_CCACHE) + set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") + set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") + set(CMAKE_OBJC_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") + set(CMAKE_OBJCXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}") + endif() +else() + message(DEBUG "Trying to find ccache on build host - skipped") +endif() diff --git a/cmake/common/compiler_common.cmake b/cmake/common/compiler_common.cmake new file mode 100644 index 0000000000..98da32c962 --- /dev/null +++ b/cmake/common/compiler_common.cmake @@ -0,0 +1,85 @@ +# ares CMake common compiler options module + +include_guard(GLOBAL) + +option(ARES_COMPILE_DEPRECATION_AS_WARNING "Downgrade deprecation warnings to actual warnings" FALSE) +mark_as_advanced(ARES_COMPILE_DEPRECATION_AS_WARNING) + +# Set C and C++ language standards to C17 and C++17 +set(CMAKE_C_STANDARD 17) +set(CMAKE_C_STANDARD_REQUIRED TRUE) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED TRUE) + +# Set symbols to be hidden by default for C and C++ +set(CMAKE_C_VISIBILITY_PRESET hidden) +set(CMAKE_CXX_VISIBILITY_PRESET hidden) +set(CMAKE_VISIBILITY_INLINES_HIDDEN TRUE) + +# clang options for C, C++, ObjC, and ObjC++ +set( + _ares_clang_common_options + -Wblock-capture-autoreleasing + # -Wswitch + # -Wdeprecated + -Wempty-body + -Wbool-conversion + -Wconstant-conversion + # -Wshorten-64-to-32 + # -Wanon-enum-enum-conversion + -Wint-conversion + -Wnon-literal-null-conversion + -Winfinite-recursion + -Werror=return-type + # -Wparentheses + -Wpointer-sign + -Wquoted-include-in-framework-header + -Wnewline-eof + # -Wsign-compare + # -Wstrict-prototypes + # -Wcomma + -Wignored-pragmas + -Wunguarded-availability + -Wuninitialized + -Wunreachable-code + # -Wunused + -Wvla + -Wformat-security + -Wno-error=strict-prototypes + -Wno-error=shorten-64-to-32 + -Wno-error=sign-compare + -Wno-error=comma + -Wno-error=parentheses + -Wno-error=unused-parameter + -Wno-error=unused-variable + -Wno-error=unused-but-set-variable + -Wno-error=deprecated-declarations + -Wno-error=deprecated-literal-operator + -Wno-error=newline-eof + -Wno-error=protocol + -Wno-error=comma + -Wno-error=deprecated-copy-with-user-provided-copy + -Wno-error=deprecated-copy + -Wno-error=anon-enum-enum-conversion + -Wno-error=deprecated-copy-with-user-provided-dtor + -Wno-error=unused-local-typedef + -Wno-error=unused-private-field +) + +set(_ares_clang_c_options ${_ares_clang_common_options}) + +# clang options for C++ +set( + _ares_clang_cxx_options + ${_ares_clang_common_options} + -Wvexing-parse + -Wdelete-non-virtual-dtor + -Wrange-loop-analysis + -Wmove + -Winvalid-offsetof + -Wno-delete-non-abstract-non-virtual-dtor +) + +if(NOT DEFINED CMAKE_COMPILE_WARNING_AS_ERROR) + set(CMAKE_COMPILE_WARNING_AS_ERROR OFF) +endif() diff --git a/cmake/common/dependencies_common.cmake b/cmake/common/dependencies_common.cmake new file mode 100644 index 0000000000..b8aec7d9ad --- /dev/null +++ b/cmake/common/dependencies_common.cmake @@ -0,0 +1,90 @@ +# ares common build dependencies module + +include_guard(GLOBAL) + +# _check_dependencies: Fetch and extract pre-built ares build dependencies +function(_check_dependencies) + file(READ "${CMAKE_CURRENT_SOURCE_DIR}/buildspec.json" buildspec) + + string(JSON dependency_data GET ${buildspec} dependencies) + + foreach(dependency IN LISTS dependencies_list) + string(JSON data GET ${dependency_data} ${dependency}) + string(JSON version GET ${data} version) + string(JSON hash GET ${data} hashes ${platform}) + string(JSON url GET ${data} baseUrl) + string(JSON label GET ${data} label) + string(JSON revision ERROR_VARIABLE error GET ${data} revision ${platform}) + + message(STATUS "Setting up ${label} (${arch})") + + set(file "${${dependency}_filename}") + set(destination "${${dependency}_destination}") + string(REPLACE "VERSION" "${version}" file "${file}") + string(REPLACE "VERSION" "${version}" destination "${destination}") + string(REPLACE "ARCH" "${arch}" file "${file}") + string(REPLACE "ARCH" "${arch}" destination "${destination}") + if(revision) + string(REPLACE "_REVISION" "_v${revision}" file "${file}") + string(REPLACE "-REVISION" "-v${revision}" file "${file}") + else() + string(REPLACE "_REVISION" "" file "${file}") + string(REPLACE "-REVISION" "" file "${file}") + endif() + + if(EXISTS "${dependencies_dir}/.dependency_${dependency}_${arch}.sha256") + file( + READ + "${dependencies_dir}/.dependency_${dependency}_${arch}.sha256" + ARES_DEPENDENCY_${dependency}_${arch}_HASH + ) + endif() + + set(skip FALSE) + if(ARES_DEPENDENCY_${dependency}_${arch}_HASH STREQUAL ${hash}) + if(found) + set(skip TRUE) + endif() + endif() + + if(skip) + message(STATUS "Setting up ${label} (${arch}) - skipped") + continue() + endif() + + set(url ${url}/${version}/${file}) + + if(NOT EXISTS "${dependencies_dir}/${file}") + message(STATUS "Downloading ${url}") + file(DOWNLOAD "${url}" "${dependencies_dir}/${file}" STATUS download_status EXPECTED_HASH SHA256=${hash}) + + list(GET download_status 0 error_code) + list(GET download_status 1 error_message) + if(error_code GREATER 0) + message(STATUS "Downloading ${url} - Failure") + message(FATAL_ERROR "Unable to download ${url}, failed with error: ${error_message}") + file(REMOVE "${dependencies_dir}/${file}") + else() + message(STATUS "Downloading ${url} - done") + endif() + endif() + + if(NOT ARES_DEPENDENCY_${dependency}_${arch}_HASH STREQUAL ${hash}) + file(REMOVE_RECURSE "${dependencies_dir}/${destination}") + endif() + + if(NOT EXISTS "${dependencies_dir}/${destination}") + file(MAKE_DIRECTORY "${dependencies_dir}/${destination}") + file(ARCHIVE_EXTRACT INPUT "${dependencies_dir}/${file}" DESTINATION "${dependencies_dir}") + endif() + + file(WRITE "${dependencies_dir}/.dependency_${dependency}_${arch}.sha256" "${hash}") + + list(APPEND CMAKE_PREFIX_PATH "${dependencies_dir}/${destination}") + message(STATUS "Setting up ${label} (${arch}) - done") + endforeach() + + list(REMOVE_DUPLICATES CMAKE_PREFIX_PATH) + + set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} CACHE PATH "CMake prefix search path" FORCE) +endfunction() diff --git a/cmake/common/helpers_common.cmake b/cmake/common/helpers_common.cmake new file mode 100644 index 0000000000..71be4904ef --- /dev/null +++ b/cmake/common/helpers_common.cmake @@ -0,0 +1,269 @@ +# ares CMake common helper functions module + +include_guard(GLOBAL) + +function(add_sourcery_command target subdir) + add_custom_command( + OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/resource.cpp ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/resource.hpp + COMMAND sourcery resource.bml resource.cpp resource.hpp + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${subdir} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/resource.bml + VERBATIM + ) + add_custom_target( + ${target}-resource + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/resource.cpp ${CMAKE_CURRENT_SOURCE_DIR}/${subdir}/resource.hpp + ) + add_dependencies(${target} ${target}-resource) + set_target_properties(${target}-resource PROPERTIES FOLDER resources PREFIX "") +endfunction() + +# message_configuration: Function to print configuration outcome +function(message_configuration) + include(FeatureSummary) + feature_summary(WHAT ALL VAR _feature_summary) + + message(DEBUG "${_feature_summary}") + + message( + NOTICE + " ..\n" + " ::.\n" + " .::. ____ _________ _____\n" + " .. .:::. / __ `/ ___/ _ \\/ ___/\n" + " .-:::::::: / /_/ / / / __(__ )\n" + " .::::. \\__,_/_/ \\___/____/\n" + "\n ares version: ${ARES_VERSION}\n" + "==================================================================================\n\n" + ) + + get_property(ARES_FEATURES_ENABLED GLOBAL PROPERTY ARES_FEATURES_ENABLED) + list(SORT ARES_FEATURES_ENABLED COMPARE NATURAL CASE SENSITIVE ORDER ASCENDING) + + if(ARES_FEATURES_ENABLED) + message(NOTICE "------------------------ Enabled Features ------------------------") + foreach(feature IN LISTS ARES_FEATURES_ENABLED) + message(NOTICE " - ${feature}") + endforeach() + endif() + + get_property(ARES_FEATURES_DISABLED GLOBAL PROPERTY ARES_FEATURES_DISABLED) + list(SORT ARES_FEATURES_DISABLED COMPARE NATURAL CASE SENSITIVE ORDER ASCENDING) + + if(ARES_FEATURES_DISABLED) + message(NOTICE "------------------------ Disabled Features ------------------------") + foreach(feature IN LISTS ARES_FEATURES_DISABLED) + message(NOTICE " - ${feature}") + endforeach() + endif() + + get_property(ARES_CORES_ENABLED GLOBAL PROPERTY ARES_CORES_ENABLED) + list(SORT ARES_CORES_ENABLED COMPARE NATURAL CASE SENSITIVE ORDER ASCENDING) + + message(NOTICE "------------------------ Enabled Cores ------------------------") + foreach(core IN LISTS ARES_CORES_ENABLED) + message(NOTICE " - ${core}") + endforeach() + + get_property(ARES_CORES_DISABLED GLOBAL PROPERTY ARES_CORES_DISABLED) + list(SORT ARES_CORES_DISABLED COMPARE NATURAL CASE SENSITIVE ORDER ASCENDING) + + message(NOTICE "------------------------ Disabled Cores ------------------------") + get_property(ARES_CORES_ALL GLOBAL PROPERTY ares_cores_all) + list(APPEND ARES_CORES_DISABLED ${ARES_CORES_ALL}) + list(REMOVE_ITEM ARES_CORES_DISABLED ${ARES_CORES}) + foreach(core IN LISTS ARES_CORES_DISABLED) + message(NOTICE " - ${core}") + endforeach() + + # message(NOTICE "==================================================================================\n") + + get_property(ARES_SUBPROJECTS_ENABLED GLOBAL PROPERTY ARES_SUBPROJECTS_ENABLED) + list(SORT ARES_SUBPROJECTS_ENABLED COMPARE NATURAL CASE SENSITIVE ORDER ASCENDING) + + if(ARES_SUBPROJECTS_ENABLED) + message(NOTICE "----------------------- Enabled Subprojects ----------------------") + foreach(subproject IN LISTS ARES_SUBPROJECTS_ENABLED) + message(NOTICE " - ${subproject}") + endforeach() + endif() + + get_property(ARES_SUBPROJECTS_DISABLED GLOBAL PROPERTY ARES_SUBPROJECTS_DISABLED) + list(SORT ARES_SUBPROJECTS_DISABLED COMPARE NATURAL CASE SENSITIVE ORDER ASCENDING) + + if(ARES_SUBPROJECTS_DISABLED) + message(NOTICE "----------------------- Disabled Subprojects ----------------------") + foreach(subproject IN LISTS ARES_SUBPROJECTS_DISABLED) + message(NOTICE " - ${subproject}") + endforeach() + endif() + message(NOTICE "==================================================================================") +endfunction() + +function(target_enable_subproject target subproject_description) + set_property(GLOBAL APPEND PROPERTY ARES_SUBPROJECTS_ENABLED "${subproject_description}") + + if(ARGN) + target_compile_definitions(${target} PRIVATE ${ARGN}) + endif() +endfunction() + +function(target_disable_subproject target subproject_description) + set_property(GLOBAL APPEND PROPERTY ARES_SUBPROJECTS_DISABLED "${subproject_description}") + + if(ARGN) + target_compile_definitions(${target} PRIVATE ${ARGN}) + endif() +endfunction() + +# target_enable_feature: Adds feature to list of enabled application features and sets optional compile definitions +function(target_enable_feature target feature_description) + set_property(GLOBAL APPEND PROPERTY ARES_FEATURES_ENABLED "${feature_description}") + + if(ARGN) + target_compile_definitions(${target} PRIVATE ${ARGN}) + endif() +endfunction() + +# enable_core: Add core to list of enabled cores +function(enable_core core_description) + set_property(GLOBAL APPEND PROPERTY ARES_CORES_ENABLED "${core_description}") +endfunction() + +# disable_core: Add core to list of disabled cores +function(disable_core core_description) + set_property(GLOBAL APPEND PROPERTY ARES_CORES_DISABLED "${core_description}") +endfunction() + +# target_disable_feature: Adds feature to list of disabled application features and sets optional compile definitions +function(target_disable_feature target feature_description) + set_property(GLOBAL APPEND PROPERTY ARES_FEATURES_DISABLED "${feature_description}") + + if(ARGN) + target_compile_definitions(${target} PRIVATE ${ARGN}) + endif() +endfunction() + +# _handle_generator_expression_dependency: Helper function to yield dependency from a generator expression +function(_handle_generator_expression_dependency library) + set(oneValueArgs FOUND_VAR) + set(multiValueArgs) + cmake_parse_arguments(var "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + set(${var_FOUND_VAR} "${var_FOUND_VAR}-NOTFOUND") + + message(DEBUG "Checking ${library}...") + + if(library MATCHES "\\$<\\$]+>:.+>" OR library MATCHES "\\$<\\$]+>>:.+>") + # Platform-dependent generator expression found. Platforms are a comma-separated list of CMake host OS identifiers. + # Convert to CMake list and check if current host OS is contained in list. + string(REGEX REPLACE "\\$<.*\\$]+)>>?:([^>]+)>" "\\1;\\2" gen_expression "${library}") + list(GET gen_expression 0 gen_platform) + list(GET gen_expression 1 gen_library) + string(REPLACE "," ";" gen_platform "${gen_platform}") + + set(${var_FOUND_VAR} "${var_FOUND_VAR}-SKIP") + + if(library MATCHES "\\$<\\$.+>") + if(NOT CMAKE_SYSTEM_NAME IN_LIST gen_platform) + set(${var_FOUND_VAR} "${gen_library}") + endif() + else() + if(CMAKE_SYSTEM_NAME IN_LIST gen_platform) + set(${var_FOUND_VAR} "${gen_library}") + endif() + endif() + elseif(library MATCHES "\\$<\\$]+>:.+>") + # Boolean generator expression found. Consider parameter a CMake variable that resolves into a CMake-like boolean + # value for a simple conditional check. + string(REGEX REPLACE "\\$<\\$]+)>:([^>]+)>" "\\1;\\2" gen_expression "${library}") + list(GET gen_expression 0 gen_boolean) + list(GET gen_expression 1 gen_library) + + set(${var_FOUND_VAR} "${var_FOUND_VAR}-SKIP") + + if(${gen_boolean}) + set(${var_FOUND_VAR} "${gen_library}") + endif() + elseif(library MATCHES "\\$]+>") + # Target-dependent generator expression found. Consider parameter to be a CMake target identifier and check for + # target existence. + string(REGEX REPLACE "\\$]+)>" "\\1" gen_target "${library}") + + set(${var_FOUND_VAR} "${var_FOUND_VAR}-SKIP") + + if(TARGET ${gen_target}) + set(${var_FOUND_VAR} "${gen_target}") + endif() + else() + # Unknown or unimplemented generator expression found. Abort script run to either add to ignore list or implement + # detection. + message(AUTHOR_WARNING "${library} is an unsupported generator expression for linked libraries.") + endif() + + if(CMAKE_VERSION VERSION_LESS 3.25) + set(${var_FOUND_VAR} ${var_FOUND_VAR} PARENT_SCOPE) + else() + return(PROPAGATE ${var_FOUND_VAR}) + endif() +endfunction() + +# find_dependencies: Check linked interface and direct dependencies of target +function(find_dependencies) + set(oneValueArgs TARGET FOUND_VAR) + set(multiValueArgs) + cmake_parse_arguments(var "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT DEFINED is_root) + # Root of recursive dependency resolution + set(is_root TRUE) + set(nested_depth 0) + else() + # Branch of recursive dependency resolution + set(is_root FALSE) + math(EXPR nested_depth "${nested_depth}+1") + endif() + + # * LINK_LIBRARIES are direct dependencies + # * INTERFACE_LINK_LIBRARIES are transitive dependencies + get_target_property(linked_libraries ${var_TARGET} LINK_LIBRARIES) + get_target_property(interface_libraries ${var_TARGET} INTERFACE_LINK_LIBRARIES) + message(DEBUG "[${nested_depth}] Linked libraries in target ${var_TARGET}: ${linked_libraries}") + message(DEBUG "[${nested_depth}] Linked interface libraries in target ${var_TARGET}: ${interface_libraries}") + + # Consider CMake targets only + list(FILTER linked_libraries INCLUDE REGEX ".+::.+") + list(FILTER interface_libraries INCLUDE REGEX ".+::.+") + + foreach(library IN LISTS linked_libraries interface_libraries) + if(NOT library) + continue() + elseif(library MATCHES "\\$<.*:[^>]+>") + # Generator expression found + _handle_generator_expression_dependency(${library} FOUND_VAR found_library) + if(found_library STREQUAL found_library-SKIP) + continue() + elseif(found_library) + set(library ${found_library}) + endif() + endif() + + message(DEBUG "[${nested_depth}] Found ${library}...") + + if(NOT library IN_LIST ${var_FOUND_VAR}) + list(APPEND found_libraries ${library}) + # Enter recursive branch + find_dependencies(TARGET ${library} FOUND_VAR ${var_FOUND_VAR}) + endif() + endforeach() + + if(NOT is_root) + set(found_libraries ${found_libraries} PARENT_SCOPE) + # Exit recursive branch + return() + endif() + + list(REMOVE_DUPLICATES found_libraries) + list(APPEND ${var_FOUND_VAR} ${found_libraries}) + set(${var_FOUND_VAR} ${${var_FOUND_VAR}} PARENT_SCOPE) +endfunction() diff --git a/cmake/common/osconfig.cmake b/cmake/common/osconfig.cmake new file mode 100644 index 0000000000..c7e9c71b30 --- /dev/null +++ b/cmake/common/osconfig.cmake @@ -0,0 +1,19 @@ +include_guard(GLOBAL) + +# Add OS-specific module directory to default search paths, and set helper variables for OS detection in other CMake list files. +if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows" OR CMAKE_HOST_SYSTEM_NAME STREQUAL "MSYS") + set(CMAKE_C_EXTENSIONS FALSE) + set(CMAKE_CXX_EXTENSIONS FALSE) + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/windows") + set(OS_WINDOWS TRUE) +elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin") + set(CMAKE_C_EXTENSIONS FALSE) + set(CMAKE_CXX_EXTENSIONS FALSE) + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos") + set(OS_MACOS TRUE) +elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD|OpenBSD") + set(CMAKE_CXX_EXTENSIONS FALSE) + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/linux") + string(TOUPPER "${CMAKE_HOST_SYSTEM_NAME}" _SYSTEM_NAME_U) + set(OS_${_SYSTEM_NAME_U} TRUE) +endif() diff --git a/cmake/common/versionconfig.cmake b/cmake/common/versionconfig.cmake new file mode 100644 index 0000000000..056b4f9f5a --- /dev/null +++ b/cmake/common/versionconfig.cmake @@ -0,0 +1,24 @@ +include_guard(GLOBAL) + +set(_ares_version 0) + +if(NOT DEFINED ARES_VERSION_OVERRIDE AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git") + execute_process( + COMMAND git describe --always --tags --dirty=-modified + OUTPUT_VARIABLE ARES_VERSION + ERROR_VARIABLE _git_describe_err + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + RESULT_VARIABLE _ares_version_result + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + if(_git_describe_err) + message(FATAL_ERROR "Could not fetch ares version tag from git.\n" ${_git_describe_err}) + endif() + string(REGEX REPLACE "^v([0-9]+)(.*)$" "\\1.0.0\\2" _ares_version "${ARES_VERSION}") + string(REGEX REPLACE "(-[0-9]+-.*|-.+)" "" ARES_VERSION_CANONICAL "${_ares_version}") +elseif(DEFINED ARES_VERSION_OVERRIDE) + set(ARES_VERSION ARES_VERSION_OVERRIDE) +endif() + +unset(_ares_version) diff --git a/cmake/finders/FindAO.cmake b/cmake/finders/FindAO.cmake new file mode 100644 index 0000000000..7fcb2ea031 --- /dev/null +++ b/cmake/finders/FindAO.cmake @@ -0,0 +1,89 @@ +#[=======================================================================[.rst: +FindSDL +------- + +Finds the SDL library. + +Imported Targets +^^^^^^^^^^^^^^^^ + +This module provides the following imported targets, if found: + +``GTK::GTK`` + +Result Variables +^^^^^^^^^^^^^^^^ + +This will define the following variables: + +``GTK_FOUND`` + True if the system has GTK 3. +``GTK_VERSION`` + The version of GTK3 which was found. +``GTK_INCLUDE_DIRS`` + Include directories needed to use GTK3. +``GTK_LIBRARIES`` + Libraries needed to link to GTK3. + +Cache Variables +^^^^^^^^^^^^^^^ + +The following cache variables may also be set: +. +``GTK_LIBRARY`` + The path to the SDL library. + +#]=======================================================================] + +include(FindPackageHandleStandardArgs) + +find_package(PkgConfig QUIET) +if(PKG_CONFIG_FOUND) + pkg_check_modules(PC_AO QUIET ao) +endif() + +message(AUTHOR_WARNING "pc ao include dirs ${PC_AO_INCLUDE_DIR}") + +find_path( + AO_INCLUDE_DIR + NAMES ao/ao.h + HINTS ${PC_AO_INCLUDE_DIR} + PATHS /usr/include /usr/local/include /usr/include/ao /usr/local/include/ao + DOC "AO include directory" +) + +find_library( + AO_LIBRARIES + NAMES ao + HINTS ${PC_AO_LIBRARY_DIRS} + PATHS /usr/lib /usr/local/lib + DOC "SDL location" +) + +set(GTK_ERROR_REASON "Ensure AO libraries are available in local library paths.") + +find_package_handle_standard_args( + AO + REQUIRED_VARS AO_LIBRARIES AO_INCLUDE_DIR + REASON_FAILURE_MESSAGE "${AO_ERROR_REASON}" +) +mark_as_advanced(GTK_INCLUDE_DIRS GTK_LIBRARY) +unset(GTK_ERROR_REASON) + +if(AO_FOUND) + if(NOT TARGET AO::AO) + add_library(AO::AO UNKNOWN IMPORTED) + set_property(TARGET AO::AO PROPERTY IMPORTED_LOCATION "${AO_LIBRARIES}") + + set_target_properties( + AO::AO + PROPERTIES + INTERFACE_COMPILE_OPTIONS "${PC_AO_CFLAGS_OTHER}" + INTERFACE_INCLUDE_DIRECTORIES "${PC_AO_INCLUDE_DIR}" + INTERFACE_LINK_LIBRARIES "${PC_AO_LINK_LIBRARIES}" + ) + endif() +endif() + +include(FeatureSummary) +set_package_properties(AO PROPERTIES URL "https://xiph.org/ao/" DESCRIPTION "Libao is a cross-platform audio library that allows programs to output audio using a simple API on a wide variety of platforms.") diff --git a/cmake/finders/FindGTK.cmake b/cmake/finders/FindGTK.cmake new file mode 100644 index 0000000000..20cdc6c7ad --- /dev/null +++ b/cmake/finders/FindGTK.cmake @@ -0,0 +1,93 @@ +#[=======================================================================[.rst: +FindSDL +------- + +Finds the SDL library. + +Imported Targets +^^^^^^^^^^^^^^^^ + +This module provides the following imported targets, if found: + +``GTK::GTK`` + +Result Variables +^^^^^^^^^^^^^^^^ + +This will define the following variables: + +``GTK_FOUND`` + True if the system has GTK 3. +``GTK_VERSION`` + The version of GTK3 which was found. +``GTK_INCLUDE_DIRS`` + Include directories needed to use GTK3. +``GTK_LIBRARIES`` + Libraries needed to link to GTK3. + +Cache Variables +^^^^^^^^^^^^^^^ + +The following cache variables may also be set: +. +``GTK_LIBRARY`` + The path to the SDL library. + +#]=======================================================================] + +include(FindPackageHandleStandardArgs) + +find_package(PkgConfig QUIET) +if(PKG_CONFIG_FOUND) + pkg_check_modules(PC_GTK QUIET gtk+-3.0) +endif() + +find_path( + GTK_INCLUDE_DIRS + NAMES gtk.h gtk/gtk.h + HINTS ${PC_GTK_INCLUDE_DIRS} + PATHS /usr/include /usr/local/include /usr/include/gtk-3.0 + DOC "GTK include directory" +) + +find_library( + GTK_LIBRARY + NAMES gtk-3 + HINTS ${PC_GTK_LIBRARY_DIRS} + PATHS /usr/lib /usr/local/lib + DOC "SDL location" +) + +set(GTK_ERROR_REASON "Ensure GTK libraries are available in local library paths.") + +find_package_handle_standard_args( + GTK + REQUIRED_VARS GTK_LIBRARY GTK_INCLUDE_DIRS + VERSION_VAR GTK_VERSION + REASON_FAILURE_MESSAGE "${GTK_ERROR_REASON}" +) +mark_as_advanced(GTK_INCLUDE_DIRS GTK_LIBRARY) +unset(GTK_ERROR_REASON) + +if(GTK_FOUND) + if(NOT TARGET GTK::GTK) + if(IS_ABSOLUTE "${GTK_LIBRARY}") + add_library(GTK::GTK UNKNOWN IMPORTED) + set_property(TARGET GTK::GTK PROPERTY IMPORTED_LOCATION "${GTK_LIBRARY}") + else() + add_library(GTK::GTK SHARED IMPORTED) + set_property(TARGET GTK::GTK PROPERTY IMPORTED_LIBNAME "${GTK_LIBRARY}") + endif() + + set_target_properties( + GTK::GTK + PROPERTIES + INTERFACE_COMPILE_OPTIONS "${PC_GTK_CFLAGS_OTHER}" + INTERFACE_INCLUDE_DIRECTORIES "${PC_GTK_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES "${PC_GTK_LINK_LIBRARIES}" + ) + endif() +endif() + +include(FeatureSummary) +set_package_properties(GTK PROPERTIES URL "https://www.gtk.org" DESCRIPTION "GTK is a free and open-source cross-platform widget toolkit for creating graphical user interfaces.") diff --git a/cmake/finders/FindMoltenVK.cmake b/cmake/finders/FindMoltenVK.cmake new file mode 100644 index 0000000000..728a64cb37 --- /dev/null +++ b/cmake/finders/FindMoltenVK.cmake @@ -0,0 +1,138 @@ +#[=======================================================================[.rst: +FindMoltenVK +------- + +Finds the MoltenVK library. + +Imported Targets +^^^^^^^^^^^^^^^^ + +This module provides the following imported targets, if found: + +``MoltenVK::MoltenVK`` + The MoltenVK library + +Result Variables +^^^^^^^^^^^^^^^^ + +This will define the following variables: + +``MoltenVK_FOUND`` + True if the system has the MoltenVK library. +``MoltenVK_VERSION`` + The version of the SDL library which was found. +``MoltenVK_LIBRARIES`` + Libraries needed to link to MoltenVK. + +Cache Variables +^^^^^^^^^^^^^^^ + +The following cache variables may also be set: + +``MoltenVK_LIBRARY`` + The path to the MoltenVK library. + +#]=======================================================================] + +# cmake-lint: disable=C0103 + +include(FindPackageHandleStandardArgs) + +find_package(PkgConfig QUIET) +if(PKG_CONFIG_FOUND) + pkg_search_module(PC_MoltenVK MoltenVK) +endif() + +# MoltenVK_set_soname: Set SONAME on imported library target +macro(MoltenVK_set_soname) + if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin") + execute_process( + COMMAND sh -c "otool -D '${MoltenVK_LIBRARY}' | grep -v '${MoltenVK_LIBRARY}'" + OUTPUT_VARIABLE _output + RESULT_VARIABLE _result + ) + + if(_result EQUAL 0 AND _output MATCHES "^@rpath/") + set_property(TARGET MoltenVK::MoltenVK PROPERTY IMPORTED_SONAME "${_output}") + endif() + elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD") + execute_process( + COMMAND sh -c "objdump -p '${MoltenVK_LIBRARY}' | grep SONAME" + OUTPUT_VARIABLE _output + RESULT_VARIABLE _result + ) + + if(_result EQUAL 0) + string(REGEX REPLACE "[ \t]+SONAME[ \t]+([^ \t]+)" "\\1" _soname "${_output}") + set_property(TARGET MoltenVK::MoltenVK PROPERTY IMPORTED_SONAME "${_soname}") + unset(_soname) + endif() + endif() + unset(_output) + unset(_result) +endmacro() + +if(PC_MoltenVK_VERSION VERSION_GREATER 0) + set(MoltenVK_VERSION ${PC_MoltenVK_VERSION}) +elseif(EXISTS "${MoltenVK_INCLUDE_DIR}/version.h") + file(STRINGS "${_VERSION_FILE}" _VERSION_STRING REGEX "^.*VERSION_(MAJOR|MINOR|PATCH)[ \t]+[0-9]+[ \t]*$") + string(REGEX REPLACE ".*VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" _VERSION_MAJOR "${_VERSION_STRING}") + string(REGEX REPLACE ".*VERSION_MINOR[ \t]+([0-9]+).*" "\\1" _VERSION_MINOR "${_VERSION_STRING}") + string(REGEX REPLACE ".*VERSION_PATCH[ \t]+([0-9]+).*" "\\1" _VERSION_PATCH "${_VERSION_STRING}") + set(MoltenVK_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_MICRO}") +else() + if(NOT MoltenVK_FIND_QUIETLY) + message(AUTHOR_WARNING "Failed to find MoltenVK version.") + endif() + set(MoltenVK_VERSION 0.0.0) +endif() + +find_library( + MoltenVK_LIBRARY + NAMES MoltenVK + HINTS ${PC_MoltenVK_LIBRARY_DIRS} + DOC "MoltenVK location" + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH + NO_PACKAGE_ROOT_PATH +) + +set( + MoltenVK_ERROR_REASON + "Ensure that ares-deps is provided as part of CMAKE_PREFIX_PATH or that MoltenVK is present in local library paths." +) + +find_package_handle_standard_args( + MoltenVK + REQUIRED_VARS MoltenVK_LIBRARY + VERSION_VAR MoltenVK_VERSION + REASON_FAILURE_MESSAGE "${MoltenVK_ERROR_REASON}" +) +unset(MoltenVK_ERROR_REASON) + +if(MoltenVK_FOUND) + if(NOT TARGET MoltenVK::MoltenVK) + if(IS_ABSOLUTE "${MoltenVK_LIBRARY}") + add_library(MoltenVK::MoltenVK UNKNOWN IMPORTED) + set_property(TARGET MoltenVK::MoltenVK PROPERTY IMPORTED_LOCATION "${MoltenVK_LIBRARY}") + else() + add_library(MoltenVK::MoltenVK SHARED IMPORTED) + set_property(TARGET MoltenVK::MoltenVK PROPERTY IMPORTED_LIBNAME "${MoltenVK_LIBRARY}") + endif() + + moltenvk_set_soname() + set_target_properties( + MoltenVK::MoltenVK + PROPERTIES INTERFACE_COMPILE_OPTIONS "${PC_MoltenVK_CFLAGS_OTHER}" VERSION ${MoltenVK_VERSION} + ) + endif() +endif() + +include(FeatureSummary) +set_package_properties( + MoltenVK + PROPERTIES + URL "https://github.com/KhronosGroup/MoltenVK" + DESCRIPTION + "MoltenVK is a Vulkan Portability implementation. It layers a subset of the high-performance, industry-standard Vulkan graphics and compute API over Apple's Metal graphics framework, enabling Vulkan applications to run on macOS, iOS and tvOS." +) diff --git a/cmake/finders/FindOSS.cmake b/cmake/finders/FindOSS.cmake new file mode 100644 index 0000000000..0c90ca4440 --- /dev/null +++ b/cmake/finders/FindOSS.cmake @@ -0,0 +1,64 @@ +#[=======================================================================[.rst: +FindSDL +------- + +Finds the SDL library. + +Imported Targets +^^^^^^^^^^^^^^^^ + +This module provides the following imported targets, if found: + +``GTK::GTK`` + +Result Variables +^^^^^^^^^^^^^^^^ + +This will define the following variables: + +``GTK_FOUND`` + True if the system has GTK 3. +``GTK_VERSION`` + The version of GTK3 which was found. +``GTK_INCLUDE_DIRS`` + Include directories needed to use GTK3. +``GTK_LIBRARIES`` + Libraries needed to link to GTK3. + +Cache Variables +^^^^^^^^^^^^^^^ + +The following cache variables may also be set: +. +``GTK_LIBRARY`` + The path to the SDL library. + +#]=======================================================================] + +include(FindPackageHandleStandardArgs) + +find_path( + OSS_INCLUDE_DIR + NAMES sys/soundcard.h + HINTS ${PC_OSS_INCLUDE_DIRS} + PATHS /usr/include /usr/local/include + DOC "OSS include directory" +) + +set(OSS_VERSION ${CMAKE_HOST_SYSTEM_VERSION}) + +find_package_handle_standard_args( + OSS + REQUIRED_VARS OSS_INCLUDE_DIR + VERSION_VAR OSS_VERSION + REASON_FAILURE_MESSAGE "Ensure that OSS is installed on the system." +) +mark_as_advanced(OSS_INCLUDE_DIR OSS_LIBRARY) + +if(OSS_FOUND) + if(NOT TARGET OSS::OSS) + add_library(OSS::OSS INTERFACE IMPORTED) + + set_target_properties(OSS::OSS PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${OSS_INCLUDE_DIR}" VERSION ${OSS_VERSION}) + endif() +endif() diff --git a/cmake/finders/FindSDL.cmake b/cmake/finders/FindSDL.cmake new file mode 100644 index 0000000000..66b5733b48 --- /dev/null +++ b/cmake/finders/FindSDL.cmake @@ -0,0 +1,147 @@ +#[=======================================================================[.rst: +FindSDL +------- + +Finds the SDL library. + +Imported Targets +^^^^^^^^^^^^^^^^ + +This module provides the following imported targets, if found: + +``SDL::SDL`` + The SDL library + +Result Variables +^^^^^^^^^^^^^^^^ + +This will define the following variables: + +``SDL_FOUND`` + True if the system has the SDL library. +``SDL_VERSION`` + The version of the SDL library which was found. +``SDL_INCLUDE_DIRS`` + Include directories needed to use SDL. +``SDL_LIBRARIES`` + Libraries needed to link to SDL. + +Cache Variables +^^^^^^^^^^^^^^^ + +The following cache variables may also be set: + +``SDL_INCLUDE_DIR`` + The directory containing ``SDL.h``. +``SDL_LIBRARY`` + The path to the SDL library. + +#]=======================================================================] + +include(FindPackageHandleStandardArgs) + +find_package(PkgConfig QUIET) +if(PKG_CONFIG_FOUND) + pkg_search_module(PC_SDL QUIET sdl2) +endif() + +# SDL_set_soname: Set SONAME on imported library target +macro(SDL_set_soname) + if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin") + execute_process( + COMMAND sh -c "otool -D '${SDL_LIBRARY}' | grep -v '${SDL_LIBRARY}'" + OUTPUT_VARIABLE _output + RESULT_VARIABLE _result + ) + + if(_result EQUAL 0 AND _output MATCHES "^@rpath/") + set_property(TARGET SDL::SDL PROPERTY IMPORTED_SONAME "${_output}") + endif() + elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD") + execute_process( + COMMAND sh -c "objdump -p '${SDL_LIBRARY}' | grep SONAME" + OUTPUT_VARIABLE _output + RESULT_VARIABLE _result + ) + + if(_result EQUAL 0) + string(REGEX REPLACE "[ \t]+SONAME[ \t]+([^ \t]+)" "\\1" _soname "${_output}") + set_property(TARGET SDL::SDL PROPERTY IMPORTED_SONAME "${_soname}") + unset(_soname) + endif() + endif() + unset(_output) + unset(_result) +endmacro() + +find_path( + SDL_INCLUDE_DIR + NAMES SDL.h SDL2/SDL.h + HINTS ${PC_SDL_INCLUDE_DIRS} + PATHS ${CMAKE_SOURCE_DIR}/.deps /usr/include /usr/local/include + DOC "SDL include directory" + # "$<$:NO_DEFAULT_PATH>" +) + +if(PC_SDL_VERSION VERSION_GREATER 0) + set(SDL_VERSION ${PC_SDL_VERSION}) +elseif(EXISTS "${SDL_INCLUDE_DIR}/version.h") + file(STRINGS "${_VERSION_FILE}" _VERSION_STRING REGEX "^.*VERSION_(MAJOR|MINOR|PATCH)[ \t]+[0-9]+[ \t]*$") + string(REGEX REPLACE ".*VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" _VERSION_MAJOR "${_VERSION_STRING}") + string(REGEX REPLACE ".*VERSION_MINOR[ \t]+([0-9]+).*" "\\1" _VERSION_MINOR "${_VERSION_STRING}") + string(REGEX REPLACE ".*VERSION_PATCH[ \t]+([0-9]+).*" "\\1" _VERSION_PATCH "${_VERSION_STRING}") + set(SDL_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_MICRO}") +else() + if(NOT SDL_FIND_QUIETLY) + message(AUTHOR_WARNING "Failed to find SDL version.") + endif() + set(SDL_VERSION 0.0.0) +endif() + +find_library( + SDL_LIBRARY + NAMES SDL2-2.0.0 SDL2-2.0 + HINTS ${PC_SDL_LIBRARY_DIRS} + PATHS ${CMAKE_SOURCE_DIR}/.deps /usr/lib /usr/local/lib + DOC "SDL location" + # "$<$:NO_DEFAULT_PATH>" +) + +if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin|Windows") + set(SDL_ERROR_REASON "Ensure that ares-deps are provided as part of CMAKE_PREFIX_PATH.") +elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD") + set(SDL_ERROR_REASON "Ensure SDL libraries are available in local library paths.") +endif() + +find_package_handle_standard_args( + SDL + REQUIRED_VARS SDL_LIBRARY SDL_INCLUDE_DIR + VERSION_VAR SDL_VERSION + REASON_FAILURE_MESSAGE "${SDL_ERROR_REASON}" +) +mark_as_advanced(SDL_INCLUDE_DIR SDL_LIBRARY) +unset(SDL_ERROR_REASON) + +if(SDL_FOUND) + if(NOT TARGET SDL::SDL) + if(IS_ABSOLUTE "${SDL_LIBRARY}") + add_library(SDL::SDL UNKNOWN IMPORTED) + set_property(TARGET SDL::SDL PROPERTY IMPORTED_LOCATION "${SDL_LIBRARY}") + else() + add_library(SDL::SDL SHARED IMPORTED) + set_property(TARGET SDL::SDL PROPERTY IMPORTED_LIBNAME "${SDL_LIBRARY}") + endif() + + sdl_set_soname() + set_target_properties( + SDL::SDL + PROPERTIES + INTERFACE_COMPILE_OPTIONS "${PC_SDL_CFLAGS_OTHER}" + INTERFACE_INCLUDE_DIRECTORIES "${SDL_INCLUDE_DIR}" + VERSION ${SDL_VERSION} + ) + endif() +endif() + +include(FeatureSummary) +set_package_properties(SDL PROPERTIES URL "https://github.com/libsdl-org/SDL" DESCRIPTION "Simple Directmedia Layer") diff --git a/cmake/finders/Findlibrashader.cmake b/cmake/finders/Findlibrashader.cmake new file mode 100644 index 0000000000..1d0c885c55 --- /dev/null +++ b/cmake/finders/Findlibrashader.cmake @@ -0,0 +1,162 @@ +#[=======================================================================[.rst: +Findlibrashader +------- + +Finds the librashader library. + +Imported Targets +^^^^^^^^^^^^^^^^ + +This module provides the following imported targets, if found: + +``librashader::librashader`` + The librashader library + +Result Variables +^^^^^^^^^^^^^^^^ + +This will define the following variables: + +``librashader_FOUND`` + True if the system has the libarashader library. +``librashader_VERSION`` + The version of the SDL library which was found. +``librashader_INCLUDE_DIRS`` + Include directories needed to use SDL. +``librashader_LIBRARIES`` + Libraries needed to link to SDL. + +Cache Variables +^^^^^^^^^^^^^^^ + +The following cache variables may also be set: + +``librashader_INCLUDE_DIR`` + The directory containing ``librashader_ld.h``. +``librashader_LIBRARY`` + The path to the librashader library. + +#]=======================================================================] + +include(FindPackageHandleStandardArgs) + +find_package(PkgConfig QUIET) +if(PKG_CONFIG_FOUND) + pkg_search_module(PC_librashader rashader) +endif() + +# librashader_set_soname: Set SONAME on imported library target +macro(librashader_set_soname) + if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin") + execute_process( + COMMAND sh -c "otool -D '${librashader_LIBRARY}' | grep -v '${librashader_LIBRARY}'" + OUTPUT_VARIABLE _output + RESULT_VARIABLE _result + ) + + if(_result EQUAL 0 AND _output MATCHES "^@rpath/") + set_property(TARGET librashader::librashader PROPERTY IMPORTED_SONAME "${_output}") + endif() + elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD") + execute_process( + COMMAND sh -c "objdump -p '${librashader_LIBRARY}' | grep SONAME" + OUTPUT_VARIABLE _output + RESULT_VARIABLE _result + ) + + if(_result EQUAL 0) + string(REGEX REPLACE "[ \t]+SONAME[ \t]+([^ \t]+)" "\\1" _soname "${_output}") + set_property(TARGET librashader::librashader PROPERTY IMPORTED_SONAME "${_soname}") + unset(_soname) + endif() + endif() + unset(_output) + unset(_result) +endmacro() + +find_path( + librashader_INCLUDE_DIR + NAMES librashader_ld.h librashader/librashader_ld.h + HINTS ${PC_librashader_INCLUDE_DIRS} + PATHS /usr/include /usr/local/include + DOC "librashader include directory" +) + +if(PC_librashader_VERSION VERSION_GREATER 0) + set(librashader_VERSION ${PC_librashader_VERSION}) +elseif(EXISTS "${librashader_INCLUDE_DIR}/version.h") + file(STRINGS "${_VERSION_FILE}" _VERSION_STRING REGEX "^.*VERSION_(MAJOR|MINOR|PATCH)[ \t]+[0-9]+[ \t]*$") + string(REGEX REPLACE ".*VERSION_MAJOR[ \t]+([0-9]+).*" "\\1" _VERSION_MAJOR "${_VERSION_STRING}") + string(REGEX REPLACE ".*VERSION_MINOR[ \t]+([0-9]+).*" "\\1" _VERSION_MINOR "${_VERSION_STRING}") + string(REGEX REPLACE ".*VERSION_PATCH[ \t]+([0-9]+).*" "\\1" _VERSION_PATCH "${_VERSION_STRING}") + set(librashader_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_MICRO}") +else() + if(NOT librashader_FIND_QUIETLY) + message(AUTHOR_WARNING "Failed to find librashader version.") + endif() + set(librashader_VERSION 0.0.0) +endif() + +find_library( + librashader_LIBRARY + NAMES librashader rashader + HINTS ${PC_librashader_LIBRARY_DIRS} + PATHS /usr/lib /usr/local/lib + DOC "librashader location" +) + +if(CMAKE_HOST_SYSTEM_NAME MATCHES "Darwin|Windows") + set(librashader_ERROR_REASON "Ensure that ares-deps is provided as part of CMAKE_PREFIX_PATH.") +elseif(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux|FreeBSD") + set(librashader_ERROR_REASON "Ensure librashader libraries are available in local library paths.") +endif() + +find_package_handle_standard_args( + librashader + REQUIRED_VARS librashader_LIBRARY + VERSION_VAR librashader_VERSION + REASON_FAILURE_MESSAGE "${librashader_ERROR_REASON}" +) +mark_as_advanced(librashader_INCLUDE_DIR librashader_LIBRARY) +unset(librashader_ERROR_REASON) + +if(librashader_FOUND AND ARES_ENABLE_LIBRASHADER) + if(NOT TARGET librashader::librashader) + add_library(librashader::librashader MODULE IMPORTED) + set_property(TARGET librashader::librashader PROPERTY IMPORTED_LOCATION "${librashader_LIBRARY}") + + librashader_set_soname() + set_target_properties( + librashader::librashader + PROPERTIES + INTERFACE_COMPILE_OPTIONS "${PC_librashader_CFLAGS_OTHER}" + INTERFACE_INCLUDE_DIRECTORIES "${librashader_INCLUDE_DIR}" + VERSION ${librashader_VERSION} + ) + endif() +endif() + +# fallback to defining a target with the header, so everything still compiles +if(NOT TARGET librashader::librashader) + if(librashader_INCLUDE_DIR) + add_library(librashader INTERFACE) + set_target_properties( + librashader + PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${librashader_INCLUDE_DIR}" + ) + add_library(librashader::librashader ALIAS librashader) + if(ARES_ENABLE_LIBRASHADER) + message(AUTHOR_WARNING "Tried to configure with librashader, but the library was NOT found. ${librashader_ERROR_REASON}") + endif() + endif() +endif() + +include(FeatureSummary) +set_package_properties( + librashader + PROPERTIES + URL "https://github.com/SnowflakePowered/librashader" + DESCRIPTION + "librashader (/ˈli:brəʃeɪdÉš/) is a preprocessor, compiler, and runtime for RetroArch 'slang' shaders, rewritten in pure Rust." +) diff --git a/cmake/linux/compilerconfig.cmake b/cmake/linux/compilerconfig.cmake new file mode 100644 index 0000000000..a25a5c2626 --- /dev/null +++ b/cmake/linux/compilerconfig.cmake @@ -0,0 +1,7 @@ +include_guard(GLOBAL) + +option(ENABLE_COMPILER_TRACE "Enable clang time-trace" OFF) +mark_as_advanced(ENABLE_COMPILER_TRACE) + +include(ccache) +include(compiler_common) diff --git a/cmake/linux/defaults.cmake b/cmake/linux/defaults.cmake new file mode 100644 index 0000000000..23641af3a9 --- /dev/null +++ b/cmake/linux/defaults.cmake @@ -0,0 +1,11 @@ +include_guard(GLOBAL) + +include(GNUInstallDirs) + +include(dependencies) + +set(ARES_BUILD_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/rundir") +set(ARES_BUILD_EXECUTABLE_DESTINATION ".") +set(ARES_INSTALL_EXECUTABLE_DESTINATION "${CMAKE_INSTALL_BINDIR}") +set(ARES_BUILD_DATA_DESTINATION ".") +set(ARES_INSTALL_DATA_DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/ares") diff --git a/cmake/linux/dependencies.cmake b/cmake/linux/dependencies.cmake new file mode 100644 index 0000000000..bed8eda475 --- /dev/null +++ b/cmake/linux/dependencies.cmake @@ -0,0 +1,21 @@ +# ares CMake linux build dependencies module + +include_guard(GLOBAL) + +include(dependencies_common) + +function(_check_dependencies_linux) + set(arch universal) + set(platform linux-${arch}) + + file(READ "${CMAKE_CURRENT_SOURCE_DIR}/buildspec.json" buildspec) + + set(dependencies_dir "${CMAKE_CURRENT_SOURCE_DIR}/.deps") + set(prebuilt_filename "ares-deps-linux-ARCH-REVISION.tar.xz") + set(prebuilt_destination "ares-deps-linux-ARCH") + set(dependencies_list prebuilt) + + _check_dependencies() +endfunction() + +_check_dependencies_linux() diff --git a/cmake/linux/helpers.cmake b/cmake/linux/helpers.cmake new file mode 100644 index 0000000000..62b78332f0 --- /dev/null +++ b/cmake/linux/helpers.cmake @@ -0,0 +1,24 @@ +include_guard(GLOBAL) + +include(helpers_common) + + +function(ares_configure_executable target) + get_target_property(target_type ${target} TYPE) + + if(target_type STREQUAL EXECUTABLE) + + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E make_directory "${ARES_BUILD_OUTPUT_DIR}/$/${ARES_BUILD_EXECUTABLE_DESTINATION}" + COMMAND + "${CMAKE_COMMAND}" -E copy_if_different "$" + "${ARES_BUILD_OUTPUT_DIR}/$/${ARES_BUILD_EXECUTABLE_DESTINATION}" + COMMENT "Copy ${target} to binary directory" + VERBATIM + ) + + install(TARGETS ${target} RUNTIME DESTINATION "${ARES_INSTALL_EXECUTABLE_DESTINATION}" COMPONENT Runtime) + endif() +endfunction() diff --git a/cmake/macos/compilerconfig.cmake b/cmake/macos/compilerconfig.cmake new file mode 100644 index 0000000000..2d97802abc --- /dev/null +++ b/cmake/macos/compilerconfig.cmake @@ -0,0 +1,53 @@ +# ares CMake macOS compiler configuration module + +include_guard(GLOBAL) + +option(ENABLE_COMPILER_TRACE "Enable clang time-trace" OFF) +mark_as_advanced(ENABLE_COMPILER_TRACE) + +include(ccache) +include(compiler_common) + +# Enable selection between arm64 and x86_64 targets +if(NOT CMAKE_OSX_ARCHITECTURES) + set(CMAKE_OSX_ARCHITECTURES arm64 CACHE STRING "Build architectures for macOS" FORCE) +endif() +set_property(CACHE CMAKE_OSX_ARCHITECTURES PROPERTY STRINGS arm64 x86_64) + +# Ensure recent enough Xcode and platform SDK +set(_ares_macos_minimum_sdk 11.1) # Minimum tested SDK +set(_ares_macos_minimum_xcode 12.4) # Sync with SDK +message(DEBUG "macOS SDK Path: ${CMAKE_OSX_SYSROOT}") +string(REGEX MATCH ".+/MacOSX.platform/Developer/SDKs/MacOSX([0-9]+\\.[0-9])+\\.sdk$" _ ${CMAKE_OSX_SYSROOT}) +set(_ares_macos_current_sdk ${CMAKE_MATCH_1}) +message(DEBUG "macOS SDK version: ${_ares_macos_current_sdk}") +if(_ares_macos_current_sdk VERSION_LESS _ares_macos_minimum_sdk) + message( + FATAL_ERROR + "Your macOS SDK version (${_ares_macos_current_sdk}) is too low. " + "The macOS ${_ares_macos_minimum_sdk} SDK (Xcode ${_ares_macos_minimum_xcode}) is required to build ares." + ) +endif() +unset(_ares_macos_current_sdk) +unset(_ares_macos_minimum_sdk) +unset(_ares_macos_minimum_xcode) + +# Enable dSYM generator for release builds +string(APPEND CMAKE_C_FLAGS_RELEASE " -g") +string(APPEND CMAKE_CXX_FLAGS_RELEASE " -g") +string(APPEND CMAKE_OBJC_FLAGS_RELEASE " -g") +string(APPEND CMAKE_OBJCXX_FLAGS_RELEASE " -g") + +if(ENABLE_COMPILER_TRACE) + add_compile_options( + -ftime-trace + ) + add_link_options(LINKER:-print_statistics) +endif() + +if(NOT XCODE) + add_compile_options( + "$<$:${_ares_clang_c_options}>" + "$<$:${_ares_clang_cxx_options}>" + ) +endif() diff --git a/cmake/macos/defaults.cmake b/cmake/macos/defaults.cmake new file mode 100644 index 0000000000..63e8c7d1ee --- /dev/null +++ b/cmake/macos/defaults.cmake @@ -0,0 +1,29 @@ +# ares CMake macOS defaults module + +include_guard(GLOBAL) + +# Set empty codesigning team if not specified as cache variable +if(NOT ARES_CODESIGN_TEAM) + set(ARES_CODESIGN_TEAM "" CACHE STRING "ares code signing team for macOS" FORCE) + + # Set ad-hoc codesigning identity if not specified as cache variable + if(NOT ARES_CODESIGN_IDENTITY) + set(ARES_CODESIGN_IDENTITY "-" CACHE STRING "ares code signing identity for macOS" FORCE) + endif() +endif() + +include(xcode) + +include(dependencies) + +# Enable find_package targets to become globally available targets +set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL TRUE) +# Use RPATHs from build tree _in_ the build tree +set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) +# Use common bundle-relative RPATH for installed targets +set(CMAKE_INSTALL_RPATH "@executable_path/../Frameworks") +# Use build tree as the install prefix +set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}) + +# configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/resources/package.applescript" +# "${CMAKE_CURRENT_BINARY_DIR}/package.applescript" @ONLY) diff --git a/cmake/macos/dependencies.cmake b/cmake/macos/dependencies.cmake new file mode 100644 index 0000000000..bcebe3cd37 --- /dev/null +++ b/cmake/macos/dependencies.cmake @@ -0,0 +1,28 @@ +# ares CMake macOS build dependencies module + +include_guard(GLOBAL) + +include(dependencies_common) + +# _check_dependencies_macos: Set up macOS slice for _check_dependencies +function(_check_dependencies_macos) + set(arch universal) + set(platform macos-${arch}) + + file(READ "${CMAKE_CURRENT_SOURCE_DIR}/buildspec.json" buildspec) + + set(dependencies_dir "${CMAKE_CURRENT_SOURCE_DIR}/.deps") + set(prebuilt_filename "ares-deps-macos-ARCH-REVISION.tar.xz") + set(prebuilt_destination "ares-deps-macos-ARCH") + set(dependencies_list prebuilt) + + _check_dependencies() + + execute_process( + COMMAND "xattr" -r -d com.apple.quarantine "${dependencies_dir}/${destination}" + RESULT_VARIABLE result + COMMAND_ERROR_IS_FATAL ANY + ) +endfunction() + +_check_dependencies_macos() diff --git a/cmake/macos/helpers.cmake b/cmake/macos/helpers.cmake new file mode 100644 index 0000000000..a6b9787100 --- /dev/null +++ b/cmake/macos/helpers.cmake @@ -0,0 +1,164 @@ +include_guard(GLOBAL) + +include(helpers_common) + +# set_target_xcode_properties: Sets Xcode-specific target attributes +function(set_target_xcode_properties target) + set(options "") + set(oneValueArgs "") + set(multiValueArgs PROPERTIES) + cmake_parse_arguments(PARSE_ARGV 0 _STXP "${options}" "${oneValueArgs}" "${multiValueArgs}") + + message(DEBUG "Setting Xcode properties for target ${target}...") + + while(_STXP_PROPERTIES) + list(POP_FRONT _STXP_PROPERTIES key value) + set_property(TARGET ${target} PROPERTY XCODE_ATTRIBUTE_${key} "${value}") + endwhile() +endfunction() + +# ares_configure_executable: Bundle entitlements, dependencies, resources to prepare macOS app bundle +function(ares_configure_executable target) + get_target_property(target_type ${target} TYPE) + + if(target_type STREQUAL EXECUTABLE) + if(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_STYLE STREQUAL Automatic) + set(entitlements_file "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/entitlements.plist") + else() + set(entitlements_file "${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/entitlements.plist") + # configure_file(cmake/macos/exportOptions.plist.in ${CMAKE_BINARY_DIR}/exportOptions.plist) + endif() + + if(NOT EXISTS "${entitlements_file}") + message(AUTHOR_WARNING "Target ${target} is missing an entitlements file in its cmake directory.") + else() + set_target_properties(${target} PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${entitlements_file}") + endif() + + _bundle_dependencies(${target}) + + install(TARGETS ${target} BUNDLE DESTINATION "." COMPONENT Application) + endif() +endfunction() + +# target_add_resource: Helper function to add a specific resource to a bundle +function(target_add_resource target resource) + message(DEBUG "Add resource ${resource} to target ${target} at destination ${destination}...") + target_sources(${target} PRIVATE "${resource}") + if(ARGN) + set(subpath ${ARGN}) + set_property(SOURCE "${resource}" PROPERTY MACOSX_PACKAGE_LOCATION "Resources/${subpath}") + else() + set_property(SOURCE "${resource}" PROPERTY MACOSX_PACKAGE_LOCATION Resources) + endif() + source_group("Resources" FILES "${resource}") +endfunction() + +# _bundle_dependencies: Resolve 3rd party dependencies and add them to macOS app bundle +function(_bundle_dependencies target) + message(DEBUG "Discover dependencies of target ${target}...") + set(found_dependencies) + find_dependencies(TARGET ${target} FOUND_VAR found_dependencies) + list(REMOVE_DUPLICATES found_dependencies) + + set(library_paths) + set(bundled_targets) + set(plugins_list) + file(GLOB sdk_library_paths /Applications/Xcode*.app) + set(system_library_path "/usr/lib/") + + foreach(library IN LISTS found_dependencies) + get_target_property(library_type ${library} TYPE) + get_target_property(is_framework ${library} FRAMEWORK) + get_target_property(is_imported ${library} IMPORTED) + + if(is_imported) + get_target_property(imported_location ${library} LOCATION) + if(NOT imported_location) + continue() + endif() + + set(is_xcode_framework FALSE) + set(is_system_framework FALSE) + + foreach(sdk_library_path IN LISTS sdk_library_paths) + if(is_xcode_framework) + break() + endif() + cmake_path(IS_PREFIX sdk_library_path "${imported_location}" is_xcode_framework) + endforeach() + cmake_path(IS_PREFIX system_library_path "${imported_location}" is_system_framework) + + if(is_system_framework OR is_xcode_framework) + continue() + elseif(is_framework) + file(REAL_PATH "../../.." library_location BASE_DIRECTORY "${imported_location}") + elseif(NOT library_type STREQUAL "STATIC_LIBRARY") + if(NOT imported_location MATCHES ".+\\.a") + set(library_location "${imported_location}") + else() + continue() + endif() + else() + continue() + endif() + + list(APPEND bundled_targets ${library}) + + list(APPEND library_paths ${library_location}) + elseif(NOT is_imported AND library_type STREQUAL "SHARED_LIBRARY") + list(APPEND library_paths ${library}) + endif() + endforeach() + + list(REMOVE_DUPLICATES library_paths) + + if(UNUSED) + # One of these would be nice, but we cannot install IMPORTed targets (librashader, SDL, MoltenVK). + # We could use install(FILES ...), but that wouldn't fixup rpaths, which obviates the need for + # install() in the first place. + install( + TARGETS ${target} ${bundled_targets} + RUNTIME_DEPENDENCIES + RUNTIME DESTINATION "$/Frameworks" + LIBRARY DESTINATION "$/Frameworks" + FRAMEWORK DESTINATION "$/Frameworks" + BUNDLE DESTINATION "." + ) + install( + IMPORTED_RUNTIME_ARTIFACTS ${target} + RUNTIME DESTINATION "$/Frameworks" + LIBRARY DESTINATION "$/Frameworks" + FRAMEWORK DESTINATION "$/Frameworks" + BUNDLE DESTINATION "." + ) + endif() + + if(XCODE) + set_property(TARGET ${target} APPEND PROPERTY XCODE_EMBED_FRAMEWORKS ${library_paths}) + else() + # This isn't strictly good practice, since the --install command should ideally be responsible for assembling + # the bundle. Using install commands to assemble an app bundle with pre-built dependencies isn't very feasible + # though, and seems to violate various CMake principles. Creating the app bundle as a part of the build also + # debatably violates CMake principles, but hopefully not too much. + + # Copy resolved dependencies into app bundle + get_target_property(IS_BUNDLE ${target} MACOSX_BUNDLE) + if(IS_BUNDLE) + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND ditto ${library_paths} "$/Frameworks/" + WORKING_DIRECTORY "$" + COMMENT "Copying dynamic libraries into app bundle" + ) + # Add an rpath for the bundled dynamic libraries + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND ${CMAKE_INSTALL_NAME_TOOL} -add_rpath "@executable_path/../Frameworks/" $ + COMMENT "Adding rpath for dynamic libraries to binary" + ) + endif() + endif() +endfunction() diff --git a/cmake/macos/resources/ccache-launcher-c.in b/cmake/macos/resources/ccache-launcher-c.in new file mode 100644 index 0000000000..560190abf6 --- /dev/null +++ b/cmake/macos/resources/ccache-launcher-c.in @@ -0,0 +1,14 @@ +#!/bin/sh + +if [[ "$1" == "${CMAKE_C_COMPILER}" ]] ; then + shift +fi + +export CCACHE_CPP2=true +export CCACHE_DEPEND=true +export CCACHE_DIRECT=true +export CCACHE_FILECLONE=true +export CCACHE_INODECACHE=true +export CCACHE_COMPILERCHECK='content' +export CCACHE_SLOPPINESS='modules,include_file_mtime,include_file_ctime,clang_index_store,system_headers' +exec "${CMAKE_C_COMPILER_LAUNCHER}" "${CMAKE_C_COMPILER}" "$@" \ No newline at end of file diff --git a/cmake/macos/resources/ccache-launcher-cxx.in b/cmake/macos/resources/ccache-launcher-cxx.in new file mode 100755 index 0000000000..a81cdc7f00 --- /dev/null +++ b/cmake/macos/resources/ccache-launcher-cxx.in @@ -0,0 +1,14 @@ +#!/bin/sh + +if [[ "$1" == "${CMAKE_CXX_COMPILER}" ]] ; then + shift +fi + +export CCACHE_CPP2=true +export CCACHE_DEPEND=true +export CCACHE_DIRECT=true +export CCACHE_FILECLONE=true +export CCACHE_INODECACHE=true +export CCACHE_COMPILERCHECK='content' +export CCACHE_SLOPPINESS='modules,include_file_mtime,include_file_ctime,clang_index_store,system_headers' +exec "${CMAKE_CXX_COMPILER_LAUNCHER}" "${CMAKE_CXX_COMPILER}" "$@" \ No newline at end of file diff --git a/cmake/macos/xcode.cmake b/cmake/macos/xcode.cmake new file mode 100644 index 0000000000..83f2d8e5d7 --- /dev/null +++ b/cmake/macos/xcode.cmake @@ -0,0 +1,168 @@ +# ares CMake macOS Xcode module + +include_guard(GLOBAL) + +set(CMAKE_XCODE_GENERATE_SCHEME TRUE) + +# Use a compiler wrapper to enable ccache in Xcode projects +if(ENABLE_CCACHE AND CCACHE_PROGRAM) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/resources/ccache-launcher-c.in" ccache-launcher-c) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos/resources/ccache-launcher-cxx.in" ccache-launcher-cxx) + + execute_process( + COMMAND chmod a+rx "${CMAKE_CURRENT_BINARY_DIR}/ccache-launcher-c" "${CMAKE_CURRENT_BINARY_DIR}/ccache-launcher-cxx" + ) + set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_CURRENT_BINARY_DIR}/ccache-launcher-c") + set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_CURRENT_BINARY_DIR}/ccache-launcher-cxx") + set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_C_COMPILER}") + set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_CXX_COMPILER}") +endif() + +# Set project variables +set(CMAKE_XCODE_ATTRIBUTE_CURRENT_PROJECT_VERSION ${ARES_BUILD_NUMBER}) +set(CMAKE_XCODE_ATTRIBUTE_DYLIB_COMPATIBILITY_VERSION 1.0.0) +set(CMAKE_XCODE_ATTRIBUTE_MARKETING_VERSION ${ARES_VERSION}) + +# Set deployment target +set(CMAKE_XCODE_ATTRIBUTE_MACOSX_DEPLOYMENT_TARGET ${CMAKE_OSX_DEPLOYMENT_TARGET}) + +if(NOT ARES_CODESIGN_TEAM) + # Switch to manual codesigning if no codesigning team is provided + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual) + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${ARES_CODESIGN_IDENTITY}") +else() + if(ARES_CODESIGN_IDENTITY AND NOT ARES_CODESIGN_IDENTITY STREQUAL "-") + # Switch to manual codesigning if a non-adhoc codesigning identity is provided + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual) + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "${ARES_CODESIGN_IDENTITY}") + else() + # Switch to automatic codesigning via valid team ID + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_STYLE Automatic) + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Development") + endif() + set(CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "${ARES_CODESIGN_TEAM}") +endif() + +# Only create a single Xcode project file +set(CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY TRUE) +# Add all libraries to project link phase (lets Xcode handle linking) +set(CMAKE_XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION) + +if(NOT ARES_BUILD_LOCAL) + # Enable codesigning with secure timestamp when not in Debug configuration (required for Notarization) + set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS[variant=Release] "--timestamp") + set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS[variant=RelWithDebInfo] "--timestamp") + set(CMAKE_XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS[variant=MinSizeRel] "--timestamp") + + # Enable codesigning with hardened runtime option when not in Debug configuration (required for Notarization) + set(CMAKE_XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME[variant=Release] YES) + set(CMAKE_XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME[variant=RelWithDebInfo] YES) + set(CMAKE_XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME[variant=MinSizeRel] YES) + + # Disable injection of Xcode's base entitlements used for debugging when not in Debug configuration (required for + # Notarization) + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_INJECT_BASE_ENTITLEMENTS[variant=Release] NO) + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_INJECT_BASE_ENTITLEMENTS[variant=RelWithDebInfo] NO) + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_INJECT_BASE_ENTITLEMENTS[variant=MinSizeRel] NO) +endif() + +# Use DWARF with separate dSYM files when in Release or MinSizeRel configuration. +# +# * Currently overruled by CMake's Xcode generator, requires adding '-g' flag to raw compiler command line for desired +# output configuration. Report to KitWare. +# +set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT[variant=Debug] dwarf) +set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT[variant=RelWithDebInfo] dwarf) +set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT[variant=Release] dwarf-with-dsym) +set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT[variant=MinSizeRel] dwarf-with-dsym) + +# Strip unused code +set(CMAKE_XCODE_ATTRIBUTE_DEAD_CODE_STRIPPING YES) + +# Build active architecture only when in Debug configuration +set(CMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH[variant=Debug] YES) + +set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES) +# Enable weak references in manual retain release +set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_WEAK YES) + +# Disable automatic linking of imported modules in ObjC +set(CMAKE_XCODE_ATTRIBUTE_CLANG_MODULES_AUTOLINK NO) +# Enable strict msg_send rules for ObjC +set(CMAKE_XCODE_ATTRIBUTE_ENABLE_STRICT_OBJC_MSGSEND YES) + +# Set default warnings for all languages +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_BOOL_CONVERSION YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_COMMA NO) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_CONSTANT_CONVERSION YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_EMPTY_BODY YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_ENUM_CONVERSION YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_INFINITE_RECURSION YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_INT_CONVERSION YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_NON_LITERAL_NULL_CONVERSION YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_RANGE_LOOP_ANALYSIS YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_STRICT_PROTOTYPES YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_SUSPICIOUS_MOVE YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_UNREACHABLE_CODE YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN__DUPLICATE_METHOD_MATCH YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_UNREACHABLE_CODE YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_SIGN_COMPARE NO) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_MISSING_PARENTHESES NO) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_TYPECHECK_CALLS_TO_PRINTF YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNDECLARED_SELECTOR YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNINITIALIZED_AUTOS YES_AGGRESSIVE) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_FUNCTION YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_PARAMETER NO) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_VALUE YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_UNUSED_VARIABLE NO) # todo +set(CMAKE_XCODE_ATTRIBUTE_GCC_NO_COMMON_BLOCKS YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_64_TO_32_BIT_CONVERSION NO) # todo + +# set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS NO) +# set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_FOUR_CHARACTER_CONSTANTS YES) +# set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_SHADOW NO) +# set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS YES) + +# Set default warnings for Obj-C and Obj-C++ +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_OBJC_LITERAL_CONVERSION YES) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK YES) +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_ALLOW_INCOMPLETE_PROTOCOL YES) # todo resolve +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_ABOUT_MISSING_NEWLINE NO) # eh +set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_ABOUT_RETURN_TYPE YES_ERROR) +set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_UNGUARDED_AVAILABILITY YES) + +# set(CMAKE_XCODE_ATTRIBUTE_CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS YES) + +# Add other warnings, downgrade errors to warnings where necessary +set( + CMAKE_XCODE_ATTRIBUTE_WARNING_CFLAGS + "-Wvla + -Wformat-security + -Wno-c++11-narrowing + -Wno-error=strict-prototypes + -Wno-error=shorten-64-to-32 + -Wno-error=sign-compare + -Wno-error=comma + -Wno-error=parentheses + -Wno-error=unused-parameter + -Wno-error=unused-variable + -Wno-error=deprecated-declarations + -Wno-error=newline-eof + -Wno-error=protocol + -Wno-error=comma" +) + +if(CMAKE_COMPILE_WARNING_AS_ERROR) + set(CMAKE_XCODE_ATTRIBUTE_GCC_TREAT_WARNINGS_AS_ERRORS NO) +endif() + +# Enable color diagnostics +set(CMAKE_COLOR_DIAGNOSTICS TRUE) + +# Disable usage of RPATH in build or install configurations +set(CMAKE_SKIP_RPATH TRUE) +# Have Xcode set default RPATH entries +set(CMAKE_XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../Frameworks") diff --git a/cmake/windows/compilerconfig.cmake b/cmake/windows/compilerconfig.cmake new file mode 100644 index 0000000000..e54eb45109 --- /dev/null +++ b/cmake/windows/compilerconfig.cmake @@ -0,0 +1,118 @@ +if(WIN32 AND NOT MINGW) + add_compile_definitions(EXCLUDE_MANIFEST_FROM_RC) #global +endif() + +include_guard(GLOBAL) + +include(ccache) +include(compiler_common) + +if(ENABLE_CCACHE AND CCACHE_PROGRAM) + if(CMAKE_C_COMPILER_ID STREQUAL "MSVC") + file(COPY_FILE ${CCACHE_PROGRAM} "${CMAKE_CURRENT_BINARY_DIR}/cl.exe") + set( + CMAKE_VS_GLOBALS + "CLToolExe=cl.exe" + "CLToolPath=${CMAKE_BINARY_DIR}" + "TrackFileAccess=false" + "UseMultiToolTask=true" + ) + set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT Embedded) + elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang") + file(COPY_FILE ${CCACHE_PROGRAM} "${CMAKE_CURRENT_BINARY_DIR}/clang-cl.exe") + set( + CMAKE_VS_GLOBALS + "CLToolExe=clang-cl.exe" + "CLToolPath=${CMAKE_BINARY_DIR}" + "TrackFileAccess=false" + "UseMultiToolTask=true" + ) + endif() +endif() + +if(CMAKE_GENERATOR_PLATFORM) + set(arch ${CMAKE_GENERATOR_PLATFORM}) + set(platform windows-${arch}) +else() + if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL ARM64) + set(arch arm64) + set(platform windows-${arch}) + else() + set(arch x64) + set(platform windows-${arch}) + endif() +endif() + +add_compile_definitions(_WIN32_WINNT=0x0601) #global + +set( + _ares_msvc_cxx_options + /MP + /Zc:__cplusplus + /utf-8 + /permissive- + $<$>:/GL> + $<$>:/Oi> + $<$>:/Ob2> + $<$>:/Ot> +) + +if(MSVC) + if(CMAKE_CXX_COMPILER_ID STREQUAL MSVC) + add_compile_options( + "$<$:${_ares_msvc_cxx_options}>" + ) + add_link_options( + $<$>:/LTCG> + $<$>:/INCREMENTAL:NO> + /Debug + ) + if(CMAKE_COMPILE_WARNING_AS_ERROR) + add_link_options(/WX) + endif() + elseif(CMAKE_CXX_COMPILER_ID STREQUAL Clang) + add_compile_options( + "$<$:${_ares_clang_c_options}>" + "$<$:${_ares_clang_cxx_options}>" + -Wno-reorder-ctor + -Wno-unused + ) + endif() + set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT ProgramDatabase) +else() + # msys2 + if(CMAKE_CXX_COMPILER_ID STREQUAL Clang) + add_compile_options( + "$<$:${_ares_clang_c_options}>" + "$<$:${_ares_clang_cxx_options}>" + -Wno-reorder-ctor + -Wno-unused + ) + set( + _ares_mingw_clang_debug_compile_options + -g + -gcodeview + ) + set( + _ares_mingw_clang_debug_link_options + -fuse-ld=lld + -g + -Wl,--pdb= + ) + add_compile_options("$<$:${_ares_mingw_clang_debug_compile_options}>") + add_link_options("$<$:${_ares_mingw_clang_debug_link_options}>") + endif() +endif() + +if(ARES_BUILD_LOCAL) + if(NOT MSVC) + add_compile_options(-march=native) + endif() +else() + # todo +endif() + + +if(NOT MINGW) + add_compile_definitions(_CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS) #global +endif() diff --git a/cmake/windows/defaults.cmake b/cmake/windows/defaults.cmake new file mode 100644 index 0000000000..9844b569fe --- /dev/null +++ b/cmake/windows/defaults.cmake @@ -0,0 +1,15 @@ +set(ARES_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") +set(ARES_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}") + +set(ARES_EXECUTABLE_DESTINATION ${ARES_OUTPUT_DIR}) +set(ARES_LIBRARY_DESTINATION lib) +set(ARES_INCLUDE_DESTINATION include) +# Set relative paths used by ares for self-discovery +set(ARES_DATA_PATH "../../${ARES_DATA_DESTINATION}") + +set(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL TRUE) + +# todo, fix: under MSYS2, CMake looks for .dll.a files rather than .lib files; tell it to also look for .lib files +set(CMAKE_FIND_LIBRARY_SUFFIXES .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) + +include(dependencies) diff --git a/cmake/windows/dependencies.cmake b/cmake/windows/dependencies.cmake new file mode 100644 index 0000000000..286f817468 --- /dev/null +++ b/cmake/windows/dependencies.cmake @@ -0,0 +1,16 @@ +include_guard(GLOBAL) + +include(dependencies_common) + +# _check_dependencies_windows: Set up Windows slice for _check_dependencies +function(_check_dependencies_windows) + set(dependencies_dir "${CMAKE_CURRENT_SOURCE_DIR}/.deps") + set(prebuilt_filename "ares-deps-windows-ARCH-REVISION.tar.xz") + set(prebuilt_destination "ares-deps-windows-ARCH") + + set(dependencies_list prebuilt) + + _check_dependencies() +endfunction() + +_check_dependencies_windows() diff --git a/cmake/windows/helpers.cmake b/cmake/windows/helpers.cmake new file mode 100644 index 0000000000..3c1496a04d --- /dev/null +++ b/cmake/windows/helpers.cmake @@ -0,0 +1,211 @@ +include_guard(GLOBAL) + +include(helpers_common) + +# ares_configure_executable: Bundle entitlements, dependencies, resources to prepare macOS app bundle +function(ares_configure_executable target) + set_target_properties(${target} PROPERTIES WIN32_EXECUTABLE TRUE) + _bundle_dependencies(${target}) + install(TARGETS ${target} DESTINATION "${ARES_EXECUTABLE_DESTINATION}/${target}/$" COMPONENT Application) +endfunction() + +# _target_install_obs: Helper function to install build artifacts to rundir and install location +function(_target_install_ares target) +endfunction() + +# Helper function to add resources into bundle +function(target_install_resources target) +endfunction() + +# Helper function to add a specific resource to a bundle +function(target_add_resource target resource) + get_property(ares_module_list GLOBAL PROPERTY ARES_MODULES_ENABLED) + if(ARGN) + set(target_destination "${ARGN}") + elseif(${target} IN_LIST ares_module_list) + set(target_destination "${ARES_DATA_DESTINATION}/ares-plugins/${target}") + elseif(target STREQUAL desktop-ui) + set(target_destination "${ARES_DATA_DESTINATION}/desktop-ui") + else() + set(target_destination "${ARES_DATA_DESTINATION}/${target}") + endif() + + message(DEBUG "Add resource '${resource}' to target ${target} at destination '${target_destination}'...") + + install(FILES "${resource}" DESTINATION "${target_destination}" COMPONENT Runtime) + + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E echo "Copy ${target} resource ${resource} to library directory" + COMMAND "${CMAKE_COMMAND}" -E make_directory "${ARES_OUTPUT_DIR}/$/${target_destination}/" + COMMAND "${CMAKE_COMMAND}" -E copy "${resource}" "${ARES_OUTPUT_DIR}/$/${target_destination}/" + COMMENT "" + VERBATIM + ) + + source_group("Resources" FILES "${resource}") +endfunction() + +# _bundle_dependencies: Resolve third party dependencies and add them to Windows binary directory +function(_bundle_dependencies target) + message(DEBUG "Discover dependencies of target ${target}...") + set(found_dependencies) + find_dependencies(TARGET ${target} FOUND_VAR found_dependencies) + + get_property(ares_module_list GLOBAL PROPERTY ARES_MODULES_ENABLED) + list(LENGTH ares_module_list num_modules) + if(num_modules GREATER 0) + add_dependencies(${target} ${ares_module_list}) + foreach(module IN LISTS ares_module_list) + find_dependencies(TARGET ${module} FOUND_VAR found_dependencies) + endforeach() + endif() + + list(REMOVE_DUPLICATES found_dependencies) + set(library_paths_DEBUG) + set(library_paths_RELWITHDEBINFO) + set(library_paths_RELEASE) + set(library_paths_MINSIZEREL) + set(plugins_list) + + foreach(library IN LISTS found_dependencies) + get_target_property(library_type ${library} TYPE) + get_target_property(is_imported ${library} IMPORTED) + + if(is_imported) + get_target_property(imported_location ${library} IMPORTED_LOCATION) + + foreach(config IN ITEMS RELEASE RELWITHDEBINFO MINSIZEREL DEBUG) + get_target_property(imported_location_${config} ${library} IMPORTED_LOCATION_${config}) + if(imported_location_${config}) + _check_library_location(${imported_location_${config}}) + elseif(NOT imported_location_${config} AND imported_location_RELEASE) + _check_library_location(${imported_location_RELEASE}) + else() + _check_library_location(${imported_location}) + endif() + endforeach() + endif() + endforeach() + + foreach(config IN ITEMS DEBUG RELWITHDEBINFO RELEASE MINSIZEREL) + list(REMOVE_DUPLICATES library_paths_${config}) + endforeach() + + if(NOT library_paths_DEBUG) + return() + endif() + + # Somewhat cursed, but in keeping with other platforms, make the build process create a runnable application. + # That means copying dependencies and packaging as part of the build process. cmake --install will redundantly + # perform this same process to conform with CMake convention. + if(CMAKE_CONFIGURATION_TYPES) + set(MULTI_CONFIG ON) + else() + set(MULTI_CONFIG OFF) + endif() + add_custom_command( + TARGET ${target} + POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E echo "Copy dependencies to binary directory (${ARES_EXECUTABLE_DESTINATION})..." + COMMAND "${CMAKE_COMMAND}" -E make_directory "${ARES_OUTPUT_DIR}/${target}" + COMMAND + "${CMAKE_COMMAND}" -E "$,copy_if_different,true>" "$<$:${library_paths_DEBUG}>" + "${ARES_EXECUTABLE_DESTINATION}/${target}/$,Debug,>/" + COMMAND + "${CMAKE_COMMAND}" -E "$,copy_if_different,true>" + "$<$:${library_paths_RELWITHDEBINFO}>" + "${ARES_EXECUTABLE_DESTINATION}/${target}/$,RelWithDebInfo,>/" + COMMAND + "${CMAKE_COMMAND}" -E "$,copy_if_different,true>" + "$<$:${library_paths_RELEASE}>" "${ARES_EXECUTABLE_DESTINATION}/${target}/$,Release,>" + COMMAND + "${CMAKE_COMMAND}" -E "$,copy_if_different,true>" + "$<$:${library_paths_MINSIZEREL}>" + "${ARES_EXECUTABLE_DESTINATION}/${target}/$,MinSizeRel,>/" + COMMENT "Copying dynamic dependencies to rundir" + VERBATIM + COMMAND_EXPAND_LISTS + ) + + + install( + FILES ${library_paths_DEBUG} + CONFIGURATIONS Debug + DESTINATION "${ARES_EXECUTABLE_DESTINATION}" + DESTINATION "${ARES_EXECUTABLE_DESTINATION}/${target}/Debug/" + COMPONENT Runtime + ) + + install( + FILES ${library_paths_RELWITHDEBINFO} + CONFIGURATIONS RelWithDebInfo + DESTINATION "${ARES_EXECUTABLE_DESTINATION}" + DESTINATION "${ARES_EXECUTABLE_DESTINATION}/${target}/RelWithDebInfo/" + COMPONENT Runtime + ) + + install( + FILES ${library_paths_RELEASE} + CONFIGURATIONS Release + DESTINATION "${ARES_EXECUTABLE_DESTINATION}" + DESTINATION "${ARES_EXECUTABLE_DESTINATION}/${target}/Release/" + COMPONENT Runtime + ) + + install( + FILES ${library_paths_MINSIZEREL} + CONFIGURATIONS MinSizeRel + DESTINATION "${ARES_EXECUTABLE_DESTINATION}" + DESTINATION "${ARES_EXECUTABLE_DESTINATION}/${target}/MinSizeRel/" + COMPONENT Runtime + ) +endfunction() + +# _check_library_location: Check for corresponding DLL given an import library path +macro(_check_library_location location) + if(library_type STREQUAL "SHARED_LIBRARY") + set(library_location "${location}") + else() + string(STRIP "${location}" location) + if(location MATCHES ".+lib$") + cmake_path(GET location FILENAME _dll_name) + cmake_path(GET location PARENT_PATH _implib_path) + cmake_path(SET _bin_path NORMALIZE "${_implib_path}/../bin") + string(REPLACE ".lib" ".dll" _dll_name "${_dll_name}") + string(REPLACE ".dll" ".pdb" _pdb_name "${_dll_name}") + + find_program(_dll_path NAMES "${_dll_name}" HINTS ${_implib_path} ${_bin_path} NO_CACHE NO_DEFAULT_PATH) + + find_program(_pdb_path NAMES "${_pdb_name}" HINTS ${_implib_path} ${_bin_path} NO_CACHE NO_DEFAULT_PATH) + + if(_dll_path) + set(library_location "${_dll_path}") + set(library_pdb_location "${_pdb_path}") + else() + unset(library_location) + unset(library_pdb_location) + endif() + unset(_dll_path) + unset(_pdb_path) + unset(_bin_path) + unset(_implib_path) + unset(_dll_name) + unset(_pdb_name) + else() + unset(library_location) + unset(library_pdb_location) + endif() + endif() + + if(library_location) + list(APPEND library_paths_${config} ${library_location}) + endif() + if(library_pdb_location) + list(APPEND library_paths_${config} ${library_pdb_location}) + endif() + unset(location) + unset(library_location) + unset(library_pdb_location) +endmacro() diff --git a/desktop-ui/CMakeLists.txt b/desktop-ui/CMakeLists.txt index 0ea05d4a2c..5174af861c 100644 --- a/desktop-ui/CMakeLists.txt +++ b/desktop-ui/CMakeLists.txt @@ -1,4 +1,5 @@ -add_executable(desktop-ui +add_executable( + desktop-ui desktop-ui.cpp resource/resource.cpp input/input.cpp @@ -10,21 +11,54 @@ add_executable(desktop-ui tools/tools.cpp ) -target_link_libraries(desktop-ui PRIVATE nall ruby hiro ares mia) - -set_target_properties( +target_sources( desktop-ui - PROPERTIES - OUTPUT_NAME ares + PRIVATE + cmake/sources.cmake + cmake/os-macos.cmake + cmake/os-linux.cmake + cmake/os-windows.cmake ) -add_sourcery_command(desktop-ui resource) +include(cmake/sources.cmake) + +get_target_property(desktop-ui_SOURCES desktop-ui SOURCES) + +set_source_files_properties(desktop-ui ${desktop-ui_SOURCES} PROPERTIES HEADER_FILE_ONLY TRUE) + +set_source_files_properties( + desktop-ui + desktop-ui.cpp + resource/resource.cpp + input/input.cpp + emulator/emulator.cpp + game-browser/game-browser.cpp + program/program.cpp + presentation/presentation.cpp + settings/settings.cpp + tools/tools.cpp + PROPERTIES HEADER_FILE_ONLY FALSE +) -if(WIN32) - target_sources(desktop-ui PRIVATE - resource/ares.rc - resource/ares.Manifest - ) +if(OS_WINDOWS) + include(cmake/os-windows.cmake) +elseif(OS_MACOS) + include(cmake/os-macos.cmake) +elseif(OS_LINUX) + include(cmake/os-linux.cmake) +elseif(OS_FREEBSD OR OS_OPENBSD) + include(cmake/os-freebsd.cmake) endif() -nall_set_properties(desktop-ui) +target_link_libraries( + desktop-ui + PRIVATE ares::ruby ares::hiro ares::ares mia chdr-static sljit +) + +set_target_properties(desktop-ui PROPERTIES OUTPUT_NAME ares) + +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${desktop-ui_SOURCES}) + +add_sourcery_command(desktop-ui resource) + +ares_configure_executable(desktop-ui) diff --git a/desktop-ui/cmake/macos/Info.plist.in b/desktop-ui/cmake/macos/Info.plist.in new file mode 100644 index 0000000000..5d373e6c9d --- /dev/null +++ b/desktop-ui/cmake/macos/Info.plist.in @@ -0,0 +1,39 @@ + + + + + LSApplicationCategoryType + public.app-category.games + CFBundleIdentifier + dev.ares.ares + CFBundleDisplayName + ares + CFBundleExecutable + ares + CFBundleIconFile + ares.icns + CFBundlePackageType + APPL + NSHighResolutionCapable + + NSSupportsAutomaticGraphicsSwitching + + LSMinimumSystemVersion + 10.9 + NSHumanReadableCopyright + Copyright © ares Team and Contributors. + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + * + + CFBundleTypeName + DocumentType + CFBundleTypeRole + Viewer + + + + diff --git a/desktop-ui/cmake/macos/entitlements.plist b/desktop-ui/cmake/macos/entitlements.plist new file mode 100644 index 0000000000..6883e4a27b --- /dev/null +++ b/desktop-ui/cmake/macos/entitlements.plist @@ -0,0 +1,10 @@ + + + + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.disable-library-validation + + + diff --git a/desktop-ui/cmake/macos/exportOptions.plist.in b/desktop-ui/cmake/macos/exportOptions.plist.in new file mode 100644 index 0000000000..b9fe6d2338 --- /dev/null +++ b/desktop-ui/cmake/macos/exportOptions.plist.in @@ -0,0 +1,14 @@ + + + + + method + developer-id + signingStyle + manual + signingCertificate + Developer ID Application + teamID + ${ARES_CODESIGN_TEAM} + + \ No newline at end of file diff --git a/desktop-ui/cmake/os-linux.cmake b/desktop-ui/cmake/os-linux.cmake new file mode 100644 index 0000000000..06915def79 --- /dev/null +++ b/desktop-ui/cmake/os-linux.cmake @@ -0,0 +1,61 @@ +# Stage and install slang shaders +if(ARES_ENABLE_LIBRASHADER) + add_custom_command( + TARGET desktop-ui + POST_BUILD + COMMAND + cp -R "${CMAKE_SOURCE_DIR}/.deps/ares-deps-linux-universal/lib/slang-shaders/." + "${ARES_BUILD_OUTPUT_DIR}/$/Shaders" + COMMENT "Copying slang shaders to staging directory" + ) + + install( + DIRECTORY "${CMAKE_SOURCE_DIR}/.deps/ares-deps-linux-universal/lib/slang-shaders/" + DESTINATION "${ARES_INSTALL_DATA_DESTINATION}/Shaders" + USE_SOURCE_PERMISSIONS + COMPONENT Runtime + ) +endif() + +# Stage and install mia database +add_custom_command( + TARGET desktop-ui + POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E make_directory "${ARES_BUILD_OUTPUT_DIR}/$/Database" + COMMAND + cp -R "${CMAKE_SOURCE_DIR}/mia/Database/." + "${ARES_BUILD_OUTPUT_DIR}/$/Database/" + COMMENT "Copying mia database to staging directory" +) + +install( + DIRECTORY "${CMAKE_SOURCE_DIR}/mia/Database/" + DESTINATION "${ARES_INSTALL_DATA_DESTINATION}/Database" + USE_SOURCE_PERMISSIONS + COMPONENT Runtime +) + +# Stage and install icon, .desktop file +add_custom_command( + TARGET desktop-ui + POST_BUILD + COMMAND + cp "${CMAKE_CURRENT_SOURCE_DIR}/resource/ares.desktop" + "${ARES_BUILD_OUTPUT_DIR}/$/ares.desktop" + COMMAND + cp "${CMAKE_CURRENT_SOURCE_DIR}/resource/ares.png" + "${ARES_BUILD_OUTPUT_DIR}/$/ares.png" + COMMENT "Copying icon to staging directory" +) + +install( + FILES "${CMAKE_CURRENT_SOURCE_DIR}/resource/ares.desktop" + DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications" + COMPONENT Runtime +) + +install( + FILES "${CMAKE_CURRENT_SOURCE_DIR}/resource/ares.png" + DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/256x256/apps" + COMPONENT Runtime +) diff --git a/desktop-ui/cmake/os-macos.cmake b/desktop-ui/cmake/os-macos.cmake new file mode 100644 index 0000000000..1fbe969380 --- /dev/null +++ b/desktop-ui/cmake/os-macos.cmake @@ -0,0 +1,96 @@ +target_sources(desktop-ui PRIVATE cmake/os-macos.cmake) + +set_target_xcode_properties( + desktop-ui + PROPERTIES PRODUCT_BUNDLE_IDENTIFIER com.ares-emulator.ares + PRODUCT_NAME ares + ASSETCATALOG_COMPILER_APPICON_NAME AppIcon + CURRENT_PROJECT_VERSION ${ARES_BUILD_NUMBER} + MARKETING_VERSION ${ARES_VERSION} + GENERATE_INFOPLIST_FILE YES + COPY_PHASE_STRIP NO + CLANG_ENABLE_OBJC_ARC YES + SKIP_INSTALL NO + INSTALL_PATH "$(LOCAL_APPS_DIR)" + INFOPLIST_KEY_CFBundleDisplayName "ares" + INFOPLIST_KEY_NSHumanReadableCopyright "(c) 2004-${CURRENT_YEAR} ares team, Near et. al." +) + +set_target_properties( + desktop-ui + PROPERTIES + OUTPUT_NAME ares + MACOSX_BUNDLE TRUE + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/resource/ares.plist" + XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY YES + XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY YES + XCODE_EMBED_PLUGINS_REMOVE_HEADERS_ON_COPY YES + XCODE_EMBED_PLUGINS_CODE_SIGN_ON_COPY YES +) + +target_add_resource(desktop-ui "${CMAKE_SOURCE_DIR}/ruby/video/metal/Shaders.metal" "Shaders") +target_add_resource(desktop-ui "${CMAKE_CURRENT_SOURCE_DIR}/resource/Assets.xcassets") + +function(target_install_shaders target) + message(DEBUG "Installing shaders for target ${target}...") + if(EXISTS "${CMAKE_SOURCE_DIR}/.deps/ares-deps-macos-universal/lib/slang-shaders") + file(GLOB_RECURSE data_files "${CMAKE_SOURCE_DIR}/.deps/ares-deps-macos-universal/lib/slang-shaders/*") + foreach(data_file IN LISTS data_files) + cmake_path( + RELATIVE_PATH + data_file + BASE_DIRECTORY "${CMAKE_SOURCE_DIR}/.deps/ares-deps-macos-universal/lib/slang-shaders/" + OUTPUT_VARIABLE relative_path + ) + cmake_path(GET relative_path PARENT_PATH relative_path) + target_sources(${target} PRIVATE "${data_file}") + set_property(SOURCE "${data_file}" PROPERTY MACOSX_PACKAGE_LOCATION "Resources/Shaders/${relative_path}") + source_group("Resources/Shaders/${relative_path}" FILES "${data_file}") + endforeach() + endif() +endfunction() + +function(target_install_database target) + message(DEBUG "Installing shaders for target ${target}...") + if(EXISTS "${CMAKE_SOURCE_DIR}/mia/Database") + file(GLOB_RECURSE data_files "${CMAKE_SOURCE_DIR}/mia/Database/*") + foreach(data_file IN LISTS data_files) + cmake_path( + RELATIVE_PATH + data_file + BASE_DIRECTORY "${CMAKE_SOURCE_DIR}/mia/Database/" + OUTPUT_VARIABLE relative_path + ) + cmake_path(GET relative_path PARENT_PATH relative_path) + target_sources(${target} PRIVATE "${data_file}") + set_property(SOURCE "${data_file}" PROPERTY MACOSX_PACKAGE_LOCATION "Resources/Database/${relative_path}") + source_group("Resources/Database/${relative_path}" FILES "${data_file}") + endforeach() + endif() +endfunction() + +# Add slang-shaders as a post-build script so we don't have an exceedingly long "Copy Files" phase +if(ARES_ENABLE_LIBRASHADER) + add_custom_command( + TARGET desktop-ui + POST_BUILD + COMMAND + ditto "${CMAKE_SOURCE_DIR}/.deps/ares-deps-macos-universal/lib/slang-shaders" + "$/Resources/Shaders/" + WORKING_DIRECTORY "$" + COMMENT "Copying slang shaders to app bundle" + ) +endif() + +# Can't use target_add_resource for this since we only want it to occur in debug configurations +add_custom_command( + TARGET desktop-ui + POST_BUILD + COMMAND $<$:ditto> + ARGS + "${CMAKE_SOURCE_DIR}/ruby/video/metal/Shaders.metallib" "$/Resources/Shaders/" + WORKING_DIRECTORY "$" + COMMENT "Copying debug .metallib to app bundle" +) + +target_install_database(desktop-ui) diff --git a/desktop-ui/cmake/os-windows.cmake b/desktop-ui/cmake/os-windows.cmake new file mode 100644 index 0000000000..2eec28ff93 --- /dev/null +++ b/desktop-ui/cmake/os-windows.cmake @@ -0,0 +1,26 @@ +target_sources(desktop-ui PRIVATE resource/ares.rc resource/ares.Manifest) + +set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT desktop-ui) + +if(ARES_ENABLE_LIBRASHADER) + add_custom_command( + TARGET desktop-ui + POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E make_directory "${ARES_EXECUTABLE_DESTINATION}/desktop-ui/$,$,>/Shaders/" + COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_SOURCE_DIR}/.deps/ares-deps-windows-${arch}/lib/slang-shaders/" + "${ARES_EXECUTABLE_DESTINATION}/desktop-ui/$,$,>/Shaders/" + WORKING_DIRECTORY "." + COMMENT "Copying slang shaders to rundir" + ) +endif() + +if(EXISTS "${CMAKE_SOURCE_DIR}/mia/Database") + add_custom_command( + TARGET desktop-ui + POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E make_directory "${ARES_EXECUTABLE_DESTINATION}/desktop-ui/$,$,>/Database/" + COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_SOURCE_DIR}/mia/Database/" + "${ARES_EXECUTABLE_DESTINATION}/desktop-ui/$,$,>/Database/" + COMMENT "Copying mia database to rundir" + ) +endif() diff --git a/desktop-ui/cmake/sources.cmake b/desktop-ui/cmake/sources.cmake new file mode 100644 index 0000000000..b272e6d517 --- /dev/null +++ b/desktop-ui/cmake/sources.cmake @@ -0,0 +1,98 @@ +target_sources( + desktop-ui + PRIVATE desktop-ui.hpp game-browser/game-browser.hpp input/hotkeys.cpp input/input.hpp presentation/presentation.hpp +) + +target_sources(desktop-ui PRIVATE game-browser/game-browser.hpp) + +target_sources(desktop-ui PRIVATE input/hotkeys.cpp input/input.hpp) + +target_sources(desktop-ui PRIVATE presentation/presentation.hpp) + +target_sources( + desktop-ui + PRIVATE + program/drivers.cpp + program/load.cpp + program/platform.cpp + program/program.hpp + program/rewind.cpp + program/states.cpp + program/utility.cpp +) + +target_sources(desktop-ui PRIVATE resource/resource.cpp resource/resource.hpp) + +target_sources( + desktop-ui + PRIVATE + settings/audio.cpp + settings/debug.cpp + settings/drivers.cpp + settings/emulators.cpp + settings/firmware.cpp + settings/home.cpp + settings/hotkeys.cpp + settings/input.cpp + settings/options.cpp + settings/paths.cpp + settings/settings.hpp + settings/video.cpp +) + +target_sources( + desktop-ui + PRIVATE + tools/cheats.cpp + tools/graphics.cpp + tools/manifest.cpp + tools/memory.cpp + tools/properties.cpp + tools/streams.cpp + tools/tools.hpp + tools/tracer.cpp +) + +target_sources( + desktop-ui + PRIVATE + emulator/arcade.cpp + emulator/atari-2600.cpp + emulator/colecovision.cpp + emulator/emulator.cpp + emulator/emulator.hpp + emulator/emulators.cpp + emulator/famicom-disk-system.cpp + emulator/famicom.cpp + emulator/game-boy-advance.cpp + emulator/game-boy-color.cpp + emulator/game-boy.cpp + emulator/game-gear.cpp + emulator/master-system.cpp + emulator/mega-32x.cpp + emulator/mega-cd-32x.cpp + emulator/mega-cd.cpp + emulator/mega-drive.cpp + emulator/msx.cpp + emulator/msx2.cpp + emulator/myvision.cpp + emulator/neo-geo-aes.cpp + emulator/neo-geo-mvs.cpp + emulator/neo-geo-pocket-color.cpp + emulator/neo-geo-pocket.cpp + emulator/nintendo-64.cpp + emulator/nintendo-64dd.cpp + emulator/pc-engine-cd.cpp + emulator/pc-engine.cpp + emulator/playstation.cpp + emulator/pocket-challenge-v2.cpp + emulator/saturn.cpp + emulator/sg-1000.cpp + emulator/super-famicom.cpp + emulator/supergrafx-cd.cpp + emulator/supergrafx.cpp + emulator/wonderswan-color.cpp + emulator/wonderswan.cpp + emulator/zx-spectrum-128.cpp + emulator/zx-spectrum.cpp +) diff --git a/desktop-ui/resource/Assets.xcassets/AppIcon.appiconset/Contents.json b/desktop-ui/resource/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000..a00ad51885 --- /dev/null +++ b/desktop-ui/resource/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "filename" : "ares@16x16.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "16x16" + }, + { + "filename" : "ares@32x32.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "16x16" + }, + { + "filename" : "ares@32x32 1.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "32x32" + }, + { + "filename" : "ares@64x64.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "32x32" + }, + { + "filename" : "ares@128x128.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "128x128" + }, + { + "filename" : "ares 1.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "128x128" + }, + { + "filename" : "ares.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "256x256" + }, + { + "filename" : "ares@512x512.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "256x256" + }, + { + "filename" : "ares@512x512 1.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "512x512" + }, + { + "filename" : "ares@1024x1024.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "512x512" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/desktop-ui/resource/Assets.xcassets/AppIcon.appiconset/ares 1.png b/desktop-ui/resource/Assets.xcassets/AppIcon.appiconset/ares 1.png new file mode 100644 index 0000000000000000000000000000000000000000..a12c79e5e9091abf22ec1f47e812cede5ba9009f GIT binary patch literal 11155 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 ZElfTBcK{Vbz9tX=kP?>@D;3rM{9l$?H8TJJ literal 0 HcmV?d00001 diff --git a/desktop-ui/resource/Assets.xcassets/AppIcon.appiconset/ares.png b/desktop-ui/resource/Assets.xcassets/AppIcon.appiconset/ares.png new file mode 100644 index 0000000000000000000000000000000000000000..a12c79e5e9091abf22ec1f47e812cede5ba9009f GIT binary patch literal 11155 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 ZElfTBcK{Vbz9tX=kP?>@D;3rM{9l$?H8TJJ literal 0 HcmV?d00001 diff --git a/desktop-ui/resource/Assets.xcassets/AppIcon.appiconset/ares@1024x1024.png b/desktop-ui/resource/Assets.xcassets/AppIcon.appiconset/ares@1024x1024.png new file mode 100644 index 0000000000000000000000000000000000000000..e3b3e73047e75e354bbfa9e53185d67e7c2f328e GIT binary patch literal 168908 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ϝ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 literal 0 HcmV?d00001 diff --git a/desktop-ui/resource/Assets.xcassets/AppIcon.appiconset/ares@128x128.png b/desktop-ui/resource/Assets.xcassets/AppIcon.appiconset/ares@128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..bd1741df9d400111cbecc57e2f8a0226161b4cf9 GIT binary patch literal 9254 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

^TodLhH|gmIwU(*0`x=uG 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

^TodLhH|gmIwU(*0`x=uG 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 ins^W~hc=lMOqV`(ZbA}s;{fVjDt5$e$U59KR# z^zh?9{Cs<8!oFsh2LK?^{*NF@FbNp|5ItsYbloN}mE*+mUr`pzNo&aB#`WG<`1#=( z`tFe>{(Grk`&=1$&K8|Qzf#vtmDm`uz+{xZih%FOAeX-UczytY@CgBYh5*D65IPG8 z0T2NIayA?|3kVzs1i}HnaNxKha2)toh&AVNI)M*ZkBa5fysFJIB#Hyz|5f~V2++I= z2&~gRSLd{wo;=Z$ci27J_rv#Z$U{YFWg>yS>Swa|WpZG~ue5#l`*-D?A5*UR@}nXj zJ2_h)CM{`-&UAY4dY`PfT;txw$YGr)VPQ$A?f}|@=IQ2UT;{gT zmbQ34rI{h^rx&;Sip5*jCcUwe1VQ`Kdmg|5xvWsA%Wto!KUsuXG4 zMIA$?!0eZRQ6q4{SBs&an(>B`Y&eOZO`7IxPGSl@avmMr?OV-CpnbYE?pTjEOv?1cNB9e zuy++rBT35Z(wX^*hJYLL!W}*NW249W5Vt&!#O9tX3BMmW9~SqfJ0oC!@ZrHHtH8TYbUXARkpN8MxczH|5Zd{l~v_`8|ZCx;gz;F;qFj zHhb)`mpFf}aV~^SzhM!bWozC)SH08KTDYzelMK8YK8NQwr6G$DP&$ulqAY@H!!#7ru{y0A_1qn)#`_jPLmw_abqT-`df*)Kx9Ydhqkq%swT)Yrv#p(N1pAd>KOYdXrT z>?3U`3M_EHR(cvdcCq?zildA;4GZyv;d{IFDzn@cj4?Kw$Ii+Cwcqy1Ey zOQ62072qI2aCq!+Oxkl;;ip)kW&9YP3F2uYOn~eR`BFMMG#B(V2mB^EGFkmoF|4ed zqg213PaEW)t$Yx=a__aiZ}1M4G`5VKCxw!GpF18~bm%eMEcSm9uhpi-X^(O>Evn)D zkjw`sLY_Dej}3}E#*vtnI?nfI%wCqs>oTBgUX9N4!BqVqSA$}sdguNS%mLlMYVjB2 z-%WoX9^1O8E16NXQXna%Q-DbwZ@I9WvC&h+WPKW5HYcd;XcX%o47Luq_oz!_YH1Wz z-V1bzZ1<3VfY-1xTG*&o`9=aXu2590j6X=$A!XX7L)qA$UGk3WQ{cvudfR7WPi)jV zzNBLQUQC}{d8(>V1|E2tem6wEZ#DRPvEb{vPfmXX`Od#{?DE@qV{AOK=^Q9+ZG{OL z-o~`-Wp$RalDyyh#Y#_bC+CwY960vxZnkjl_LQNT?5I__PkBEZ3d$YKEkX~LDHV06 zF&lb6F13NM4zTIhu|L6fZgLA1`Ju6?+KbqY#maj71&bCke{kXKfl}(4Y6&2iI+D7m ze1jFvC8Xx7g#*AhNbp(TkHWq_3{ZiD7#V}rY&(5EVL6L}(zfB&yI=3Rgw!fokAp=y zNJ2xmr+Ea-uc2sGO7>@fMI-et)HGBk2@{Jzg_(|wVRfrhm22$qSGqQXB$Efdc?Ic31mQKKd<;lPP?r>VUYJYN6gu}C^(cavrlHEN0YLO>Qo{nKNNyF5x8kFbf+a*Dgbl4>q;IJ@Ur$Dwb%KIjKWSL3;fvK} zI;l(xm)t}ui&Bo8G*^y&zGacIt?q5K`N`yXdIb73B@ggmk7@2lT(BPPbQnTo%%CO@ ztn7}^UO2~yS|a&u#2@D(Re2m6(s7;EP01!)DBh1d-4_VX1vMe2X-H zN+-YvumqPPB4ta)9_8YhUgN0MHC5~~xueg+bCo)tZc9Kjl29|C!D{e+tV#^77X0>J z#wWMI`OX5t2!uN3P1$x6y=0tMS0_aFf=!FA#+<(KhXqxyB)XLE9!w zvS=xa4%41F;{_qub4lnHasclQ=U7pids6VRRd^$gIh+nR2 zJTi(Z#Do1=@6Sq8Oo{NqM-gftUYSQ#Mt{CgU$v1WJ&e(2OT`d)*~uRVBk2!rPIET< zmm_SQXCZKfm&8hGMejKa8Ro0ZX^#YD7{{bfG@+XZ0LR^dKV5urFQZ` z{MDt}0AUKMd&MFeE_0_p_CDhIKu}9c&p3vMWQ4PCx^aSaqXce2*PhAQPJ - com.apple.security.cs.allow-jit - + com.apple.security.get-task-allow + + com.apple.security.cs.allow-jit + diff --git a/desktop-ui/resource/ares.plist b/desktop-ui/resource/ares.plist index 5d373e6c9d..2a050ea535 100644 --- a/desktop-ui/resource/ares.plist +++ b/desktop-ui/resource/ares.plist @@ -2,38 +2,46 @@ - LSApplicationCategoryType - public.app-category.games - CFBundleIdentifier - dev.ares.ares - CFBundleDisplayName - ares - CFBundleExecutable - ares - CFBundleIconFile - ares.icns - CFBundlePackageType - APPL - NSHighResolutionCapable - - NSSupportsAutomaticGraphicsSwitching - - LSMinimumSystemVersion - 10.9 - NSHumanReadableCopyright - Copyright © ares Team and Contributors. - CFBundleDocumentTypes - - - CFBundleTypeExtensions - - * - - CFBundleTypeName - DocumentType - CFBundleTypeRole - Viewer - - + LSApplicationCategoryType + public.app-category.games + CFBundleIdentifier + com.ares-emulator.ares + CFBundleDisplayName + ares + CFBundleExecutable + ares + CFBundlePackageType + APPL + CFBundleIcons + + CFBundlePrimaryIcon + + CFBundleIconFiles + + Assets + + + + NSHighResolutionCapable + + NSSupportsAutomaticGraphicsSwitching + + LSMinimumSystemVersion + 10.13 + NSHumanReadableCopyright + Copyright © ares Team and Contributors. + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + * + + CFBundleTypeName + DocumentType + CFBundleTypeRole + Viewer + + diff --git a/hiro/CMakeLists.txt b/hiro/CMakeLists.txt index 99bbd74aa3..327a571c36 100644 --- a/hiro/CMakeLists.txt +++ b/hiro/CMakeLists.txt @@ -1,102 +1,22 @@ -add_library(hiro STATIC hiro.cpp) +add_library(hiro STATIC) +add_library(ares::hiro ALIAS hiro) -target_link_libraries(hiro PUBLIC nall) +target_link_libraries(hiro PUBLIC ares::nall) -#PKG_CONFIG ?= pkg-config +include(cmake/sources.cmake) - -if(platform STREQUAL windows) - if(NOT hiro) - set(hiro windows) - endif() - - if(hiro STREQUAL windows) - target_compile_definitions(hiro PRIVATE HIRO_WINDOWS) - target_link_libraries(hiro PRIVATE kernel32 user32 gdi32 advapi32 ole32 comctl32 comdlg32 uxtheme msimg32 dwmapi) - endif() - - if(hiro STREQUAL gtk2) -# hiro.flags = $(flags.cpp) -DHIRO_GTK=2 $(shell pkg-config --cflags gtk+-2.0) -Wno-deprecated-declarations -# hiro.options = $(shell pkg-config --libs gtk+-2.0) - endif() - - if(hiro STREQUAL gtk3) -# hiro.flags = $(flags.cpp) -DHIRO_GTK=3 $(shell pkg-config --cflags gtk+-3.0) -Wno-deprecated-declarations -# hiro.options = $(shell pkg-config --libs gtk+-3.0) - endif() +if(OS_WINDOWS) + include(cmake/os-windows.cmake) +elseif(OS_MACOS) + include(cmake/os-macos.cmake) +elseif(OS_LINUX) + include(cmake/os-linux.cmake) +elseif(OS_FREEBSD OR OS_OPENBSD) + include(cmake/os-freebsd.cmake) endif() -if(platform STREQUAL macos) - if(NOT hiro) - set(hiro cocoa) - endif() - - if(hiro STREQUAL cocoa) -# hiro.flags = $(flags.objcpp) -w -DHIRO_COCOA -# hiro.options = -framework Cocoa -framework Carbon -framework IOKit -framework Security - endif() -endif() - -if(platform STREQUAL linux OR platform STREQUAL bsd) - if(NOT hiro) - set(hiro gtk3) - endif() - - if(hiro STREQUAL gtk2) -# hiro.flags = $(flags.cpp) -DHIRO_GTK=2 $(shell $(PKG_CONFIG) --cflags gtk+-2.0) -Wno-deprecated-declarations -# hiro.options = -L/usr/local/lib -lX11 $(shell $(PKG_CONFIG) --libs gtk+-2.0) - endif() - - if(hiro STREQUAL gtk2-se) -# flags += -DHiro_SourceEdit -# hiro.flags = $(flags.cpp) -DHIRO_GTK=2 $(shell $(PKG_CONFIG) --cflags gtk+-2.0 gtksourceview-2.0) -Wno-deprecated-declarations -# hiro.options = -L/usr/local/lib -lX11 $(shell $(PKG_CONFIG) --libs gtk+-2.0 gtksourceview-2.0) - endif() - - if(hiro STREQUAL gtk3) -# hiro.flags = $(flags.cpp) -DHIRO_GTK=3 $(shell $(PKG_CONFIG) --cflags gtk+-3.0) -Wno-deprecated-declarations -# hiro.options = -L/usr/local/lib -lX11 $(shell $(PKG_CONFIG) --libs gtk+-3.0) - endif() - - if(hiro STREQUAL gtk3-se) -# flags += -DHiro_SourceEdit -# hiro.flags = $(flags.cpp) -DHIRO_GTK=3 $(shell $(PKG_CONFIG) --cflags gtk+-3.0 gtksourceview-3.0) -Wno-deprecated-declarations -# hiro.options = -L/usr/local/lib -lX11 $(shell $(PKG_CONFIG) --libs gtk+-3.0 gtksourceview-3.0) - endif() - - if(hiro STREQUAL qt4) -# moc = /usr/local/lib/qt4/bin/moc -# hiro.flags = $(flags.cpp) -DHIRO_QT=4 $(shell $(PKG_CONFIG) --cflags QtCore QtGui) -# hiro.options = -L/usr/local/lib -lX11 $(shell $(PKG_CONFIG) --libs QtCore QtGui) - endif() - - if(hiro STREQUAL qt5) -# moc = $(shell $(PKG_CONFIG) --variable=host_bins Qt5Core)/moc -# hiro.flags = $(flags.cpp) -DHIRO_QT=5 -fPIC $(shell $(PKG_CONFIG) --cflags Qt5Core Qt5Gui Qt5Widgets) -# hiro.options = -L/usr/local/lib -lX11 $(shell $(PKG_CONFIG) --libs Qt5Core Qt5Gui Qt5Widgets) - endif() -endif() - -if(NOT hiro.resource) - set(hiro.resource windows/hiro.rc) -endif() - -#hiro.objects := \ -# $(object.path)/hiro-$(hiro).o \ -# $(if $(filter windows,$(hiro)),$(object.path)/hiro-resource$(hiro.resource.extension)) - -#$(object.path)/hiro-$(hiro).o: $(hiro.path)/hiro.cpp -# $(if $(filter qt%,$(hiro)),$(info Compiling $(hiro.path)/qt/qt.moc ...)) -# $(if $(filter qt%,$(hiro)),@$(moc) -i -o $(hiro.path)/qt/qt.moc $(hiro.path)/qt/qt.hpp) -# $(info Compiling $(subst ../,,$<) ...) -# @$(compiler) $(hiro.flags) $(flags) $(flags.deps) -c $< $(call obj,$@) - -#$(object.path)/hiro-resource$(hiro.resource.extension): $(hiro.resource) -# $(info Compiling $(subst ../,,$<) ...) -# @$(windres) $(call hiro.resource.command,$<,$@) +add_sourcery_command(hiro resource) -#hiro.verbose: -# $(info hiro Target:) -# $(info $([space]) $(hiro)) +target_include_directories(hiro PRIVATE ${CMAKE_SOURCE_DIR}) -add_sourcery_command(hiro resource) +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${hiro_SOURCES}) diff --git a/hiro/cmake/os-bsd.cmake b/hiro/cmake/os-bsd.cmake new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/hiro/cmake/os-bsd.cmake @@ -0,0 +1 @@ + diff --git a/hiro/cmake/os-linux.cmake b/hiro/cmake/os-linux.cmake new file mode 100644 index 0000000000..64b3ed5e92 --- /dev/null +++ b/hiro/cmake/os-linux.cmake @@ -0,0 +1,31 @@ +find_package(X11) + +option(USE_QT5 "Use Qt5 UI backend" OFF) +mark_as_advanced(USE_QT5) + +if(NOT USE_QT5) + find_package(GTK REQUIRED) + target_compile_definitions(hiro PRIVATE HIRO_GTK) + + target_link_libraries(hiro PRIVATE GTK::GTK X11::X11) + + target_enable_feature(hiro "GTK3 UI backend" HIRO_GTK=3) +else() + find_package(Qt6 COMPONENTS Widgets Xcb REQUIRED) + + find_program(qt_moc moc-qt6 moc) + + execute_process( + COMMAND qt_moc -i -o ${CMAKE_CURRENT_SOURCE_DIR}/qt/qt.moc ${CMAKE_CURRENT_SOURCE_DIR}/qt/qt.hpp + ) + + target_link_libraries(hiro PRIVATE X11::X11 Qt6::Core Qt6::Gui Qt6::Widgets Qt6::Xcb) + + target_enable_feature(hiro "Qt6 UI backend" HIRO_QT=5) +endif() + +get_target_property(hiro_SOURCES hiro SOURCES) + +set_source_files_properties(hiro ${hiro_SOURCES} PROPERTIES HEADER_FILE_ONLY TRUE) + +set_source_files_properties(hiro hiro.cpp PROPERTIES HEADER_FILE_ONLY FALSE) diff --git a/hiro/cmake/os-macos.cmake b/hiro/cmake/os-macos.cmake new file mode 100644 index 0000000000..f94b729d13 --- /dev/null +++ b/hiro/cmake/os-macos.cmake @@ -0,0 +1,24 @@ +target_sources(hiro PRIVATE cmake/os-macos.cmake hiro.mm hiro.cpp) + +target_enable_feature(hiro "Cocoa UI backend" HIRO_COCOA) + +target_compile_definitions(hiro PRIVATE PLATFORM_MACOS) + +target_link_libraries( + hiro + PRIVATE + "$" + "$" + "$" + "$" +) + +get_target_property(hiro_SOURCES hiro SOURCES) + +set_source_files_properties(hiro ${hiro_SOURCES} PROPERTIES HEADER_FILE_ONLY TRUE) + +if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) + set_source_files_properties(hiro hiro.mm PROPERTIES HEADER_FILE_ONLY FALSE) +else() + set_source_files_properties(hiro hiro.cpp PROPERTIES HEADER_FILE_ONLY FALSE) +endif() diff --git a/hiro/cmake/os-windows.cmake b/hiro/cmake/os-windows.cmake new file mode 100644 index 0000000000..79be943fce --- /dev/null +++ b/hiro/cmake/os-windows.cmake @@ -0,0 +1,15 @@ +target_enable_feature(hiro "Win32 UI" HIRO_WINDOWS) +target_link_libraries( + hiro + PRIVATE kernel32 user32 gdi32 advapi32 ole32 comctl32 comdlg32 uxtheme msimg32 dwmapi +) + +set(hiro.resource windows/hiro.rc) + +get_target_property(hiro_SOURCES hiro SOURCES) + +target_sources(hiro PRIVATE cmake/os-windows.cmake) + +set_source_files_properties(hiro ${hiro_SOURCES} PROPERTIES HEADER_FILE_ONLY TRUE) + +set_source_files_properties(hiro hiro.cpp PROPERTIES HEADER_FILE_ONLY FALSE) diff --git a/hiro/cmake/sources.cmake b/hiro/cmake/sources.cmake new file mode 100644 index 0000000000..48b3d431c2 --- /dev/null +++ b/hiro/cmake/sources.cmake @@ -0,0 +1,451 @@ +if(OS_MACOS) + target_sources(hiro PRIVATE hiro.mm) +else() + target_sources(hiro PRIVATE hiro.cpp) +endif() + +target_sources( + hiro + PRIVATE + hiro.hpp + components.hpp +) + +target_sources( + hiro + PRIVATE + core/alignment.cpp + core/alignment.hpp + core/application.cpp + core/application.hpp + core/attribute.cpp + core/attribute.hpp + core/browser-window.cpp + core/browser-window.hpp + core/color.cpp + core/color.hpp + core/core.cpp + core/core.hpp + core/desktop.cpp + core/desktop.hpp + core/font.cpp + core/font.hpp + core/geometry.cpp + core/geometry.hpp + core/gradient.cpp + core/gradient.hpp + core/group.cpp + core/group.hpp + core/hotkey.cpp + core/hotkey.hpp + core/keyboard.cpp + core/keyboard.hpp + core/lock.hpp + core/menu-bar.cpp + core/menu-bar.hpp + core/message-window.cpp + core/message-window.hpp + core/monitor.cpp + core/monitor.hpp + core/mouse-cursor.cpp + core/mouse-cursor.hpp + core/mouse.cpp + core/mouse.hpp + core/object.cpp + core/object.hpp + core/popup-menu.cpp + core/popup-menu.hpp + core/position.cpp + core/position.hpp + core/shared.hpp + core/sizable.cpp + core/sizable.hpp + core/size.cpp + core/size.hpp + core/status-bar.cpp + core/status-bar.hpp + core/system-color.hpp + core/text-cursor.cpp + core/text-cursor.hpp + core/timer.cpp + core/timer.hpp + core/window.cpp + core/window.hpp +) + +target_sources( + hiro + PRIVATE + core/action/action.cpp + core/action/action.hpp + core/action/menu-check-item.cpp + core/action/menu-check-item.hpp + core/action/menu-item.cpp + core/action/menu-item.hpp + core/action/menu-radio-item.cpp + core/action/menu-radio-item.hpp + core/action/menu-separator.cpp + core/action/menu-separator.hpp + core/action/menu.cpp + core/action/menu.hpp +) + +target_sources( + hiro + PRIVATE + core/widget/button.cpp + core/widget/button.hpp + core/widget/canvas.cpp + core/widget/canvas.hpp + core/widget/check-button.cpp + core/widget/check-button.hpp + core/widget/check-label.cpp + core/widget/check-label.hpp + core/widget/combo-button-item.cpp + core/widget/combo-button-item.hpp + core/widget/combo-button.cpp + core/widget/combo-button.hpp + core/widget/combo-edit-item.cpp + core/widget/combo-edit-item.hpp + core/widget/combo-edit.cpp + core/widget/combo-edit.hpp + core/widget/console.cpp + core/widget/console.hpp + core/widget/frame.cpp + core/widget/frame.hpp + core/widget/hex-edit.cpp + core/widget/hex-edit.hpp + core/widget/horizontal-scroll-bar.cpp + core/widget/horizontal-scroll-bar.hpp + core/widget/horizontal-slider.cpp + core/widget/horizontal-slider.hpp + core/widget/icon-view-item.cpp + core/widget/icon-view-item.hpp + core/widget/icon-view.cpp + core/widget/icon-view.hpp + core/widget/label.cpp + core/widget/label.hpp + core/widget/line-edit.cpp + core/widget/line-edit.hpp + core/widget/progress-bar.cpp + core/widget/progress-bar.hpp + core/widget/radio-button.cpp + core/widget/radio-button.hpp + core/widget/radio-label.cpp + core/widget/radio-label.hpp + core/widget/source-edit.cpp + core/widget/source-edit.hpp + core/widget/tab-frame-item.cpp + core/widget/tab-frame-item.hpp + core/widget/tab-frame.cpp + core/widget/tab-frame.hpp + core/widget/table-view-cell.cpp + core/widget/table-view-cell.hpp + core/widget/table-view-column.cpp + core/widget/table-view-column.hpp + core/widget/table-view-item.cpp + core/widget/table-view-item.hpp + core/widget/table-view.cpp + core/widget/table-view.hpp + core/widget/text-edit.cpp + core/widget/text-edit.hpp + core/widget/tree-view-item.cpp + core/widget/tree-view-item.hpp + core/widget/tree-view.cpp + core/widget/tree-view.hpp + core/widget/vertical-scroll-bar.cpp + core/widget/vertical-scroll-bar.hpp + core/widget/vertical-slider.cpp + core/widget/vertical-slider.hpp + core/widget/viewport.cpp + core/widget/viewport.hpp + core/widget/widget.cpp + core/widget/widget.hpp +) + +target_sources( + hiro + PRIVATE + extension/about-dialog.cpp + extension/about-dialog.hpp + extension/browser-dialog.cpp + extension/browser-dialog.hpp + extension/extension.cpp + extension/extension.hpp + extension/fixed-layout.cpp + extension/fixed-layout.hpp + extension/horizontal-layout.cpp + extension/horizontal-layout.hpp + extension/horizontal-resize-grip.cpp + extension/horizontal-resize-grip.hpp + extension/list-view.cpp + extension/list-view.hpp + extension/message-dialog.cpp + extension/message-dialog.hpp + extension/name-dialog.cpp + extension/name-dialog.hpp + extension/shared.hpp + extension/table-layout.cpp + extension/table-layout.hpp + extension/vertical-layout.cpp + extension/vertical-layout.hpp + extension/vertical-resize-grip.cpp + extension/vertical-resize-grip.hpp +) + +if(OS_MACOS) + target_sources( + hiro + PRIVATE + cocoa/application.cpp + cocoa/application.hpp + cocoa/browser-window.cpp + cocoa/browser-window.hpp + cocoa/desktop.cpp + cocoa/desktop.hpp + cocoa/font.cpp + cocoa/font.hpp + cocoa/group.cpp + cocoa/group.hpp + cocoa/header.hpp + cocoa/keyboard.cpp + cocoa/keyboard.hpp + cocoa/menu-bar.cpp + cocoa/menu-bar.hpp + cocoa/message-window.cpp + cocoa/message-window.hpp + cocoa/monitor.cpp + cocoa/monitor.hpp + cocoa/mouse.cpp + cocoa/mouse.hpp + cocoa/object.cpp + cocoa/object.hpp + cocoa/platform.cpp + cocoa/platform.hpp + cocoa/popup-menu.cpp + cocoa/popup-menu.hpp + cocoa/sizable.cpp + cocoa/sizable.hpp + cocoa/status-bar.cpp + cocoa/status-bar.hpp + cocoa/timer.cpp + cocoa/timer.hpp + cocoa/utility.cpp + cocoa/window.cpp + cocoa/window.hpp + ) + + target_sources( + hiro + PRIVATE + cocoa/action/action.cpp + cocoa/action/action.hpp + cocoa/action/menu-check-item.cpp + cocoa/action/menu-check-item.hpp + cocoa/action/menu-item.cpp + cocoa/action/menu-item.hpp + cocoa/action/menu-protocol.hpp + cocoa/action/menu-radio-item.cpp + cocoa/action/menu-radio-item.hpp + cocoa/action/menu-separator.cpp + cocoa/action/menu-separator.hpp + cocoa/action/menu.cpp + cocoa/action/menu.hpp + ) + + target_sources( + hiro + PRIVATE + cocoa/widget/button.cpp + cocoa/widget/button.hpp + cocoa/widget/canvas.cpp + cocoa/widget/canvas.hpp + cocoa/widget/check-button.cpp + cocoa/widget/check-button.hpp + cocoa/widget/check-label.cpp + cocoa/widget/check-label.hpp + cocoa/widget/combo-button-item.cpp + cocoa/widget/combo-button-item.hpp + cocoa/widget/combo-button.cpp + cocoa/widget/combo-button.hpp + cocoa/widget/console.cpp + cocoa/widget/console.hpp + cocoa/widget/frame.cpp + cocoa/widget/frame.hpp + cocoa/widget/hex-edit.cpp + cocoa/widget/hex-edit.hpp + cocoa/widget/horizontal-scroll-bar.cpp + cocoa/widget/horizontal-scroll-bar.hpp + cocoa/widget/horizontal-slider.cpp + cocoa/widget/horizontal-slider.hpp + cocoa/widget/label.cpp + cocoa/widget/label.hpp + cocoa/widget/line-edit.cpp + cocoa/widget/line-edit.hpp + cocoa/widget/progress-bar.cpp + cocoa/widget/progress-bar.hpp + cocoa/widget/radio-button.cpp + cocoa/widget/radio-button.hpp + cocoa/widget/radio-label.cpp + cocoa/widget/radio-label.hpp + cocoa/widget/tab-frame-item.cpp + cocoa/widget/tab-frame-item.hpp + cocoa/widget/tab-frame.cpp + cocoa/widget/tab-frame.hpp + cocoa/widget/table-view-cell.cpp + cocoa/widget/table-view-cell.hpp + cocoa/widget/table-view-column.cpp + cocoa/widget/table-view-column.hpp + cocoa/widget/table-view-item.cpp + cocoa/widget/table-view-item.hpp + cocoa/widget/table-view.cpp + cocoa/widget/table-view.hpp + cocoa/widget/text-edit.cpp + cocoa/widget/text-edit.hpp + cocoa/widget/tree-view-item.cpp + cocoa/widget/tree-view-item.hpp + cocoa/widget/tree-view.cpp + cocoa/widget/tree-view.hpp + cocoa/widget/vertical-scroll-bar.cpp + cocoa/widget/vertical-scroll-bar.hpp + cocoa/widget/vertical-slider.cpp + cocoa/widget/vertical-slider.hpp + cocoa/widget/viewport.cpp + cocoa/widget/viewport.hpp + cocoa/widget/widget.cpp + cocoa/widget/widget.hpp + ) +elseif(OS_WINDOWS) + target_sources( + hiro + PRIVATE + windows/application.cpp + windows/application.hpp + windows/browser-window.cpp + windows/browser-window.hpp + windows/desktop.cpp + windows/desktop.hpp + windows/font.cpp + windows/font.hpp + windows/group.cpp + windows/group.hpp + windows/header.hpp + windows/hiro.Manifest + windows/hiro.rc + windows/keyboard.cpp + windows/keyboard.hpp + windows/menu-bar.cpp + windows/menu-bar.hpp + windows/message-window.cpp + windows/message-window.hpp + windows/monitor.cpp + windows/monitor.hpp + windows/mouse.cpp + windows/mouse.hpp + windows/object.cpp + windows/object.hpp + windows/platform.cpp + windows/platform.hpp + windows/popup-menu.cpp + windows/popup-menu.hpp + windows/settings.cpp + windows/settings.hpp + windows/sizable.cpp + windows/sizable.hpp + windows/status-bar.cpp + windows/status-bar.hpp + windows/timer.cpp + windows/timer.hpp + windows/tool-tip.cpp + windows/tool-tip.hpp + windows/utility.cpp + windows/window.cpp + windows/window.hpp + ) + + target_sources( + hiro + PRIVATE + windows/action/action.cpp + windows/action/action.hpp + windows/action/menu-check-item.cpp + windows/action/menu-check-item.hpp + windows/action/menu-item.cpp + windows/action/menu-item.hpp + windows/action/menu-radio-item.cpp + windows/action/menu-radio-item.hpp + windows/action/menu-separator.cpp + windows/action/menu-separator.hpp + windows/action/menu.cpp + windows/action/menu.hpp + ) + + target_sources( + hiro + PRIVATE + windows/widget/button.cpp + windows/widget/button.hpp + windows/widget/canvas.cpp + windows/widget/canvas.hpp + windows/widget/check-button.cpp + windows/widget/check-button.hpp + windows/widget/check-label.cpp + windows/widget/check-label.hpp + windows/widget/combo-button-item.cpp + windows/widget/combo-button-item.hpp + windows/widget/combo-button.cpp + windows/widget/combo-button.hpp + windows/widget/frame.cpp + windows/widget/frame.hpp + windows/widget/hex-edit.cpp + windows/widget/hex-edit.hpp + windows/widget/horizontal-scroll-bar.cpp + windows/widget/horizontal-scroll-bar.hpp + windows/widget/horizontal-slider.cpp + windows/widget/horizontal-slider.hpp + windows/widget/label.cpp + windows/widget/label.hpp + windows/widget/line-edit.cpp + windows/widget/line-edit.hpp + windows/widget/progress-bar.cpp + windows/widget/progress-bar.hpp + windows/widget/radio-button.cpp + windows/widget/radio-button.hpp + windows/widget/radio-label.cpp + windows/widget/radio-label.hpp + windows/widget/tab-frame-item.cpp + windows/widget/tab-frame-item.hpp + windows/widget/tab-frame.cpp + windows/widget/tab-frame.hpp + windows/widget/table-view-cell.cpp + windows/widget/table-view-cell.hpp + windows/widget/table-view-column.cpp + windows/widget/table-view-column.hpp + windows/widget/table-view-item.cpp + windows/widget/table-view-item.hpp + windows/widget/table-view.cpp + windows/widget/table-view.hpp + windows/widget/text-edit.cpp + windows/widget/text-edit.hpp + windows/widget/tree-view-item.cpp + windows/widget/tree-view-item.hpp + windows/widget/tree-view.cpp + windows/widget/tree-view.hpp + windows/widget/vertical-scroll-bar.cpp + windows/widget/vertical-scroll-bar.hpp + windows/widget/vertical-slider.cpp + windows/widget/vertical-slider.hpp + windows/widget/viewport.cpp + windows/widget/viewport.hpp + windows/widget/widget.cpp + windows/widget/widget.hpp + ) +endif() + +target_sources( + hiro + PRIVATE + cmake/sources.cmake + cmake/os-windows.cmake + cmake/os-linux.cmake +) diff --git a/hiro/hiro.mm b/hiro/hiro.mm new file mode 100644 index 0000000000..57e019c79b --- /dev/null +++ b/hiro/hiro.mm @@ -0,0 +1 @@ +#include "hiro.cpp" diff --git a/libco/CMakeLists.txt b/libco/CMakeLists.txt index 1c9d6b183a..ad6889ee80 100644 --- a/libco/CMakeLists.txt +++ b/libco/CMakeLists.txt @@ -1 +1,33 @@ add_library(libco STATIC libco.c) + +string(TOLOWER ${CMAKE_SYSTEM_PROCESSOR} LOWERCASE_CMAKE_SYSTEM_PROCESSOR) + +if(LOWERCASE_CMAKE_SYSTEM_PROCESSOR MATCHES "(i[3-6]86|x86)") + target_sources(libco PRIVATE x86.c) +elseif(LOWERCASE_CMAKE_SYSTEM_PROCESSOR MATCHES "(x64|x86_64|amd64|e2k)") + target_sources(libco PRIVATE amd64.c) +elseif(LOWERCASE_CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64(le)?") + target_sources(libco PRIVATE ppc64v2.c) +elseif(LOWERCASE_CMAKE_SYSTEM_PROCESSOR MATCHES "(riscv)") + target_sources(libco PRIVATE riscv.c) +elseif(LOWERCASE_CMAKE_SYSTEM_PROCESSOR MATCHES "(aarch64|arm64)") + target_sources(libco PRIVATE aarch64.c) +elseif(LOWERCASE_CMAKE_SYSTEM_PROCESSOR MATCHES "(arm)") + target_sources(libco PRIVATE arm.c) +elseif(LOWERCASE_CMAKE_SYSTEM_PROCESSOR MATCHES "(ppc)") + target_sources(libco PRIVATE ppc.c) +elseif(OS_WINDOWS) + target_sources(libco PRIVATE fiber.c) +else() + target_sources(libco PRIVATE sjlj.c) +endif() + +target_sources(libco PRIVATE libco.h settings.h) + +get_target_property(libco_SOURCES libco SOURCES) + +target_include_directories(libco INTERFACE ..) + +set_source_files_properties(libco ${libco_SOURCES} PROPERTIES HEADER_FILE_ONLY TRUE) + +set_source_files_properties(libco libco.c PROPERTIES HEADER_FILE_ONLY FALSE) diff --git a/mia/CMakeLists.txt b/mia/CMakeLists.txt index 6be72640cd..7efb4eed71 100644 --- a/mia/CMakeLists.txt +++ b/mia/CMakeLists.txt @@ -1,23 +1,151 @@ add_library(mia STATIC mia.cpp resource/resource.cpp) +add_library(ares::mia ALIAS mia) -target_compile_definitions(mia PUBLIC MIA_LIBRARY) +target_sources( + mia + PRIVATE + resource/resource.hpp + medium/arcade.cpp + medium/atari-2600.cpp + medium/bs-memory.cpp + medium/colecovision.cpp + medium/famicom-disk-system.cpp + medium/famicom.cpp + medium/game-boy-advance.cpp + medium/game-boy-color.cpp + medium/game-boy.cpp + medium/game-gear.cpp + medium/mame.cpp + medium/master-system.cpp + medium/medium.cpp + medium/medium.hpp + medium/mega-32x.cpp + medium/mega-cd.cpp + medium/mega-drive.cpp + medium/msx.cpp + medium/msx2.cpp + medium/myvision.cpp + medium/neo-geo-crypt.hpp + medium/neo-geo-pocket-color.cpp + medium/neo-geo-pocket.cpp + medium/neo-geo.cpp + medium/nintendo-64.cpp + medium/nintendo-64dd.cpp + medium/pc-engine-cd.cpp + medium/pc-engine.cpp + medium/playstation.cpp + medium/pocket-challenge-v2.cpp + medium/saturn.cpp + medium/sc-3000.cpp + medium/sg-1000.cpp + medium/sufami-turbo.cpp + medium/super-famicom.cpp + medium/supergrafx.cpp + medium/wonderswan-color.cpp + medium/wonderswan.cpp + medium/zx-spectrum.cpp +) -target_link_libraries(mia PUBLIC nall ares PRIVATE tzxfile) +target_sources(mia PRIVATE pak/pak.cpp pak/pak.hpp) -add_sourcery_command(mia resource) +target_sources( + mia + PRIVATE + program/game-importer.cpp + program/game-importer.hpp + program/game-manager.cpp + program/game-manager.hpp + program/home.cpp + program/home.hpp + program/program.cpp + program/program.hpp + program/system-selection.cpp + program/system-selection.hpp +) +target_sources(mia PRIVATE settings/settings.cpp settings/settings.hpp) -add_executable(mia-standalone mia.cpp resource/resource.cpp) +target_sources( + mia + PRIVATE + system/arcade.cpp + system/atari-2600.cpp + system/colecovision.cpp + system/famicom.cpp + system/game-boy-advance.cpp + system/game-boy-color.cpp + system/game-boy.cpp + system/game-gear.cpp + system/master-system.cpp + system/mega-32x.cpp + system/mega-cd-32x.cpp + system/mega-cd.cpp + system/mega-drive.cpp + system/msx.cpp + system/msx2.cpp + system/myvision.cpp + system/neo-geo-aes.cpp + system/neo-geo-mvs.cpp + system/neo-geo-pocket-color.cpp + system/neo-geo-pocket.cpp + system/nintendo-64.cpp + system/nintendo-64dd.cpp + system/pc-engine.cpp + system/playstation.cpp + system/pocket-challenge-v2.cpp + system/saturn.cpp + system/sc-3000.cpp + system/sg-1000.cpp + system/super-famicom.cpp + system/supergrafx.cpp + system/system.cpp + system/system.hpp + system/wonderswan-color.cpp + system/wonderswan.cpp + system/zx-spectrum-128.cpp + system/zx-spectrum.cpp +) -target_link_libraries(mia-standalone PUBLIC nall hiro ares PRIVATE tzxfile) +target_compile_definitions(mia PRIVATE MIA_LIBRARY) -add_sourcery_command(mia-standalone resource) +target_link_libraries(mia PUBLIC ares::nall ares::ares ares::hiro PRIVATE tzxfile) + +add_executable(mia-ui mia.cpp resource/resource.cpp) + +target_link_libraries( + mia-ui + PUBLIC ares::nall ares::hiro ares::ares + PRIVATE + tzxfile + "$<$:$>" + "$<$:$>" + "$<$:$>" +) if(WIN32) - target_sources(mia-standalone PRIVATE - resource/mia.rc - resource/mia.Manifest - ) + target_sources(mia-ui PRIVATE resource/mia.rc resource/mia.Manifest) endif() -nall_set_properties(mia-standalone) +get_target_property(mia_SOURCES mia SOURCES) + +set_source_files_properties(mia ${mia_SOURCES} PROPERTIES HEADER_FILE_ONLY TRUE) + +set_source_files_properties(mia mia.cpp resource/resource.cpp PROPERTIES HEADER_FILE_ONLY FALSE) + +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${mia_SOURCES}) + +set_target_properties( + mia-ui + PROPERTIES + OUTPUT_NAME mia + MACOSX_BUNDLE TRUE + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/resource/mia.plist" + XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY YES + XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY YES + XCODE_EMBED_PLUGINS_REMOVE_HEADERS_ON_COPY YES + XCODE_EMBED_PLUGINS_CODE_SIGN_ON_COPY YES +) + +ares_configure_executable(mia-ui) +target_enable_subproject(mia-ui "mia (manifest generator)") +set_target_properties(mia-ui PROPERTIES FOLDER tools PREFIX "") diff --git a/mia/CMakeLists.txt.rej b/mia/CMakeLists.txt.rej new file mode 100644 index 0000000000..7bc94b4a58 --- /dev/null +++ b/mia/CMakeLists.txt.rej @@ -0,0 +1,10 @@ +diff a/mia/CMakeLists.txt b/mia/CMakeLists.txt (rejected hunks) +@@ -119,7 +119,7 @@ target_sources( + + target_compile_definitions(mia PUBLIC MIA_LIBRARY) + +-target_link_libraries(mia PUBLIC ares::nall ares::ares PRIVATE tzxfile) ++target_link_libraries(mia PUBLIC ares::nall ares::ares ares::hiro PRIVATE tzxfile) + + add_executable(mia-ui mia.cpp resource/resource.cpp) + diff --git a/mia/cmake/macos/entitlements.plist b/mia/cmake/macos/entitlements.plist new file mode 100644 index 0000000000..6883e4a27b --- /dev/null +++ b/mia/cmake/macos/entitlements.plist @@ -0,0 +1,10 @@ + + + + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.disable-library-validation + + + diff --git a/mia/cmake/os-macos.cmake b/mia/cmake/os-macos.cmake new file mode 100644 index 0000000000..695e0ca89b --- /dev/null +++ b/mia/cmake/os-macos.cmake @@ -0,0 +1,28 @@ +set_target_properties( + ${target} + PROPERTIES + OUTPUT_NAME mia + MACOSX_BUNDLE TRUE + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/resource/mia.plist" + XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY YES + XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY YES + XCODE_EMBED_PLUGINS_REMOVE_HEADERS_ON_COPY YES + XCODE_EMBED_PLUGINS_CODE_SIGN_ON_COPY YES +) + +# cmake-format: off +set_target_xcode_properties( + ${target} + PROPERTIES PRODUCT_BUNDLE_IDENTIFIER com.ares-emulator.mia + PRODUCT_NAME mia + ASSETCATALOG_COMPILER_APPICON_NAME AppIcon + CURRENT_PROJECT_VERSION ${ARES_BUILD_NUMBER} + MARKETING_VERSION ${ARES_VERSION} + GENERATE_INFOPLIST_FILE YES + COPY_PHASE_STRIP NO + CLANG_ENABLE_OBJC_ARC YES + SKIP_INSTALL NO + INSTALL_PATH "$(LOCAL_APPS_DIR)" + INFOPLIST_KEY_CFBundleDisplayName "mia" + INFOPLIST_KEY_NSHumanReadableCopyright "(c) 2004-${CURRENT_YEAR} ares team, Near et. al." +) diff --git a/nall/CMakeLists.txt b/nall/CMakeLists.txt index 4405deb088..cae9503817 100644 --- a/nall/CMakeLists.txt +++ b/nall/CMakeLists.txt @@ -1,263 +1,56 @@ -add_library(nall OBJECT - nall.cpp - main.cpp - ../thirdparty/sljitAllocator.cpp -) - -target_link_libraries(nall PUBLIC sljit libchdr) - - -# platform detection -if(NOT platform) - if(CMAKE_SYSTEM_NAME STREQUAL "Windows") - set(platform windows) - elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") - set(platform macos) - elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(platform linux) - elseif(CMAKE_SYSTEM_NAME MATCHES "BSD") - set(platform bsd) - else() - message(FATAL_ERROR "unknown platform, please specify manually.") - endif() -endif() - -# compiler detection -if(NOT compiler) - if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") - set(compiler cl) - elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - set(compiler g++) - elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(compiler clang++) - else() - message(FATAL_ERROR "unknown compiler, please specify manually.") - endif() -endif() - -if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86|i[3-6]86)$") - set(machine x86) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|amd64|AMD64)$") - set(machine amd64) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64|ARM64)$") - set(machine arm64) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(armv7l?|arm|ARM)$") - set(machine arm32) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(ppc64|ppc64le)") - set(machine ppc64) -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64") - set(machine rv64) -elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv32") - set(machine rv32) -endif() - -# global compiler flags -target_compile_features(nall PUBLIC c_std_11) -set_target_properties(nall PROPERTIES C_EXTENSIONS OFF) - -target_compile_features(nall PUBLIC cxx_std_17) -set_target_properties(nall PROPERTIES CXX_EXTENSIONS OFF) - -if(MSVC) - target_compile_options(nall PUBLIC /W2) -endif() - -# explicit architecture flags to allow for cross-compilation on macos -if(platform STREQUAL macos) - if(arch STREQUAL amd64) - add_compile_options(-arch x86_64) #global - add_link_options(-arch x86_64) #global - elseif(arch STREQUAL arm64) - add_compile_options(-arch arm64) #global - add_link_options(-arch arm64) #global - endif() - if(NOT machine STREQUAL arch) - set(local FALSE) - endif() -endif() - -# architecture detection -if(NOT arch) - if(machine) - set(arch ${machine}) - else() - message(FATAL_ERROR "unknown arch, please specify manually.") - endif() -endif() - -# build optimization levels -#ifeq ($(build),debug) -# symbols = true -# ifeq ($(cl),true) -# flags += -Od -# else -# flags += -Og -# endif -# flags += -DBUILD_DEBUG -#else ifeq ($(build),stable) -# flags += -O1 -DBUILD_STABLE -#else ifeq ($(build),minified) -# flags += -Os -DBUILD_MINIFIED -#else ifeq ($(build),release) -# flags += -O2 -DBUILD_RELEASE -#else ifeq ($(build),optimized) -# ifeq ($(cl),true) -# flags += -O2 -# else -# flags += -O3 -fomit-frame-pointer -# endif -# flags += -DBUILD_OPTIMIZED -#else -# $(error unrecognized build type.) -#endif - -target_compile_definitions(nall PUBLIC BUILD_$) - -if(local) - target_compile_definitions(nall PUBLIC BUILD_LOCAL) -endif() - -# debugging information -#ifeq ($(symbols),true) -# ifeq ($(cl),true) -# flags += -Zi -FS -# options += -debug -# ifneq ($(build),debug) -# options += -opt:ref,icf -# endif -# else -# flags += -g -# ifeq ($(platform),windows) -# ifeq ($(findstring clang++,$(compiler)),clang++) -# ifeq ($(symformat),gdb) -# flags += -ggdb -# else -# flags += -gcodeview -# endif -# ifeq ($(msvc),true) -# options += -Wl,-debug -# else -# options += -Wl,-pdb= -# endif -# endif -# endif -# endif -#endif - -# link-time optimization -#ifeq ($(lto),true) -# ifeq ($(cl),true) -# ifneq ($(findstring clang,$(compiler)),clang) -# flags += -GL -# options += -ltcg:incremental -ltcgout:$(object.path)/$(name).iobj -# else -# flags += -flto=thin -# options += -lldltocache:$(object.path)/lto -# endif -# else -# ifneq ($(findstring clang++,$(compiler)),clang++) -# flags += -flto=auto -fno-fat-lto-objects -# else -# flags += -flto=thin -# options += -flto=thin -# ifeq ($(platform),macos) -# options += -Wl,-cache_path_lto,$(object.path)/lto -# else ifeq ($(msvc),true) -# options += -Wl,-lldltocache:$(object.path)/lto -# else -# options += -Wl,--thinlto-cache-dir=$(object.path)/lto -# endif -# endif -# endif -#endif - -# openmp support -#ifeq ($(openmp),true) -# # macOS Xcode does not ship with OpenMP support -# ifneq ($(platform),macos) -# flags += -fopenmp -# options += -fopenmp -# endif -#endif - -# clang settings -if(compiler STREQUAL clang++) - target_compile_options(nall PUBLIC -fno-strict-aliasing -fwrapv) - if(NOT platform STREQUAL macos) - target_link_options(nall PUBLIC -fuse-ld=lld) - endif() -# gcc settings -elseif(compiler STREQUAL g++) - target_compile_options(nall PUBLIC -fno-strict-aliasing -fwrapv -Wno-trigraphs) -endif() - -# windows settings -if(platform STREQUAL windows) - # target Windows 7 - add_compile_definitions(_WIN32_WINNT=0x0601) #global - if(NOT MINGW) - add_compile_definitions(_CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS) #global - endif() - target_link_libraries(nall PUBLIC ws2_32 ole32 shell32 shlwapi) - if(MINGW) - target_link_options(nall PUBLIC -mthreads -static) - endif() - if(console) - target_compile_definitions(nall PUBLIC SUBSYTEM_CONSOLE) - else() - target_compile_definitions(nall PUBLIC SUBSYTEM_WINDOWS) - endif() -endif() - -function(nall_set_properties target) - set_target_properties(${target} PROPERTIES WIN32_EXECUTABLE $>) -endfunction() - -# macos settings -#ifeq ($(platform),macos) -# flags += -stdlib=libc++ -mmacosx-version-min=10.9 -Wno-auto-var-id -fobjc-arc -# options += -lc++ -lobjc -mmacosx-version-min=10.9 -# # allow mprotect() on dynamic recompiler code blocks -# options += -Wl,-segprot,__DATA,rwx,rw -#endif - -# linux settings -#ifeq ($(platform),linux) -# options += -ldl -#endif - -# bsd settings -#ifeq ($(platform),bsd) -# flags += -I/usr/local/include -# options += -Wl,-rpath=/usr/local/lib -# options += -Wl,-rpath=/usr/local/lib/gcc8 -# options += -lstdc++ -lm -#endif - -# threading support -#ifeq ($(threaded),true) -# ifneq ($(filter $(platform),linux bsd),) -# flags += -pthread -# options += -pthread -lrt -# endif -#endif - -#nall.verbose: -# $(info Compiler:) -# $(info $([space]) $(compiler)) -# $(info Compiler Flags:) -# $(foreach n,$(sort $(call unique,$(flags))),$(if $(filter-out -I%,$n),$(info $([space]) $n))) -# $(info Linker Options:) -# $(foreach n,$(sort $(call unique,$(options))),$(if $(filter-out -l%,$n),$(info $([space]) $n))) - -set(platform ${platform} PARENT_SCOPE) -set(compiler ${compiler} PARENT_SCOPE) -set(machine ${machine} PARENT_SCOPE) -set(local ${local} PARENT_SCOPE) -set(arch ${arch} PARENT_SCOPE) - -message("platform ${platform}") -message("compiler ${compiler}") -message("machine ${machine}") -message("local ${local}") -message("arch ${arch}") +add_library(nall OBJECT main.cpp nall.cpp sljitAllocator.cpp) +add_library(ares::nall ALIAS nall) + +include(cmake/sources.cmake) + +target_link_libraries(nall PUBLIC sljit chdr-static) +target_compile_definitions(nall PRIVATE CMAKE) +target_compile_options( + nall + PRIVATE + $<$:-Wno-switch + -Wno-parentheses + -Wno-shorten-64-to-32 + -Wno-comma + -Wno-sign-compare + -Wno-deprecated-literal-operator + -Wno-unused> +) + +if(OS_WINDOWS) + include(cmake/os-windows.cmake) +elseif(OS_MACOS) + include(cmake/os-macos.cmake) +elseif(OS_LINUX) + include(cmake/os-linux.cmake) +elseif(OS_FREEBSD OR OS_OPENBSD) + include(cmake/os-freebsd.cmake) +endif() + +get_target_property(nall_SOURCES nall SOURCES) +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${nall_SOURCES}) +set_source_files_properties(${nall_SOURCES} PROPERTIES HEADER_FILE_ONLY TRUE) + +set_source_files_properties(nall nall.cpp main.cpp sljitAllocator.cpp PROPERTIES HEADER_FILE_ONLY FALSE) + +# global compiler flags +target_compile_features(nall PUBLIC c_std_11) +set_target_properties(nall PROPERTIES C_EXTENSIONS OFF) + +target_compile_features(nall PUBLIC cxx_std_17) +set_target_properties(nall PROPERTIES CXX_EXTENSIONS OFF) + +target_compile_definitions( + nall + PUBLIC + $<$:BUILD_DEBUG=1> + $<$:BUILD_RELEASE=1> + $<$:BUILD_RELEASE=1> + $<$:BUILD_MINIFIED=1> +) + +if(ARES_BUILD_LOCAL) + target_compile_definitions(nall PUBLIC BUILD_LOCAL) +endif() + +target_include_directories(nall PRIVATE ${CMAKE_SOURCE_DIR}) diff --git a/nall/cmake/os-freebsd.cmake b/nall/cmake/os-freebsd.cmake new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/nall/cmake/os-freebsd.cmake @@ -0,0 +1 @@ + diff --git a/nall/cmake/os-linux.cmake b/nall/cmake/os-linux.cmake new file mode 100644 index 0000000000..12b719c99c --- /dev/null +++ b/nall/cmake/os-linux.cmake @@ -0,0 +1,9 @@ +target_compile_definitions(nall PUBLIC PLATFORM_LINUX) + +target_sources( + nall + PRIVATE # cmake-format: sortable + xorg/clipboard.hpp + xorg/guard.hpp + xorg/xorg.hpp +) diff --git a/nall/cmake/os-macos.cmake b/nall/cmake/os-macos.cmake new file mode 100644 index 0000000000..3059cf1a02 --- /dev/null +++ b/nall/cmake/os-macos.cmake @@ -0,0 +1,8 @@ +target_sources(nall PRIVATE macos/guard.hpp) + +target_sources(nall PRIVATE cmake/os-macos.cmake) + +target_compile_definitions(nall PUBLIC PLATFORM_MACOS) + +target_link_libraries(nall PRIVATE "$") +target_compile_options(nall PRIVATE -Wno-error=switch) diff --git a/nall/cmake/os-windows.cmake b/nall/cmake/os-windows.cmake new file mode 100644 index 0000000000..b99f28efab --- /dev/null +++ b/nall/cmake/os-windows.cmake @@ -0,0 +1,41 @@ +target_sources( + nall + PRIVATE + windows/detour.cpp + windows/detour.hpp + windows/guid.cpp + windows/guid.hpp + windows/launcher.cpp + windows/launcher.hpp + windows/registry.cpp + windows/registry.hpp + windows/service.hpp + windows/shared-memory.hpp + windows/utf8.cpp + windows/utf8.hpp + windows/windows.hpp +) + +if(MSVC) + target_compile_options(nall PRIVATE /W2) +endif() + +target_link_libraries(nall PUBLIC ws2_32 ole32 shell32 shlwapi) +if(MINGW) + target_link_options(nall PUBLIC -mthreads -static) +endif() +if(CONSOLE) + target_compile_definitions(nall PUBLIC SUBSYTEM_CONSOLE) +else() + target_compile_definitions(nall PUBLIC SUBSYTEM_WINDOWS) +endif() +target_link_libraries(nall PUBLIC ws2_32 ole32 shell32 shlwapi) + +set_source_files_properties( + nall + windows/detour.cpp + windows/launcher.cpp + windows/registry.cpp + windows/utf8.cpp + PROPERTIES HEADER_FILE_ONLY TRUE +) diff --git a/nall/cmake/sources.cmake b/nall/cmake/sources.cmake new file mode 100644 index 0000000000..1e591e38a6 --- /dev/null +++ b/nall/cmake/sources.cmake @@ -0,0 +1,296 @@ +target_sources( + nall + PRIVATE + adaptive-array.hpp + algorithm.hpp + any.hpp + arguments.hpp + arithmetic.hpp + array-span.hpp + array-view.hpp + array.hpp + atoi.hpp + bcd.hpp + bit.hpp + bump-allocator.hpp + case-range.hpp + cd.hpp + chrono.hpp + counting-sort.hpp + directory.cpp + directory.hpp + dl.cpp + dl.hpp + endian.hpp + file-buffer.hpp + file-map.cpp + file-map.hpp + file.hpp + float-env.hpp + function.hpp + galois-field.hpp + hashset.hpp + hid.hpp + image.hpp + induced-sort.hpp + inline-if.hpp + inode.cpp + inode.hpp + instance.hpp + interpolation.hpp + intrinsics.hpp + ips.hpp + iterator.hpp + literals.hpp + locale.hpp + location.hpp + main.hpp + map.hpp + matrix-multiply.hpp + matrix.hpp + maybe.hpp + memory.cpp + memory.hpp + merge-sort.hpp + nall.cpp + nall.hpp + path.cpp + path.hpp + platform.cpp + platform.hpp + pointer.hpp + primitives.hpp + priority-queue.hpp + property.hpp + queue.hpp + random.cpp + random.hpp + range.hpp + reed-solomon.hpp + run.cpp + run.hpp + serial.hpp + serializer.hpp + service.hpp + set.hpp + shared-memory.hpp + shared-pointer.hpp + stdint.hpp + string.hpp + suffix-array.hpp + terminal.cpp + terminal.hpp + thread.cpp + thread.hpp + traits.hpp + unique-pointer.hpp + utility.hpp + variant.hpp + varint.hpp + vector.hpp + vfs.hpp + view.hpp +) + +target_sources(nall PRIVATE arithmetic/barrett.hpp arithmetic/natural.hpp arithmetic/unsigned.hpp) + +target_sources(nall PRIVATE beat/single/apply.hpp beat/single/create.hpp) + +target_sources( + nall + PRIVATE cd/crc16.hpp cd/edc.hpp cd/efm.hpp cd/rspc.hpp cd/scrambler.hpp cd/session.hpp cd/sync.hpp +) + +target_sources(nall PRIVATE cipher/chacha20.hpp) + +target_sources(nall PRIVATE database/odbc.hpp database/sqlite3.hpp) + +target_sources( + nall + PRIVATE + decode/base.hpp + decode/base64.hpp + decode/bmp.hpp + decode/bwt.hpp + decode/chd.hpp + decode/cue.hpp + decode/gzip.hpp + decode/html.hpp + decode/huffman.hpp + decode/inflate.hpp + decode/lzsa.hpp + decode/mtf.hpp + decode/png.hpp + decode/rle.hpp + decode/url.hpp + decode/wav.hpp + decode/zip.hpp +) + +target_sources(nall PRIVATE dsp/iir/biquad.hpp dsp/iir/dc-removal.hpp dsp/iir/one-pole.hpp dsp/resampler/cubic.hpp) + +target_sources( + nall + PRIVATE + elliptic-curve/curve25519.hpp + elliptic-curve/ed25519.hpp + elliptic-curve/modulo25519-optimized.hpp + elliptic-curve/modulo25519-reference.hpp +) + +target_sources(nall PRIVATE emulation/21fx.hpp) + +target_sources( + nall + PRIVATE + encode/base.hpp + encode/base64.hpp + encode/bmp.hpp + encode/bwt.hpp + encode/html.hpp + encode/huffman.hpp + encode/lzsa.hpp + encode/mtf.hpp + encode/png.hpp + encode/rle.hpp + encode/url.hpp + encode/wav.hpp + encode/zip.hpp +) + +target_sources(nall PRIVATE gdb/Readme.md gdb/server.cpp gdb/server.hpp gdb/watchpoint.hpp) + +target_sources( + nall + PRIVATE + hash/crc16.hpp + hash/crc32.hpp + hash/crc64.hpp + hash/hash.hpp + hash/sha224.hpp + hash/sha256.hpp + hash/sha384.hpp + hash/sha512.hpp +) + +target_sources( + nall + PRIVATE + image/blend.hpp + image/core.hpp + image/fill.hpp + image/interpolation.hpp + image/load.hpp + image/multifactor.hpp + image/scale.hpp + image/static.hpp + image/utility.hpp +) + +target_sources(nall PRIVATE mac/poly1305.hpp) + +target_sources(nall PRIVATE posix/service.hpp posix/shared-memory.hpp) + +target_sources( + nall + PRIVATE + primitives/bit-field.hpp + primitives/bit-range.hpp + primitives/boolean.hpp + primitives/integer.hpp + primitives/literals.hpp + primitives/natural.hpp + primitives/real.hpp + primitives/types.hpp +) + +target_sources(nall PRIVATE queue/spsc.hpp queue/st.hpp) + +target_sources( + nall + PRIVATE + recompiler/amd64/amd64.hpp + recompiler/amd64/constants.hpp + recompiler/amd64/emitter.hpp + recompiler/amd64/encoder-calls-systemv.hpp + recompiler/amd64/encoder-calls-windows.hpp + recompiler/amd64/encoder-instructions.hpp + recompiler/generic/constants.hpp + recompiler/generic/encoder-calls.hpp + recompiler/generic/encoder-instructions.hpp + recompiler/generic/generic.hpp +) + +target_sources( + nall + PRIVATE + string/atoi.hpp + string/cast.hpp + string/compare.hpp + string/convert.hpp + string/core.hpp + string/find.hpp + string/format.hpp + string/match.hpp + string/pascal.hpp + string/replace.hpp + string/split.hpp + string/trim.hpp + string/utf8.hpp + string/utility.hpp + string/vector.hpp + string/view.hpp + string/allocator/adaptive.hpp + string/allocator/copy-on-write.hpp + string/allocator/small-string-optimization.hpp + string/allocator/vector.hpp + string/eval/evaluator.hpp + string/eval/literal.hpp + string/eval/node.hpp + string/eval/parser.hpp + string/markup/bml.hpp + string/markup/find.hpp + string/markup/node.hpp + string/markup/xml.hpp +) + +target_sources( + nall + PRIVATE tcptext/tcp-socket.cpp tcptext/tcp-socket.hpp tcptext/tcptext-server.cpp tcptext/tcptext-server.hpp +) + +target_sources( + nall + PRIVATE + vector/access.hpp + vector/assign.hpp + vector/compare.hpp + vector/core.hpp + vector/iterator.hpp + vector/memory.hpp + vector/modify.hpp + vector/utility.hpp + vector/specialization/u8.hpp +) + +target_sources( + nall + PRIVATE + vfs/attribute.hpp + vfs/cdrom.hpp + vfs/directory.hpp + vfs/disk.hpp + vfs/file.hpp + vfs/memory.hpp + vfs/node.hpp + vfs/vfs.hpp +) + +target_sources( + nall + PRIVATE + cmake/os-macos.cmake + cmake/os-windows.cmake + cmake/os-linux.cmake) + +target_sources(nall PRIVATE cmake/sources.cmake) diff --git a/nall/decode/inflate.hpp b/nall/decode/inflate.hpp index 5e1d7d2d19..f901b48696 100644 --- a/nall/decode/inflate.hpp +++ b/nall/decode/inflate.hpp @@ -123,7 +123,8 @@ inline auto decode(state* s, huffman* h) -> s32 { } inline auto construct(huffman* h, s16* length, s32 n) -> s32 { - s32 symbol, len, left; + s32 symbol, left; + u32 len; s16 offs[MAXBITS + 1]; for(len = 0; len <= MAXBITS; len++) h->count[len] = 0; diff --git a/nall/intrinsics.hpp b/nall/intrinsics.hpp index b3cfb69002..9058732a0b 100644 --- a/nall/intrinsics.hpp +++ b/nall/intrinsics.hpp @@ -25,6 +25,7 @@ namespace nall { static constexpr bool GCC = 0; static constexpr bool Microsoft = 0; }; +#if !defined(CMAKE) #pragma clang diagnostic error "-Wgnu-case-range" #pragma clang diagnostic error "-Wgnu-statement-expression" #pragma clang diagnostic error "-Wvla" @@ -39,7 +40,7 @@ namespace nall { #pragma clang diagnostic ignored "-Wabsolute-value" #pragma clang diagnostic ignored "-Wtrigraphs" #pragma clang diagnostic ignored "-Wattributes" - #pragma clang diagnostic ignored "-Winvalid-offsetof" +#endif #elif defined(__GNUC__) #define COMPILER_GCC struct Compiler { @@ -47,6 +48,7 @@ namespace nall { static constexpr bool GCC = 1; static constexpr bool Microsoft = 0; }; +#if !defined(CMAKE) #pragma GCC diagnostic error "-Wvla" #pragma GCC diagnostic warning "-Wimplicit-fallthrough" #pragma GCC diagnostic warning "-Wreturn-type" @@ -57,7 +59,7 @@ namespace nall { #pragma GCC diagnostic ignored "-Wtrigraphs" #pragma GCC diagnostic ignored "-Wattributes" #pragma GCC diagnostic ignored "-Wstringop-overflow" //GCC 10.2 warning heuristic is buggy - #pragma GCC diagnostic ignored "-Winvalid-offsetof" +#endif #elif defined(_MSC_VER) #define COMPILER_MICROSOFT struct Compiler { @@ -65,11 +67,13 @@ namespace nall { static constexpr bool GCC = 0; static constexpr bool Microsoft = 1; }; +#if !defined(CMAKE) #pragma warning(disable:4146) //unary minus operator applied to unsigned type, result still unsigned #pragma warning(disable:4244) //conversion from 'type1' to 'type2', possible loss of data #pragma warning(disable:4804) //unsafe use of type 'bool' in operation #pragma warning(disable:4805) //unsafe mix of type 'bool' and type 'type' in operation #pragma warning(disable:4996) //libc "deprecation" warnings +#endif #else #error "unable to detect compiler" #endif @@ -86,7 +90,7 @@ namespace nall { static constexpr bool BSD = 0; }; #elif defined(__APPLE__) - #define PLATFORM_MACOS + // #define PLATFORM_MACOS struct Platform { static constexpr bool Windows = 0; static constexpr bool MacOS = 1; @@ -104,7 +108,7 @@ namespace nall { static constexpr bool BSD = 0; }; #elif defined(linux) || defined(__linux__) - #define PLATFORM_LINUX + // #define PLATFORM_LINUX struct Platform { static constexpr bool Windows = 0; static constexpr bool MacOS = 0; diff --git a/nall/macos/guard.hpp b/nall/macos/guard.hpp index 96cd4d6904..876b6c5bf3 100644 --- a/nall/macos/guard.hpp +++ b/nall/macos/guard.hpp @@ -3,7 +3,10 @@ #define Boolean CocoaBoolean #define decimal CocoaDecimal -#define DEBUG CocoaDebug +#ifdef DEBUG +#undef DEBUG +#define DEBUG CocoaDebug +#endif #else #undef NALL_MACOS_GUARD_HPP diff --git a/nall/sljitAllocator.cpp b/nall/sljitAllocator.cpp new file mode 100644 index 0000000000..0d8146d6f9 --- /dev/null +++ b/nall/sljitAllocator.cpp @@ -0,0 +1,9 @@ +#include + +#include +#include + +auto sljit_nall_malloc_exec(sljit_uw size, void* exec_allocator_data) -> void* { + auto allocator = (nall::bump_allocator*)exec_allocator_data; + return allocator->tryAcquire(size, false); +} diff --git a/ruby/CMakeLists.txt b/ruby/CMakeLists.txt index 7b37c4e8a9..8de8751811 100644 --- a/ruby/CMakeLists.txt +++ b/ruby/CMakeLists.txt @@ -1,149 +1,63 @@ -add_library(ruby STATIC ruby.cpp) +add_library(ruby STATIC) +add_library(ares::ruby ALIAS ruby) -target_link_libraries(ruby PUBLIC nall PRIVATE thirdparty) +option(ARES_ENABLE_LIBRASHADER "Configure with librashader and slang shaders" ON) - -if(NOT ruby) - if(platform STREQUAL windows) - list(APPEND ruby video.direct3d9 video.gdi) - if (arch STREQUAL x86 OR arch STREQUAL amd64) - list(APPEND ruby video.wgl) - endif() - list(APPEND ruby audio.wasapi audio.xaudio2 audio.directsound audio.waveout) #audio.asio - list(APPEND ruby input.windows) - -# ifeq ($(call which,pkg-config),) -# # TODO: Check presence of libSDL -# else() -# # If we're in a posix shell, use pkg-config/pkg-check -# pkg_check = $(if $(shell pkg-config $1 && echo 1),$2) -# ruby += $(call pkg_check,sdl2,input.sdl) -# ruby += $(call pkg_check,sdl2,audio.sdl) -# endif() - elseif(platform STREQUAL macos) - list(APPEND ruby video.cgl) - list(APPEND ruby audio.openal) - list(APPEND ruby input.quartz) #input.carbon - elseif(platform STREQUAL linux) -# pkg_check = $(if $(shell pkg-config $1 && echo 1),$2) - list(APPEND ruby video.glx video.glx2 video.xshm) -# ruby += $(call pkg_check,xv,video.xvideo) - list(APPEND ruby audio.oss audio.alsa) -# ruby += $(call pkg_check,openal,audio.openal) -# ruby += $(call pkg_check,libpulse,audio.pulseaudio) -# ruby += $(call pkg_check,libpulse-simple,audio.pulseaudiosimple) -# ruby += $(call pkg_check,ao,audio.ao) - list(APPEND ruby input.xlib) -# ruby += $(call pkg_check,libudev,input.udev) -# ruby += $(call pkg_check,sdl2,input.sdl) -# ruby += $(call pkg_check,sdl2,audio.sdl) - elseif(platform STREQUAL bsd) -# pkg_check = $(if $(shell pkg-config $1 && echo 1),$2) - list(APPEND ruby video.glx video.glx2 video.xshm) -# ruby += $(call pkg_check,xv,video.xvideo) - list(APPEND ruby audio.oss) -# ruby += $(call pkg_check,openal,audio.openal) -# ruby += $(call pkg_check,libpulse,audio.pulseaudio) -# ruby += $(call pkg_check,libpulse-simple,audio.pulseaudiosimple) -# ruby += $(call pkg_check,ao,audio.ao) - list(APPEND ruby input.uhid input.xlib) -# ruby += $(call pkg_check,sdl2,input.sdl) -# ruby += $(call pkg_check,sdl2,audio.sdl) - endif() -endif() - -if(platform STREQUAL macos) -# ruby.flags := $(flags.objcpp) +if(OS_MACOS) + target_sources(ruby PRIVATE ruby.mm) else() -# ruby.flags := $(flags.cpp) + target_sources(ruby PRIVATE ruby.cpp) endif() -foreach(c IN LISTS ruby) - target_compile_definitions(ruby PRIVATE $>) -endforeach() +target_sources(ruby PRIVATE ruby.hpp) -#ifeq ($(call which,pkg-config),) -# # TODO: add SDL2 cflags -#else() -# ruby.flags += $(if $(findstring input.sdl,$(ruby)),$(shell pkg-config sdl2 --cflags)) -# ruby.flags += $(if $(findstring audio.sdl,$(ruby)),$(shell pkg-config sdl2 --cflags)) -#endif() +target_sources(ruby PRIVATE audio/audio.cpp audio/audio.hpp audio/sdl.cpp) -set(ruby.options "") +target_sources(ruby PRIVATE input/input.cpp input/input.hpp input/sdl.cpp) -#ruby.options += $(if $(findstring video.cgl,$(ruby)),-framework OpenGL) -if(video.direct3d9 IN_LIST ruby) - target_link_libraries(ruby PRIVATE d3d9) -endif() -#ruby.options += $(if $(findstring video.glx,$(ruby)),-lGL) -if(video.wgl IN_LIST ruby) - target_link_libraries(ruby PRIVATE opengl32) -endif() -#ruby.options += $(if $(findstring video.xvideo,$(ruby)),-lXv) +target_sources( + ruby + PRIVATE + video/video.cpp + video/video.hpp + video/opengl/bind.hpp + video/opengl/main.hpp + video/opengl/opengl.hpp + video/opengl/surface.hpp + video/opengl/texture.hpp + video/opengl/utility.hpp +) -#ruby.options += $(if $(findstring audio.alsa,$(ruby)),-lasound) -#ruby.options += $(if $(findstring audio.ao,$(ruby)),-lao) -if(audio.directsound IN_LIST ruby) - target_link_libraries(ruby PRIVATE dsound uuid) -endif() -#ruby.options += $(if $(findstring audio.pulseaudio,$(ruby)),-lpulse) -#ruby.options += $(if $(findstring audio.pulseaudiosimple,$(ruby)),-lpulse-simple) -if(audio.wasapi IN_LIST ruby) - target_link_libraries(ruby PRIVATE avrt uuid) -endif() -if(audio.waveout IN_LIST ruby) - target_link_libraries(ruby PRIVATE winmm) -endif() -if(audio.xaudio2 IN_LIST ruby) - target_link_libraries(ruby PRIVATE ole32) +if(OS_WINDOWS) + include(cmake/os-windows.cmake) +elseif(OS_MACOS) + include(cmake/os-macos.cmake) +elseif(OS_LINUX) + include(cmake/os-linux.cmake) +elseif(OS_FREEBSD OR OS_OPENBSD) + include(cmake/os-freebsd.cmake) endif() -if(platform STREQUAL windows) -# ifeq ($(call which,pkg-config),) -# # TODO: add SDL2 ldflags -# else() -# ruby.options += $(if $(findstring input.sdl,$(ruby)),$(shell pkg-config sdl2 --libs --static)) -# ruby.options += $(if $(findstring audio.sdl,$(ruby)),$(shell pkg-config sdl2 --libs --static)) -# endif() -else() -# ruby.options += $(if $(findstring input.sdl,$(ruby)),$(shell pkg-config sdl2 --libs)) -# ruby.options += $(if $(findstring audio.sdl,$(ruby)),$(shell pkg-config sdl2 --libs)) -endif() +target_sources( + ruby + PRIVATE + cmake/os-macos.cmake + cmake/os-windows.cmake + cmake/os-linux.cmake +) -#ruby.options += $(if $(findstring input.udev,$(ruby)),-ludev) -#ruby.options += $(if $(findstring input.uhid,$(ruby)),-lusbhid) -if(input.windows IN_LIST ruby) - target_link_libraries(ruby PRIVATE dinput8 dxguid) -endif() +target_link_libraries(ruby PUBLIC ares::nall) -if(platform STREQUAL windows) - if(audio.openal IN_LIST ruby) - target_link_libraries(ruby PRIVATE openal32) - endif() -endif() +target_include_directories(ruby PRIVATE ${CMAKE_SOURCE_DIR}) -if(platform STREQUAL macos) -# ruby.options += -framework IOKit -# ruby.options += $(if $(findstring audio.openal,$(ruby)),-framework OpenAL) -endif() +get_target_property(ruby_SOURCES ruby SOURCES) -if(platform STREQUAL linux) -# ruby.options += -lX11 -lXext -lXrandr -# ruby.options += $(if $(findstring audio.openal,$(ruby)),-lopenal) -endif() +set_source_files_properties(ruby ${ruby_SOURCES} PROPERTIES HEADER_FILE_ONLY TRUE) -if(platform STREQUAL bsd) -# ruby.options += -lX11 -lXext -lXrandr -# ruby.options += $(if $(findstring audio.openal,$(ruby)),-lopenal -fuse-ld=bfd) -# # -fuse-ld=bfd: see FreeBSD bug 219089 +if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) + set_source_files_properties(ruby ruby.mm PROPERTIES HEADER_FILE_ONLY FALSE) +else() + set_source_files_properties(ruby ruby.cpp PROPERTIES HEADER_FILE_ONLY FALSE) endif() -#ruby.objects := $(object.path)/ruby.o - -#$(object.path)/ruby.o: $(ruby.path)/ruby.cpp $(call rwildcard,$(ruby.path)) -# $(info Compiling $(subst ../,,$<) ...) -# @$(compiler) $(ruby.flags) $(flags) $(flags.deps) -c $< $(call obj,$@) - -#ruby.verbose: -# $(info ruby Drivers:) -# $(foreach n,$(ruby),$(info $([space]) $n)) +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${ruby_SOURCES}) diff --git a/ruby/audio/sdl.cpp b/ruby/audio/sdl.cpp index d2992001f7..b0671f963f 100644 --- a/ruby/audio/sdl.cpp +++ b/ruby/audio/sdl.cpp @@ -1,8 +1,4 @@ -#if defined(MACOS_COMPILED_SDL) -#include "SDL.h" -#else #include -#endif struct AudioSDL : AudioDriver { AudioSDL& self = *this; diff --git a/ruby/cmake/os-freebsd.cmake b/ruby/cmake/os-freebsd.cmake new file mode 100644 index 0000000000..ef4ca14ead --- /dev/null +++ b/ruby/cmake/os-freebsd.cmake @@ -0,0 +1,30 @@ +target_sources( + ruby + PRIVATE # cmake-format: sortable + video/glx.cpp +) + +target_sources( + ruby + PRIVATE # cmake-format: sortable + audio/oss.cpp + audio/alsa.cpp + audio/openal.cpp + audio/sdl.cpp + audio/pulseaudio.cpp + audio/pulseaudio-simple.cpp + audio/ao.cpp +) + +target_sources( + ruby + PRIVATE # cmake-format: sortable + input/xlib.cpp + input/sdl.cpp + input/mouse/xlib.cpp + input/keyboard/xlib.cpp + input/joypad/sdl.cpp + input/joypad/udev.cpp + input/joypad/uhid.cpp + input/joypad/xinput.cpp +) diff --git a/ruby/cmake/os-linux.cmake b/ruby/cmake/os-linux.cmake new file mode 100644 index 0000000000..fa1a302cb2 --- /dev/null +++ b/ruby/cmake/os-linux.cmake @@ -0,0 +1,90 @@ +target_sources( + ruby + PRIVATE # cmake-format: sortable + video/glx.cpp +) + +target_sources( + ruby + PRIVATE # cmake-format: sortable + audio/oss.cpp + audio/alsa.cpp + audio/openal.cpp + audio/sdl.cpp + audio/pulseaudio.cpp + audio/pulseaudio-simple.cpp + audio/ao.cpp +) + +target_sources( + ruby + PRIVATE # cmake-format: sortable + input/xlib.cpp + input/sdl.cpp + input/mouse/xlib.cpp + input/keyboard/xlib.cpp + input/joypad/sdl.cpp + input/joypad/udev.cpp + input/joypad/uhid.cpp + input/joypad/xinput.cpp +) + +find_package(X11 REQUIRED) +find_package(OpenGL REQUIRED) + +target_link_libraries(ruby PRIVATE X11::Xrandr OpenGL::GLX) + +target_enable_feature(ruby "GLX OpenGL video driver" VIDEO_GLX) +target_enable_feature(ruby "Xlib input driver" INPUT_XLIB) + +find_package(OpenAL) +find_package(librashader) +find_package(SDL) +find_package(OSS) +find_package(ALSA) +find_package(PulseAudio) +find_package(AO) + +if(OpenAL_FOUND) + target_enable_feature(ruby "OpenAL audio driver" AUDIO_OPENAL) +endif() + +if(librashader_FOUND AND ARES_ENABLE_LIBRASHADER) + target_enable_feature(ruby "librashader OpenGL runtime" LIBRA_RUNTIME_OPENGL) +else() + # continue to define the runtime so openGL compiles + target_compile_definitions(ruby PRIVATE LIBRA_RUNTIME_OPENGL) +endif() + +if(OSS_FOUND) + target_enable_feature(ruby "OSS audio driver" AUDIO_OSS) +endif() + +if(ALSA_FOUND) + target_enable_feature(ruby "ALSA audio driver" AUDIO_ALSA) +endif() + +if(PulseAudio_FOUND) + target_enable_feature(ruby "PulseAudio audio driver" AUDIO_PULSEAUDIO) +endif() + +if(AO_FOUND) + target_enable_feature(ruby "ao audio driver" AUDIO_AO) +endif() + +if(SDL_FOUND) + target_enable_feature(ruby "SDL input driver" INPUT_SDL) + target_enable_feature(ruby "SDL audio driver" AUDIO_SDL) +endif() + +target_link_libraries( + ruby + PRIVATE + $<$:SDL::SDL> + $<$:OpenAL::OpenAL> + $<$:librashader::librashader> + $<$:OSS::OSS> + $<$:ALSA::ALSA> + $<$:pulse> + $<$:AO::AO> +) diff --git a/ruby/cmake/os-macos.cmake b/ruby/cmake/os-macos.cmake new file mode 100644 index 0000000000..b8b7d2d1a1 --- /dev/null +++ b/ruby/cmake/os-macos.cmake @@ -0,0 +1,64 @@ +find_package(SDL) +find_package(librashader) + +target_sources( + ruby + PRIVATE video/cgl.cpp video/metal/metal.cpp video/metal/metal.hpp video/metal/Shaders.metal video/metal/ShaderTypes.h +) + +target_sources(ruby PRIVATE audio/openal.cpp audio/sdl.cpp) + +target_sources( + ruby + PRIVATE + input/quartz.cpp + input/keyboard/quartz.cpp + input/sdl.cpp + input/mouse/nsmouse.cpp + input/joypad/iokit.cpp + input/joypad/sdl.cpp +) + +target_sources(ruby PRIVATE cmake/os-macos.cmake ruby.mm ruby.cpp) + +target_link_libraries( + ruby + PRIVATE + "$" + "$" + "$" + "$" + "$" + "$" + "$" + $<$:SDL::SDL> + $<$:librashader::librashader> +) + +target_enable_feature(ruby "OpenGL video driver" VIDEO_CGL) +target_enable_feature(ruby "Metal video driver" VIDEO_METAL) +target_enable_feature(ruby "OpenAL audio driver" AUDIO_OPENAL) +if(SDL_FOUND) + target_enable_feature(ruby "SDL input driver" INPUT_SDL) + target_enable_feature(ruby "SDL audio driver" AUDIO_SDL) +endif() +if(librashader_FOUND AND ARES_ENABLE_LIBRASHADER) + target_enable_feature(ruby "librashader OpenGL runtime" LIBRA_RUNTIME_OPENGL) + target_enable_feature(ruby "librashader Metal runtime" LIBRA_RUNTIME_METAL) +else() + target_compile_definitions(ruby PRIVATE LIBRA_RUNTIME_OPENGL LIBRA_RUNTIME_METAL) +endif() +target_enable_feature(ruby "Quartz input driver" INPUT_QUARTZ) + +target_compile_definitions(ruby PUBLIC PLATFORM_MACOS) + +add_custom_command( + TARGET ruby + POST_BUILD + COMMAND $<$:xcrun> + ARGS -sdk macosx metal -o shaders.ir -c -gline-tables-only -frecord-sources Shaders.metal + COMMAND $<$:xcrun> + ARGS -sdk macosx metallib -o shaders.metallib shaders.ir + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/video/metal + COMMENT "Compiling debug .metallib for Metal debugging" +) diff --git a/ruby/cmake/os-windows.cmake b/ruby/cmake/os-windows.cmake new file mode 100644 index 0000000000..dfe4f21431 --- /dev/null +++ b/ruby/cmake/os-windows.cmake @@ -0,0 +1,71 @@ +target_sources( + ruby + PRIVATE # cmake-format: sortable + video/direct3d9.cpp + video/wgl.cpp +) + +target_sources( + ruby + PRIVATE # cmake-format: sortable + audio/wasapi.cpp + audio/xaudio2.cpp + audio/xaudio2.hpp + audio/directsound.cpp + audio/waveout.cpp + audio/sdl.cpp +) + +target_sources( + ruby + PRIVATE # cmake-format: sortable + input/sdl.cpp + input/shared/rawinput.cpp + input/windows.cpp + input/keyboard/rawinput.cpp + input/mouse/rawinput.cpp + input/joypad/directinput.cpp +) + +find_package(SDL) +find_package(librashader) +find_package(OpenAL) + +target_enable_feature(ruby "Direct3D 9 video driver" VIDEO_DIRECT3D9) +target_enable_feature(ruby "OpenGL video driver" VIDEO_WGL) +target_enable_feature(ruby "WASAPI audio driver" AUDIO_WASAPI) +target_enable_feature(ruby "XAudio2 audio driver" AUDIO_XAUDIO2) +target_enable_feature(ruby "DirectSound audio driver" AUDIO_DIRECTSOUND) +target_enable_feature(ruby "waveOut audio driver" AUDIO_WAVEOUT) +target_enable_feature(ruby "Windows input driver (XInput/DirectInput)" INPUT_WINDOWS) + +if(SDL_FOUND) + target_enable_feature(ruby "SDL input driver" INPUT_SDL) +endif() + +if(OpenAL_FOUND) + target_enable_feature(ruby "OpenAL audio driver" AUDIO_OPENAL) +endif() + +if(librashader_FOUND AND ARES_ENABLE_LIBRASHADER) + target_enable_feature(ruby "librashader OpenGL runtime" LIBRA_RUNTIME_OPENGL) +else() + target_compile_definitions(ruby PRIVATE LIBRA_RUNTIME_OPENGL) +endif() + +target_link_libraries( + ruby + PRIVATE + $<$:OpenAL::OpenAL> + $<$:librashader::librashader> + $<$:SDL::SDL> + d3d9 + opengl32 + dsound + uuid + avrt + winmm + ole32 + dinput8 + dxguid +) diff --git a/ruby/input/sdl.cpp b/ruby/input/sdl.cpp index ff23b8e881..44d3e30744 100644 --- a/ruby/input/sdl.cpp +++ b/ruby/input/sdl.cpp @@ -1,8 +1,4 @@ -#if defined(MACOS_COMPILED_SDL) -#include "SDL.h" -#else #include -#endif #if defined(PLATFORM_WINDOWS) #include "shared/rawinput.cpp" diff --git a/ruby/ruby.mm b/ruby/ruby.mm new file mode 100644 index 0000000000..a013f357f4 --- /dev/null +++ b/ruby/ruby.mm @@ -0,0 +1 @@ +#include "ruby.cpp" diff --git a/ruby/video/metal/metal.hpp b/ruby/video/metal/metal.hpp index 030c283a25..ed04f065ad 100644 --- a/ruby/video/metal/metal.hpp +++ b/ruby/video/metal/metal.hpp @@ -6,9 +6,9 @@ // #include -#include +#include -#include "librashader_ld.h" +#include #include "ShaderTypes.h" struct Metal; diff --git a/ruby/video/opengl/opengl.hpp b/ruby/video/opengl/opengl.hpp index 15e90bbc7b..5e75e393f6 100644 --- a/ruby/video/opengl/opengl.hpp +++ b/ruby/video/opengl/opengl.hpp @@ -16,9 +16,10 @@ #error "ruby::OpenGL3: unsupported platform" #endif +#include + #include "bind.hpp" #include "utility.hpp" -#include "librashader_ld.h" struct OpenGL; diff --git a/ruby/video/opengl/utility.hpp b/ruby/video/opengl/utility.hpp index e6a6e90c14..5c275a50c3 100644 --- a/ruby/video/opengl/utility.hpp +++ b/ruby/video/opengl/utility.hpp @@ -1,4 +1,4 @@ static auto glrSize(u32 size) -> u32 { return size; -//return bit::round(size); //return nearest power of two + //return bit::round(size); //return nearest power of two } diff --git a/ruby/video/video.cpp b/ruby/video/video.cpp index 2c24fdde81..b9624b9b20 100644 --- a/ruby/video/video.cpp +++ b/ruby/video/video.cpp @@ -314,7 +314,7 @@ auto Video::hasMonitors() -> vector { } else { //getting the name of the monitor on macOS: "Think Different" auto screenDictionary = [screen deviceDescription]; - auto screenID = [screenDictionary objectForKey:@"NSScreenNumber"]; + id screenID = [screenDictionary objectForKey:@"NSScreenNumber"]; auto displayID = [screenID unsignedIntValue]; CFUUIDRef displayUUID = CGDisplayCreateUUIDFromDisplayID(displayID); io_service_t displayPort = CGDisplayGetDisplayIDFromUUID(displayUUID); diff --git a/tests/i8080/CMakeLists.txt b/tests/i8080/CMakeLists.txt index d84f1daca5..4185394d46 100644 --- a/tests/i8080/CMakeLists.txt +++ b/tests/i8080/CMakeLists.txt @@ -3,6 +3,8 @@ add_executable(i8080 ../../ares/component/processor/i8080/i8080.cpp ) -target_link_libraries(i8080 PRIVATE nall ares) +target_include_directories(i8080 PRIVATE ${CMAKE_SOURCE_DIR}) -nall_set_properties(i8080) +target_link_libraries(i8080 PRIVATE nall ares) +set_target_properties(i8080 PROPERTIES FOLDER tests PREFIX "") +ares_configure_executable(i8080) diff --git a/thirdparty/CMakeLists.txt b/thirdparty/CMakeLists.txt index d6f9e8c17a..9945c0afc6 100644 --- a/thirdparty/CMakeLists.txt +++ b/thirdparty/CMakeLists.txt @@ -1,9 +1,3 @@ -add_library(thirdparty INTERFACE) - -target_include_directories(thirdparty INTERFACE - ../thirdparty -) - add_library(sljit STATIC sljit/sljit_src/sljitLir.c ) @@ -11,50 +5,49 @@ add_library(sljit STATIC target_include_directories(sljit PUBLIC ../thirdparty) target_compile_definitions(sljit PUBLIC SLJIT_HAVE_CONFIG_PRE=1 SLJIT_HAVE_CONFIG_POST=1) -add_library(libchdr STATIC - libchdr/src/libchdr_bitstream.c - libchdr/src/libchdr_cdrom.c - libchdr/src/libchdr_chd.c - libchdr/src/libchdr_flac.c - libchdr/src/libchdr_huffman.c +# lzma +add_subdirectory(libchdr/deps/lzma-24.05 EXCLUDE_FROM_ALL) + list(APPEND CHDR_LIBS lzma) + list(APPEND CHDR_INCLUDES lzma) - libchdr/deps/lzma-19.00/src/Alloc.c - libchdr/deps/lzma-19.00/src/Bra86.c - libchdr/deps/lzma-19.00/src/BraIA64.c - libchdr/deps/lzma-19.00/src/CpuArch.c - libchdr/deps/lzma-19.00/src/Delta.c - libchdr/deps/lzma-19.00/src/LzFind.c - libchdr/deps/lzma-19.00/src/Lzma86Dec.c - libchdr/deps/lzma-19.00/src/LzmaDec.c - libchdr/deps/lzma-19.00/src/LzmaEnc.c - libchdr/deps/lzma-19.00/src/Sort.c +# zlib +if (WITH_SYSTEM_ZLIB) + find_package(ZLIB REQUIRED) + list(APPEND PLATFORM_LIBS ZLIB::ZLIB) +else() + option(ZLIB_BUILD_EXAMPLES "Enable Zlib Examples" OFF) + add_subdirectory(libchdr/deps/zlib-1.3.1 EXCLUDE_FROM_ALL) + set_target_properties(zlibstatic PROPERTIES POSITION_INDEPENDENT_CODE ON FOLDER thirdparty PREFIX "") + list(APPEND CHDR_LIBS zlibstatic) +endif() - libchdr/deps/zlib-1.2.13/adler32.c - libchdr/deps/zlib-1.2.13/compress.c - libchdr/deps/zlib-1.2.13/crc32.c - libchdr/deps/zlib-1.2.13/deflate.c - libchdr/deps/zlib-1.2.13/infback.c - libchdr/deps/zlib-1.2.13/inffast.c - libchdr/deps/zlib-1.2.13/inflate.c - libchdr/deps/zlib-1.2.13/inftrees.c - libchdr/deps/zlib-1.2.13/trees.c - libchdr/deps/zlib-1.2.13/uncompr.c - libchdr/deps/zlib-1.2.13/zutil.c -) +# zstd +option(ZSTD_BUILD_SHARED "BUILD SHARED LIBRARIES" OFF) +option(ZSTD_BUILD_PROGRAMS "BUILD PROGRAMS" OFF) +add_subdirectory(libchdr/deps/zstd-1.5.6/build/cmake EXCLUDE_FROM_ALL) +list(APPEND CHDR_LIBS libzstd_static) +#-------------------------------------------------- +# chdr +#-------------------------------------------------- -target_include_directories(libchdr - PUBLIC ../thirdparty/libchdr/include - PRIVATE - ../thirdparty/libchdr/deps/lzma-19.00/include - ../thirdparty/libchdr/deps/zlib-1.2.13 +set(CHDR_SOURCES + libchdr/src/libchdr_bitstream.c + libchdr/src/libchdr_cdrom.c + libchdr/src/libchdr_chd.c + libchdr/src/libchdr_flac.c + libchdr/src/libchdr_huffman.c ) -target_compile_definitions(libchdr PRIVATE - _7ZIP_ST - # instruct glibc to declare fseeko/ftello - _LARGEFILE_SOURCE +list(APPEND CHDR_INCLUDES ${CMAKE_CURRENT_BINARY_DIR}/libchdr/include) + +add_library(chdr-static STATIC ${CHDR_SOURCES}) +target_include_directories(chdr-static PUBLIC ${CHDR_INCLUDES} PUBLIC libchdr/include) +target_link_libraries(chdr-static PRIVATE ${CHDR_LIBS} ${PLATFORM_LIBS}) +target_compile_options(chdr-static PRIVATE + $<$:-Wno-unreachable-code -Wno-unused-function> ) + add_library(tzxfile STATIC TZXFile/TZXAudioGenerator.cpp TZXFile/TZXBlock.cpp @@ -96,3 +89,13 @@ add_library(ymfm STATIC target_include_directories(ymfm PUBLIC ../thirdparty/ymfm/src ) + +target_compile_options(ymfm PRIVATE $<$:-Wno-unreachable-code>) + +set_target_properties(ymfm PROPERTIES FOLDER thirdparty PREFIX "") +set_target_properties(tzxfile PROPERTIES FOLDER thirdparty PREFIX "") +set_target_properties(chdr-static PROPERTIES FOLDER thirdparty PREFIX "") +set_target_properties(sljit PROPERTIES FOLDER thirdparty PREFIX "") +set_target_properties(zlib PROPERTIES FOLDER thirdparty PREFIX "") +set_target_properties(lzma PROPERTIES FOLDER thirdparty PREFIX "") +set_target_properties(libzstd_static PROPERTIES FOLDER thirdparty PREFIX "") diff --git a/thirdparty/libchdr/deps/zlib-1.3.1/zconf.h b/thirdparty/libchdr/deps/zlib-1.3.1/zconf.h.included similarity index 100% rename from thirdparty/libchdr/deps/zlib-1.3.1/zconf.h rename to thirdparty/libchdr/deps/zlib-1.3.1/zconf.h.included diff --git a/tools/genius/CMakeLists.txt b/tools/genius/CMakeLists.txt index 6b43ea832e..edbcbfe5cb 100644 --- a/tools/genius/CMakeLists.txt +++ b/tools/genius/CMakeLists.txt @@ -1,3 +1,22 @@ add_executable(genius genius.cpp) -target_link_libraries(genius PRIVATE nall hiro) +target_sources(genius PRIVATE genius.hpp) + +target_enable_subproject(genius "genius (database editor)") + +target_include_directories(genius PRIVATE ${CMAKE_SOURCE_DIR}) + +if(OS_WINDOWS) + include(cmake/os-windows.cmake) +elseif(OS_MACOS) + include(cmake/os-macos.cmake) +elseif(OS_LINUX) + include(cmake/os-linux.cmake) +elseif(OS_FREEBSD OR OS_OPENBSD) + include(cmake/os-freebsd.cmake) +endif() + +target_link_libraries(genius PRIVATE nall ares::hiro) + +ares_configure_executable(genius) +set_target_properties(genius PROPERTIES FOLDER tools PREFIX "") diff --git a/tools/genius/cmake/macos/Info.plist.in b/tools/genius/cmake/macos/Info.plist.in new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/genius/cmake/macos/entitlements.plist b/tools/genius/cmake/macos/entitlements.plist new file mode 100644 index 0000000000..6883e4a27b --- /dev/null +++ b/tools/genius/cmake/macos/entitlements.plist @@ -0,0 +1,10 @@ + + + + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.disable-library-validation + + + diff --git a/tools/genius/cmake/os-linux.cmake b/tools/genius/cmake/os-linux.cmake new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/genius/cmake/os-macos.cmake b/tools/genius/cmake/os-macos.cmake new file mode 100644 index 0000000000..18d0201cfd --- /dev/null +++ b/tools/genius/cmake/os-macos.cmake @@ -0,0 +1,35 @@ +target_link_libraries( + genius + PRIVATE # cmake-format: sortable + "$" +) + +set_target_properties( + genius + PROPERTIES + OUTPUT_NAME genius + MACOSX_BUNDLE TRUE + MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/data/genius.plist" + XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY YES + XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY YES + XCODE_EMBED_PLUGINS_REMOVE_HEADERS_ON_COPY YES + XCODE_EMBED_PLUGINS_CODE_SIGN_ON_COPY YES +) + +# cmake-format: off +set_target_xcode_properties( + genius + PROPERTIES PRODUCT_BUNDLE_IDENTIFIER com.ares-emulator.genius + PRODUCT_NAME genius + ASSETCATALOG_COMPILER_APPICON_NAME AppIcon + CURRENT_PROJECT_VERSION ${ARES_BUILD_NUMBER} + MARKETING_VERSION ${ARES_VERSION} + GENERATE_INFOPLIST_FILE YES + COPY_PHASE_STRIP NO + CLANG_ENABLE_OBJC_ARC YES + SKIP_INSTALL NO + INSTALL_PATH "$(LOCAL_APPS_DIR)" + INFOPLIST_KEY_CFBundleDisplayName "genius" + INFOPLIST_KEY_NSHumanReadableCopyright "(c) 2004-${CURRENT_YEAR} ares team, Near et. al." +) +# cmake-format: on diff --git a/tools/mame2bml/CMakeLists.txt b/tools/mame2bml/CMakeLists.txt index 9f9cbf1501..4d61b91562 100644 --- a/tools/mame2bml/CMakeLists.txt +++ b/tools/mame2bml/CMakeLists.txt @@ -1,5 +1,8 @@ add_executable(mame2bml mame2bml.cpp) -target_link_libraries(mame2bml PRIVATE nall) +target_include_directories(mame2bml PRIVATE ${CMAKE_SOURCE_DIR}) -nall_set_properties(mame2bml) +target_link_libraries(mame2bml PRIVATE nall) +set_target_properties(mame2bml PROPERTIES FOLDER tools PREFIX "") +target_enable_subproject(mame2bml "mame2bml (MAME manifest converter)") +ares_configure_executable(mame2bml) diff --git a/tools/sourcery/CMakeLists.txt b/tools/sourcery/CMakeLists.txt index 4a2b580388..1450d96df0 100644 --- a/tools/sourcery/CMakeLists.txt +++ b/tools/sourcery/CMakeLists.txt @@ -1,5 +1,11 @@ add_executable(sourcery sourcery.cpp) -target_link_libraries(sourcery PRIVATE nall) +target_include_directories(sourcery PRIVATE ${CMAKE_SOURCE_DIR}) -nall_set_properties(sourcery) +target_link_libraries(sourcery PRIVATE nall "$<$:$>") + +ares_configure_executable(sourcery) + +target_enable_subproject(sourcery "sourcery (resource compiler)") + +set_target_properties(sourcery PROPERTIES FOLDER tools PREFIX "")