conan.tools.apple

Warning

These tools are still experimental (so subject to breaking changes) but with very stable syntax. We encourage the usage of it to be prepared for Conan 2.0.

XcodeDeps

Available since: 1.42.0

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:

conanfile.py
class Pkg(ConanFile):
    generators = "XcodeDeps"
conanfile.txt
[generators]
XcodeDeps

And it can also be fully instantiated in the conanfile generate() method:

conanfile.py
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 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 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_libpng.xcconfig
├── conan_libpng_debug_x86_64.xcconfig
├── conan_libpng_release_x86_64.xcconfig
├── conan_libpng_vars_debug_x86_64.xcconfig
├── conan_libpng_vars_release_x86_64.xcconfig
├── conan_zlib.xcconfig
├── conan_zlib_debug_x86_64.xcconfig
├── conan_zlib_release_x86_64.xcconfig
├── conan_zlib_vars_debug_x86_64.xcconfig
├── conan_zlib_vars_release_x86_64.xcconfig
├── conandeps.xcconfig
└── conan_config.xcconfig

The first conan install with the default Release and x86_64 configuration generates:

  • conan_libpng_vars_release_x86_64.xcconfig: declares some intermediate variables that are included in conan_libpng_release_x86_64.xcconfig

  • conan_libpng_release_x86_64.xcconfig: includes conan_libpng_vars_release_x86_64.xcconfig and declares variables with conditional logic to be considered only for the active configuration in Xcode or the one passed by command line to xcodebuild.

  • conan_libpng.xcconfig: includes conan_libpng_release_x86_64.xcconfig and declares the following Xcode build settings: HEADER_SEARCH_PATHS, GCC_PREPROCESSOR_DEFINITIONS, OTHER_CFLAGS, OTHER_CPLUSPLUSFLAGS, FRAMEWORK_SEARCH_PATHS, LIBRARY_SEARCH_PATHS, OTHER_LDFLAGS. It also includes the generated xcconfig files for transitive dependencies (conan_zlib.xcconfig in this case).

  • Same 3 files will be generated for each dependency in the graph. In this case, as zlib is a dependency of libpng it will generate: conan_zlib_vars_release_x86_64.xcconfig, conan_zlib_release_x86_64.xcconfig and conan_zlib.xcconfig.

  • conandeps.xcconfig: configuration files 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_vars_debug_x86_64.xcconfig: same variables as the one below for Debug configuration.

  • conan_libpng_debug_x86_64.xcconfig: same variables as the one below for Debug configuration.

  • conan_libpng.xcconfig: this file has been already creted by the previous command, now it’s modified to add the include for conan_libpng_debug_x86_64.xcconfig.

  • Like in the previous command the same 3 files will be generated for each dependency in the graph. In this case, as zlib is a dependency of libpng it will generate: conan_zlib_vars_debug_x86_64.xcconfig, conan_zlib_debug_x86_64.xcconfig and conan_zlib.xcconfig.

  • conandeps.xcconfig: configuration files 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).

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.2.11"

    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 wether we want to link with shared or static libraries.

XcodeToolchain

Available since: 1.46.0

The XcodeToolchain is the toolchain generator for Xcode. It will generate .xcconfig configuration files that can be added to Xcode projects. This generator translates the current package configuration, settings, and options, into Xcode .xcconfig files syntax.

The XcodeToolchain generator can be used by name in conanfiles:

conanfile.py
class Pkg(ConanFile):
    generators = "XcodeToolchain"
conanfile.txt
[generators]
XcodeToolchain

And it can also be fully instantiated in the conanfile generate() method:

from conan import ConanFile
from conan.tools.apple import XcodeToolchain

class App(ConanFile):
    settings = "os", "arch", "compiler", "build_type"

    def generate(self):
        tc = XcodeToolchain(self)
        tc.generate()

The XcodeToolchain will generate three files after a conan install command. As explained above for the XcodeDeps generator, each different configuration will create a set of files with different names. For example, running conan install for Release first and then Debug configuration:

$ conan install conanfile.py # default is Release
$ conan install conanfile.py -s build_type=Debug

Will create these files:

.
├── conan_config.xcconfig
├── conantoolchain_release_x86_64.xcconfig
├── conantoolchain_debug_x86_64.xcconfig
├── conantoolchain.xcconfig
└── conan_global_flags.xcconfig

Those files are:

  • The main conan_config.xcconfig file, to be added to the project. Includes both the files from this generator and the generated by the XcodeDeps in case it was also set.

  • conantoolchain_<debug/release>_x86_64.xcconfig: declares CLANG_CXX_LIBRARY, CLANG_CXX_LANGUAGE_STANDARD and MACOSX_DEPLOYMENT_TARGET variables with conditional logic depending on the build configuration, architecture and sdk set.

  • conantoolchain.xcconfig: aggregates all the conantoolchain_<config>_<arch>.xcconfig files for the different installed configurations.

  • conan_global_flags.xcconfig: this file will only be generated in case of any configuration variables related to compiler or linker flags are set. Check the configuration section below for more details.

Every invocation to conan install with different configuration will create a new conantoolchain_<config>_<arch>.xcconfig file that is aggregated in the conantoolchain.xcconfig, so you can have different configurations included in your Xcode project.

The XcodeToolchain files can declare the following Xcode build settings based on Conan settings values:

  • MACOSX_DEPLOYMENT_TARGET is based on the value of the os.version setting and will make the build system to pass the flag -mmacosx-version-min with that value (if set). It defines the operating system version the binary should run into.

  • CLANG_CXX_LANGUAGE_STANDARD is based on the value of the compiler.cppstd setting that sets the C++ language standard.

  • CLANG_CXX_LIBRARY is based on the value of the compiler.libcxx setting and sets the version of the C++ standard library to use.

One of the advantages of using toolchains is that they can help to achieve the exact same build with local development flows, than when the package is created in the cache.

conf

This toolchain is also affected by these [conf] variables:

  • tools.build:cxxflags list of C++ flags.

  • tools.build:cflags list of pure C flags.

  • tools.build:sharedlinkflags list of flags that will be used by the linker when creating a shared library.

  • tools.build:exelinkflags list of flags that will be used by the linker when creating an executable.

  • tools.build:defines list of preprocessor definitions.

If you set any of these variables, the toolchain will use them to generate the conan_global_flags.xcconfig file that will be included from the conan_config.xcconfig file.

XcodeBuild

Available since: 1.46.0

The Xcode build helper is a wrapper around the command line invocation of Xcode. It will abstract the calls like xcodebuild -project app.xcodeproj -configuration <config> -arch <arch> ...

The Xcode helper can be used like:

from conan import conanfile
from conan.tools.apple import XcodeBuild

class App(ConanFile):
    settings = "os", "arch", "compiler", "build_type"

    def build(self):
        xcodebuild = XcodeBuild(self)
        xcodebuild.build("app.xcodeproj")

Xcode.build() method

def build(self, xcodeproj, target=None):
  • xcodeproj: the xcodeproj file to build.

  • target: the target to build, in case this argument is passed to the build() method it will add the -target argument to the build system call. If not passed, it will build all the targets passing the -alltargets argument instead.

The Xcode.build() method internally implements a call to xcodebuild like:

$ xcodebuild -project app.xcodeproj -configuration <configuration> -arch <architecture> <sdk> <verbosity> -target <target>/-alltargets

Where:

  • configuration is the configuration, typically Release or Debug, which will be obtained from settings.build_type.

  • architecture is the build architecture, a mapping from the settings.arch to the common architectures defined by Apple ‘i386’, ‘x86_64’, ‘armv7’, ‘arm64’, etc.

  • sdk is set based on the values of the os.sdk and os.sdk_version defining the SDKROOT Xcode build setting according to them. For example, setting os.sdk=iOS and os.sdk_version=8.3` will pass SDKROOT=iOS8.3 to the build system. In case you defined the tools.apple:sdk_path in your [conf] this value will take preference and will directly pass SDKROOT=<tools.apple:sdk_path> so take into account that for this case the skd located in that path should set your os.sdk and os.sdk_version settings values.

  • verbosity is the verbosity level for the build and can take value ‘verbose’ or ‘quiet’ if set by tools.apple.xcodebuild:verbosity in your [conf]

conf

  • tools.apple.xcodebuild:verbosity verbosity value for the build, can be ‘verbose’ or ‘quiet’

  • tools.apple:sdk_path path for the sdk location, will set the SDKROOT value with preference over composing the value from the os.sdk and os.sdk_version settings.