xcodebuild - Xcode custom build rule, file dependencies in order - Stack Overflow

I have added my own build rule to Xcode, to compile a custom type of file. Let's call it .foo.I n

I have added my own build rule to Xcode, to compile a custom type of file. Let's call it .foo.

I need to be able to specify that file A should be compiled before file B (since B depends on A). I have already written the logic to calculate these dependencies in a Run Script build phase, which runs before the Compile Sources phase. I can guarantee that there are no cycles (or if there are, it's ok for the build to fail).

How do I tell Xcode about these file dependencies for .foo files, so that it compiles them in the right order?

Things I've tried:

  • outputting a "discovered dependency file" for each .foo file, into the derived sources directory, then adding it to my .foo build rule. I believe the syntax of the file should be B.foo: A.foo (indicating that A must be compiled before B). I've tried it with both just filenames and with full paths. Xcode is finding the file, but does not seem to act upon it.
  • Outputting an xcfilelist for each .foo file. This one I can't get to work -- in the "Input file lists" section of my .foo rule, Xcode doesn't seem to want to expand any build variables that refer to the current file. For example, if I add an item $(DERIVED_SOURCES_DIR)/$(INPUT_FILE_NAME).deps to the "input file lists" section, Xcode will expand "DERIVED_SOURCES_DIR" but will not expand "INPUT_FILE_NAME". From this I conclude that you can't have a per-file input file list, you can only have one single list for the whole .foo build rule. Is this assumption correct?

What am I missing? There must be a way of telling Xcode about file dependencies, right?

Specific questions about .d files:

In a "discovered dependency file" (i.e. a .d file), as I understand it the syntax is <target>: <dep> <dep> <dep>.

  1. Should the target be a full path or just a filename?
  2. Should the target refer to my .foo file (the thing I'm building, inside my source folder), or my .foo.out file (the thing it builds, inside my derived files folder)?
  3. The deps, i.e. the things that need to be built before the target: same question regarding full path, and do they refer to the source or the built output?

I have looked in Xcode's build timeline, and all my .foo files are building in parallel, it doesn't seem to be paying attention to anything I put in the .d files. So I suspect I'm getting the syntax wrong somehow.

I have added my own build rule to Xcode, to compile a custom type of file. Let's call it .foo.

I need to be able to specify that file A should be compiled before file B (since B depends on A). I have already written the logic to calculate these dependencies in a Run Script build phase, which runs before the Compile Sources phase. I can guarantee that there are no cycles (or if there are, it's ok for the build to fail).

How do I tell Xcode about these file dependencies for .foo files, so that it compiles them in the right order?

Things I've tried:

  • outputting a "discovered dependency file" for each .foo file, into the derived sources directory, then adding it to my .foo build rule. I believe the syntax of the file should be B.foo: A.foo (indicating that A must be compiled before B). I've tried it with both just filenames and with full paths. Xcode is finding the file, but does not seem to act upon it.
  • Outputting an xcfilelist for each .foo file. This one I can't get to work -- in the "Input file lists" section of my .foo rule, Xcode doesn't seem to want to expand any build variables that refer to the current file. For example, if I add an item $(DERIVED_SOURCES_DIR)/$(INPUT_FILE_NAME).deps to the "input file lists" section, Xcode will expand "DERIVED_SOURCES_DIR" but will not expand "INPUT_FILE_NAME". From this I conclude that you can't have a per-file input file list, you can only have one single list for the whole .foo build rule. Is this assumption correct?

What am I missing? There must be a way of telling Xcode about file dependencies, right?

Specific questions about .d files:

In a "discovered dependency file" (i.e. a .d file), as I understand it the syntax is <target>: <dep> <dep> <dep>.

  1. Should the target be a full path or just a filename?
  2. Should the target refer to my .foo file (the thing I'm building, inside my source folder), or my .foo.out file (the thing it builds, inside my derived files folder)?
  3. The deps, i.e. the things that need to be built before the target: same question regarding full path, and do they refer to the source or the built output?

I have looked in Xcode's build timeline, and all my .foo files are building in parallel, it doesn't seem to be paying attention to anything I put in the .d files. So I suspect I'm getting the syntax wrong somehow.

Share Improve this question edited Mar 12 at 16:57 Amy Worrall asked Mar 12 at 10:57 Amy WorrallAmy Worrall 15.8k3 gold badges44 silver badges65 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 0

I’ve dealt with this before when adding a custom build rule in Xcode. Getting the file dependencies to work took some experimenting, but here’s what finally worked for me:

1. Use Absolute Paths in the .d Files

Both the target (the file you’re building) and its dependencies need to have full absolute paths, not just filenames or relative paths.

2. Target Should Be the Output File

In the.d file, the target must refer to the output of your build rule (e.g., A.foo.out), not the source file (A.foo).

Example:

/path/to/DerivedData/B.foo.out: /path/to/DerivedData/A.foo.out

This informs Xcode that B.foo.out is dependent on A.foo.out.

3. Inform Xcode About the.d File

In your build rule settings:

Add the.d file under Output Files

Example: $(DERIVED_SOURCES_DIR)/$(INPUT_FILE_BASE).d

Mark the box that indicates it's a dependency file.

4. Create Clean Build

Do a clean build after having this set up. Xcode caching can conceal problems otherwise.

In Short:

Use absolute paths.

Targets and dependencies are output files, not sources.

Register the.d files correctly in the build rule.

This made Xcode compile my files in the correct order. Hope this helps!

  1. Generate .d Files with Absolute Paths

    • In your Run Script phase, output a .d file for each .foo file using absolute paths to the output files (not source files). For example, if B.foo depends on A.foo:

      CollapseWrapCopy

      /path/to/DerivedData/.../B.foo.out: /path/to/DerivedData/.../A.foo.out

      • Use build variables like $(DERIVED_FILE_DIR) to compute paths dynamically, e.g.:

        bash

        CollapseWrapCopy

        echo "$(DERIVED_FILE_DIR)/B.foo.out: $(DERIVED_FILE_DIR)/A.foo.out" > "$(DERIVED_SOURCES_DIR)/B.d"

  2. Configure the .foo Build Rule

    In your custom build rule for *.foo files:

    • Output Files:

      • Add the compiled output: $(DERIVED_FILE_DIR)/$(INPUT_FILE_BASE).foo.out

        Add the .d file: $(DERIVED_SOURCES_DIR)/$(INPUT_FILE_BASE).d

      • Check “Use Discovered Dependency File” and set it to $(DERIVED_SOURCES_DIR)/$(INPUT_FILE_BASE).d.

      • Ensure your script compiles $(INPUT_FILE_PATH) to $(DERIVED_FILE_DIR)/$(INPUT_FILE_BASE).foo.out.

  3. Ensure Proper Build Order

    Since your Run Script runs before Compile Sources, it should generate the .d files in time for the build rule (which runs during Compile Sources). Verify this in the Build Phases tab.

  4. Clean and Test

    Do a Clean Build Folder (Cmd+Shift+K) to clear caches. Check the build timeline to confirm A.foo compiles before B.foo.

Xcode respects .d files when they’re tied to a build rule’s output and use absolute paths to output files. Previous (e.g., source-to-source deps like B.foo: A.foo) didn’t work because Xcode needs the dependency chain based on compiled outputs.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744757273a4591957.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信