XcodeDepsο
The XcodeDeps tool is the dependency information generator for Xcode. It will generate multiple
.xcconfig configuration files, the can be used by consumers using xcodebuild or Xcode. To use
them just add the generated configuration files to the Xcode project or set the -xcconfig
argument from the command line.
The XcodeDeps generator can be used by name in conanfiles:
class Pkg(ConanFile):
generators = "XcodeDeps"
[generators]
XcodeDeps
And it can also be fully instantiated in the conanfile generate() method:
from conan import ConanFile
from conan.tools.apple import XcodeDeps
class Pkg(ConanFile):
settings = "os", "compiler", "arch", "build_type"
requires = "libpng/1.6.37@" # Note libpng has zlib as transitive dependency
def generate(self):
xcode = XcodeDeps(self)
xcode.generate()
When the XcodeDeps generator is used, every invocation of conan install will
generate several configuration files, per direct dependency and configuration. For the conanfile.py
above, for example:
$ conan install conanfile.py # default is Release
$ conan install conanfile.py -s build_type=Debug
This generator is multi-configuration. It will generate different files for the different Debug/Release configurations for each direct requirement. It will also generate one single file (conandeps.xcconfig) aggregating all the files for the direct dependencies (just libpng in this case). The above commands generate the following files:
.
βββ conan_config.xcconfig
βββ conan_libpng.xcconfig
βββ conan_libpng_libpng.xcconfig
βββ conan_libpng_libpng_debug_x86_64.xcconfig
βββ conan_libpng_libpng_release_x86_64.xcconfig
βββ conandeps.xcconfig
Note that even though libpng depends on zlib, no conan_zlib* files are generated. The XcodeDeps generator only emits xcconfig files for direct dependencies, and inlines all transitive data (include directories, library names, flags, etc.) into the props file of the direct dependency.
The first conan install with the default Release and x86_64 configuration generates:
conan_libpng_libpng_release_x86_64.xcconfig: declares variables with conditional logic to be considered only for the active configuration in Xcode or the one passed by command line to xcodebuild. The values inlined here include the includedirs, libs, libdirs, flags, etc., from libpng and from all of its transitive dependencies (in this case, also zlib), merged into a single set of variables named after the direct dependency.
conan_libpng_libpng.xcconfig: includes conan_libpng_libpng_release_x86_64.xcconfig and declares the following Xcode build settings using the inlined values:
SYSTEM_HEADER_SEARCH_PATHS,GCC_PREPROCESSOR_DEFINITIONS,OTHER_CFLAGS,OTHER_CPLUSPLUSFLAGS,FRAMEWORK_SEARCH_PATHS,LIBRARY_SEARCH_PATHS,OTHER_LDFLAGS. This file no longer includes any xcconfig file from transitive dependencies, since the data is already inlined in the props file.conan_libpng.xcconfig: in this case it only includes conan_libpng_libpng.xcconfig, but in the case that the required package has components, this file will include all of the components of the package.
conandeps.xcconfig: configuration file including all direct dependencies, in this case, it just includes
conan_libpng.xcconfig.The main conan_config.xcconfig file, to be added to the project. Includes both the files from this generator and the generated by the XcodeToolchain in case it was also set.
The second conan install -s build_type=Debug generates:
conan_libpng_libpng_debug_x86_64.xcconfig: same variables as the one above for Debug configuration, also containing the inlined data from transitive dependencies.
conan_libpng_libpng.xcconfig: this file has been already created by the previous command, now itβs modified to add the include for conan_libpng_libpng_debug_x86_64.xcconfig.
conan_libpng.xcconfig: this file will remain the same.
conandeps.xcconfig: configuration file including all direct dependencies, in this case, it just includes
conan_libpng.xcconfig.The main conan_config.xcconfig file, to be added to the project. Includes both the files from this generator and the generated by the XcodeToolchain in case it was also set.
If you want to add this dependencies to you Xcode project, you just have to add the conan_config.xcconfig configuration file for all of the configurations you want to use (usually Debug and Release).
Additional variables definedο
Besides the variables that define the Xcode build settings mentioned above, there are additional variables declared that may be useful to use in your Xcode project:
PACKAGE_ROOT_<package_name>: Set to the location of the package_folder attribute.
Components supportο
This generator supports packages with components. That means that:
If a dependency
package_info()declarescpp_info.requireson some components, only the data from those components (and their transitive components) will be inlined into the props file of the direct dependency. Components that are not required by anyone are not inlined.The current package
requireswill be fully dependent on and all components. Recall that thepackage_info()only applies for consumers, but not to the current package.
Custom configurationsο
If your Xcode project defines custom configurations, like ReleaseShared, or MyCustomConfig,
it is possible to define it into the XcodeDeps generator, so different project configurations can
use different set of dependencies. Letβs say that our current project can be built as a shared library,
with the custom configuration ReleaseShared, and the package also controls this with the shared
option:
from conan import ConanFile
from conan.tools.apple import XcodeDeps
class Pkg(ConanFile):
settings = "os", "compiler", "arch", "build_type"
options = {"shared": [True, False]}
default_options = {"shared": False}
requires = "zlib/1.3.1"
def generate(self):
xcode = XcodeDeps(self)
# We assume that -o *:shared=True is used to install all shared deps too
if self.options.shared:
xcode.configuration = str(self.settings.build_type) + "Shared"
xcode.generate()
This will manage to generate new .xcconfig files for this custom configuration, and when you switch to this configuration in the IDE, the build system will take the correct values depending whether we want to link with shared or static libraries.