====== Driver ====== .. contents:: :local: Introduction ============ This document describes the lld driver. The purpose of this document is to describe both the motivation and design goals for the driver, as well as details of the internal implementation. Overview ======== The lld driver is designed to support a number of different command line interfaces. The main interfaces we plan to support are binutils ld, Apple's ld64, and Microsoft's link.exe. Flavors ------- Each of these different interfaces is referred to as a flavor. There is also an extra flavor for ``lld -core``. This is equivalent to ``-cc1`` in clang. The current flavors are. * ld * ld64 * link * core Selecting a Flavor ^^^^^^^^^^^^^^^^^^ There are two different ways to tell lld which flavor to be. They are checked in order, so the second overrides the first. The first is to symlink :program:`lld` as :program:`lld-{flavor}` or just :program:`{flavor}`. You can also specify it as the first command line argument using ``-flavor``:: $ lld -flavor ld There is a shortcut for ``-flavor core`` as ``-core``. Argument translation and lld -core ---------------------------------- Due to the different driver flavors and the need to write portable tests, there is ``lld -core``. Driver flavors translate options into ``lld -core`` options. These options are then forwarded to ``lld -core`` to run the actual link. The options passed to ``lld -core`` can be seen by passing ``-###`` to any driver flavor. Targets ------- The ``-target `` option can be passed to any driver flavor to link for a specific target. You can also prefix the :program:`lld` symlink with a target triple to default to that target. If neither of these is set, the default target is the target LLVM was configured for. Adding an Option ================ #. Add the option to the desired :file:`lib/Driver/{flavor}Options.td`. #. If there is no ``lld -core`` option, add the option to :file:`lib/Driver/CoreOptions.td`. All ``lld -core`` start with a single - and if they have a value, it is joined with a =. ``lld -core`` options should have sensible, non-abbreviated names and should be shared between flavors where possible. #. Modify the ``{flavor}Driver::transform`` function to transform the added option into one or more core options. #. Add the option to :cpp:class:`lld::LinkerOptions` in :file:`include/lld/Driver/LinkerOptions.h` and modify the move constructor to move the option value. #. Modify :cpp:func:`lld::parseCoreArgs` in :file:`lib/Driver/Drivers.cpp` to fill the :cpp:class:`lld::LinkerOptions` with the new option. #. Modify lld to use the new option. Adding a Flavor =============== #. Add an entry for the flavor in :file:`include/lld/Driver/Driver.h` to :cpp:class:`lld::Driver::Flavor`. #. Add an entry in :file:`tools/lld/lld.cpp` to :cpp:func:`lld::Driver::strToFlavor`. This allows the flavor to be selected via symlink and :option:`-flavor`. #. Add a tablegen file called :file:`lib/Driver/{flavor}Options.td` that describes the options. If the options are a superset of another driver, that driver's td file can simply be included. The :file:`{flavor}Options.td` file must also be added to :file:`lib/Driver/CMakeLists.txt`. #. Add a ``{flavor}::{flavor}OptTable`` as a subclass of :cpp:class:`llvm::opt::OptTable` in :file:`lib/Driver/Drivers.cpp`. #. Add a ``{flavor}Driver`` as a subclass of :cpp:class:`lld::Driver` in :file:`lib/Driver/Drivers.cpp`. It must have a :cpp:func:`transform` function which takes argc/argv and returns a ``lld -core`` ArgList. #. Modify :cpp:func:`Driver::create` to create an instance of the new driver.