jerrymarino / xcbuildkit

xcbuildkit is a framework to extend or replace Xcode's build system
Other
216 stars 17 forks source link

[DNM] Example of how to pass indexing info response messages with symlinked object file #35

Closed thiagohmcruz closed 2 years ago

thiagohmcruz commented 2 years ago

Experiment

Small experiment to illustrate how we could potentially symlink indexing related files to bazel-out in such a way that Xcode continues to work. To repro the state below checkout this branch and follow these steps:

  1. Better to cleanup DD state before anything: rm -fr ~/Library/Developer/Xcode/DerivedData
  2. Make sure indexing is enabled: make enable_indexing
  3. Open iOSApp/iOSApp.xcodeproj and build the CLI target (on M1 make sure you selected the (Rosetta) scheme for this experiment)
  4. You should be able to find an object file under DD (see (1) in the screenshot):
    find ~/Library/Developer/Xcode/DerivedData -name '*main.o'
  5. Move that file to a different place (see (2) in the screenshot), say mv path/to/main.o ~/Desktop/.
  6. Now where that file was located a symlink pointing to where you moved the original object file (see (3) in the screenshot):
    
    cd ~/Library/Developer/Xcode/DerivedData/iOSApp-frrxxdgefswljmaayjgcihttruuq/Build/Intermediates.noindex/iOSApp.build/Debug/CLI.build/Objects-normal/x86_64

ln -s ~/Desktop/main.o main.o

7. Now launch Xcode with SourceKit logging:
```sh
make open_xcode_with_sk_logging
  1. Tail the log file to see updates (see (4) in the screenshot):
    tail -f /tmp/xcode_sourcekit.log | grep main.o
  2. In Xcode without triggering a new build that would override the symlink above edit iOSApp/CLI/main.m, say change the value of that string or allocate a new var and note that SK doesn't get into any kind of weird state (saw crashes / infinite loops in the past while testing this) and that messages involving main.o continue to be interpreted the same way:

    tail -f /tmp/xcode_sourcekit.log | grep main.o
    
    "/Users/thiago/Library/Developer/Xcode/DerivedData/iOSApp-frrxxdgefswljmaayjgcihttruuq/Index/Build/Intermediates.noindex/iOSApp.build/Debug/CLI.build/Objects-normal/x86_64/main.o",
    "/iOSApp.build/Debug/CLI.build/Objects-normal/x86_64/main.o",

symlinked_obj_sk_log

Thoughts

With that I'm still trying to find the right way to interpret these results:

  1. Does that mean that indexing accepts symlink-ed inputs like this and in theory we could symlink all the way to the object files generated by Bazel (planning to test that next using XCHammer projs generated in rules_ios)?
  2. Any chance this only works because we're hitting some sort of cache that is not really trying to go back to disk and find the file where the symlink is?
  3. If you compare results in the SK log when using this experiment versus vanilla Xcode in vanilla mode you'll see more instances of messages referencing main.o than the ones generated in this experiment. Meaning that we're probably not passing all the same messages yet (although apparently this is enough for Xcode to do its thing and not crash).
thiagohmcruz commented 2 years ago

See https://github.com/jerrymarino/xcbuildkit/pull/43

This was just an exercise to show that this is possible, the PR above implements the bulk of the logic for this.

jerrymarino commented 2 years ago

Cool SGTM - @thiagohmcruz ! Yeah it seems like we're going a slightly different approach on this 👍