diff --git a/CI/conan/base/cross-macro.j2 b/CI/conan/base/cross-macro.j2 new file mode 100644 index 000000000..a1829b5f6 --- /dev/null +++ b/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 -%} \ No newline at end of file diff --git a/CI/conan/base/cross-windows b/CI/conan/base/cross-windows new file mode 100644 index 000000000..5c3c55115 --- /dev/null +++ b/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 diff --git a/CI/conan/mingw32-linux.jinja b/CI/conan/mingw32-linux.jinja new file mode 100644 index 000000000..7173a0969 --- /dev/null +++ b/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) }} \ No newline at end of file diff --git a/CI/conan/mingw64-linux.jinja b/CI/conan/mingw64-linux.jinja new file mode 100644 index 000000000..4c6b59ef0 --- /dev/null +++ b/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) }} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 8762f8c77..ebd1e6620 100644 --- a/CMakeLists.txt +++ b/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") diff --git a/CMakePresets.json b/CMakePresets.json index d31671bc1..2abf86650 100644 --- a/CMakePresets.json +++ b/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" } ] } diff --git a/conanfile.py b/conanfile.py index a3030c689..174170eae 100644 --- a/conanfile.py +++ b/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/*")