conanfile.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. from conan import ConanFile
  2. from conan.tools.apple import is_apple_os
  3. from conan.tools.cmake import CMakeToolchain
  4. from conan.tools.files import save
  5. from conan.tools.microsoft import is_msvc
  6. from glob import glob
  7. import os
  8. required_conan_version = ">=2.13.0"
  9. class VCMI(ConanFile):
  10. settings = "os", "compiler", "build_type", "arch"
  11. generators = "CMakeDeps"
  12. _libRequires = [
  13. "boost/[^1.69]",
  14. "luajit/2.1.0-beta3",
  15. "minizip/[^1.2.12]",
  16. "zlib/[^1.2.12]",
  17. ]
  18. _clientRequires = [
  19. "onetbb/[^2021.7]",
  20. "sdl_image/[^2.8.2]",
  21. "sdl_mixer/[^2.8.0]",
  22. "sdl_ttf/[^2.0.18]",
  23. ]
  24. _launcherRequires = [
  25. "xz_utils/[^5.2.5]", # innoextract
  26. ]
  27. requires = _libRequires + _clientRequires + _launcherRequires
  28. options = {
  29. "with_ffmpeg": [True, False],
  30. }
  31. default_options = {
  32. "with_ffmpeg": True,
  33. }
  34. @property
  35. def _isMobilePlatform(self):
  36. return self.settings.os == "iOS" or self.settings.os == "Android"
  37. def config_options(self):
  38. # static on "single app" platforms
  39. isSdlShared = not self._isMobilePlatform
  40. self.options["sdl"].shared = isSdlShared
  41. self.options["sdl_image"].shared = isSdlShared
  42. self.options["sdl_mixer"].shared = isSdlShared
  43. self.options["sdl_ttf"].shared = isSdlShared
  44. if self.settings.os == "Android":
  45. self.options["qt"].android_sdk = os.getenv("ANDROID_HOME")
  46. def configure(self):
  47. self.options["sdl"].sdl2main = self.settings.os != "iOS"
  48. self.options["qt"].qttools = True
  49. self.options["qt"].qtandroidextras = self.settings.os == "Android" # TODO: in Qt 6 it's part of Core
  50. self.options["qt"].openssl = not is_apple_os(self)
  51. if self._isMobilePlatform:
  52. self.options["qt"].opengl = "es2"
  53. # static Qt for iOS is the only viable option at the moment
  54. if self.settings.os == "iOS":
  55. self.options["qt"].shared = False
  56. # MSVC static build requires static runtime, but VCMI uses dynamic runtime
  57. if is_msvc(self):
  58. self.options["ffmpeg"].shared = True
  59. def requirements(self):
  60. # client
  61. if self.options.with_ffmpeg:
  62. self.requires("ffmpeg/[>=4.4]")
  63. # On Android SDL version must be the same as the version of Java wrapper for SDL in VCMI source code
  64. # Wrapper can be found in the following directory: android/vcmi-app/src/main/java/org/libsdl/app
  65. # TODO: try enabling version range once there's no conflict
  66. # sdl_image & sdl_ttf depend on earlier version
  67. # ERROR: Version conflict: Conflict between sdl/2.28.5 and sdl/2.28.3 in the graph.
  68. # Conflict originates from sdl_mixer/2.8.0
  69. # upcoming SDL version 3.0+ is not supported at the moment due to API breakage
  70. # SDL versions between 2.22-2.26.1 have broken sound
  71. # self.requires("sdl/[^2.26.1 || >=2.0.20 <=2.22.0]")
  72. # versions before 2.30.7 don't build for Android with NDK 27: https://github.com/libsdl-org/SDL/issues/9792
  73. self.requires("sdl/2.30.9", override=True)
  74. # launcher
  75. if self.settings.os == "Android":
  76. self.requires("qt/[~5.15.14]") # earlier versions have serious bugs
  77. else:
  78. self.requires("qt/[~5.15.2]")
  79. def _pathForCmake(self, path):
  80. # CMake doesn't like \ in strings
  81. return path.replace(os.path.sep, os.path.altsep) if os.path.altsep else path
  82. def _generateRuntimeLibsFile(self):
  83. # create file with list of libs to copy to the package for distribution
  84. runtimeLibsFile = self._pathForCmake(os.path.join(self.build_folder, "_runtime_libs.txt"))
  85. runtimeLibExtension = {
  86. "Android": "so",
  87. "iOS": "dylib",
  88. "Macos": "dylib",
  89. "Windows": "dll",
  90. }.get(str(self.settings.os))
  91. runtimeLibs = []
  92. for _, dep in self.dependencies.host.items():
  93. # Qt libs are copied using *deployqt
  94. if dep.ref.name == "qt":
  95. continue
  96. runtimeLibDir = ''
  97. if self.settings.os == "Windows":
  98. if len(dep.cpp_info.bindirs) > 0:
  99. runtimeLibDir = dep.cpp_info.bindir
  100. elif len(dep.cpp_info.libdirs) > 0:
  101. runtimeLibDir = dep.cpp_info.libdir
  102. if len(runtimeLibDir) > 0:
  103. runtimeLibs += glob(os.path.join(runtimeLibDir, f"*.{runtimeLibExtension}"))
  104. save(self, runtimeLibsFile, "\n".join(runtimeLibs))
  105. return runtimeLibsFile
  106. def generate(self):
  107. tc = CMakeToolchain(self)
  108. tc.variables["USING_CONAN"] = True
  109. tc.variables["CONAN_RUNTIME_LIBS_FILE"] = self._generateRuntimeLibsFile()
  110. if self.settings.os == "Android":
  111. tc.variables["CMAKE_ANDROID_API"] = str(self.settings.os.api_level)
  112. elif self.settings.os == "Windows":
  113. tc.variables["CONAN_RUNENV_SCRIPT"] = self._pathForCmake(os.path.join(self.build_folder, "conanrun.bat"))
  114. tc.generate()