This answer applies to Xcode 8.x, and I think for Xcode 9.0.
First, you must be sure that "Find Implicit Dependencies" is enabled in the Create panel of the schema you are trying to build.
Target "A" can be made "implicitly" dependent on target "B" in two ways:
- Target A has a build phase of Link Binary With Libraries, in which there is a library on its list with the same name as product B. This product can be either in one project or in another project in the workspace. Notice that I said "same name." Just because you chose libA.a from target A does not mean that implicit dependencies will build it if you have another libA.a product for a different target. See below for more details.
- Target A has a “File Copy Phase” that copies a file with a base name that matches Product B. Typically, the “Copy Files” build phase cannot link to a file, t in the same project as its target, but you can configure dependency between projects if you create a dummy file for the copy phase to copy the same name as product B. For example, if you have a workspace that contains two projects ProjectA and ProjectB. ProjectA has TargetA, which creates libA.a, and ProjectB has TargetB, which creates libB.a. TargetA can get TargetB to build libB.a by getting a "fake" zero byte file as part of TargetA, called libB.a, and that would be enough to get libB.a, although libB.a is in the "Copy Files" phase - this is a completely different file than the TargetB build product release. If you select the "Copy only during installation" checkbox, Xcode will not actually execute the copy, but will resolve the dependency anyway. In fact, you can delete a fake file from your disk, created solely to add something to the "Copy files" phase (but you must leave it in your project).
So why would anyone want to make a horror that is “2”? I can come up with a couple of reasons.
- TargetA requires some files copied / generated by TargetB, but TargetB does not create a library for communication. Perhaps you can get around this if TargetB builds a small dummy library, but it can be painful for other reasons.
- Suppose I had projectA, targetA, and libA.a (and equivalents for projects B, C, and D), and libA.a depended on libB.a and libC.a, which needed to create libD.a (first, maybe with some headings and / or sources). You can do all this using the “Link With Libraries” phase (aka solution # 1), but in this case you will get two copies of the .o files in libD in the latest linked version of libA. If you do it deep enough (for example, a workspace in which there are 40 projects that have different levels of dependencies on each other), you will quickly get huge library files with several identical .o files in them, and your link times will become terrifying.
If you think these are far-fetched situations, I am currently hitting both of them, transferring some of the legacy codes from a series of explicit dependencies to implicit dependencies. Why am I moving on to implicit dependencies? Since explicit dependencies in Xcode require nesting in the project, and once you get enough explicit dependencies, the project browser will be very slow and you will see a lot of bikes inside Xcode for random things.
What happens if you have two goals within the same workspace that generate products with the same name and depend on them on the third goal? Implicit dependencies will choose one. It seems to be doing a match based on the base name of the product (so that foo / bar.a and baz / bar.a are the same) and will select the first one that it finds.
dmaclach
source share