static void WorkerThreadFunc( void* userPtr, void* lsMemory ) { BT_PROFILE( "WorkerThreadFunc" ); WorkerThreadLocalStorage* localStorage = (WorkerThreadLocalStorage*) lsMemory; localStorage->status = WorkerThreadStatus::kWaitingForWork; //printf( "WorkerThreadFunc: worker %d start working\n", localStorage->threadId ); JobContext* jobContext = (JobContext*) userPtr; while ( jobContext->m_workersShouldCheckQueue ) { if ( IJob* job = jobContext->consumeJob() ) { localStorage->status = WorkerThreadStatus::kWorking; job->executeJob(); localStorage->status = WorkerThreadStatus::kWaitingForWork; } else { // todo: spin wait a bit to avoid hammering the empty queue } } //printf( "WorkerThreadFunc stop working\n" ); localStorage->status = WorkerThreadStatus::kSleeping; // go idle }
ToolChain::InvocationInfo toolchains::Darwin::constructInvocation(const LinkJobAction &job, const JobContext &context) const { assert(context.Output.getPrimaryOutputType() == types::TY_Image && "Invalid linker output type."); const Driver &D = getDriver(); const llvm::Triple &Triple = getTriple(); InvocationInfo II{"ld"}; ArgStringList &Arguments = II.Arguments; if (context.Args.hasArg(options::OPT_driver_use_filelists) || context.Inputs.size() > TOO_MANY_FILES) { Arguments.push_back("-filelist"); Arguments.push_back(context.getTemporaryFilePath("inputs", "LinkFileList")); II.FilelistInfo = {Arguments.back(), types::TY_Object, FilelistInfo::Input}; } else { addPrimaryInputsOfType(Arguments, context.Inputs, types::TY_Object); } addInputsOfType(Arguments, context.InputActions, types::TY_Object); if (context.OI.DebugInfoKind == IRGenDebugInfoKind::Normal) { size_t argCount = Arguments.size(); if (context.OI.CompilerMode == OutputInfo::Mode::SingleCompile) addInputsOfType(Arguments, context.Inputs, types::TY_SwiftModuleFile); else addPrimaryInputsOfType(Arguments, context.Inputs, types::TY_SwiftModuleFile); if (Arguments.size() > argCount) { assert(argCount + 1 == Arguments.size() && "multiple swiftmodules found for -g"); Arguments.insert(Arguments.end() - 1, "-add_ast_path"); } } switch (job.getKind()) { case LinkKind::None: llvm_unreachable("invalid link kind"); case LinkKind::Executable: // The default for ld; no extra flags necessary. break; case LinkKind::DynamicLibrary: Arguments.push_back("-dylib"); break; } assert(Triple.isOSDarwin()); // FIXME: If we used Clang as a linker instead of going straight to ld, // we wouldn't have to replicate Clang's logic here. bool wantsObjCRuntime = false; if (Triple.isiOS()) wantsObjCRuntime = Triple.isOSVersionLT(8); else if (Triple.isWatchOS()) wantsObjCRuntime = Triple.isOSVersionLT(2); else if (Triple.isMacOSX()) wantsObjCRuntime = Triple.isMacOSXVersionLT(10, 10); if (context.Args.hasFlag(options::OPT_link_objc_runtime, options::OPT_no_link_objc_runtime, /*default=*/wantsObjCRuntime)) { llvm::SmallString<128> ARCLiteLib(D.getSwiftProgramPath()); llvm::sys::path::remove_filename(ARCLiteLib); // 'swift' llvm::sys::path::remove_filename(ARCLiteLib); // 'bin' llvm::sys::path::append(ARCLiteLib, "lib", "arc"); if (!llvm::sys::fs::is_directory(ARCLiteLib)) { // If we don't have a 'lib/arc/' directory, find the "arclite" library // relative to the Clang in the active Xcode. ARCLiteLib.clear(); if (findXcodeClangPath(ARCLiteLib)) { llvm::sys::path::remove_filename(ARCLiteLib); // 'clang' llvm::sys::path::remove_filename(ARCLiteLib); // 'bin' llvm::sys::path::append(ARCLiteLib, "lib", "arc"); } } if (!ARCLiteLib.empty()) { llvm::sys::path::append(ARCLiteLib, "libarclite_"); ARCLiteLib += getPlatformNameForTriple(Triple); ARCLiteLib += ".a"; Arguments.push_back("-force_load"); Arguments.push_back(context.Args.MakeArgString(ARCLiteLib)); // Arclite depends on CoreFoundation. Arguments.push_back("-framework"); Arguments.push_back("CoreFoundation"); } else { // FIXME: We should probably diagnose this, but this is not a place where // we can emit diagnostics. Silently ignore it for now. } } context.Args.AddAllArgValues(Arguments, options::OPT_Xlinker); context.Args.AddAllArgs(Arguments, options::OPT_linker_option_Group); context.Args.AddAllArgs(Arguments, options::OPT_F); if (context.Args.hasArg(options::OPT_enable_app_extension)) { // Keep this string fixed in case the option used by the // compiler itself changes. Arguments.push_back("-application_extension"); } // Liking in sanitizers will add rpaths, which might negatively interact when // other rpaths are involved, so we should make sure we add the rpaths after // all user-specified rpaths. if (context.OI.SelectedSanitizer == SanitizerKind::Address) addLinkSanitizerLibArgsForDarwin(context.Args, Arguments, "asan", *this); if (context.OI.SelectedSanitizer == SanitizerKind::Thread) addLinkSanitizerLibArgsForDarwin(context.Args, Arguments, "tsan", *this); if (context.Args.hasArg(options::OPT_embed_bitcode, options::OPT_embed_bitcode_marker)) { Arguments.push_back("-bitcode_bundle"); } if (!context.OI.SDKPath.empty()) { Arguments.push_back("-syslibroot"); Arguments.push_back(context.Args.MakeArgString(context.OI.SDKPath)); } Arguments.push_back("-lobjc"); Arguments.push_back("-lSystem"); Arguments.push_back("-arch"); Arguments.push_back(context.Args.MakeArgString(getTriple().getArchName())); // Add the runtime library link path, which is platform-specific and found // relative to the compiler. SmallString<128> RuntimeLibPath; getRuntimeLibraryPath(RuntimeLibPath, context.Args, *this); Arguments.push_back("-L"); Arguments.push_back(context.Args.MakeArgString(RuntimeLibPath)); if (context.Args.hasArg(options::OPT_profile_generate)) { SmallString<128> LibProfile(RuntimeLibPath); llvm::sys::path::remove_filename(LibProfile); // remove platform name llvm::sys::path::append(LibProfile, "clang", "lib", "darwin"); StringRef RT; if (Triple.isiOS()) { if (Triple.isTvOS()) RT = "tvos"; else RT = "ios"; } else if (Triple.isWatchOS()) { RT = "watchos"; } else { assert(Triple.isMacOSX()); RT = "osx"; } StringRef Sim; if (tripleIsAnySimulator(Triple)) { Sim = "sim"; } llvm::sys::path::append(LibProfile, "libclang_rt.profile_" + RT + Sim + ".a"); // FIXME: Continue accepting the old path for simulator libraries for now. if (!Sim.empty() && !llvm::sys::fs::exists(LibProfile)) { llvm::sys::path::remove_filename(LibProfile); llvm::sys::path::append(LibProfile, "libclang_rt.profile_" + RT + ".a"); } Arguments.push_back(context.Args.MakeArgString(LibProfile)); } // FIXME: We probably shouldn't be adding an rpath here unless we know ahead // of time the standard library won't be copied. Arguments.push_back("-rpath"); Arguments.push_back(context.Args.MakeArgString(RuntimeLibPath)); // FIXME: Properly handle deployment targets. assert(Triple.isiOS() || Triple.isWatchOS() || Triple.isMacOSX()); if (Triple.isiOS()) { bool isiOSSimulator = tripleIsiOSSimulator(Triple); if (Triple.isTvOS()) { if (isiOSSimulator) Arguments.push_back("-tvos_simulator_version_min"); else Arguments.push_back("-tvos_version_min"); } else { if (isiOSSimulator) Arguments.push_back("-ios_simulator_version_min"); else Arguments.push_back("-iphoneos_version_min"); } unsigned major, minor, micro; Triple.getiOSVersion(major, minor, micro); addVersionString(context.Args, Arguments, major, minor, micro); } else if (Triple.isWatchOS()) { if (tripleIsWatchSimulator(Triple)) Arguments.push_back("-watchos_simulator_version_min"); else Arguments.push_back("-watchos_version_min"); unsigned major, minor, micro; Triple.getOSVersion(major, minor, micro); addVersionString(context.Args, Arguments, major, minor, micro); } else { Arguments.push_back("-macosx_version_min"); unsigned major, minor, micro; Triple.getMacOSXVersion(major, minor, micro); addVersionString(context.Args, Arguments, major, minor, micro); } Arguments.push_back("-no_objc_category_merging"); // This should be the last option, for convenience in checking output. Arguments.push_back("-o"); Arguments.push_back(context.Output.getPrimaryOutputFilename().c_str()); return II; }
ToolChain::InvocationInfo ToolChain::constructInvocation(const MergeModuleJobAction &job, const JobContext &context) const { InvocationInfo II{SWIFT_EXECUTABLE_NAME}; ArgStringList &Arguments = II.Arguments; if (context.OI.CompilerMode == OutputInfo::Mode::UpdateCode) II.ExecutableName = SWIFT_UPDATE_NAME; else Arguments.push_back("-frontend"); // We just want to emit a module, so pass -emit-module without any other // mode options. Arguments.push_back("-emit-module"); if (context.Args.hasArg(options::OPT_driver_use_filelists) || context.Inputs.size() > TOO_MANY_FILES) { Arguments.push_back("-filelist"); Arguments.push_back(context.getTemporaryFilePath("inputs", "")); II.FilelistInfo = {Arguments.back(), types::TY_SwiftModuleFile, FilelistInfo::Input}; addInputsOfType(Arguments, context.InputActions, types::TY_SwiftModuleFile); } else { size_t origLen = Arguments.size(); (void)origLen; addInputsOfType(Arguments, context.Inputs, types::TY_SwiftModuleFile); addInputsOfType(Arguments, context.InputActions, types::TY_SwiftModuleFile); assert(Arguments.size() - origLen >= context.Inputs.size() + context.InputActions.size()); assert((Arguments.size() - origLen == context.Inputs.size() || !context.InputActions.empty()) && "every input to MergeModule must generate a swiftmodule"); } // Tell all files to parse as library, which is necessary to load them as // serialized ASTs. Arguments.push_back("-parse-as-library"); addCommonFrontendArgs(*this, context.OI, context.Output, context.Args, Arguments); Arguments.push_back("-module-name"); Arguments.push_back(context.Args.MakeArgString(context.OI.ModuleName)); assert(context.Output.getPrimaryOutputType() == types::TY_SwiftModuleFile && "The MergeModule tool only produces swiftmodule files!"); const std::string &ObjCHeaderOutputPath = context.Output.getAdditionalOutputForType(types::TY_ObjCHeader); if (!ObjCHeaderOutputPath.empty()) { Arguments.push_back("-emit-objc-header-path"); Arguments.push_back(ObjCHeaderOutputPath.c_str()); } Arguments.push_back("-o"); Arguments.push_back( context.Args.MakeArgString(context.Output.getPrimaryOutputFilename())); return II; }
ToolChain::InvocationInfo ToolChain::constructInvocation(const CompileJobAction &job, const JobContext &context) const { InvocationInfo II{SWIFT_EXECUTABLE_NAME}; ArgStringList &Arguments = II.Arguments; if (context.OI.CompilerMode == OutputInfo::Mode::UpdateCode) II.ExecutableName = SWIFT_UPDATE_NAME; else Arguments.push_back("-frontend"); // Determine the frontend mode option. const char *FrontendModeOption = nullptr; switch (context.OI.CompilerMode) { case OutputInfo::Mode::StandardCompile: case OutputInfo::Mode::SingleCompile: { switch (context.Output.getPrimaryOutputType()) { case types::TY_Object: FrontendModeOption = "-c"; break; case types::TY_RawSIL: FrontendModeOption = "-emit-silgen"; break; case types::TY_SIL: FrontendModeOption = "-emit-sil"; break; case types::TY_RawSIB: FrontendModeOption = "-emit-sibgen"; break; case types::TY_SIB: FrontendModeOption = "-emit-sib"; break; case types::TY_LLVM_IR: FrontendModeOption = "-emit-ir"; break; case types::TY_LLVM_BC: FrontendModeOption = "-emit-bc"; break; case types::TY_Assembly: FrontendModeOption = "-S"; break; case types::TY_SwiftModuleFile: // Since this is our primary output, we need to specify the option here. FrontendModeOption = "-emit-module"; break; case types::TY_Nothing: // We were told to output nothing, so get the last mode option and use that. if (const Arg *A = context.Args.getLastArg(options::OPT_modes_Group)) FrontendModeOption = A->getSpelling().data(); else llvm_unreachable("We were told to perform a standard compile, " "but no mode option was passed to the driver."); break; case types::TY_Swift: case types::TY_dSYM: case types::TY_AutolinkFile: case types::TY_Dependencies: case types::TY_SwiftModuleDocFile: case types::TY_ClangModuleFile: case types::TY_SerializedDiagnostics: case types::TY_ObjCHeader: case types::TY_Image: case types::TY_SwiftDeps: case types::TY_Remapping: llvm_unreachable("Output type can never be primary output."); case types::TY_INVALID: llvm_unreachable("Invalid type ID"); } break; } case OutputInfo::Mode::Immediate: case OutputInfo::Mode::REPL: llvm_unreachable("REPL and immediate modes handled elsewhere"); case OutputInfo::Mode::UpdateCode: // Make sure that adding '-update-code' will permit accepting all arguments // '-c' accepts. FrontendModeOption = "-c"; break; } assert(FrontendModeOption != nullptr && "No frontend mode option specified!"); Arguments.push_back(FrontendModeOption); assert(context.Inputs.empty() && "The Swift frontend does not expect to be fed any input Jobs!"); // Add input arguments. switch (context.OI.CompilerMode) { case OutputInfo::Mode::StandardCompile: case OutputInfo::Mode::UpdateCode: { assert(context.InputActions.size() == 1 && "The Swift frontend expects exactly one input (the primary file)!"); auto *IA = cast<InputAction>(context.InputActions[0]); const Arg &PrimaryInputArg = IA->getInputArg(); if (context.Args.hasArg(options::OPT_driver_use_filelists) || context.getTopLevelInputFiles().size() > TOO_MANY_FILES) { Arguments.push_back("-filelist"); Arguments.push_back(context.getAllSourcesPath()); Arguments.push_back("-primary-file"); PrimaryInputArg.render(context.Args, Arguments); } else { bool FoundPrimaryInput = false; for (auto inputPair : context.getTopLevelInputFiles()) { if (!types::isPartOfSwiftCompilation(inputPair.first)) continue; // See if this input should be passed with -primary-file. if (!FoundPrimaryInput && PrimaryInputArg.getIndex() == inputPair.second->getIndex()) { Arguments.push_back("-primary-file"); FoundPrimaryInput = true; } Arguments.push_back(inputPair.second->getValue()); } } break; } case OutputInfo::Mode::SingleCompile: { if (context.Args.hasArg(options::OPT_driver_use_filelists) || context.InputActions.size() > TOO_MANY_FILES) { Arguments.push_back("-filelist"); Arguments.push_back(context.getAllSourcesPath()); } else { for (const Action *A : context.InputActions) { cast<InputAction>(A)->getInputArg().render(context.Args, Arguments); } } break; } case OutputInfo::Mode::Immediate: case OutputInfo::Mode::REPL: llvm_unreachable("REPL and immediate modes handled elsewhere"); } if (context.Args.hasArg(options::OPT_parse_stdlib)) Arguments.push_back("-disable-objc-attr-requires-foundation-module"); addCommonFrontendArgs(*this, context.OI, context.Output, context.Args, Arguments); // Pass the optimization level down to the frontend. context.Args.AddLastArg(Arguments, options::OPT_O_Group); if (context.Args.hasArg(options::OPT_parse_as_library) || context.Args.hasArg(options::OPT_emit_library)) Arguments.push_back("-parse-as-library"); context.Args.AddLastArg(Arguments, options::OPT_parse_sil); Arguments.push_back("-module-name"); Arguments.push_back(context.Args.MakeArgString(context.OI.ModuleName)); const std::string &ModuleOutputPath = context.Output.getAdditionalOutputForType(types::ID::TY_SwiftModuleFile); if (!ModuleOutputPath.empty()) { Arguments.push_back("-emit-module-path"); Arguments.push_back(ModuleOutputPath.c_str()); } const std::string &ObjCHeaderOutputPath = context.Output.getAdditionalOutputForType(types::ID::TY_ObjCHeader); if (!ObjCHeaderOutputPath.empty()) { assert(context.OI.CompilerMode == OutputInfo::Mode::SingleCompile && "The Swift tool should only emit an Obj-C header in single compile" "mode!"); Arguments.push_back("-emit-objc-header-path"); Arguments.push_back(ObjCHeaderOutputPath.c_str()); } const std::string &SerializedDiagnosticsPath = context.Output.getAdditionalOutputForType(types::TY_SerializedDiagnostics); if (!SerializedDiagnosticsPath.empty()) { Arguments.push_back("-serialize-diagnostics-path"); Arguments.push_back(SerializedDiagnosticsPath.c_str()); } const std::string &DependenciesPath = context.Output.getAdditionalOutputForType(types::TY_Dependencies); if (!DependenciesPath.empty()) { Arguments.push_back("-emit-dependencies-path"); Arguments.push_back(DependenciesPath.c_str()); } const std::string &ReferenceDependenciesPath = context.Output.getAdditionalOutputForType(types::TY_SwiftDeps); if (!ReferenceDependenciesPath.empty()) { Arguments.push_back("-emit-reference-dependencies-path"); Arguments.push_back(ReferenceDependenciesPath.c_str()); } const std::string &FixitsPath = context.Output.getAdditionalOutputForType(types::TY_Remapping); if (!FixitsPath.empty()) { Arguments.push_back("-emit-fixits-path"); Arguments.push_back(FixitsPath.c_str()); } if (context.OI.numThreads > 0) { Arguments.push_back("-num-threads"); Arguments.push_back( context.Args.MakeArgString(Twine(context.OI.numThreads))); } // Add the output file argument if necessary. if (context.Output.getPrimaryOutputType() != types::TY_Nothing) { if (context.Args.hasArg(options::OPT_driver_use_filelists) || context.Output.getPrimaryOutputFilenames().size() > TOO_MANY_FILES) { Arguments.push_back("-output-filelist"); Arguments.push_back(context.getTemporaryFilePath("outputs", "")); II.FilelistInfo = {Arguments.back(), context.Output.getPrimaryOutputType(), FilelistInfo::Output}; } else { for (auto &FileName : context.Output.getPrimaryOutputFilenames()) { Arguments.push_back("-o"); Arguments.push_back(FileName.c_str()); } } } if (context.Args.hasArg(options::OPT_embed_bitcode_marker)) Arguments.push_back("-embed-bitcode-marker"); return II; }
ToolChain::InvocationInfo toolchains::Darwin::constructInvocation(const LinkJobAction &job, const JobContext &context) const { assert(context.Output.getPrimaryOutputType() == file_types::TY_Image && "Invalid linker output type."); if (context.Args.hasFlag(options::OPT_static_executable, options::OPT_no_static_executable, false)) { llvm::report_fatal_error("-static-executable is not supported on Darwin"); } const Driver &D = getDriver(); const llvm::Triple &Triple = getTriple(); // Configure the toolchain. // By default, use the system `ld` to link. const char *LD = "ld"; if (const Arg *A = context.Args.getLastArg(options::OPT_tools_directory)) { StringRef toolchainPath(A->getValue()); // If there is a 'ld' in the toolchain folder, use that instead. if (auto toolchainLD = llvm::sys::findProgramByName("ld", {toolchainPath})) { LD = context.Args.MakeArgString(toolchainLD.get()); } } InvocationInfo II = {LD}; ArgStringList &Arguments = II.Arguments; if (context.shouldUseInputFileList()) { Arguments.push_back("-filelist"); Arguments.push_back(context.getTemporaryFilePath("inputs", "LinkFileList")); II.FilelistInfos.push_back({Arguments.back(), file_types::TY_Object, FilelistInfo::WhichFiles::Input}); } else { addPrimaryInputsOfType(Arguments, context.Inputs, context.Args, file_types::TY_Object); } addInputsOfType(Arguments, context.InputActions, file_types::TY_Object); if (context.OI.CompilerMode == OutputInfo::Mode::SingleCompile) addInputsOfType(Arguments, context.Inputs, context.Args, file_types::TY_SwiftModuleFile, "-add_ast_path"); else addPrimaryInputsOfType(Arguments, context.Inputs, context.Args, file_types::TY_SwiftModuleFile, "-add_ast_path"); // Add all .swiftmodule file inputs as arguments, preceded by the // "-add_ast_path" linker option. addInputsOfType(Arguments, context.InputActions, file_types::TY_SwiftModuleFile, "-add_ast_path"); switch (job.getKind()) { case LinkKind::None: llvm_unreachable("invalid link kind"); case LinkKind::Executable: // The default for ld; no extra flags necessary. break; case LinkKind::DynamicLibrary: Arguments.push_back("-dylib"); break; } assert(Triple.isOSDarwin()); // FIXME: If we used Clang as a linker instead of going straight to ld, // we wouldn't have to replicate a bunch of Clang's logic here. // Always link the regular compiler_rt if it's present. // // Note: Normally we'd just add this unconditionally, but it's valid to build // Swift and use it as a linker without building compiler_rt. SmallString<128> CompilerRTPath; getClangLibraryPath(context.Args, CompilerRTPath); llvm::sys::path::append( CompilerRTPath, Twine("libclang_rt.") + getDarwinLibraryNameSuffixForTriple(Triple, /*simulator*/false) + ".a"); if (llvm::sys::fs::exists(CompilerRTPath)) Arguments.push_back(context.Args.MakeArgString(CompilerRTPath)); if (context.Args.hasFlag(options::OPT_link_objc_runtime, options::OPT_no_link_objc_runtime, /*Default=*/wantsObjCRuntime(Triple))) { llvm::SmallString<128> ARCLiteLib(D.getSwiftProgramPath()); llvm::sys::path::remove_filename(ARCLiteLib); // 'swift' llvm::sys::path::remove_filename(ARCLiteLib); // 'bin' llvm::sys::path::append(ARCLiteLib, "lib", "arc"); if (!llvm::sys::fs::is_directory(ARCLiteLib)) { // If we don't have a 'lib/arc/' directory, find the "arclite" library // relative to the Clang in the active Xcode. ARCLiteLib.clear(); if (findXcodeClangPath(ARCLiteLib)) { llvm::sys::path::remove_filename(ARCLiteLib); // 'clang' llvm::sys::path::remove_filename(ARCLiteLib); // 'bin' llvm::sys::path::append(ARCLiteLib, "lib", "arc"); } } if (!ARCLiteLib.empty()) { llvm::sys::path::append(ARCLiteLib, "libarclite_"); ARCLiteLib += getPlatformNameForTriple(Triple); ARCLiteLib += ".a"; Arguments.push_back("-force_load"); Arguments.push_back(context.Args.MakeArgString(ARCLiteLib)); // Arclite depends on CoreFoundation. Arguments.push_back("-framework"); Arguments.push_back("CoreFoundation"); } else { // FIXME: We should probably diagnose this, but this is not a place where // we can emit diagnostics. Silently ignore it for now. } } context.Args.AddAllArgValues(Arguments, options::OPT_Xlinker); context.Args.AddAllArgs(Arguments, options::OPT_linker_option_Group); for (const Arg *arg : context.Args.filtered(options::OPT_F, options::OPT_Fsystem)) { Arguments.push_back("-F"); Arguments.push_back(arg->getValue()); } if (context.Args.hasArg(options::OPT_enable_app_extension)) { // Keep this string fixed in case the option used by the // compiler itself changes. Arguments.push_back("-application_extension"); } // Linking sanitizers will add rpaths, which might negatively interact when // other rpaths are involved, so we should make sure we add the rpaths after // all user-specified rpaths. if (context.OI.SelectedSanitizers & SanitizerKind::Address) addLinkSanitizerLibArgsForDarwin(context.Args, Arguments, "asan", *this); if (context.OI.SelectedSanitizers & SanitizerKind::Thread) addLinkSanitizerLibArgsForDarwin(context.Args, Arguments, "tsan", *this); // Only link in libFuzzer for executables. if (job.getKind() == LinkKind::Executable && (context.OI.SelectedSanitizers & SanitizerKind::Fuzzer)) addLinkSanitizerLibArgsForDarwin(context.Args, Arguments, "fuzzer", *this, /*shared=*/false); if (context.Args.hasArg(options::OPT_embed_bitcode, options::OPT_embed_bitcode_marker)) { Arguments.push_back("-bitcode_bundle"); } if (!context.OI.SDKPath.empty()) { Arguments.push_back("-syslibroot"); Arguments.push_back(context.Args.MakeArgString(context.OI.SDKPath)); } Arguments.push_back("-lobjc"); Arguments.push_back("-lSystem"); Arguments.push_back("-arch"); Arguments.push_back(context.Args.MakeArgString(getTriple().getArchName())); // Add the runtime library link path, which is platform-specific and found // relative to the compiler. SmallString<128> RuntimeLibPath; getRuntimeLibraryPath(RuntimeLibPath, context.Args, /*Shared=*/true); // Link the standard library. Arguments.push_back("-L"); if (context.Args.hasFlag(options::OPT_static_stdlib, options::OPT_no_static_stdlib, false)) { SmallString<128> StaticRuntimeLibPath; getRuntimeLibraryPath(StaticRuntimeLibPath, context.Args, /*Shared=*/false); Arguments.push_back(context.Args.MakeArgString(StaticRuntimeLibPath)); Arguments.push_back("-lc++"); Arguments.push_back("-framework"); Arguments.push_back("Foundation"); Arguments.push_back("-force_load_swift_libs"); } else { Arguments.push_back(context.Args.MakeArgString(RuntimeLibPath)); // FIXME: We probably shouldn't be adding an rpath here unless we know ahead // of time the standard library won't be copied. SR-1967 Arguments.push_back("-rpath"); Arguments.push_back(context.Args.MakeArgString(RuntimeLibPath)); } if (context.Args.hasArg(options::OPT_profile_generate)) { SmallString<128> LibProfile; getClangLibraryPath(context.Args, LibProfile); StringRef RT; if (Triple.isiOS()) { if (Triple.isTvOS()) RT = "tvos"; else RT = "ios"; } else if (Triple.isWatchOS()) { RT = "watchos"; } else { assert(Triple.isMacOSX()); RT = "osx"; } StringRef Sim; if (tripleIsAnySimulator(Triple)) { Sim = "sim"; } llvm::sys::path::append(LibProfile, "libclang_rt.profile_" + RT + Sim + ".a"); // FIXME: Continue accepting the old path for simulator libraries for now. if (!Sim.empty() && !llvm::sys::fs::exists(LibProfile)) { llvm::sys::path::remove_filename(LibProfile); llvm::sys::path::append(LibProfile, "libclang_rt.profile_" + RT + ".a"); } Arguments.push_back(context.Args.MakeArgString(LibProfile)); } // FIXME: Properly handle deployment targets. assert(Triple.isiOS() || Triple.isWatchOS() || Triple.isMacOSX()); if (Triple.isiOS()) { bool isiOSSimulator = tripleIsiOSSimulator(Triple); if (Triple.isTvOS()) { if (isiOSSimulator) Arguments.push_back("-tvos_simulator_version_min"); else Arguments.push_back("-tvos_version_min"); } else { if (isiOSSimulator) Arguments.push_back("-ios_simulator_version_min"); else Arguments.push_back("-iphoneos_version_min"); } unsigned major, minor, micro; Triple.getiOSVersion(major, minor, micro); addVersionString(context.Args, Arguments, major, minor, micro); } else if (Triple.isWatchOS()) { if (tripleIsWatchSimulator(Triple)) Arguments.push_back("-watchos_simulator_version_min"); else Arguments.push_back("-watchos_version_min"); unsigned major, minor, micro; Triple.getOSVersion(major, minor, micro); addVersionString(context.Args, Arguments, major, minor, micro); } else { Arguments.push_back("-macosx_version_min"); unsigned major, minor, micro; Triple.getMacOSXVersion(major, minor, micro); addVersionString(context.Args, Arguments, major, minor, micro); } Arguments.push_back("-no_objc_category_merging"); // This should be the last option, for convenience in checking output. Arguments.push_back("-o"); Arguments.push_back( context.Args.MakeArgString(context.Output.getPrimaryOutputFilename())); return II; }