Pārlūkot izejas kodu

vcmi: enable Conan builds for cross-compiling Win

This patch enables usage of Conan for cross-compiling Windows
builds instead of MXE.
Konstantin 2 gadi atpakaļ
vecāks
revīzija
a24ec53df2

+ 20 - 0
CI/conan/base/cross-macro.j2

@@ -0,0 +1,20 @@
+{% macro generate_env(target_host) -%}
+CONAN_CROSS_COMPILE={{ target_host }}-
+CHOST={{ target_host }}
+AR={{ target_host }}-ar
+AS={{ target_host }}-as
+CC={{ target_host }}-gcc
+CXX={{ target_host }}-g++
+RANLIB={{ target_host }}-ranlib
+STRIP={{ target_host }}-strip
+{%- endmacro -%}
+
+{% macro generate_env_win32(target_host) -%}
+CONAN_SYSTEM_LIBRARY_LOCATION=/usr/lib/gcc/{{ target_host }}/10-posix/
+RC={{ target_host }}-windres
+{%- endmacro -%}
+
+{% macro generate_conf(target_host) -%}
+tools.build:compiler_executables = {"c": "{{ target_host }}-gcc", "cpp": "{{ target_host }}-g++"}
+tools.build:sysroot = /usr/{{ target_host }}
+{%- endmacro -%}

+ 10 - 0
CI/conan/base/cross-windows

@@ -0,0 +1,10 @@
+[settings]
+os=Windows
+compiler=gcc
+compiler.libcxx=libstdc++11
+compiler.version=10
+compiler.cppstd=11
+build_type=Release
+
+[conf]
+tools.cmake.cmaketoolchain:generator = Ninja

+ 15 - 0
CI/conan/mingw32-linux.jinja

@@ -0,0 +1,15 @@
+{% import 'base/cross-macro.j2' as cross -%}
+include(base/cross-windows)
+{% set target_host="i686-w64-mingw32" %}
+
+[settings]
+arch=x86
+
+[conf]
+{{ cross.generate_conf(target_host)}}
+tools.build:cflags = ["-msse2"]
+tools.build:cxxflags = ["-msse2"]
+
+[env]
+{{ cross.generate_env(target_host) }}
+{{ cross.generate_env_win32(target_host) }}

+ 13 - 0
CI/conan/mingw64-linux.jinja

@@ -0,0 +1,13 @@
+{% import 'base/cross-macro.j2' as cross -%}
+include(base/cross-windows)
+{% set target_host="x86_64-w64-mingw32" %}
+
+[settings]
+arch=x86_64
+
+[conf]
+{{ cross.generate_conf(target_host)}}
+
+[env]
+{{ cross.generate_env(target_host) }}
+{{ cross.generate_env_win32(target_host) }}

+ 35 - 4
CMakeLists.txt

@@ -91,7 +91,7 @@ if(APPLE_IOS AND COPY_CONFIG_ON_BUILD)
 endif()
 
 # No QT Linguist on MXE
-if((MINGW) AND (${CMAKE_CROSSCOMPILING}))
+if((MINGW) AND (${CMAKE_CROSSCOMPILING}) AND (NOT USING_CONAN))
 	set(ENABLE_TRANSLATIONS OFF)
 endif()
 
@@ -329,6 +329,27 @@ if(ENABLE_LUA)
 	add_definitions(-DSCRIPTING_ENABLED=1)
 endif()
 
+if(USING_CONAN AND (MINGW AND CMAKE_HOST_UNIX))
+	# Hack for workaround https://github.com/conan-io/conan-center-index/issues/15405
+	# Remove once it will be fixed
+	execute_process(COMMAND
+		bash -c "grep -rl Mf ${CONAN_INSTALL_FOLDER} | xargs sed -i 's/Mf/mf/g'"
+	)
+	# Hack for workaround ffmpeg broken linking (conan ffmpeg forgots to link to ws2_32)
+	# Remove once it will be fixed
+	execute_process(COMMAND
+		bash -c "grep -rl secur32 ${CONAN_INSTALL_FOLDER} | xargs sed -i 's/secur32)/secur32 ws2_32)/g'"
+	)
+	execute_process(COMMAND
+		bash -c "grep -rl secur32 ${CONAN_INSTALL_FOLDER} | xargs sed -i 's/secur32 mfplat/secur32 ws2_32 mfplat/g'"
+	)
+	# Fixup tbb for cross-compiling on Conan
+	# Remove once it will be fixed
+	execute_process(COMMAND
+		bash -c "grep -rl tbb12 ${CONAN_INSTALL_FOLDER} | xargs sed -i 's/tbb tbb12/tbb12/g'"
+	)
+endif()
+
 ############################################
 #        Finding packages                  #
 ############################################
@@ -545,9 +566,19 @@ endif()
 
 
 if(WIN32)
-	file(GLOB dep_files
-		${dep_files}
-		"${CMAKE_FIND_ROOT_PATH}/bin/*.dll")
+	if(USING_CONAN)
+		#Conan imports enabled
+		vcmi_install_conan_deps("\${CMAKE_INSTALL_PREFIX}")
+		file(GLOB dep_files
+				${dep_files}
+				"${CMAKE_SYSROOT}/bin/*.dll" 
+				"${CMAKE_SYSROOT}/lib/*.dll" 
+				"${CONAN_SYSTEM_LIBRARY_LOCATION}/*.dll")
+	else()
+		file(GLOB dep_files
+				${dep_files}
+				"${CMAKE_FIND_ROOT_PATH}/bin/*.dll")
+	endif()
 
 	if((${CMAKE_CROSSCOMPILING}) AND (DEFINED MSYS))
 		message(STATUS "Detected MXE build")

+ 24 - 0
CMakePresets.json

@@ -81,6 +81,19 @@
                 "FORCE_BUNDLED_MINIZIP": "ON"
             }
         },
+        {
+            "name": "windows-mingw-conan-linux",
+            "displayName": "Ninja+Conan release",
+            "description": "VCMI Windows Ninja using Conan on Linux",
+            "inherits": [
+                "build-with-conan",
+                "default-release"
+            ],
+            "cacheVariables": {
+                "CMAKE_BUILD_TYPE": "Release",
+                "FORCE_BUNDLED_FL": "ON"
+            }
+        },
         {
             "name": "macos-ninja-release",
             "displayName": "Ninja release",
@@ -222,6 +235,12 @@
             "configurePreset": "windows-msvc-release",
             "inherits": "default-release"
         },
+        {
+            "name": "windows-mingw-conan-linux",
+            "configurePreset": "windows-mingw-conan-linux",
+            "inherits": "default-release",
+            "configuration": "Release"
+        },
         {
             "name": "ios-release-conan",
             "configurePreset": "ios-release-conan",
@@ -271,6 +290,11 @@
             "name": "windows-msvc-release",
             "configurePreset": "windows-msvc-release",
             "inherits": "default-release"
+        },
+        {
+            "name": "windows-mingw-conan-linux",
+            "configurePreset": "windows-mingw-conan-linux",
+            "inherits": "default-release"
         }
     ]
 }

+ 20 - 2
conanfile.py

@@ -1,6 +1,7 @@
 from conan import ConanFile
 from conan.errors import ConanInvalidConfiguration
 from conan.tools.apple import is_apple_os
+from conan.tools.build import cross_building
 from conan.tools.cmake import CMakeDeps, CMakeToolchain
 from conans import tools
 
@@ -37,7 +38,9 @@ class VCMI(ConanFile):
 
     def configure(self):
         # SDL_image and Qt depend on it, in iOS both are static
-        self.options["libpng"].shared = self.settings.os != "iOS"
+        # Enable static libpng due to https://github.com/conan-io/conan-center-index/issues/15440,
+        # which leads to VCMI crashes of MinGW
+        self.options["libpng"].shared = is_apple_os(self) and self.settings.os != "iOS"
         # static Qt for iOS is the only viable option at the moment
         self.options["qt"].shared = self.settings.os != "iOS"
 
@@ -157,6 +160,11 @@ class VCMI(ConanFile):
         self.options["qt"].openssl = not is_apple_os(self)
         if self.settings.os == "iOS":
             self.options["qt"].opengl = "es2"
+        if not is_apple_os(self) and cross_building(self):
+            self.options["qt"].cross_compile = self.env["CONAN_CROSS_COMPILE"]
+        # No Qt OpenGL for cross-compiling for Windows, Conan does not support it
+        if self.settings.os == "Windows" and cross_building(self):
+            self.options["qt"].opengl = "no"
 
         # transitive deps
         # doesn't link to overridden bzip2 & zlib, the tool isn't needed anyway
@@ -184,6 +192,9 @@ class VCMI(ConanFile):
             ]
             for lib in systemLibsOverrides:
                 self.requires(f"{lib}@vcmi/apple", override=True)
+        else:
+            self.requires("zlib/[~1.2.13]", override=True) # minizip / Qt
+            self.requires("libiconv/[~1.17]", override=True) # ffmpeg / sdl
 
         # TODO: the latest official release of LuaJIT (which is quite old) can't be built for arm
         if self.options.with_luajit and not str(self.settings.arch).startswith("arm"):
@@ -193,6 +204,8 @@ class VCMI(ConanFile):
         tc = CMakeToolchain(self)
         tc.variables["USING_CONAN"] = True
         tc.variables["CONAN_INSTALL_FOLDER"] = self.install_folder
+        if cross_building(self) and self.settings.os == "Windows":
+            tc.variables["CONAN_SYSTEM_LIBRARY_LOCATION"] = self.env["CONAN_SYSTEM_LIBRARY_LOCATION"]
         tc.generate()
 
         deps = CMakeDeps(self)
@@ -214,4 +227,9 @@ class VCMI(ConanFile):
             deps.generate()
 
     def imports(self):
-       self.copy("*.dylib", "Frameworks", "lib")
+        if is_apple_os(self):
+            self.copy("*.dylib", "Frameworks", "lib")
+        elif self.settings.os == "Windows":
+            self.copy("*.dll", src="bin/archdatadir/plugins/platforms", dst="platforms")
+            self.copy("*.dll", src="bin/archdatadir/plugins/styles", dst="styles")
+            self.copy("*.dll", src="@bindirs", dst="", excludes="archdatadir/*")