1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-22 22:13:35 +02:00

Merge pull request #1073 from kambala-decapitator/ios-conan

[Conan] add iOS support, bump dependencies, improvements
This commit is contained in:
Andrii Danylchenko 2022-10-22 12:40:48 +03:00 committed by GitHub
commit c2cc801f60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 458 additions and 173 deletions

View File

@ -95,7 +95,8 @@ jobs:
test: 0 test: 0
pack: 1 pack: 1
extension: ipa extension: ipa
preset: ios-release preset: ios-release-conan
conan_profile: ios-arm64
- platform: mxe - platform: mxe
os: ubuntu-20.04 os: ubuntu-20.04
mxe: i686-w64-mingw32.shared mxe: i686-w64-mingw32.shared
@ -136,7 +137,10 @@ jobs:
--no-imports \ --no-imports \
--build=never \ --build=never \
--profile:build=default \ --profile:build=default \
--profile:host=CI/conan/${{ matrix.conan_profile }} --profile:host=CI/conan/${{ matrix.conan_profile }} \
--options with_apple_system_libs=True
env:
GENERATE_ONLY_BUILT_CONFIG: 1
- name: Git branch name - name: Git branch name
id: git-branch-name id: git-branch-name

2
.gitignore vendored
View File

@ -2,7 +2,7 @@
/server/vcmiserver /server/vcmiserver
/launcher/vcmilauncher /launcher/vcmilauncher
/launcher/vcmilauncher_automoc.cpp /launcher/vcmilauncher_automoc.cpp
/conan-generated /conan-*
build/ build/
.cache/* .cache/*

View File

@ -138,6 +138,6 @@ vcmi_set_output_dir(Nullkiller "AI")
enable_pch(Nullkiller) enable_pch(Nullkiller)
install(TARGETS Nullkiller RUNTIME DESTINATION ${AI_LIB_DIR} LIBRARY DESTINATION ${AI_LIB_DIR}) install(TARGETS Nullkiller RUNTIME DESTINATION ${AI_LIB_DIR} LIBRARY DESTINATION ${AI_LIB_DIR})
if(APPLE_IOS) if(APPLE_IOS AND NOT USING_CONAN)
install(IMPORTED_RUNTIME_ARTIFACTS TBB::tbb LIBRARY DESTINATION ${LIB_DIR}) # CMake 3.21+ install(IMPORTED_RUNTIME_ARTIFACTS TBB::tbb LIBRARY DESTINATION ${LIB_DIR}) # CMake 3.21+
endif() endif()

14
CI/conan/ios-arm64 Normal file
View File

@ -0,0 +1,14 @@
[settings]
os=iOS
os.version=12.0
os.sdk=iphoneos
arch=armv8
compiler=apple-clang
compiler.version=13
compiler.libcxx=libc++
build_type=Release
[options]
[build_requires]
[env]
[conf]
tools.cmake.cmaketoolchain:generator = Ninja

14
CI/conan/ios-armv7 Normal file
View File

@ -0,0 +1,14 @@
[settings]
os=iOS
os.version=10.0
os.sdk=iphoneos
arch=armv7
compiler=apple-clang
compiler.version=13
compiler.libcxx=libc++
build_type=Release
[options]
[build_requires]
[env]
[conf]
tools.cmake.cmaketoolchain:generator = Ninja

View File

@ -9,3 +9,5 @@ build_type=Release
[options] [options]
[build_requires] [build_requires]
[env] [env]
[conf]
tools.cmake.cmaketoolchain:generator = Ninja

View File

@ -9,3 +9,5 @@ build_type=Release
[options] [options]
[build_requires] [build_requires]
[env] [env]
[conf]
tools.cmake.cmaketoolchain:generator = Ninja

View File

@ -2,6 +2,6 @@
echo DEVELOPER_DIR=/Applications/Xcode_13.4.1.app >> $GITHUB_ENV echo DEVELOPER_DIR=/Applications/Xcode_13.4.1.app >> $GITHUB_ENV
curl -L 'https://github.com/vcmi/vcmi-ios-deps/releases/latest/download/vcmi-ios-depends-xc13.2.1.txz' \ mkdir ~/.conan ; cd ~/.conan
curl -L 'https://github.com/vcmi/vcmi-ios-deps/releases/download/1.1/ios-arm64.xz' \
| tar -xf - | tar -xf -
build/fix_install_paths.command

View File

@ -5,5 +5,5 @@ echo DEVELOPER_DIR=/Applications/Xcode_13.4.1.app >> $GITHUB_ENV
brew install ninja brew install ninja
mkdir ~/.conan ; cd ~/.conan mkdir ~/.conan ; cd ~/.conan
curl -L "https://github.com/vcmi/vcmi-deps-macos/releases/latest/download/$DEPS_FILENAME.txz" \ curl -L "https://github.com/vcmi/vcmi-deps-macos/releases/download/1.1/$DEPS_FILENAME.txz" \
| tar -xf - | tar -xf -

View File

@ -180,9 +180,11 @@ if(APPLE_IOS)
set(CMAKE_MACOSX_RPATH 1) set(CMAKE_MACOSX_RPATH 1)
set(CMAKE_OSX_DEPLOYMENT_TARGET 12.0) set(CMAKE_OSX_DEPLOYMENT_TARGET 12.0)
list(APPEND CMAKE_FIND_ROOT_PATH "${CMAKE_PREFIX_PATH}") # required for Boost if(NOT USING_CONAN)
set(CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH FALSE) list(APPEND CMAKE_FIND_ROOT_PATH "${CMAKE_PREFIX_PATH}") # required for Boost
set(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH FALSE) set(CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH FALSE)
set(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH FALSE)
endif()
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED NO) set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED NO)
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED_FOR_APPS YES) set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED_FOR_APPS YES)
@ -294,7 +296,7 @@ if(TARGET zlib::zlib)
endif() endif()
set(FFMPEG_COMPONENTS avutil swscale avformat avcodec) set(FFMPEG_COMPONENTS avutil swscale avformat avcodec)
if(APPLE_IOS) if(APPLE_IOS AND NOT USING_CONAN)
list(APPEND FFMPEG_COMPONENTS swresample) list(APPEND FFMPEG_COMPONENTS swresample)
endif() endif()
find_package(ffmpeg COMPONENTS ${FFMPEG_COMPONENTS}) find_package(ffmpeg COMPONENTS ${FFMPEG_COMPONENTS})
@ -309,6 +311,9 @@ endif()
find_package(SDL2 REQUIRED) find_package(SDL2 REQUIRED)
find_package(SDL2_image REQUIRED) find_package(SDL2_image REQUIRED)
if(TARGET SDL2_image::SDL2_image)
add_library(SDL2::Image ALIAS SDL2_image::SDL2_image)
endif()
find_package(SDL2_mixer REQUIRED) find_package(SDL2_mixer REQUIRED)
if(TARGET SDL2_mixer::SDL2_mixer) if(TARGET SDL2_mixer::SDL2_mixer)
add_library(SDL2::Mixer ALIAS SDL2_mixer::SDL2_mixer) add_library(SDL2::Mixer ALIAS SDL2_mixer::SDL2_mixer)

View File

@ -6,6 +6,14 @@
"hidden": true, "hidden": true,
"binaryDir": "${sourceDir}/out/build/${presetName}" "binaryDir": "${sourceDir}/out/build/${presetName}"
}, },
{
"name": "build-with-conan",
"hidden": true,
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "${sourceDir}/conan-generated/conan_toolchain.cmake",
"FORCE_BUNDLED_MINIZIP": "OFF"
}
},
{ {
"name": "base-release", "name": "base-release",
"inherits": "release-binary-dir", "inherits": "release-binary-dir",
@ -81,9 +89,11 @@
"name": "macos-conan-ninja-release", "name": "macos-conan-ninja-release",
"displayName": "Ninja+Conan release", "displayName": "Ninja+Conan release",
"description": "VCMI MacOS Ninja using Conan", "description": "VCMI MacOS Ninja using Conan",
"inherits": "default-release", "inherits": [
"build-with-conan",
"default-release"
],
"cacheVariables": { "cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "${sourceDir}/conan-generated/conan_toolchain.cmake",
"CMAKE_BUILD_TYPE": "Release" "CMAKE_BUILD_TYPE": "Release"
} }
}, },
@ -122,16 +132,42 @@
} }
}, },
{ {
"name": "ios-release", "name": "ios-device-conan",
"displayName": "iOS release", "displayName": "Base iOS device using Conan",
"description": "VCMI iOS release", "description": "Base VCMI preset for iOS device using Conan",
"inherits": [ "inherits": [
"base-release", "build-with-conan",
"ios-device", "ios-device"
"release-binary-dir" ]
},
{
"name": "base-ios-release",
"displayName": "Base iOS release",
"description": "Base VCMI preset for iOS release",
"inherits": "base-release",
"hidden": true,
"cacheVariables": {
"BUNDLE_IDENTIFIER_PREFIX": "eu.vcmi"
}
},
{
"name": "ios-release-conan",
"displayName": "iOS+Conan release",
"description": "VCMI iOS release using Conan",
"inherits": [
"base-ios-release",
"ios-device-conan"
]
},
{
"name": "ios-release-legacy",
"displayName": "iOS release using legacy dependencies",
"description": "VCMI iOS release using legacy dependencies",
"inherits": [
"base-ios-release",
"ios-device"
], ],
"cacheVariables": { "cacheVariables": {
"BUNDLE_IDENTIFIER_PREFIX": "eu.vcmi",
"CMAKE_PREFIX_PATH": "${sourceDir}/build/iphoneos" "CMAKE_PREFIX_PATH": "${sourceDir}/build/iphoneos"
} }
} }
@ -184,14 +220,19 @@
"inherits": "default-release" "inherits": "default-release"
}, },
{ {
"name": "ios-release", "name": "ios-release-conan",
"configurePreset": "ios-release", "configurePreset": "ios-release-conan",
"inherits": "default-release", "inherits": "default-release",
"configuration": "Release", "configuration": "Release",
"targets": ["vcmiclient"], "targets": ["vcmiclient"],
"nativeToolOptions": [ "nativeToolOptions": [
"CODE_SIGNING_ALLOWED_FOR_APPS=NO" "CODE_SIGNING_ALLOWED_FOR_APPS=NO"
] ]
},
{
"name": "ios-release-legacy",
"configurePreset": "ios-release-legacy",
"inherits": "ios-release-conan"
} }
], ],
"testPresets": [ "testPresets": [

View File

@ -26,6 +26,7 @@ To use VCMI you need to own original data files.
Platform support is constantly tested by continuous integration and CMake configuration adjusted to generate nice looking projects for all major IDE. Following guides will help you to setup build environment with no effort: Platform support is constantly tested by continuous integration and CMake configuration adjusted to generate nice looking projects for all major IDE. Following guides will help you to setup build environment with no effort:
* (optional) All platforms: [using Conan package manager to obtain prebuilt dependencies](docs/conan.md)
* [On Linux](https://wiki.vcmi.eu/How_to_build_VCMI_(Linux)) * [On Linux](https://wiki.vcmi.eu/How_to_build_VCMI_(Linux))
* [On Linux for Windows with MXE](https://wiki.vcmi.eu/How_to_build_VCMI_(Linux/Cmake/MXE)) * [On Linux for Windows with MXE](https://wiki.vcmi.eu/How_to_build_VCMI_(Linux/Cmake/MXE))
* [On macOS](https://wiki.vcmi.eu/How_to_build_VCMI_(macOS)) * [On macOS](https://wiki.vcmi.eu/How_to_build_VCMI_(macOS))

View File

@ -268,9 +268,11 @@ vcmi_set_output_dir(vcmiclient "")
enable_pch(vcmiclient) enable_pch(vcmiclient)
if(APPLE_IOS) if(APPLE_IOS)
vcmi_install_conan_deps("\${CMAKE_INSTALL_PREFIX}")
add_custom_command(TARGET vcmiclient POST_BUILD add_custom_command(TARGET vcmiclient POST_BUILD
COMMAND ios/set_build_version.sh "$<TARGET_BUNDLE_CONTENT_DIR:vcmiclient>" COMMAND ios/set_build_version.sh "$<TARGET_BUNDLE_CONTENT_DIR:vcmiclient>"
COMMAND ${CMAKE_COMMAND} --install "${CMAKE_BINARY_DIR}" --component "${CMAKE_INSTALL_DEFAULT_COMPONENT_NAME}" --config "$<CONFIG>" --prefix "$<TARGET_BUNDLE_CONTENT_DIR:vcmiclient>" COMMAND ${CMAKE_COMMAND} --install "${CMAKE_BINARY_DIR}" --component "${CMAKE_INSTALL_DEFAULT_COMPONENT_NAME}" --config "$<CONFIG>" --prefix "$<TARGET_BUNDLE_CONTENT_DIR:vcmiclient>"
COMMAND ios/rpath_remove_symlinks.sh
COMMAND ios/codesign.sh COMMAND ios/codesign.sh
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
) )

View File

@ -134,3 +134,16 @@ function(install_vcpkg_imported_tgt tgt)
message("${tgt_name}: ${TGT_DLL}") message("${tgt_name}: ${TGT_DLL}")
install(FILES ${TGT_DLL} DESTINATION ${BIN_DIR}) install(FILES ${TGT_DLL} DESTINATION ${BIN_DIR})
endfunction(install_vcpkg_imported_tgt) endfunction(install_vcpkg_imported_tgt)
# install dependencies from Conan, install_dir should contain \${CMAKE_INSTALL_PREFIX}
function(vcmi_install_conan_deps install_dir)
if(NOT USING_CONAN)
return()
endif()
install(CODE "
execute_process(COMMAND
conan imports \"${CMAKE_SOURCE_DIR}\" --install-folder \"${CMAKE_SOURCE_DIR}/conan-generated\" --import-folder \"${install_dir}\"
)
file(REMOVE \"${install_dir}/conan_imports_manifest.txt\")
")
endfunction()

View File

@ -502,7 +502,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
if("${LIBRARY_TYPE}" STREQUAL SHARED) if("${LIBRARY_TYPE}" STREQUAL SHARED)
install(TARGETS ${TARGET_NAME} RUNTIME DESTINATION ${LIB_DIR} LIBRARY DESTINATION ${LIB_DIR}) install(TARGETS ${TARGET_NAME} RUNTIME DESTINATION ${LIB_DIR} LIBRARY DESTINATION ${LIB_DIR})
endif() endif()
if(APPLE_IOS) if(APPLE_IOS AND NOT USING_CONAN)
get_target_property(LINKED_LIBS ${TARGET_NAME} LINK_LIBRARIES) get_target_property(LINKED_LIBS ${TARGET_NAME} LINK_LIBRARIES)
foreach(LINKED_LIB IN LISTS LINKED_LIBS) foreach(LINKED_LIB IN LISTS LINKED_LIBS)
if(NOT TARGET ${LINKED_LIB}) if(NOT TARGET ${LINKED_LIB})

View File

@ -1,166 +1,181 @@
from conan import ConanFile from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools.apple import is_apple_os from conan.tools.apple import is_apple_os
from conan.tools.cmake import CMakeDeps from conan.tools.cmake import CMakeDeps, CMakeToolchain
from conans import tools from conans import tools
import os required_conan_version = ">=1.51.3"
class VCMI(ConanFile): class VCMI(ConanFile):
settings = "os", "compiler", "build_type", "arch" settings = "os", "compiler", "build_type", "arch"
generators = "CMakeToolchain"
requires = [ requires = [
"boost/1.79.0", "boost/[^1.69]",
"ffmpeg/4.4", "minizip/[~1.2.12]",
"minizip/1.2.12", "onetbb/[^2021.3]", # Nullkiller AI
"onetbb/2021.3.0", # Nullkiller AI "qt/[~5.15.2]", # launcher
"qt/5.15.5", # launcher "sdl/[~2.24.0]",
"sdl/2.0.20", "sdl_image/[~2.0.5]",
"sdl_image/2.0.5", "sdl_mixer/[~2.0.4]",
"sdl_mixer/2.0.4", "sdl_ttf/[~2.0.18]",
"sdl_ttf/2.0.18",
] ]
options = {
def _disableQtOptions(disableFlag, options): "default_options_of_requirements": [True, False],
return " ".join([f"-{disableFlag}-{tool}" for tool in options]) "with_apple_system_libs": [True, False],
"with_ffmpeg": [True, False],
_qtOptions = [ "with_luajit": [True, False],
_disableQtOptions("no", [ }
"gif",
"ico",
]),
_disableQtOptions("no-feature", [
# xpm format is required for Drag'n'Drop support
"imageformat_bmp",
"imageformat_jpeg",
"imageformat_ppm",
"imageformat_xbm",
# we need only macdeployqt
# TODO: disabling these doesn't disable generation of CMake targets
# TODO: in Qt 6.3 it's a part of qtbase
# "assistant",
# "designer",
# "distancefieldgenerator",
# "kmap2qmap",
# "linguist",
# "makeqpf",
# "pixeltool",
# "qdbus",
# "qev",
# "qtattributionsscanner",
# "qtdiag",
# "qtpaths",
# "qtplugininfo",
]),
]
default_options = { default_options = {
# shared libs "default_options_of_requirements": False,
"with_apple_system_libs": False,
"with_ffmpeg": True,
"with_luajit": False,
"boost/*:shared": True, "boost/*:shared": True,
"libpng/*:shared": True, # SDL_image and Qt depend on it
"minizip/*:shared": True, "minizip/*:shared": True,
"onetbb/*:shared": True, "onetbb/*:shared": True,
"qt/*:shared": True, }
def configure(self):
# SDL_image and Qt depend on it, in iOS both are static
self.options["libpng"].shared = self.settings.os != "iOS"
# static Qt for iOS is the only viable option at the moment
self.options["qt"].shared = self.settings.os != "iOS"
if self.options.default_options_of_requirements:
return
# we need only the following Boost parts: # we need only the following Boost parts:
# date_time filesystem locale program_options system thread # date_time filesystem locale program_options system thread
# some other parts are also enabled because they're dependents # some other parts are also enabled because they're dependents
# see e.g. conan-center-index/recipes/boost/all/dependencies # see e.g. conan-center-index/recipes/boost/all/dependencies
"boost/*:without_context": True, self.options["boost"].without_context = True
"boost/*:without_contract": True, self.options["boost"].without_contract = True
"boost/*:without_coroutine": True, self.options["boost"].without_coroutine = True
"boost/*:without_fiber": True, self.options["boost"].without_fiber = True
"boost/*:without_graph": True, self.options["boost"].without_graph = True
"boost/*:without_graph_parallel": True, self.options["boost"].without_graph_parallel = True
"boost/*:without_iostreams": True, self.options["boost"].without_iostreams = True
"boost/*:without_json": True, self.options["boost"].without_json = True
"boost/*:without_log": True, self.options["boost"].without_log = True
"boost/*:without_math": True, self.options["boost"].without_math = True
"boost/*:without_mpi": True, self.options["boost"].without_mpi = True
"boost/*:without_nowide": True, self.options["boost"].without_nowide = True
"boost/*:without_python": True, self.options["boost"].without_python = True
"boost/*:without_random": True, self.options["boost"].without_random = True
"boost/*:without_regex": True, self.options["boost"].without_regex = True
"boost/*:without_serialization": True, self.options["boost"].without_serialization = True
"boost/*:without_stacktrace": True, self.options["boost"].without_stacktrace = True
"boost/*:without_test": True, self.options["boost"].without_test = True
"boost/*:without_timer": True, self.options["boost"].without_timer = True
"boost/*:without_type_erasure": True, self.options["boost"].without_type_erasure = True
"boost/*:without_wave": True, self.options["boost"].without_wave = True
"ffmpeg/*:avdevice": False, self.options["ffmpeg"].avdevice = False
"ffmpeg/*:avfilter": False, self.options["ffmpeg"].avfilter = False
"ffmpeg/*:postproc": False, self.options["ffmpeg"].postproc = False
"ffmpeg/*:swresample": False, self.options["ffmpeg"].swresample = False
"ffmpeg/*:with_freetype": False, self.options["ffmpeg"].with_freetype = False
"ffmpeg/*:with_libfdk_aac": False, self.options["ffmpeg"].with_libfdk_aac = False
"ffmpeg/*:with_libmp3lame": False, self.options["ffmpeg"].with_libmp3lame = False
"ffmpeg/*:with_libvpx": False, self.options["ffmpeg"].with_libvpx = False
"ffmpeg/*:with_libwebp": False, self.options["ffmpeg"].with_libwebp = False
"ffmpeg/*:with_libx264": False, self.options["ffmpeg"].with_libx264 = False
"ffmpeg/*:with_libx265": False, self.options["ffmpeg"].with_libx265 = False
"ffmpeg/*:with_openh264": False, self.options["ffmpeg"].with_openh264 = False
"ffmpeg/*:with_openjpeg": False, self.options["ffmpeg"].with_openjpeg = False
"ffmpeg/*:with_opus": False, self.options["ffmpeg"].with_opus = False
"ffmpeg/*:with_programs": False, self.options["ffmpeg"].with_programs = False
"ffmpeg/*:with_ssl": False, self.options["ffmpeg"].with_ssl = False
"ffmpeg/*:with_vorbis": False, self.options["ffmpeg"].with_vorbis = False
"sdl/*:vulkan": False, self.options["sdl"].sdl2main = self.settings.os != "iOS"
self.options["sdl"].vulkan = False
"sdl_image/*:imageio": True, self.options["sdl_image"].lbm = False
"sdl_image/*:lbm": False, self.options["sdl_image"].pnm = False
"sdl_image/*:pnm": False, self.options["sdl_image"].svg = False
"sdl_image/*:svg": False, self.options["sdl_image"].tga = False
"sdl_image/*:tga": False, self.options["sdl_image"].with_libjpeg = False
"sdl_image/*:with_libjpeg": False, self.options["sdl_image"].with_libtiff = False
"sdl_image/*:with_libtiff": False, self.options["sdl_image"].with_libwebp = False
"sdl_image/*:with_libwebp": False, self.options["sdl_image"].xcf = False
"sdl_image/*:xcf": False, self.options["sdl_image"].xpm = False
"sdl_image/*:xpm": False, self.options["sdl_image"].xv = False
"sdl_image/*:xv": False, if is_apple_os(self):
self.options["sdl_image"].imageio = True
"sdl_mixer/*:flac": False, self.options["sdl_mixer"].flac = False
"sdl_mixer/*:mad": False, self.options["sdl_mixer"].mad = False
"sdl_mixer/*:mikmod": False, self.options["sdl_mixer"].mikmod = False
"sdl_mixer/*:modplug": False, self.options["sdl_mixer"].modplug = False
"sdl_mixer/*:nativemidi": False, self.options["sdl_mixer"].nativemidi = False
"sdl_mixer/*:opus": False, self.options["sdl_mixer"].opus = False
"sdl_mixer/*:wav": False, self.options["sdl_mixer"].wav = False
"qt/*:config": " ".join(_qtOptions), def _disableQtOptions(disableFlag, options):
"qt/*:openssl": False, return " ".join([f"-{disableFlag}-{tool}" for tool in options])
"qt/*:qttools": True,
"qt/*:with_freetype": False, _qtOptions = [
"qt/*:with_libjpeg": False, _disableQtOptions("no", [
"qt/*:with_md4c": False, "gif",
"qt/*:with_mysql": False, "ico",
"qt/*:with_odbc": False, ]),
"qt/*:with_openal": False, _disableQtOptions("no-feature", [
"qt/*:with_pq": False, # xpm format is required for Drag'n'Drop support
"imageformat_bmp",
"imageformat_jpeg",
"imageformat_ppm",
"imageformat_xbm",
# we need only macdeployqt
# TODO: disabling these doesn't disable generation of CMake targets
# TODO: in Qt 6.3 it's a part of qtbase
# "assistant",
# "designer",
# "distancefieldgenerator",
# "kmap2qmap",
# "linguist",
# "makeqpf",
# "pixeltool",
# "qdbus",
# "qev",
# "qtattributionsscanner",
# "qtdiag",
# "qtpaths",
# "qtplugininfo",
]),
]
self.options["qt"].config = " ".join(_qtOptions)
self.options["qt"].qttools = True
self.options["qt"].with_freetype = False
self.options["qt"].with_libjpeg = False
self.options["qt"].with_md4c = False
self.options["qt"].with_mysql = False
self.options["qt"].with_odbc = False
self.options["qt"].with_openal = False
self.options["qt"].with_pq = False
self.options["qt"].openssl = not is_apple_os(self)
if self.settings.os == "iOS":
self.options["qt"].opengl = "es2"
# transitive deps # transitive deps
"pcre2/*:build_pcre2grep": False, # doesn't link to overridden bzip2 & zlib, the tool isn't needed anyway # doesn't link to overridden bzip2 & zlib, the tool isn't needed anyway
} self.options["pcre2"].build_pcre2grep = False
def configure(self):
# workaround: macOS deployment target isn't passed to linker when building Boost
# TODO: remove when https://github.com/conan-io/conan-center-index/pull/12468 is merged
if is_apple_os(self):
osVersion = self.settings.get_safe("os.version")
if osVersion:
deploymentTargetFlag = tools.apple_deployment_target_flag(
self.settings.os,
osVersion,
self.settings.get_safe("os.sdk"),
self.settings.get_safe("os.subsystem"),
self.settings.get_safe("arch")
)
self.options["boost"].extra_b2_flags = f"linkflags={deploymentTargetFlag}"
def requirements(self): def requirements(self):
# TODO: will no longer be needed after merging https://github.com/conan-io/conan-center-index/pull/13399
self.requires("libpng/[~1.6.38]", override=True) # freetype / Qt
if self.options.default_options_of_requirements:
self.requires("libjpeg/9e", override=True) # libtiff / Qt
self.requires("freetype/[~2.12.1]", override=True) # sdl_ttf / Qt
if self.options.with_ffmpeg:
self.requires("libwebp/[~1.2.4]", override=True) # sdl_image / ffmpeg
if self.options.with_ffmpeg:
self.requires("ffmpeg/[^4.4]")
# use Apple system libraries instead of external ones # use Apple system libraries instead of external ones
if is_apple_os(self): if self.options.with_apple_system_libs and not self.options.default_options_of_requirements and is_apple_os(self):
systemLibsOverrides = [ systemLibsOverrides = [
"bzip2/1.0.8", "bzip2/1.0.8",
"libiconv/1.17", "libiconv/1.17",
@ -168,15 +183,19 @@ class VCMI(ConanFile):
"zlib/1.2.12", "zlib/1.2.12",
] ]
for lib in systemLibsOverrides: for lib in systemLibsOverrides:
self.requires(f"{lib}@kambala/apple", override=True) self.requires(f"{lib}@vcmi/apple", override=True)
# TODO: the latest official release of LuaJIT (which is quite old) can't be built for arm Mac # TODO: the latest official release of LuaJIT (which is quite old) can't be built for arm
if self.settings.os != "Macos" or self.settings.arch != "armv8": if self.options.with_luajit and not str(self.settings.arch).startswith("arm"):
self.requires("luajit/2.0.5") self.requires("luajit/[~2.0.5]")
def generate(self): def generate(self):
tc = CMakeToolchain(self)
tc.variables["USING_CONAN"] = True
tc.generate()
deps = CMakeDeps(self) deps = CMakeDeps(self)
if os.getenv("USE_CONAN_WITH_ALL_CONFIGS", "0") == "0": if tools.get_env("GENERATE_ONLY_BUILT_CONFIG", default=False):
deps.generate() deps.generate()
return return

147
docs/conan.md Normal file
View File

@ -0,0 +1,147 @@
# Using dependencies from Conan
[Conan](https://conan.io/) is a package manager for C/C++. We provide prebuilt binary dependencies for some platforms that are used by our CI, but they can also be consumed by users to build VCMI. However, it's not required to use only the prebuilt binaries: you can build them from source as well.
## Supported platforms
The following platforms are supported and known to work, others might require changes to our [conanfile.py](../conanfile.py) or upstream recipes.
- **macOS**: x86_64 (Intel) - target 10.13 (High Sierra), arm64 (Apple Silicon) - target 11.0 (Big Sur)
- **iOS**: arm64 - target 12.0
## Getting started
1. [Install Conan](https://docs.conan.io/en/latest/installation.html)
2. Execute in terminal: `conan profile new default --detect`
## Download dependencies
0. If your platform is not on the list of supported ones or you don't want to use our prebuilt binaries, you can still build dependencies from source or try consuming prebuilt binaries from the central Conan repository - [ConanCenter](https://conan.io/center/). In this case skip to the [next section](#generate-cmake-integration) directly.
1. Check if your build environment can use the prebuilt binaries: basically, that your compiler version (or Xcode major version) matches the information below. If you're unsure, simply advance to the next step.
- macOS: libraries are built with Apple clang 13 (Xcode 13.4.1), should be consumable by Xcode and Xcode CLT 13.x
- iOS: libraries are built with Apple clang 13 (Xcode 13.4.1), should be consumable by Xcode 13.x
2. Download the binaries archive and unpack it to `~/.conan` directory:
- [macOS](https://github.com/vcmi/vcmi-deps-macos/releases/latest): pick **intel.txz** if you have Intel Mac, otherwise - **intel-cross-arm.txz**
- [iOS](https://github.com/vcmi/vcmi-ios-deps/releases/latest)
3. Only if you have Apple Silicon Mac and trying to build for macOS or iOS: follow [instructions how to build Qt host tools for Apple Silicon](https://github.com/vcmi/vcmi-ios-deps#note-for-arm-macs), on step 3 copy them to `~/.conan/data/qt/5.15.x/_/_/package/SOME_HASH/bin` (`5.15.x` and `SOME_HASH` are placeholders).
## Generate CMake integration
Conan needs to generate CMake toolchain file to make dependencies available to CMake. See `CMakeDeps` and `CMakeToolchain` [in the official documentation](https://docs.conan.io/en/latest/reference/conanfile/tools/cmake.html) for details.
In terminal `cd` to the VCMI source directory and run the following command. If you want to download prebuilt binaries from ConanCenter, also read the [next section](#using-prebuilt-binaries-from-conancenter).
<pre>
conan install . \
--install-folder=<b><i>conan-generated</i></b> \
--no-imports \
--build=<b><i>never</i></b> \
--profile:build=default \
--profile:host=<b><i>CI/conan/PROFILE</i></b>
</pre>
The highlighted parts can be adjusted:
- ***conan-generated***: directory (absolute or relative) where the generated files will appear. This value is used in CMake presets from VCMI, but you can actually use any directory and override it in your local CMake presets.
- ***never***: use this value to avoid building any dependency from source. You can also use `missing` to build recipes, that are not present in your local cache, from source.
- ***CI/conan/PROFILE***: if you want to consume our prebuilt binaries, ***PROFILE*** must be replaced with one of filenames from our [Conan profiles directory](../CI/conan) (determining the right file should be straight-forward). Otherwise, either select one of our profiles or replace ***CI/conan/PROFILE*** with `default` (your default profile).
If you use `--build=never` and this command fails, then it means that you can't use prebuilt binaries out of the box. For example, try using `--build=missing` instead.
VCMI "recipe" also has some options that you can specify. For example, if you don't care about game videos, you can disable FFmpeg dependency by passing `-o with_ffmpeg=False`. If you only want to make release build, you can use `GENERATE_ONLY_BUILT_CONFIG=1` environment variable to skip generating files for other configurations (our CI does this).
_Note_: you can find full reference of this command [in the official documentation](https://docs.conan.io/en/latest/reference/commands/consumer/install.html) or by executing `conan help install`.
### Using prebuilt binaries from ConanCenter
First, check if binaries for [your platform](https://github.com/conan-io/conan-center-index/blob/master/docs/supported_platforms_and_configurations.md) are produced.
You must adjust the above `conan install` command:
1. Replace ***CI/conan/PROFILE*** with `default`.
2. Additionally pass `-o default_options_of_requirements=True`: this disables all custom options of our `conanfile.py` to match ConanCenter builds.
## Configure project for building
You must pass the generated toolchain file to CMake invocation.
- if using custom CMake presets, just make sure to inherit our `build-with-conan` preset. If you store Conan generated files in a non-default directory, define the path to the generated toolchain in `toolchainFile` field (or `CMAKE_TOOLCHAIN_FILE` cache variable) or include CMake presets file generated by Conan.
- otherwise, if passing CMake options on the command line, use `--toolchain` option (available in CMake 3.21+) or `CMAKE_TOOLCHAIN_FILE` variable.
## Examples
In these examples only the minimum required amount of options is passed to `cmake` invocation, you can pass additional ones as needed.
### Use our prebuilt binaries to build for macOS x86_64 with Xcode
```
conan install . \
--install-folder=conan-generated \
--no-imports \
--build=never \
--profile:build=default \
--profile:host=CI/conan/macos-intel
cmake -S . -B build -G Xcode \
--toolchain conan-generated/conan_toolchain.cmake
```
### Try to use binaries from ConanCenter for your platform
If you also want to build the missing binaries from source, use `--build=missing` instead of `--build=never`.
```
conan install . \
--install-folder=~/my-dir \
--no-imports \
--build=never \
--profile:build=default \
--profile:host=default \
-o default_options_of_requirements=True
cmake -S . -B build \
-D CMAKE_TOOLCHAIN_FILE=~/my-dir/conan_toolchain.cmake
```
### Use our prebuilt binaries to build for iOS arm64 device with custom preset
```
conan install . \
--install-folder=~/my-dir \
--no-imports \
--build=never \
--profile:build=default \
--profile:host=CI/conan/ios-arm64
cmake --preset ios-conan
```
`CMakeUserPresets.json` file:
```json
{
"version": 3,
"cmakeMinimumRequired": {
"major": 3,
"minor": 21,
"patch": 0
},
"configurePresets": [
{
"name": "ios-conan",
"displayName": "iOS",
"inherits": ["build-with-conan", "ios-device"],
"toolchainFile": "~/my-dir/conan_toolchain.cmake",
"cacheVariables": {
"BUNDLE_IDENTIFIER_PREFIX": "com.YOUR-NAME",
"CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM": "YOUR_TEAM_ID"
}
}
]
}
```

View File

@ -8,3 +8,4 @@ target_link_libraries(iOS_utils PRIVATE
target_include_directories(iOS_utils PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_include_directories(iOS_utils PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
vcmi_set_output_dir(iOS_utils "") vcmi_set_output_dir(iOS_utils "")
install(TARGETS iOS_utils RUNTIME DESTINATION ${LIB_DIR} LIBRARY DESTINATION ${LIB_DIR})

7
ios/rpath_remove_symlinks.sh Executable file
View File

@ -0,0 +1,7 @@
#!/usr/bin/env bash
cd "$CODESIGNING_FOLDER_PATH/Frameworks"
tbbFilename=$(otool -L libNullkiller.dylib | egrep --only-matching 'libtbb\S+')
if [[ -L "$tbbFilename" ]]; then
mv -f "$(readlink "$tbbFilename")" "$tbbFilename"
fi

View File

@ -119,6 +119,18 @@ enable_pch(vcmilauncher)
if(APPLE_IOS) if(APPLE_IOS)
set(ICONS_DESTINATION ${DATA_DIR}) set(ICONS_DESTINATION ${DATA_DIR})
# workaround https://github.com/conan-io/conan-center-index/issues/13332
if(USING_CONAN)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/QIOSIntegrationPlugin.h
"#include <QtPlugin>\nQ_IMPORT_PLUGIN(QIOSIntegrationPlugin)"
)
# target_include_directories(vcmilauncher PRIVATE ${CMAKE_BINARY_DIR})
target_link_libraries(vcmilauncher
Qt${QT_VERSION_MAJOR}::QIOSIntegrationPlugin
qt::QIOSIntegrationPlugin
)
endif()
else() else()
set(ICONS_DESTINATION ${DATA_DIR}/launcher) set(ICONS_DESTINATION ${DATA_DIR}/launcher)

View File

@ -12,6 +12,13 @@
#include <QApplication> #include <QApplication>
// Conan workaround https://github.com/conan-io/conan-center-index/issues/13332
#ifdef VCMI_IOS
#if __has_include("QIOSIntegrationPlugin.h")
#include "QIOSIntegrationPlugin.h"
#endif
#endif
int main(int argc, char * argv[]) int main(int argc, char * argv[])
{ {
int result; int result;

View File

@ -97,7 +97,7 @@ void CSettingsView::loadSettings()
ui->lineEditUserDataDir->setText(pathToQString(VCMIDirs::get().userDataPath())); ui->lineEditUserDataDir->setText(pathToQString(VCMIDirs::get().userDataPath()));
ui->lineEditGameDir->setText(pathToQString(VCMIDirs::get().binaryPath())); ui->lineEditGameDir->setText(pathToQString(VCMIDirs::get().binaryPath()));
ui->lineEditTempDir->setText(pathToQString(VCMIDirs::get().userCachePath())); ui->lineEditTempDir->setText(pathToQString(VCMIDirs::get().userLogsPath()));
std::string encoding = settings["general"]["encoding"].String(); std::string encoding = settings["general"]["encoding"].String();
size_t encodingIndex = boost::range::find(knownEncodingsList, encoding) - knownEncodingsList; size_t encodingIndex = boost::range::find(knownEncodingsList, encoding) - knownEncodingsList;

View File

@ -9,9 +9,8 @@ if(APPLE_MACOS)
if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL CMAKE_SYSTEM_PROCESSOR) if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL CMAKE_SYSTEM_PROCESSOR)
# deploy Qt dylibs with macdeployqt # deploy Qt dylibs with macdeployqt
find_program(TOOL_MACDEPLOYQT NAMES macdeployqt PATHS ${qt_base_dir}/bin) find_program(TOOL_MACDEPLOYQT NAMES macdeployqt PATHS ${qt_base_dir}/bin)
if(NOT TOOL_MACDEPLOYQT) endif()
message(FATAL_ERROR "Could not find macdeployqt") if(TOOL_MACDEPLOYQT)
endif()
install(CODE " install(CODE "
execute_process(COMMAND execute_process(COMMAND
\"${TOOL_MACDEPLOYQT}\" \"${bundleDir}\" -verbose=2 \"${TOOL_MACDEPLOYQT}\" \"${bundleDir}\" -verbose=2
@ -38,12 +37,7 @@ if(APPLE_MACOS)
endif() endif()
# deploy other dylibs with conan # deploy other dylibs with conan
install(CODE " vcmi_install_conan_deps("${bundleContentsDir}")
execute_process(COMMAND
conan imports \"${CMAKE_SOURCE_DIR}\" --install-folder \"${CMAKE_SOURCE_DIR}/conan-generated\" --import-folder \"${bundleContentsDir}\"
)
file(REMOVE \"${bundleContentsDir}/conan_imports_manifest.txt\")
")
# perform ad-hoc codesigning # perform ad-hoc codesigning
set(codesignCommand "codesign --verbose=4 --force --options=runtime --timestamp=none --sign -") set(codesignCommand "codesign --verbose=4 --force --options=runtime --timestamp=none --sign -")