nodejs/node · error · Exception

Multiple toolsets not supported in xcode build (target %s)

Error message

Multiple toolsets not supported in xcode build (target %s)

What it means

Raised as an Exception by the xcode generator's GenerateOutput when a target's toolset is not the default 'target' toolset. The Xcode generator does not support multiple toolsets (e.g. host-vs-target cross compilation) within a single project, so any target with spec['toolset'] != 'target' is rejected.

Source

Thrown at tools/gyp/pylib/gyp/generator/xcode.py:705

        # Add gyp/gypi files to project
        if not generator_flags.get("standalone"):
            main_group = pbxp.GetProperty("mainGroup")
            build_group = gyp.xcodeproj_file.PBXGroup({"name": "Build"})
            main_group.AppendChild(build_group)
            for included_file in build_file_dict["included_files"]:
                build_group.AddOrGetFileByPath(included_file, False)

    xcode_targets = {}
    xcode_target_to_target_dict = {}
    for qualified_target in target_list:
        [build_file, target_name, _toolset] = gyp.common.ParseQualifiedTarget(
            qualified_target
        )

        spec = target_dicts[qualified_target]
        if spec["toolset"] != "target":
            raise Exception(
                "Multiple toolsets not supported in xcode build (target %s)"
                % qualified_target
            )
        configuration_names = [spec["default_configuration"]]
        for configuration_name in sorted(spec["configurations"].keys()):
            if configuration_name not in configuration_names:
                configuration_names.append(configuration_name)
        xcp = xcode_projects[build_file]
        pbxp = xcp.project

        # Set up the configurations for the target according to the list of names
        # supplied.
        xccl = CreateXCConfigurationList(configuration_names)

        # Create an XCTarget subclass object for the target. The type with
        # "+bundle" appended will be used if the target has "mac_bundle" set.
        # loadable_modules not in a mac_bundle are mapped to
        # com.googlecode.gyp.xcode.bundle, a pseudo-type that xcode.py interprets

View on GitHub (pinned to 1b2de5e052)

Solutions

  1. Use a generator that supports multiple toolsets (make/ninja) instead of xcode for such trees.
  2. Restructure so targets default to the 'target' toolset, or exclude host-toolset targets when generating for xcode.
  3. Split host-toolset builds into a separate gyp invocation/generator output.

Example fix

// before
'targets': [{ 'target_name': 'host_tool', 'toolset': 'host', 'type': 'executable' }]
// after — drop toolset or build host tools separately for xcode
'targets': [{ 'target_name': 'host_tool', 'type': 'executable' }]
Defensive patterns

Strategy: validation

Validate before calling

for qt in target_list:
    spec = target_dicts[qt]
    if spec.get('toolset', 'target') != 'target':
        raise ValueError(f'non-target toolset not supported by xcode: {qt}')

Type guard

def is_default_toolset(spec) -> bool:
    return spec.get('toolset', 'target') == 'target'

Prevention

When it happens

Trigger: Generating Xcode projects for a .gyp tree that contains targets with toolset set to a non-'target' value (e.g. 'host'). The check at xcode.py:710 fires for the first such qualified_target.

Common situations: A cross-compilation setup that defines host toolset targets; a .gypi include meant for make/ninja accidentally pulled into an xcode build; sharing a gyp tree across generators where only some support multiple toolsets.

Related errors


AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13). Data as JSON: /api/errors/8d8a584b04f4d726. Report an issue: GitHub.