浏览代码

Merge pull request #1204 from IvanSavenko/single_process_app_upgrade

[1.2] Single process app support for platforms other than ios
Andrii Danylchenko 2 年之前
父节点
当前提交
8c07ddbae0

+ 3 - 1
AI/EmptyAI/StdInc.h

@@ -4,4 +4,6 @@
 
 // This header should be treated as a pre compiled header file(PCH) in the compiler building settings.
 
-// Here you can add specific libraries and macros which are specific to this project.
+// Here you can add specific libraries and macros which are specific to this project.
+
+VCMI_LIB_USING_NAMESPACE

+ 16 - 13
CMakeLists.txt

@@ -33,10 +33,6 @@ if(APPLE)
 	endif()
 endif()
 
-if(APPLE_IOS)
-	set(BUILD_SINGLE_APP 1)
-endif()
-
 ############################################
 #        User-provided options             #
 ############################################
@@ -64,6 +60,7 @@ endif(NOT ${CMAKE_VERSION} VERSION_LESS "3.16.0")
 option(ENABLE_GITVERSION "Enable Version.cpp with Git commit hash" ON)
 option(ENABLE_DEBUG_CONSOLE "Enable debug console for Windows builds" ON)
 option(ENABLE_MULTI_PROCESS_BUILDS "Enable /MP flag for MSVS solution" ON)
+option(ENABLE_SINGLE_APP_BUILD "Builds client and server as single executable" OFF)
 
 # Used for Snap packages and also useful for debugging
 if(NOT APPLE_IOS)
@@ -74,11 +71,20 @@ endif()
 set(PACKAGE_NAME_SUFFIX "" CACHE STRING "Suffix for CPack package name")
 set(PACKAGE_FILE_NAME "" CACHE STRING "Override for CPack package filename")
 
+if(APPLE_IOS AND NOT ENABLE_SINGLE_APP_BUILD)
+	set(ENABLE_SINGLE_APP_BUILD ON)
+endif()
+
 # ERM depends on LUA implicitly
 if(ENABLE_ERM AND NOT ENABLE_LUA)
 	set(ENABLE_LUA ON)
 endif()
 
+# We want to deploy assets into build directory for easier debugging without install
+if(NOT APPLE_IOS AND NOT COPY_CONFIG_ON_BUILD)
+	set(COPY_CONFIG_ON_BUILD OFF)
+endif()
+
 ############################################
 #        Miscellaneous options             #
 ############################################
@@ -162,8 +168,8 @@ set(CMAKE_XCODE_ATTRIBUTE_MARKETING_VERSION ${APP_SHORT_VERSION})
 set(CMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH NO)
 set(CMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH[variant=Debug] YES)
 
-if(BUILD_SINGLE_APP)
-	add_compile_definitions(SINGLE_PROCESS_APP=1)
+if(ENABLE_SINGLE_APP_BUILD)
+	add_definitions(-DSINGLE_PROCESS_APP=1)
 endif()
 
 if(APPLE_IOS)
@@ -274,7 +280,7 @@ if(NOT WIN32 AND NOT APPLE_IOS)
 endif()
 
 if(ENABLE_LUA)
-	add_compile_definitions(SCRIPTING_ENABLED=1)
+	add_definitions(-DSCRIPTING_ENABLED=1)
 endif()
 
 ############################################
@@ -426,13 +432,10 @@ if(APPLE_IOS)
 endif()
 
 include(VCMI_lib)
-if(BUILD_SINGLE_APP)
-	add_subdirectory(lib_client)
+add_subdirectory(lib)
+set(VCMI_LIB_TARGET vcmi)
+if(ENABLE_SINGLE_APP_BUILD)
 	add_subdirectory(lib_server)
-	set(VCMI_LIB_TARGET vcmi_lib_client)
-else()
-	add_subdirectory(lib)
-	set(VCMI_LIB_TARGET vcmi)
 endif()
 
 if(ENABLE_ERM)

+ 4 - 21
Global.h

@@ -15,18 +15,6 @@
 // Fixed width bool data type is important for serialization
 static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size.");
 
-#ifdef __GNUC__
-#  define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__)
-#endif
-
-#if !defined(__clang__) && defined(__GNUC__) && (GCC_VERSION < 470)
-#  error VCMI requires at least gcc-4.7.2 for successful compilation or clang-3.1. Please update your compiler
-#endif
-
-#if defined(__GNUC__) && (GCC_VERSION == 470 || GCC_VERSION == 471)
-#  error This GCC version has buggy std::array::at version and should not be used. Please update to 4.7.2 or later
-#endif
-
 /* ---------------------------------------------------------------------------- */
 /* Suppress some compiler warnings */
 /* ---------------------------------------------------------------------------- */
@@ -122,10 +110,6 @@ static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size.");
 #  define STRONG_INLINE inline
 #endif
 
-#define TO_STRING_HELPER(x) #x
-#define TO_STRING(x) TO_STRING_HELPER(x)
-#define LINE_IN_FILE __FILE__ ":" TO_STRING(__LINE__)
-
 #define _USE_MATH_DEFINES
 
 #include <cstdio>
@@ -233,7 +217,10 @@ typedef boost::lock_guard<boost::recursive_mutex> TLockGuardRec;
 /* ---------------------------------------------------------------------------- */
 // Import + Export macro declarations
 #ifdef VCMI_WINDOWS
-#  ifdef __GNUC__
+#ifdef VCMI_DLL_STATIC
+#    define DLL_IMPORT
+#    define DLL_EXPORT
+#elif defined(__GNUC__)
 #    define DLL_IMPORT __attribute__((dllimport))
 #    define DLL_EXPORT __attribute__((dllexport))
 #  else
@@ -503,9 +490,6 @@ namespace vstd
 		ptr = nullptr;
 	}
 
-#if _MSC_VER >= 1800
-	using std::make_unique;
-#else
 	template<typename T>
 	std::unique_ptr<T> make_unique()
 	{
@@ -531,7 +515,6 @@ namespace vstd
 	{
 		return std::unique_ptr<T>(new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2), std::forward<Arg3>(arg3), std::forward<Arg4>(arg4)));
 	}
-#endif
 
 	template <typename Container>
 	typename Container::const_reference circularAt(const Container &r, size_t index)

+ 1 - 1
client/CMakeLists.txt

@@ -263,7 +263,7 @@ elseif(APPLE_IOS)
 	set(CMAKE_EXE_LINKER_FLAGS "-Wl,-e,_client_main")
 endif()
 
-if(BUILD_SINGLE_APP)
+if(ENABLE_SINGLE_APP_BUILD)
 	target_link_libraries(vcmiclient PRIVATE vcmiserver)
 	if(ENABLE_LAUNCHER)
 		target_link_libraries(vcmiclient PRIVATE vcmilauncher)

+ 6 - 3
client/CServerHandler.cpp

@@ -25,12 +25,15 @@
 #include "../lib/CAndroidVMHelper.h"
 #elif defined(VCMI_IOS)
 #include "ios/utils.h"
-#include "../server/CVCMIServer.h"
-
 #include <dispatch/dispatch.h>
 #else
 #include "../lib/Interprocess.h"
 #endif
+
+#ifdef SINGLE_PROCESS_APP
+#include "../server/CVCMIServer.h"
+#endif
+
 #include "../lib/CConfigHandler.h"
 #include "../lib/CGeneralTextHandler.h"
 #include "../lib/CThreadHelper.h"
@@ -142,7 +145,7 @@ void CServerHandler::resetStateForLobby(const StartInfo::EMode mode, const std::
 	else
 		myNames.push_back(settings["general"]["playerName"].String());
 
-#if !defined(VCMI_ANDROID) && !defined(VCMI_IOS)
+#if !defined(VCMI_ANDROID) && !defined(SINGLE_PROCESS_APP)
 	shm.reset();
 
 	if(!settings["session"]["disable-shm"].Bool())

+ 1 - 1
cmake_modules/VCMI_lib.cmake

@@ -485,7 +485,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
 	enable_pch(${TARGET_NAME})
 
 	# We want to deploy assets into build directory for easier debugging without install
-	if(NOT APPLE_IOS)
+	if(COPY_CONFIG_ON_BUILD)
 		add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
 			COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/config
 			COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/Mods

+ 1 - 1
launcher/CMakeLists.txt

@@ -91,7 +91,7 @@ if(WIN32)
 	set(launcher_ICON VCMI_launcher.rc)
 endif()
 
-if(BUILD_SINGLE_APP)
+if(ENABLE_SINGLE_APP_BUILD)
 	add_library(vcmilauncher STATIC ${launcher_SRCS} ${launcher_HEADERS} ${launcher_UI_HEADERS})
 else()
 	add_executable(vcmilauncher WIN32 ${launcher_SRCS} ${launcher_HEADERS} ${launcher_UI_HEADERS} ${launcher_ICON})

+ 4 - 0
lib/CConsoleHandler.cpp

@@ -19,6 +19,8 @@ boost::mutex CConsoleHandler::smx;
 
 DLL_LINKAGE CConsoleHandler * console = nullptr;
 
+VCMI_LIB_NAMESPACE_END
+
 #ifndef VCMI_WINDOWS
 	typedef std::string TColor;
 	#define CONSOLE_GREEN "\x1b[1;32m"
@@ -51,6 +53,8 @@ DLL_LINKAGE CConsoleHandler * console = nullptr;
 
 static TColor defColor;
 
+VCMI_LIB_NAMESPACE_BEGIN
+
 #ifdef VCMI_WINDOWS
 
 void printWinError()

+ 0 - 2
lib/CGameState.h

@@ -297,8 +297,6 @@ private:
 	CRandomGenerator rand;
 	Services * services;
 
-	friend class CCallback;
-	friend class CClient;
 	friend class IGameCallback;
 	friend class CMapHandler;
 	friend class CGameHandler;

+ 3 - 0
lib/CMakeLists.txt

@@ -1 +1,4 @@
 add_main_lib(vcmi SHARED)
+if(ENABLE_SINGLE_APP_BUILD)
+	target_compile_definitions(vcmi PUBLIC VCMI_LIB_NAMESPACE=LIB_CLIENT)
+endif()

+ 36 - 25
lib/VCMIDirs.cpp

@@ -15,6 +15,26 @@
 #include "iOS_utils.h"
 #endif
 
+#ifdef VCMI_ANDROID
+#include "CAndroidVMHelper.h"
+#endif
+
+#ifdef VCMI_WINDOWS
+
+#ifdef __MINGW32__
+	#define _WIN32_IE 0x0500
+
+	#ifndef CSIDL_MYDOCUMENTS
+	#define CSIDL_MYDOCUMENTS CSIDL_PERSONAL
+	#endif
+#endif // __MINGW32__
+
+#include <windows.h>
+#include <shlobj.h>
+#include <shellapi.h>
+
+#endif
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 namespace bfs = boost::filesystem;
@@ -46,8 +66,8 @@ std::string IVCMIDirs::genHelpString() const
 		"  user cache:		" + userCachePath().string() + "\n"
 		"  user config:		" + userConfigPath().string() + "\n"
 		"  user logs:		" + userLogsPath().string() + "\n"
-		"  user saves:		" + userSavePath().string() + "\n";
-		"  user extracted:	" + userExtractedPath().string() + "\n"; // Should end without new-line?
+		"  user saves:		" + userSavePath().string() + "\n"
+		"  user extracted:	" + userExtractedPath().string() + "\n";
 }
 
 void IVCMIDirs::init()
@@ -60,25 +80,9 @@ void IVCMIDirs::init()
 	bfs::create_directories(userSavePath());
 }
 
-#ifdef VCMI_ANDROID
-#include "CAndroidVMHelper.h"
-
-#endif
 
 #ifdef VCMI_WINDOWS
 
-#ifdef __MINGW32__
-    #define _WIN32_IE 0x0500
-
-	#ifndef CSIDL_MYDOCUMENTS
-	#define CSIDL_MYDOCUMENTS CSIDL_PERSONAL
-	#endif
-#endif // __MINGW32__
-
-#include <windows.h>
-#include <shlobj.h>
-#include <shellapi.h>
-
 // Generates script file named _temp.bat in 'to' directory and runs it
 // Script will:
 // - Wait util 'exeName' ends.
@@ -361,13 +365,20 @@ class IVCMIDirsUNIX : public IVCMIDirs
 		bfs::path clientPath() const override;
 		bfs::path serverPath() const override;
 
-		virtual bool developmentMode() const;
+		virtual bool developmentModeData() const;
+		virtual bool developmentModeBinaries() const;
 };
 
-bool IVCMIDirsUNIX::developmentMode() const
+bool IVCMIDirsUNIX::developmentModeData() const
+{
+	// We want to be able to run VCMI from single directory. E.g to run from build output directory
+	return bfs::exists("config") && bfs::exists("Mods") && bfs::exists("../CMakeCache.txt");
+}
+
+bool IVCMIDirsUNIX::developmentModeBinaries() const
 {
 	// We want to be able to run VCMI from single directory. E.g to run from build output directory
-	return bfs::exists("AI") && bfs::exists("config") && bfs::exists("Mods") && bfs::exists("vcmiserver") && bfs::exists("vcmiclient");
+	return bfs::exists("AI") && bfs::exists("../CMakeCache.txt");
 }
 
 bfs::path IVCMIDirsUNIX::clientPath() const { return binaryPath() / "vcmiclient"; }
@@ -511,7 +522,7 @@ std::vector<bfs::path> VCMIDirsOSX::dataPaths() const
 {
 	std::vector<bfs::path> ret;
 	//FIXME: need some proper codepath for detecting running from build output directory
-	if(developmentMode())
+	if(developmentModeData())
 	{
 		ret.push_back(".");
 	}
@@ -584,7 +595,7 @@ std::vector<bfs::path> VCMIDirsXDG::dataPaths() const
 	// in vcmi fs last directory has highest priority
 	std::vector<bfs::path> ret;
 
-	if(developmentMode())
+	if(developmentModeData())
 	{
 		//For now we'll disable usage of system directories when VCMI running from bin directory
 		ret.push_back(".");
@@ -616,7 +627,7 @@ std::vector<bfs::path> VCMIDirsXDG::dataPaths() const
 
 bfs::path VCMIDirsXDG::libraryPath() const
 {
-	if(developmentMode())
+	if(developmentModeBinaries())
 		return ".";
 	else
 		return M_LIB_DIR;
@@ -624,7 +635,7 @@ bfs::path VCMIDirsXDG::libraryPath() const
 
 bfs::path VCMIDirsXDG::binaryPath() const
 {
-	if(developmentMode())
+	if(developmentModeBinaries())
 		return ".";
 	else
 		return M_BIN_DIR;

+ 0 - 2
lib_client/CMakeLists.txt

@@ -1,2 +0,0 @@
-add_main_lib(vcmi_lib_client SHARED)
-target_compile_definitions(vcmi_lib_client PUBLIC VCMI_LIB_NAMESPACE=LIB_CLIENT)

+ 1 - 0
lib_server/CMakeLists.txt

@@ -1,2 +1,3 @@
 add_main_lib(vcmi_lib_server STATIC)
 target_compile_definitions(vcmi_lib_server PUBLIC VCMI_LIB_NAMESPACE=LIB_SERVER)
+target_compile_definitions(vcmi_lib_server PUBLIC VCMI_DLL_STATIC=1)

+ 1 - 1
mapeditor/CMakeLists.txt

@@ -116,7 +116,7 @@ if(APPLE)
 	set_property(GLOBAL PROPERTY AUTOGEN_TARGETS_FOLDER vcmieditor)
 endif()
 
-target_link_libraries(vcmieditor vcmi Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Network)
+target_link_libraries(vcmieditor ${VCMI_LIB_TARGET} Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Network)
 target_include_directories(vcmieditor
 	PUBLIC	${CMAKE_CURRENT_SOURCE_DIR}
 )

+ 9 - 4
mapeditor/graphics.h

@@ -13,16 +13,21 @@
 #include "../lib/GameConstants.h"
 #include <QImage>
 
+VCMI_LIB_NAMESPACE_BEGIN
+
 class CGHeroInstance;
 class CGTownInstance;
+class CGObjectInstance;
+class EntityService;
+class JsonNode;
+class ObjectTemplate;
+
+VCMI_LIB_NAMESPACE_END
+
 class CHeroClass;
 struct InfoAboutHero;
 struct InfoAboutTown;
-class CGObjectInstance;
-class ObjectTemplate;
 class Animation;
-class EntityService;
-class JsonNode;
 
 /// Handles fonts, hero images, town images, various graphics
 class Graphics

+ 4 - 0
mapeditor/jsonutils.cpp

@@ -51,6 +51,8 @@ static JsonMap VariantToMap(QVariantMap variant)
 	return map;
 }
 
+VCMI_LIB_NAMESPACE_BEGIN
+
 namespace JsonUtils
 {
 
@@ -123,3 +125,5 @@ void JsonToFile(QString filename, QVariant object)
 }
 
 }
+
+VCMI_LIB_NAMESPACE_END

+ 4 - 0
mapeditor/jsonutils.h

@@ -12,6 +12,8 @@
 #include <QVariant>
 #include "../lib/JsonNode.h"
 
+VCMI_LIB_NAMESPACE_BEGIN
+
 namespace JsonUtils
 {
 QVariant toVariant(const JsonNode & node);
@@ -20,3 +22,5 @@ QVariant JsonFromFile(QString filename);
 JsonNode toJson(QVariant object);
 void JsonToFile(QString filename, QVariant object);
 }
+
+VCMI_LIB_NAMESPACE_END

+ 4 - 1
mapeditor/mainwindow.h

@@ -7,9 +7,12 @@
 #include "../lib/Terrain.h"
 #include "resourceExtractor/ResourceConverter.h"
 
-class CMap;
 class ObjectBrowser;
+
+VCMI_LIB_NAMESPACE_BEGIN
+class CMap;
 class CGObjectInstance;
+VCMI_LIB_NAMESPACE_END
 
 namespace Ui
 {

+ 4 - 0
mapeditor/maphandler.h

@@ -19,10 +19,14 @@
 #include <QPixmap>
 #include <QRect>
 
+VCMI_LIB_NAMESPACE_BEGIN
+
 class CGObjectInstance;
 class CGBoat;
 class PlayerColor;
 
+VCMI_LIB_NAMESPACE_END
+
 struct TileObject
 {
 	CGObjectInstance *obj;

+ 3 - 0
mapeditor/mapview.h

@@ -16,7 +16,10 @@
 #include "../lib/int3.h"
 
 
+VCMI_LIB_NAMESPACE_BEGIN
 class CGObjectInstance;
+VCMI_LIB_NAMESPACE_END
+
 class MainWindow;
 class MapController;
 

+ 6 - 2
mapeditor/scenelayer.h

@@ -14,11 +14,15 @@
 
 class MapSceneBase;
 class MapScene;
-class CGObjectInstance;
 class MapController;
-class CMap;
 class MapHandler;
 
+VCMI_LIB_NAMESPACE_BEGIN
+class CMap;
+class CGObjectInstance;
+VCMI_LIB_NAMESPACE_END
+
+
 class AbstractLayer : public QObject
 {
 	Q_OBJECT

+ 3 - 2
server/CMakeLists.txt

@@ -22,8 +22,9 @@ if(ANDROID) # android needs client/server to be libraries, not executables, so w
 	return()
 endif()
 
-if(BUILD_SINGLE_APP)
+if(ENABLE_SINGLE_APP_BUILD)
 	add_library(vcmiserver STATIC ${server_SRCS} ${server_HEADERS})
+	target_compile_definitions(vcmiserver PUBLIC VCMI_DLL_STATIC=1)
 	set(server_LIBS vcmi_lib_server)
 else()
 	add_executable(vcmiserver ${server_SRCS} ${server_HEADERS})
@@ -50,6 +51,6 @@ endif()
 vcmi_set_output_dir(vcmiserver "")
 enable_pch(vcmiserver)
 
-if(NOT BUILD_SINGLE_APP)
+if(NOT ENABLE_SINGLE_APP_BUILD)
 	install(TARGETS vcmiserver DESTINATION ${BIN_DIR})
 endif()

+ 1 - 1
server/CVCMIServer.cpp

@@ -1043,7 +1043,7 @@ static void handleCommandOptions(int argc, char * argv[], boost::program_options
 #endif
 int main(int argc, char * argv[])
 {
-#if !defined(VCMI_ANDROID) && !defined(VCMI_IOS)
+#if !defined(VCMI_ANDROID) && !defined(SINGLE_PROCESS_APP)
 	// Correct working dir executable folder (not bundle folder) so we can use executable relative paths
 	boost::filesystem::current_path(boost::filesystem::system_complete(argv[0]).parent_path());
 #endif