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_config.xcconfig
├── conan_libpng.xcconfig
├── conan_libpng_libpng.xcconfig
├── conan_libpng_libpng_debug_x86_64.xcconfig
├── conan_libpng_libpng_release_x86_64.xcconfig
├── conan_zlib.xcconfig
├── conan_zlib_zlib.xcconfig
├── conan_zlib_zlib_debug_x86_64.xcconfig
├── conan_zlib_zlib_release_x86_64.xcconfig
└── conandeps.xcconfig

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.

  • conan_libpng_libpng.xcconfig: includes conan_libpng_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_zlib.xcconfig in this case).

  • 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.

  • 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_zlib_release_x86_64.xcconfig, conan_zlib_zlib.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_libpng_debug_x86_64.xcconfig: same variables as the one below for Debug configuration.

  • conan_libpng_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.

  • conan_libpng.xcconfig: this file will remain the same.

  • 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_zlib_debug_x86_64.xcconfig, conan_zlib_zlib.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).

Components support

Since Conan version 1.49.0, this generator supports packages with components. That means that:

  • If a dependency package_info() declares cpp_info.requires on some components, the generated .xcconfig files will contain includes to only those components.

  • The current package requires will be fully dependent on and all components. Recall that the package_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.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.

conan.tools.apple.fix_apple_shared_install_name()

def fix_apple_shared_install_name(conanfile):

Parameters:

  • conanfile: Conanfile instance.

This tool will search for all the dylib files in the conanfile’s package_folder and fix both the LC_ID_DYLIB and LC_LOAD_DYLIB fields on those files using the install_name_tool utility available in macOS.

  • For LC_ID_DYLIB which is the field containing the install name of the library, it will change the install name to one that uses the @rpath. For example, if the install name is /path/to/lib/libname.dylib, the new install name will be @rpath/libname.dylib. This is done by executing internally something like:

install_name_tool /path/to/lib/libname.dylib -id @rpath/libname.dylib
  • For LC_LOAD_DYLIB which is the field containing the path to the library dependencies, it will change the path of the dependencies to one that uses the @rpath. For example, if the path is /path/to/lib/dependency.dylib, the new path will be @rpath/dependency.dylib. This is done by executing internally something like:

install_name_tool /path/to/lib/libname.dylib -change /path/to/lib/dependency.dylib @rpath/dependency.dylib

This tool is typically needed by recipes that use Autotools as the build system and in the case that the correct install names are not fixed in the library being packaged. Use this tool, if needed, in the conanfile’s package() method like:

from conan.tools.apple import fix_apple_shared_install_name

class HelloConan(ConanFile):

  ...

  def package(self):
      autotools = Autotools(self)
      autotools.install()
      fix_apple_shared_install_name(self)