Xcode dependencies across different build director

2019-02-23 18:15发布

问题:

I am trying to set up Xcode for a project which contains multiple executables and static libraries. I have created multiple targets and set up the linking and dependencies, and initially everything works great. The catch...

This is an existing project which already has Visual Studio and Makefile builds. Those builds put the libraries in a lib/Debug directory and the executables in bin/Debug. So in Xcode I changed the Build Products Path to "lib" and "bin" respectively (so we can use one set of documentation for all of the platforms). This puts the compiled targets in the right place, but completely breaks both the linking (Library not found) and the dependencies.

I can fix the linking by adding $(SRCROOT)/lib/Debug to the Library Search Paths for each executable (but it feels like Xcode should be able to figure this out on its own, which makes me think I'm doing something wrong).

But — I can't figure out how to get the dependencies working again. If I change a library source file, the library will rebuild but not the dependent executables. If I force a build of the executable Xcode returns success without doing anything; it thinks the target is up to date. If I clean the target and then rebuild it works.

So, any ideas here? Is Xcode being fundamentally stupid in this regard, or is it me (I'm leaning toward the latter)?

Update: I've posted a sample project to demonstrate the issue at http://share.industriousone.com/XcodeDepsIssue.zip. Build it once, then modify MyStaticLib.c and build it again. The executable will not relink (and it should). Many thanks for any help on this one.

回答1:

starkos, thanks for publishing your conclusion. It validated my experience as well. This situation really screwed me, so it was nice to know I wasn't just missing something.

I did however discover a workaround that avoids creating multiple projects or keeping the library and its dependent in the same directory. It is a hack, but it does work here.

I know it's a bit late but better than never.

For the dependency library, add a "Copy Files Build Phase", with Absolute Path as the destination, and the path text field should be the directory where the DEPENDENT target lives. Then click on Products, find the dependency library (will end with .a), and drag it into the "Copy Files Build Phase." If you now build, this will put the library into its own directory like before and THEN also copy it into the dependent's target directory.

For the dependent, you can now remove the dependency's output directory from the Library Search Paths. This will cause it to find the library copy. If you do this, the dependent will indeed be relinked each time the dependency .a is relinked.

The negatives are, of course, the extra time for the copy, and the necessity to specify (in the Copy phase) the target directory for each dependent of your library. Beats the hell out of the alternatives though....



回答2:

Xcode doesn't automatically set up dependencies based on use of build products; you have to set up explicit target dependencies yourself.

Project > Edit Target Settings, General tab, + button, add any targets that are prerequisites to building the selected target. That should get you going again.



回答3:

I've researched this some more and the answer is no, Xcode 3.x doesn't track dependencies between targets that live in different directories. You can work around it by giving each library its own project, and adding each of those to a master project. Or you can keep all of your targets in one directory. Pick your poison.



回答4:

Here is my solution for this weird behavior in xcode 4.3.1. You have to add build pre-action in scheme:

rm -f ${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}

and choose which build settings to use for this script. Each time before build, target executable will be removed and rebuild completely. It helped for me, and i hope it helps you.

NOTE: Have tried to put this script in project build phase, and result was negative - debugger could not connect process to start debugging.

Good luck!



回答5:

OK, it would help to have the text of the Linking... build line that's failing. But a couple of things:

1) You shouldn't be linking to anything in $(SRCROOT). That's your project sources. The two places to find things to link are $(SYMROOT) (the Build Products directory) or $(DSTROOT) (the Installed Products directory).

One thing you could do is to have a common Build Directory, then use 'xcodebuild install' action to install the products in the Installation Directory. The other is to use a Copy Files build phase to copy them after building, so you can link against them in $(SYMROOT) but still have them where your Windows compatriots expect them.

THere is probably a way to set up the per-target build products directories correctly, but I'd really have to see the project itself to figure it out.