Xcode build rules: ignore output, or invoke file mapping in compilation order

I'm working on an Xcode c++ project consisting of 2 targets. This project needs to compile on both Xcode 9.2 and the latest Xcode.

  • Target 1 is merely a helper target; it builds a dummy cmdline hello world app. But the target is abused by attaching a build rule on it, which calls an external utility to transform .xyz files into a set of .inc and .metal files. Basically,
    • files matching: .xyz
    • custom script: ...
    • output files:
      • $(INPUT_FILE_DIR)/$(INPUT_FILE_BASE).metal
  • Target 2 is the main app, which includes these .metal files as source files, and in which there are .cpp files that #include these .inc files.
  • Target 2 has target 1 as a dependency, to ensure target 1 updates the .metal and .inc files when needed before target 2 starts compiling.
  • The .xyz files have their target membership set to only target 1, and the .metal and .inc files belong only to target 2.

This works, insofar that all .metal and .inc files are definitely updated when needed before the target 2 starts compiling.

However, when building this helper target 1, Xcode insists on also compiling and linking in the build rule's output .metal files into target 1's binary (I think). How can I stop this from happening? This is problematic, because adding in these .metal files fails the link phase of target 1 (these metal files have extra dependencies of their own).

Previously target 1's build rule's output section only listed the .inc file types. That way this setup works, presumably because Xcode doesn't have any association for .inc files and thus doesn't pick them up after building them. However, to ensure Xcode's is-up-to-date check also checks the .xyz and resulting .metal file dependency, I'd like to have .metal listed in the output files list as well.

I tried to put the build rule itself on target 2, also nicely negating the need for this helper target 1, but then Xcode doesn't get it's source file compilation order straight. If I delete all resulting .inc files, Xcode happily first compiles some .cpp files in which these .inc files are #included before coming round to invoke the .xyz -> .inc build rule. So I guess Xcode doesn't take a build rule's input -> output mapping into consideration in the cpp-#included-files-are-up-to-date build dependency tree?

I also tried negating the .metal files from being taken up by adding yet another build rule on target 1, this one specifying "metal files" and just not supplying any script. This does work.

But I can't believe it is not possible to convince Xcode to ignore a build rule's output file list, stopping it from further compiling/linking them...

Is there any setting anywhere controlling this behavior? Or, better yet, is there a way I can put the build rule on target 2 while also getting Xcode's cpp #include dependency into the mix, as I failed to do above?

Read more here: https://stackoverflow.com/questions/68471071/xcode-build-rules-ignore-output-or-invoke-file-mapping-in-compilation-order

Content Attribution

This content was originally published by Carl Colijn at Recent Questions - Stack Overflow, and is syndicated here via their RSS feed. You can read the original post over there.

%d bloggers like this: