From 120e1006d04ed62e011b2342842ac6c54f0673c3 Mon Sep 17 00:00:00 2001 From: Arves100 Date: Tue, 18 Jun 2019 21:42:25 +0200 Subject: [PATCH] All: Microsoft Visual C++ compatibility code --- CMakeLists.txt | 20 +++- include/mgba/core/version.h | 16 +-- include/mgba/internal/gba/input.h | 3 +- src/core/version.c.in | 14 +-- src/gba/input.c | 2 +- src/platform/cmake/FindSDL2.cmake | 181 +++++++++++++++++++++++++++++ src/platform/cmake/Findepoxy.cmake | 14 +++ src/platform/sdl/CMakeLists.txt | 7 ++ src/platform/sdl/main.c | 2 +- 9 files changed, 236 insertions(+), 23 deletions(-) create mode 100644 src/platform/cmake/FindSDL2.cmake create mode 100644 src/platform/cmake/Findepoxy.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 50ec9fc3e..8b3451987 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,6 @@ cmake_minimum_required(VERSION 3.1) +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/src/platform/cmake/") + if(POLICY CMP0025) cmake_policy(SET CMP0025 NEW) endif() @@ -245,16 +247,18 @@ endif() if(WIN32) set(WIN32_VERSION "${LIB_VERSION_MAJOR},${LIB_VERSION_MINOR},${LIB_VERSION_PATCH}") add_definitions(-D_WIN32_WINNT=0x0600) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -municode") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -municode") + if(MSVC) + add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN) + set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) + add_definitions(-D_UNICODE -DUNICODE) + else() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -municode") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -municode") + endif() list(APPEND OS_LIB ws2_32 shlwapi) list(APPEND CORE_VFS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/windows/vfs-w32.c) file(GLOB OS_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/windows/*.c) source_group("Windows-specific code" FILES ${OS_SRC}) - if(MSVC) - add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN) - set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE) - endif() elseif(UNIX) set(USE_PTHREADS ON) @@ -944,6 +948,10 @@ if(NOT SKIP_LIBRARY) add_library(${BINARY_NAME} STATIC ${SRC}) endif() + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/mgba-util) + include(GenerateExportHeader) + generate_export_header(${BINARY_NAME} BASE_NAME mgba STATIC_DEFINE BUILD_STATIC EXPORT_FILE_NAME ${CMAKE_CURRENT_BINARY_DIR}/include/mgba-util/dllexports.h) + target_include_directories(${BINARY_NAME} BEFORE PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}/include) set_target_properties(${BINARY_NAME} PROPERTIES VERSION ${LIB_VERSION_STRING} SOVERSION ${LIB_VERSION_ABI} COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}" COMPILE_OPTIONS "${FEATURE_FLAGS}") add_dependencies(${BINARY_NAME} version-info) diff --git a/include/mgba/core/version.h b/include/mgba/core/version.h index 47086618f..b261ab6d3 100644 --- a/include/mgba/core/version.h +++ b/include/mgba/core/version.h @@ -10,13 +10,15 @@ extern "C" { #endif -extern const char* const gitCommit; -extern const char* const gitCommitShort; -extern const char* const gitBranch; -extern const int gitRevision; -extern const char* const binaryName; -extern const char* const projectName; -extern const char* const projectVersion; +#include + +extern MGBA_EXPORT const char* const gitCommit; +extern MGBA_EXPORT const char* const gitCommitShort; +extern MGBA_EXPORT const char* const gitBranch; +extern MGBA_EXPORT const int gitRevision; +extern MGBA_EXPORT const char* const binaryName; +extern MGBA_EXPORT const char* const projectName; +extern MGBA_EXPORT const char* const projectVersion; #ifdef __cplusplus } diff --git a/include/mgba/internal/gba/input.h b/include/mgba/internal/gba/input.h index 03cb8b5e0..179e935f4 100644 --- a/include/mgba/internal/gba/input.h +++ b/include/mgba/internal/gba/input.h @@ -7,12 +7,13 @@ #define GBA_INPUT_H #include +#include CXX_GUARD_START #include -extern const struct mInputPlatformInfo GBAInputInfo; +extern MGBA_EXPORT const struct mInputPlatformInfo GBAInputInfo; enum GBAKey { GBA_KEY_A = 0, diff --git a/src/core/version.c.in b/src/core/version.c.in index b8c87fb70..00028e4c5 100644 --- a/src/core/version.c.in +++ b/src/core/version.c.in @@ -5,10 +5,10 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include -const char* const gitCommit = "${GIT_COMMIT}"; -const char* const gitCommitShort = "${GIT_COMMIT_SHORT}"; -const char* const gitBranch = "${GIT_BRANCH}"; -const int gitRevision = ${GIT_REV}; -const char* const binaryName = "${BINARY_NAME}"; -const char* const projectName = "${PROJECT_NAME}"; -const char* const projectVersion = "${VERSION_STRING}"; +MGBA_EXPORT const char* const gitCommit = "${GIT_COMMIT}"; +MGBA_EXPORT const char* const gitCommitShort = "${GIT_COMMIT_SHORT}"; +MGBA_EXPORT const char* const gitBranch = "${GIT_BRANCH}"; +MGBA_EXPORT const int gitRevision = ${GIT_REV}; +MGBA_EXPORT const char* const binaryName = "${BINARY_NAME}"; +MGBA_EXPORT const char* const projectName = "${PROJECT_NAME}"; +MGBA_EXPORT const char* const projectVersion = "${VERSION_STRING}"; diff --git a/src/gba/input.c b/src/gba/input.c index 8b24dc3f2..4c7d6b09a 100644 --- a/src/gba/input.c +++ b/src/gba/input.c @@ -7,7 +7,7 @@ #include -const struct mInputPlatformInfo GBAInputInfo = { +MGBA_EXPORT const struct mInputPlatformInfo GBAInputInfo = { .platformName = "gba", .keyId = (const char*[]) { "A", diff --git a/src/platform/cmake/FindSDL2.cmake b/src/platform/cmake/FindSDL2.cmake new file mode 100644 index 000000000..091faba16 --- /dev/null +++ b/src/platform/cmake/FindSDL2.cmake @@ -0,0 +1,181 @@ +# SDL2_LIBRARY, the name of the library to link against +# SDL2_FOUND, if false, do not try to link to SDL2 +# SDL2_INCLUDE_DIR, where to find SDL.h +# +# This module responds to the the flag: +# SDL2_BUILDING_LIBRARY +# If this is defined, then no SDL2main will be linked in because +# only applications need main(). +# Otherwise, it is assumed you are building an application and this +# module will attempt to locate and set the the proper link flags +# as part of the returned SDL2_LIBRARY variable. +# +# Don't forget to include SDLmain.h and SDLmain.m your project for the +# OS X framework based version. (Other versions link to -lSDL2main which +# this module will try to find on your behalf.) Also for OS X, this +# module will automatically add the -framework Cocoa on your behalf. +# +# +# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration +# and no SDL2_LIBRARY, it means CMake did not find your SDL2 library +# (SDL2.dll, libsdl2.so, SDL2.framework, etc). +# Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again. +# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value +# as appropriate. These values are used to generate the final SDL2_LIBRARY +# variable, but when these values are unset, SDL2_LIBRARY does not get created. +# +# +# $SDL2DIR is an environment variable that would +# correspond to the ./configure --prefix=$SDL2DIR +# used in building SDL2. +# l.e.galup 9-20-02 +# +# Modified by Eric Wing. +# Added code to assist with automated building by using environmental variables +# and providing a more controlled/consistent search behavior. +# Added new modifications to recognize OS X frameworks and +# additional Unix paths (FreeBSD, etc). +# Also corrected the header search path to follow "proper" SDL guidelines. +# Added a search for SDL2main which is needed by some platforms. +# Added a search for threads which is needed by some platforms. +# Added needed compile switches for MinGW. +# +# On OSX, this will prefer the Framework version (if found) over others. +# People will have to manually change the cache values of +# SDL2_LIBRARY to override this selection or set the CMake environment +# CMAKE_INCLUDE_PATH to modify the search paths. +# +# Note that the header path has changed from SDL2/SDL.h to just SDL.h +# This needed to change because "proper" SDL convention +# is #include "SDL.h", not . This is done for portability +# reasons because not all systems place things in SDL2/ (see FreeBSD). +# +#========================================================================= +# +# Copyright (c) 1993-2015 Ken Martin, Will Schroeder, Bill Lorensen +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names +# of any contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#========================================================================= +# +SET(SDL2_SEARCH_PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local + /usr + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt + ${SDL2_PATH} +) + +FIND_PATH(SDL2_INCLUDE_DIR SDL.h + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES include/SDL2 include + PATHS ${SDL2_SEARCH_PATHS} ${SDL2_LIBRARY_TEMP}/../.. +) + +FIND_LIBRARY(SDL2_LIBRARY_TEMP + NAMES SDL2 + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES lib64 lib + PATHS ${SDL2_SEARCH_PATHS} ${SDL2_INCLUDE_DIR}/../.. +) + +IF(NOT SDL2_BUILDING_LIBRARY) + IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") + # Non-OS X framework versions expect you to also dynamically link to + # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms + # seem to provide SDL2main for compatibility even though they don't + # necessarily need it. + FIND_LIBRARY(SDL2MAIN_LIBRARY + NAMES SDL2main + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES lib64 lib + PATHS ${SDL2_SEARCH_PATHS} + ) + ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") +ENDIF(NOT SDL2_BUILDING_LIBRARY) + +# SDL2 may require threads on your system. +# The Apple build may not need an explicit flag because one of the +# frameworks may already provide it. +# But for non-OSX systems, I will use the CMake Threads package. +IF(NOT APPLE) + FIND_PACKAGE(Threads) +ENDIF(NOT APPLE) + +# MinGW needs an additional library, mwindows +# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows +# (Actually on second look, I think it only needs one of the m* libraries.) +IF(MINGW) + SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW") +ENDIF(MINGW) + +IF(SDL2_LIBRARY_TEMP) + # For SDL2main + IF(NOT SDL2_BUILDING_LIBRARY) + IF(SDL2MAIN_LIBRARY) + SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP}) + ENDIF(SDL2MAIN_LIBRARY) + ENDIF(NOT SDL2_BUILDING_LIBRARY) + + # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. + # CMake doesn't display the -framework Cocoa string in the UI even + # though it actually is there if I modify a pre-used variable. + # I think it has something to do with the CACHE STRING. + # So I use a temporary variable until the end so I can set the + # "real" variable in one-shot. + IF(APPLE) + SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa") + ENDIF(APPLE) + + # For threads, as mentioned Apple doesn't need this. + # In fact, there seems to be a problem if I used the Threads package + # and try using this line, so I'm just skipping it entirely for OS X. + IF(NOT APPLE) + SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT}) + ENDIF(NOT APPLE) + + # For MinGW library + IF(MINGW) + SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP}) + ENDIF(MINGW) + + # Set the final string here so the GUI reflects the final state. + SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found") + # Set the temp variable to INTERNAL so it is not seen in the CMake GUI + SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "") +ENDIF(SDL2_LIBRARY_TEMP) + +INCLUDE(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) diff --git a/src/platform/cmake/Findepoxy.cmake b/src/platform/cmake/Findepoxy.cmake new file mode 100644 index 000000000..1f56add79 --- /dev/null +++ b/src/platform/cmake/Findepoxy.cmake @@ -0,0 +1,14 @@ +find_path(EPOXY_INCLUDE_DIRS NAMES epoxy/gl.h PATH_SUFFIX include) +find_library(EPOXY_LIBRARIES NAMES epoxy_0 PATH_SUFFIX lib) + +if (NOT EPOXY_LIBRARIES) + find_library(EPOXY_LIBRARIES NAMES epoxy PATH_SUFFIX lib) +endif() + +if(EPOXY_LIBRARIES AND EPOXY_INCLUDE_DIRS) + set(epoxy_FOUND TRUE) +endif() + +if (WIN32 AND NOT epoxy_FOUND) + message(FATAL_ERROR "Windows requires epoxy module!") +endif() diff --git a/src/platform/sdl/CMakeLists.txt b/src/platform/sdl/CMakeLists.txt index 36e73b686..6f3bdf5ed 100644 --- a/src/platform/sdl/CMakeLists.txt +++ b/src/platform/sdl/CMakeLists.txt @@ -3,6 +3,10 @@ set(SDL_VERSION "2" CACHE STRING "Version of SDL to use (1.2 or 2)") if (SDL_VERSION EQUAL "2") include(FindPkgConfig) pkg_search_module(SDL2 sdl2) + if (NOT SDL2_FOUND) + find_package(SDL2) + endif() + if (SDL2_FOUND) set(SDL_INCLUDE_DIR ${SDL2_INCLUDE_DIRS}) set(SDL_LIBRARY ${SDL2_LIBRARIES}) @@ -105,6 +109,9 @@ target_link_libraries(${BINARY_NAME}-sdl ${BINARY_NAME} ${PLATFORM_LIBRARY} ${OP if(NOT WIN32) set_target_properties(${BINARY_NAME}-sdl PROPERTIES OUTPUT_NAME ${BINARY_NAME}) endif() +if (WIN32 AND MSVC) + set_target_properties(${BINARY_NAME}-sdl PROPERTIES LINK_FLAGS "/SUBSYSTEM:CONSOLE") +endif() install(TARGETS ${BINARY_NAME}-sdl DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${BINARY_NAME}-sdl) if(UNIX) install(FILES ${CMAKE_SOURCE_DIR}/doc/mgba.6 DESTINATION ${MANDIR}/man6 COMPONENT ${BINARY_NAME}-sdl) diff --git a/src/platform/sdl/main.c b/src/platform/sdl/main.c index 0bb340c23..deda42506 100644 --- a/src/platform/sdl/main.c +++ b/src/platform/sdl/main.c @@ -178,7 +178,7 @@ int main(int argc, char** argv) { return ret; } -#ifdef _WIN32 +#if defined(_WIN32) && !defined(_UNICODE) #include int wmain(int argc, wchar_t** argv) {