[cmake-developers] Extending XCode scheme generation support

Steven Velez sbv1976 at gmail.com
Fri Sep 29 14:34:36 EDT 2017


Hi guys,

Any thoughts on this?

TL;DR Version:

We can add some target properties that the Xcode generator uses to
customize schemes:

* XCODE_SCHEME_NAME
* XCODE_SCHEME_LAUNCH_OPTS
* XCODE_SCHEME_LAUNCH_ADTL_OPTS
* XCODE_SCHEME_LAUNCH_RUNNABLE
* XCODE_SCHEME_LAUNCH_ARGUMENTS
* XCODE_SCHEME_LAUNCH_ENVIRONMENT

OR

The configure_file function can be augmented to be runnable during
generation so that it can process generator expressions which are
defined to support this scheme-customization workflow.

Thanks,
Steven


On Thu, Sep 21, 2017 at 9:36 PM, Steven Velez <sbv1976 at gmail.com> wrote:
> Hello Again,
>
> Sorry for the delay.  After some consideration and investigation, I have the
> following two proposals:
>
> # Property-Centric
> In this proposal, the generation of the scheme files is customized primarily by
> a user setting additional, specialized properties on a given target, which then
> affect the generation of the scheme files associated with that target.  Scheme
> files are persisted as xml, and currently, each scheme file contains six
> elements directly underneath the root element which correspond to each of the
> [scheme actions](http://help.apple.com/xcode/mac/8.3/#/devd9c8382e7) available
> in the scheme editor.
>
> To this end, with one exception, the specialized properties defined for this
> purpose will follow the convention `XCODE_SCHEME_<ACTIONNAME>_<CONFIGID>` where
> `<ACTIONNAME>` may be one of `BUILD`, `TEST`, `LAUNCH`, `PROFILE`, `ANALYZE`,
> `ARCHIVE` and `<CONFIGID>` will be appropriate to the particular item being
> configured and detailed further below.  The exception to this convention is the
> `XCODE_SCHEME_NAME` property which will be used to override the default name of
> the generated scheme that by default matches the name of the target it is
> associated to. It can even be set to the empty string in order to completely
> disable scheme generation for select targets.
>
> These properties will be ignored by all generators but the Xcode generator.
>
> ## CONFIGIDs
> Being unable to find official, public documentation on the design and format of
> xcode scheme files, experimental analysis has revealed that that there are
> approximately three classes of configuration methods used in each action's xml
> element.  The first class of options are specified as attributes of the action's
> xml element.  The second class of options are specified as elements providing
> name/value pairs via attributes and are are children of an `AdditionalOptions`
> element in the action element, and the final class is everything else and which
> has a different format in each case.
>
> This proposal is primarily concerned with extending and controlling the
> configuration of the Launch action and therefore includes CONFIGIDs that apply
> to that action, though it is possible and in some cases likely that they will
> have general utility in most other actions.  These are as follows:
>
> * `OPTS` - Properties with this config id will be a CMake list of name/value
> pairs where the names and values are strings separated by the first embedded
> equals sign. Once parsed, the names will be used to identify xml attributes to
> set on the action element and the values will of course be the values set on
> those attributes.
> * `ADTL_OPTS` - Like with the `OPTS` config id, this will be a list of
> name/value pairs.  However, the names and values will be used to define xml
> elements of the form `<AdditionalOption key="&name;" value="&value;"
> isEnabled="YES"/>` which are then added to the `<AdditionalOptions>` element
> of the current action.  Note, that there are no provisions for controlling the
> `isEnabled` state of an option besides those programmatic elements of CMake
> which would make it possible to specify (or not) a given additional option.
> It is unclear what the semantic difference is between "options" and
> "additional options" as there is no clear distinction in the Xcode UI.
> * `RUNNABLE` - This is a simple string which can be interpreted as a target
> reference if it matches the name of an executable target in the project, or a
> literal path to an executable on the file system otherwise.  In either case,
> it specifies the executable which will be run when the scheme is active.  When
> no `RUNNABLE` target is specified, the current, default runnable is used.
> * `ARGUMENTS` - Is a CMake list of strings that each define an element of the
> form `<CommandLineArgument argument="&value;" isEnabled="YES" />` to add to
> the `<CommandLineArguments>` element of the current action.  As with
> `ADTL_OPTS`, `isEnabled` cannot be changed. These values are passed to the
> executable specified by `RUNNABLE` as command line arguments.
> * `ENVIRONMENT` - This is similar to `ADTL_OPTS` except the elements created are
> of the form `<EnvironemtVariable key="&name;" value="&value;"
> isEnabled="YES"/>` and they are added to the `<EnvironmentVariables>` element
> of the current action.  These values are used to initialize the process
> environment of the executable specified by `RUNNABLE`
>
> ## Unexplored/Unsupported
> Support for scheme action pre and post actions are not part of this proposal
> because it is believed that in order to support them, target property names will
> either have to be excessively cumbersome, or the supported functionality will
> need to be excessively specialized and limited.
>
> ## Explicit list of properties
> When conventions above are expanded to meet the needs of the Launch action, this
> results in the following six properties which can be applied to any target.
>
> * `XCODE_SCHEME_NAME`
> * `XCODE_SCHEME_LAUNCH_OPTS`
> * `XCODE_SCHEME_LAUNCH_ADTL_OPTS`
> * `XCODE_SCHEME_LAUNCH_RUNNABLE`
> * `XCODE_SCHEME_LAUNCH_ARGUMENTS`
> * `XCODE_SCHEME_LAUNCH_ENVIRONMENT`
>
> ## Generator Expressions
> The properties specified for scheme customization should support generator
> expressions.  Most notably, `XCODE_SCHEME_NAME` should recognize `$<CONFIG>`,
> generating a different scheme file for each configuration.  The value that
> `$<CONFIG>` evaluates to for `XCODE_SCHEME_NAME` should persist for every
> evaluation of `$<CONFIG>` while a given scheme file is being generated.  If
> `$<CONFIG>` is used in a property for which `$<CONFIG>` was not also indicated
> in `XCODE_SCHEME_NAME`, the results are undefined.
>
> ## Examples
>
> Configure xcode to generate a scheme that will aid in debugging a cli program's
> help option
> ```
> add_executable(simple_tool simpletool.c)
> set_target_properties(simple_tool
>     XCODE_SCHEME_LAUNCH_ARGUMENTS --help)
> ```
>
> Configure schemes that build specific shared libraries to execute a common
> executable target.
> ```
> add_library(tools1 SHARED tools1.c)
> add_library(tools2 SHARED tools2.c)
> add_executable(main main.c)
> target_link_libraries(main tools1 tools2)
>
> set_target_properties(tools1 tools2
>     XCODE_SCHEME_NAME "$<TARGET:NAME>|$<CONFIG>"
>     XCODE_SCHEME_LAUNCH_OPTS "buildConfiguration=$<CONFIG>"
>     XCODE_SCHEME_LAUNCH_RUNNABLE main)
> ```
>
> Enable test tooling built in to the app via an environment variable and coax the
> linker in to loading the Qt debug libraries
> ```
> add_executable(qtapp qtmain.cpp)
> set(_env
>     "ENABLE_TEST_TOOLBAR=1"
>     "$<$<CONFIG:debug>:DYLD_IMAGE_SUFFIX=_debug>")
> set_target_properties(qtapp
>     XCODE_SCHEME_NAME "qtapp -- $<CONFIG>"
>     XCODE_SCHEME_ENVIRONMENT ${_env})
> ```
>
> # Scheme-File-centric
> While the property-centric proposal described above seems relatively capable,
> and it follows conventions established by the `MACOSX_*`, `VS_*`, `XCODE_*`
> properties already defined and others, they seem fairly invasive, high
> maintenance, and they do not allow schemes targeting built-in projects (such as
> ALL_BUILD) to be customized.  Further, it seems as though scheme/target
> relationships are basically 1:1.  Apart from configuration variants, it is not
> possible to have more than one scheme reference a given target as a build
> dependency, and it is certainly not possible to have the build action of a
> scheme build more than a single top-level target.
>
> I believe all of these issues could be addressed and additional leverage given
> to users to utilize the full abilities of schemes now and in the future, by
> adding two additional CMake features.
>
> The first is to add a flag to `configure_file` that will cause it to run during
> the generation phase and therefore be able to expand generator expressions.
>
> The second is to define an xcode-specific read-only target property:
> `XCODE_BLUEPRINT_ID`.
>
> Once these constructs are available, a user could configure files with bits of
> xml that look like this:
> ```xml
> <BuildableReference
>    BuildableIdentifier = "primary"
>    BlueprintIdentifier = "$<TARGET_PROPERTY:footarget,XCODE_BLUEPRINT_ID>"
>    BuildableName = "ALL_BUILD"
>    BlueprintName = "ALL_BUILD"
>    ReferencedContainer = "container:foo.xcodeproj">
> ```
>
> I believe that the fact that the blue print id for a given target changes on
> each generation, is the only thing preventing scheme files from being manually
> (and flexibly) created during the configure phase.
>
> In full disclaimer: I have not investigated the feasibility of implementing such
> a solution
>
> Thanks,
> Steven
>
> On Fri, Sep 15, 2017 at 11:48 AM, Steven Velez <sbv1976 at gmail.com> wrote:
>> Sure.. but I haven't even thought about it much yet.  So when that has
>> happened, I'll make a more formal proposal.
>>
>> Thanks,
>> Steven
>>
>> On Fri, Sep 15, 2017 at 11:04 AM, Brad King <brad.king at kitware.com> wrote:
>>>
>>> On 09/15/2017 10:55 AM, Steven Velez wrote:
>>> > I am assuming that the lack of response indicates that there has not
>>> > been much thought or interest expressed along this dimension of the
>>> > feature.
>>> >
>>> > Would a better way to approach this be to implement a prototype and
>>> > create a WIP MR?
>>>
>>> Can you post a more specific proposal here?  E.g. with proposed
>>> target properties to control it and show some examples.
>>>
>>> Thanks,
>>> -Brad
>>
>>


More information about the cmake-developers mailing list