- if ( _options.outputKind() == Options::kObjectFile )
- return;
-
- // process frameworks specified in .o linker options
- for (CStringSet::const_iterator it = state.linkerOptionFrameworks.begin(); it != state.linkerOptionFrameworks.end(); ++it) {
- const char* frameworkName = *it;
- Options::FileInfo info = _options.findFramework(frameworkName);
- if ( ! this->libraryAlreadyLoaded(info.path) ) {
- info.ordinal = _linkerOptionOrdinal.nextLinkerOptionOrdinal();
- try {
- ld::File* reader = this->makeFile(info, true);
- ld::dylib::File* dylibReader = dynamic_cast<ld::dylib::File*>(reader);
- if ( dylibReader != NULL ) {
- if ( ! dylibReader->installPathVersionSpecific() ) {
+ if ( _options.outputKind() == Options::kObjectFile )
+ return;
+
+ while (! state.unprocessedLinkerOptionLibraries.empty() || ! state.unprocessedLinkerOptionFrameworks.empty()) {
+
+ // process frameworks specified in .o linker options
+ CStringSet newFrameworks = std::move(state.unprocessedLinkerOptionFrameworks);
+ state.unprocessedLinkerOptionFrameworks.clear();
+ for (const char* frameworkName : newFrameworks) {
+ if ( state.linkerOptionFrameworks.count(frameworkName) )
+ continue;
+ Options::FileInfo info = _options.findFramework(frameworkName);
+ if ( ! this->frameworkAlreadyLoaded(info.path, frameworkName) ) {
+ _linkerOptionOrdinal = _linkerOptionOrdinal.nextLinkerOptionOrdinal();
+ info.ordinal = _linkerOptionOrdinal;
+ try {
+ ld::File* reader = this->makeFile(info, true);
+ ld::dylib::File* dylibReader = dynamic_cast<ld::dylib::File*>(reader);
+ if ( dylibReader != NULL ) {
+ if ( ! dylibReader->installPathVersionSpecific() ) {
+ dylibReader->forEachAtom(handler);
+ dylibReader->setImplicitlyLinked();
+ dylibReader->setSpeculativelyLoaded();
+ this->addDylib(dylibReader, info);
+ }
+ }
+ else {
+ throwf("framework linker option at %s is not a dylib", info.path);
+ }
+ }
+ catch (const char* msg) {
+ warning("Auto-Linking supplied '%s', %s", info.path, msg);
+ }
+ }
+ state.linkerOptionFrameworks.insert(frameworkName);
+ }
+
+ // process libraries specified in .o linker options
+ // fixme optimize with std::move?
+ CStringSet newLibraries = std::move(state.unprocessedLinkerOptionLibraries);
+ state.unprocessedLinkerOptionLibraries.clear();
+ for (const char* libName : newLibraries) {
+ if ( state.linkerOptionLibraries.count(libName) )
+ continue;
+ Options::FileInfo info = _options.findLibrary(libName);
+ if ( ! this->libraryAlreadyLoaded(info.path) ) {
+ _linkerOptionOrdinal = _linkerOptionOrdinal.nextLinkerOptionOrdinal();
+ info.ordinal = _linkerOptionOrdinal;
+ try {
+ //<rdar://problem/17787306> -force_load_swift_libs
+ info.options.fForceLoad = _options.forceLoadSwiftLibs() && (strncmp(libName, "swift", 5) == 0);
+ ld::File* reader = this->makeFile(info, true);
+ ld::dylib::File* dylibReader = dynamic_cast<ld::dylib::File*>(reader);
+ ld::archive::File* archiveReader = dynamic_cast<ld::archive::File*>(reader);
+ if ( dylibReader != NULL ) {
+ dylibReader->forEachAtom(handler);