Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add docs for Xcode tools #2431

Merged
merged 2 commits into from Mar 3, 2022
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
160 changes: 154 additions & 6 deletions reference/conanfile/tools/apple.rst
Expand Up @@ -7,6 +7,7 @@ conan.tools.apple

These tools are **experimental** and subject to breaking changes.

.. _conan_tools_apple_xcodedeps:

XcodeDeps
---------
Expand Down Expand Up @@ -37,7 +38,7 @@ And it can also be fully instantiated in the conanfile ``generate()`` method:
.. code-block:: python
:caption: conanfile.py

from conans import ConanFile
from conan import ConanFile
from conan.tools.apple import XcodeDeps

class Pkg(ConanFile):
Expand Down Expand Up @@ -75,7 +76,8 @@ case). The above commands generate the following files:
├── conan_zlib_release_x86_64.xcconfig
├── conan_zlib_vars_debug_x86_64.xcconfig
├── conan_zlib_vars_release_x86_64.xcconfig
└── conandeps.xcconfig
├── conandeps.xcconfig
└── conan_config.xcconfig


The first ``conan install`` with the default *Release* and *x86_64* configuration generates:
Expand All @@ -85,6 +87,7 @@ The first ``conan install`` with the default *Release* and *x86_64* configuratio
- *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 :ref:`XcodeToolchain<conan_tools_apple_xcodetoolchain>` in case it was also set.

The second ``conan install -s build_type=Debug`` generates:

Expand All @@ -93,10 +96,11 @@ The second ``conan install -s build_type=Debug`` generates:
- *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 :ref:`XcodeToolchain<conan_tools_apple_xcodetoolchain>` in case it was also set.

If you want to add this dependencies to you Xcode project, you just have to add the
*conandeps.xcconfig* configuration file for all of the configurations you want to use (usually
*Debug* and *Release*).
*conan_config.xcconfig* configuration file for all of the configurations you want to use
(usually *Debug* and *Release*).

Custom configurations
+++++++++++++++++++++
Expand All @@ -109,7 +113,7 @@ option:

.. code-block:: python

from conans import ConanFile
from conan import ConanFile
from conan.tools.apple import XcodeDeps

class Pkg(ConanFile):
Expand All @@ -127,4 +131,148 @@ option:

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

.. _conan_tools_apple_xcodetoolchain:

XcodeToolchain
--------------

Available since: `1.46.0 <https://github.com/conan-io/conan/releases>`_

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:

.. code-block:: python
:caption: conanfile.py

class Pkg(ConanFile):
generators = "XcodeToolchain"

.. code-block:: text
:caption: conanfile.txt

[generators]
XcodeToolchain

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

.. code:: python

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:

.. code-block:: bash

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

Will create these files:

.. code-block:: bash

.
├── conan_config.xcconfig
├── conantoolchain_release_x86_64.xcconfig
├── conantoolchain_debug_x86_64.xcconfig
└── conantoolchain.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
:ref:`XcodeDeps<conan_tools_apple_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.


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.


XcodeBuild
----------

Available since: `1.46.0 <https://github.com/conan-io/conan/releases>`_

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:

.. code:: python

from conan import conanfile
from conan.tools.apple import XcodeBuild
czoido marked this conversation as resolved.
Show resolved Hide resolved

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

def build(self):
xcodebuild = Xcode(self)
czoido marked this conversation as resolved.
Show resolved Hide resolved
xcodebuild.build("app.xcodeproj")

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

.. code:: bash

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

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 :ref:`[conf]<global_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
:ref:`[conf]<global_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.