Xcode: Link libraries using "Link Binary With Libraries" build phase
Some work has been done on making Xcode projects great again, but there are some edge cases that need to be addressed.
Here are some options that would take care of that:
- Use custom CMake variable (CMAKE_XCODE_FORCE_LINK_BUILD_PHASE:BOOL) - we could inform the developer of possible consequences with name conflicts and it could be used at it's own risk. That would only be necessary for file paths and imported targets only as on regular targets we can use the standard exception rules.
- Link all file paths and imported targets through linker flags, and also add these files to Xcode project for embedding - kind of duplication, but should work.
- Same as 2nd, but also have the CMake variable to force use Xcode linking options whatever the costs.
What objects support "Link Binary With Libraries" build phase:
- Dynamic library
- Framework (also as a static library)
- Bundle
- Executable (app bundle and command line)
What linkage mechanism to use for objects:
- Object file - linker flags
- Static lib (file or imported target) - linker flags
- Static lib (target) - build phase[1]
- Dynamic library - build phase[2]
- Framework - build phase[3]
- Bundle - build phase[4]
- This is only for convenience, as static linking happens before bundle packaging and thus won't affect archival or embedding. The only exception is if static lib is not built in "default output dir", then we fall back to linker flags.
- We need these objects to be added to Xcode project for future work on "Embed Frameworks" build phase (dynamic libraries need to be embedded as they are linked at runtime). But we'll have issues in the case with name conflicts, and there is no clear way to detect name conflicts from Xcode generator perspective.
- Same problems as with 2nd, but there is no direct way to link framework as a full path in clang, the only (crazy) way is to link the contained library directly and I'm not sure whether that would work for dynamic framework.
- This is not linked in "Link Binary With Libraries" build phase as they are loaded later at runtime using Bundle APIs (dlopen under the hood), but will be embedded in "Embed Plugins" build phase (similar to "Embed Frameworks").
Standard exceptions should apply (i.e. libraries should be linked using OTHER_LDFLAGS
build setting instead):
- Same library is not linked in all configurations
- Library name does not have the same in all configurations (the paths can differ, but that applies to targets as files don't have inter-configuration references and we can't be sure whether it's the same lib if path changes)
- Library target does not use "default output dir" (risk of having name resolution conflicts, but also shouldn't matter as custom path won't change between archive and regular build if it's absolute path)