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 <sbv1...@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.k...@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 > > -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake-developers