38

Like many people, I would love to have Xcode use a folder structure that mirrors the folder-structure on disk. However, I cannot get the code in "folder references" (the cyan folders) to show up in my project targets under "Compile Sources." Is there any way to do this?

I have managed to even add a cyan folder to the "Compile Sources" build phase, but that does not result in the contents of that folder being added.

How can I use folder references for code?

gcamp
  • 14,622
  • 4
  • 54
  • 85
Dan Rosenstark
  • 68,471
  • 58
  • 283
  • 421
  • 1
    Not every uber useful GitHub project that enhances iOS spits out a framework, therefore I feel your pain. I prefer to create submodules in my project folder and then simply softlink them to the meaningful subfolders of the submodule so that every update via Git will stay relevant. Plus I can always play with the submodules's demo project. Adding this softlink folder/file then to my main project works and lets things compile just fine. Not a great thing to do but it lets me sleep at nite :) – pulkitsinghal May 16 '12 at 18:44
  • so the files exist both in your big project and in the subproject (i.e., these two don't know about each other)? – Dan Rosenstark May 16 '12 at 22:02
  • The submodule is just a sibling folder which wasn't written very well to generate a framework file for me to use. The soft-link exists in my big project and the actual git updatable file exists in the submodule. I would only count the submodule as a "subproject" IF I dragged and dropped the .xcodeproj file for it into my big project's open xcode window but that is not always a necessity. We can always do a screen share so that I can show it to you if you'd like, not sure how to kick that off from here though. – pulkitsinghal May 17 '12 at 13:46
  • I think I get it. So in your big project you refer to files (via folder softlinks using `ln` I guess) that are actually in a different project(s) and also under different version control. Is that correct? – Dan Rosenstark May 17 '12 at 14:47
  • Yss ... but just to be clear ... the "different" projects are submodules (its a git term) of my main project ... why make them submodules? so that my team gets the full picture when they do git clone --recursive and the super project works out of the box ... the submodules' respective repos are followed up on and downloaded from – pulkitsinghal May 17 '12 at 18:36
  • @pulkitsinghal Okay, awesome stuff and thanks for the comments. I will check out git submodules and try to avoid Xcode as much as possible. – Dan Rosenstark May 17 '12 at 19:12
  • Anyone get this working? – funroll Nov 12 '14 at 19:56

4 Answers4

21

The simple (and very unfortunate) answer is that Folder References under Xcode remain broken and buggy, they don't work. Tested 04-Mar-2017 in Xcode 8.2.1

Below is an example exploration so you do not have to waste your time replicating the Xcode failure.

(incidentally buggy Xcode crashed twice while I was producing this example)

Per the question, the overall desire is to use a folder reference in Xcode so Xcode picks up all the files in the folder and includes them in the project, and by proxy will update automatically based upon any Finder or Xcode changes of the folder. In this way 50 projects all leveraging the same set of common source code files do not have to be individually updated when those folders get changed. Below explores how this is broken in Xcode (tested in 8.2.1)

The example: ViewController.m includes NSError+Core.h so we want everything from the folder "NSError+Core" to be added to the project.

enter image description here

NSError+Core.h is in this centrally located development folder

enter image description here

Drag the source folder from the Finder into the Project under the "Support" group (nothing up my sleeves, simple drag)

enter image description here

Xcode dutifully offers to add the drag to the target, note the "Create folder references" is selected, not "Create group references". Note also it is clear that Xcode is offering and is told to add this folder and files to the targets.

enter image description here

Although everything looks like it should work, the compiler does not pick up the header file and a recompile yields the same results... can't find header. Ditching the DerivedData does not help either.

enter image description here

So doing a double check, we check the "Compile Sources" under the project and sure enough, the source file is not there either. Remember, Xcode 'added' it to the target...

enter image description here

So what if we drag it from the folder into the "Support" group...

enter image description here

It offers to add them to the project again?! Note that the settings are identical to the first time they were drug in by virtue of the parent folder drag instead of files...

enter image description here

And now the source file shows up in the "Compile Sources" list. Note the bizarre double listing of the files in the project.

(Xcode crashed shortly after snapping this screen shot)

enter image description here

And of course the compiler can now find the header file and the error clears on the import as it should have the first time we drug it in...

enter image description here

Did it just need a little help to "find" the file? If so, the "Create folder references" does exactly what?

So we try and tidy up and drag the files back from the parent "Supporting Files" group to their rightful folder. Without any confirmation, indication, notification, the files just vanish from the group and nothing happens in the NSError+Core folder.

enter image description here

Oh by the way, it really did delete them from the project too... The Compile Sources no longer has the NSError+Core.m reference.

enter image description here

SO to sum up, "Folder references" as implemented thus far do not seem to have any useful purpose... It would appear to be a 6+ year old dunsel on the USS Xcode.

Cerniuk
  • 14,220
  • 2
  • 29
  • 27
  • 5
    Excellent answer. I'm consistently amazed at how many issues like this exist in Xcode - and it crashes all the time for me too. Just not good enough for "prime time". – HughHughTeotl Apr 05 '17 at 21:54
  • **See it the way Apple does:** "If we allow files from folder-reference to compile, people may create structure in Xcode once, and develop with some-other IDE" (more 3rd-party IDE options means less money for Apple). – Top-Master Jul 24 '22 at 06:50
3

I just tried doing this to share code across multiple Xcode projects, and our team came to the conclusion that it's better to create an Xcode project that contains all of your shared classes, compiles them into a static/dynamic library, and then add that as a subproject to those that need the shared code. Then you can set up target dependencies and link your shared library. This will get you the "automatic updating" every time you add a new class to the shared library project.

This approach also works well with submodules or even cocoapods/carthage.

armcknight
  • 149
  • 6
3

Kevin - linked source folders, folder references, etc, are super useful for when you have a common code base shared across different IDEs, like I do for my games that I compile on Windows, Mac, iOS, Android, Linux, etc. I have 3 different IDEs all building the same shared codebase, so it's very helpful when one automatically picks up on a new file and adds it right into the project after I merely run svn update, and I svn commit from one IDE (say XCode) and my Eclipse in Windows project picks up the change. I have a different project for each because each IDE likes the project files in a certain configuration so it's easier for me to have multiple SVN directories (base-project, project-ios, project-android) that all share code in base-project than to have one mega project directory with the different IDE bits unhappily all shoved into subdirectories (which is what I tried the first time around).

Furthermore - it used to work fine in XCode 3. They seemed to not like that useful of a feature so it is no longer working in XCode 4 as I've just found out.

rbgrn
  • 304
  • 2
  • 6
  • 2
    Thanks for that, though it's not an answer but rather a comment. – Dan Rosenstark Nov 19 '11 at 11:40
  • 2
    This makes no sense for an IDE that tracks files independently of the filesystem. To get the same effect in Xcode, you use a sub-project, and you share that sub-project among several different projects. You can add new files to the sub-project and the parent projects will "automatically" pick them up. – Lily Ballard Nov 25 '11 at 07:48
  • 4
    @Kevin: This won't work if you need different compiler options, e.g. different SDKs, different architectures, etc., will it? E.g. just think about two targets: One for iOS and one for OS X; both share the same code. Each time I add a file, I must make sure it is added to both targets; this is error prone. If I could just tell both targets to compile all files in this folder/group, the targets will always be perfectly in sync. – Mecki Apr 18 '12 at 19:18
  • 4
    Totally agree. If you came from Linux world you would always think about making your working flow fit your need, while if you are from Apple world, you just follow and tell people "this is not best practice anymore because Apple removed this feature". – superarts.org May 29 '14 at 03:53
  • A solution is to use CMake to maintain a single description of the project across all platforms, so you can update that once and all platforms will get see the changes. – bames53 Sep 29 '15 at 16:16
  • I'm using Xcode 7 and while I have not tried this on previous versions, using folder references to share source files between projects and have them build as if they are a part of the project itself, and not a statically linked library, seems to be working fine for me. The same c++ files can build in ios Simulator and OSX command-line tool with no fancy static library or git submodule business. not sure if this is an Xcode fix or if I'm overlooking something else that's obvious. – johnbakers Jan 10 '16 at 11:38
-12

You can't. Why are you even trying? A folder reference's job is to embody a folder, without having entries for all the individual files in the folder. It's primary use is for copying an entire folder of resources verbatim into a project. If you want to compile the sources though, then those sources must be referenced in the Compile Sources build phase of the target, which requires having individual entries for each file.

Depending on what's in the folder, it might make more sense to have a Makefile or some other external build process that builds the content in the folder into a static library. This way you can invoke that build process from a Shell Script Phase, and then just link in the resulting static library. Alternatively if you're using this folder as a way to have a shared bit of code (e.g. an svn:externals or git submodule), you could give that folder its own Xcode project and then embed that project into any of your other projects which share this folder.

Lily Ballard
  • 182,031
  • 33
  • 381
  • 347
  • 5
    Perhaps it's misguided, but I would merely like to be able to add, move and delete files in the filesystem and have that be reflected by the folder structure. You can do this in every other language I've worked with, and it's very important for a version control system, because the files have names AND locations that you see when you do `git log --name-status`, for instance. – Dan Rosenstark Sep 27 '11 at 03:07
  • @Yar: This has nothing to do with the language. It's the IDE that doesn't track the file movements you make on the filesystem. I fully expect other IDE's for other languages to have a similar problem. Heck, Makefiles don't track movements you make to files in the filesystem :P As for your bit about VCS, I don't understand what you're trying to say there. Git is actually rather unique in that it infers file movements. If you were using SVN, you'd have to inform it that you moved the file (and where). – Lily Ballard Sep 27 '11 at 04:13
  • Thanks for that. True that it's about IDE not language. It's not about GIT tracking moves or not. It's about filenames being meaningful without location information. IDEs for Ruby, Visual C#, Java and PHP do not have any problem considering files in a file system. Java has some rules, of course, as do most frameworks, like RoR, on what has to go where. – Dan Rosenstark Sep 27 '11 at 05:04
  • Most language IDEs tend to use the filesystem as the sole way to organize files. Xcode maintains a separate tree of files and does not require your filesystem hierarchy to match the tree in Xcode. – Lily Ballard Sep 27 '11 at 06:28
  • That's what I thought, but I just wanted to get definitive confirmation. Thank you for your answer. – Dan Rosenstark Sep 27 '11 at 12:24
  • The other new answer to this question is not really an answer, but it is for you, Kevin. – Dan Rosenstark Nov 24 '11 at 08:36
  • 2
    Now after some thought, this is 100% right: "Most language IDEs tend to use the filesystem as the sole way to organize files. Xcode maintains a separate tree of files and does not require your filesystem hierarchy to match the tree in Xcode." But I think it's worth mentioning that it sucks horribly, especially in terms of how it integrates with git or any VCS. – Dan Rosenstark May 17 '12 at 17:09
  • 1
    "Why are you even trying?" - why the hell not? This sort of thing would be absolutely perfect for git submodules or svn externs. Xcode could at least give the option of using a folder reference for source code... would the world really end? – Herr Grumps Jul 25 '13 at 06:30
  • 7
    _To answer “Why are you even trying?”:_ **For directories containing autogenerated code.** [mogenerator](http://rentzsch.github.io/mogenerator/) is one good example, but code auto-generation of course is applicable to a wide variety of medium-to-large sized projects. – Slipp D. Thompson Sep 30 '13 at 19:35
  • I don't know if I'm supposed to upvote or downvote this answer (; It's clearly the correct answer because adding folder refs just doesn't work. But at this point I'm more impressed with how low the score is.. – dcow Feb 18 '16 at 19:57