|
21 | 21 | #include "swift/Basic/TaskQueue.h"
|
22 | 22 | #include "swift/Config.h"
|
23 | 23 | #include "swift/Driver/Compilation.h"
|
| 24 | +#include "clang/Driver/DarwinSDKInfo.h" |
24 | 25 | #include "swift/Driver/Driver.h"
|
25 | 26 | #include "swift/Driver/Job.h"
|
26 | 27 | #include "swift/Option/Options.h"
|
@@ -481,61 +482,138 @@ toolchains::Darwin::addProfileGenerationArgs(ArgStringList &Arguments,
|
481 | 482 | }
|
482 | 483 | }
|
483 | 484 |
|
| 485 | +/// Remap the given version number via the version map, or produce \c None if |
| 486 | +/// there is no mapping for this version. |
| 487 | +static Optional<llvm::VersionTuple> remapVersion( |
| 488 | + const llvm::StringMap<llvm::VersionTuple> &versionMap, |
| 489 | + llvm::VersionTuple version) { |
| 490 | + // The build number is never used in the lookup. |
| 491 | + version = version.withoutBuild(); |
| 492 | + |
| 493 | + // Look for this specific version. |
| 494 | + auto known = versionMap.find(version.getAsString()); |
| 495 | + if (known != versionMap.end()) |
| 496 | + return known->second; |
| 497 | + |
| 498 | + // If an extra ".0" was specified (in the subminor version), drop that |
| 499 | + // and look again. |
| 500 | + if (!version.getSubminor() || *version.getSubminor() != 0) |
| 501 | + return None; |
| 502 | + |
| 503 | + version = llvm::VersionTuple(version.getMajor(), *version.getMinor()); |
| 504 | + known = versionMap.find(version.getAsString()); |
| 505 | + if (known != versionMap.end()) |
| 506 | + return known->second; |
| 507 | + |
| 508 | + // If another extra ".0" wa specified (in the minor version), drop that |
| 509 | + // and look again. |
| 510 | + if (!version.getMinor() || *version.getMinor() != 0) |
| 511 | + return None; |
| 512 | + |
| 513 | + version = llvm::VersionTuple(version.getMajor()); |
| 514 | + known = versionMap.find(version.getAsString()); |
| 515 | + if (known != versionMap.end()) |
| 516 | + return known->second; |
| 517 | + |
| 518 | + return None; |
| 519 | +} |
| 520 | + |
484 | 521 | void
|
485 | 522 | toolchains::Darwin::addDeploymentTargetArgs(ArgStringList &Arguments,
|
486 | 523 | const JobContext &context) const {
|
487 |
| - const llvm::Triple &Triple = getTriple(); |
488 |
| - // FIXME: Properly handle deployment targets. |
489 |
| - assert(Triple.isiOS() || Triple.isWatchOS() || Triple.isMacOSX()); |
490 |
| - if (Triple.isiOS()) { |
491 |
| - bool isiOSSimulator = tripleIsiOSSimulator(Triple); |
492 |
| - if (Triple.isTvOS()) { |
493 |
| - if (isiOSSimulator) |
494 |
| - Arguments.push_back("-tvos_simulator_version_min"); |
495 |
| - else |
496 |
| - Arguments.push_back("-tvos_version_min"); |
| 524 | + auto addPlatformVersionArg = [&](const llvm::Triple &triple) { |
| 525 | + // Compute the name of the platform for the linker. |
| 526 | + const char *platformName; |
| 527 | + if (tripleIsMacCatalystEnvironment(triple)) { |
| 528 | + platformName = "mac-catalyst"; |
497 | 529 | } else {
|
498 |
| - if (isiOSSimulator) |
499 |
| - Arguments.push_back("-ios_simulator_version_min"); |
500 |
| - else if (tripleIsMacCatalystEnvironment(Triple)) |
501 |
| - Arguments.push_back("-maccatalyst_version_min"); |
502 |
| - else |
503 |
| - Arguments.push_back("-iphoneos_version_min"); |
| 530 | + switch (getDarwinPlatformKind(triple)) { |
| 531 | + case DarwinPlatformKind::MacOS: |
| 532 | + platformName = "macos"; |
| 533 | + break; |
| 534 | + case DarwinPlatformKind::IPhoneOS: |
| 535 | + platformName = "ios"; |
| 536 | + break; |
| 537 | + case DarwinPlatformKind::IPhoneOSSimulator: |
| 538 | + platformName = "ios-simulator"; |
| 539 | + break; |
| 540 | + case DarwinPlatformKind::TvOS: |
| 541 | + platformName = "tvos"; |
| 542 | + break; |
| 543 | + case DarwinPlatformKind::TvOSSimulator: |
| 544 | + platformName = "tvos-simulator"; |
| 545 | + break; |
| 546 | + case DarwinPlatformKind::WatchOS: |
| 547 | + platformName = "watchos"; |
| 548 | + break; |
| 549 | + case DarwinPlatformKind::WatchOSSimulator: |
| 550 | + platformName = "watchos-simulator"; |
| 551 | + break; |
| 552 | + } |
504 | 553 | }
|
| 554 | + |
| 555 | + // Compute the platform version. |
505 | 556 | unsigned major, minor, micro;
|
506 |
| - Triple.getiOSVersion(major, minor, micro); |
507 |
| - addVersionString(context.Args, Arguments, major, minor, micro); |
| 557 | + if (tripleIsMacCatalystEnvironment(triple)) { |
| 558 | + triple.getiOSVersion(major, minor, micro); |
| 559 | + |
| 560 | + // Mac Catalyst was introduced with an iOS deployment target of 13.0; |
| 561 | + // the linker doesn't want to see a deployment target before that. |
| 562 | + if (major < 13) { |
| 563 | + major = 13; |
| 564 | + minor = 0; |
| 565 | + micro = 0; |
| 566 | + } |
| 567 | + } else { |
| 568 | + switch (getDarwinPlatformKind((triple))) { |
| 569 | + case DarwinPlatformKind::MacOS: |
| 570 | + triple.getMacOSXVersion(major, minor, micro); |
| 571 | + break; |
| 572 | + case DarwinPlatformKind::IPhoneOS: |
| 573 | + case DarwinPlatformKind::IPhoneOSSimulator: |
| 574 | + case DarwinPlatformKind::TvOS: |
| 575 | + case DarwinPlatformKind::TvOSSimulator: |
| 576 | + triple.getiOSVersion(major, minor, micro); |
| 577 | + break; |
| 578 | + case DarwinPlatformKind::WatchOS: |
| 579 | + case DarwinPlatformKind::WatchOSSimulator: |
| 580 | + triple.getOSVersion(major, minor, micro); |
| 581 | + break; |
| 582 | + } |
| 583 | + } |
| 584 | + |
| 585 | + // Compute the SDK version. |
| 586 | + unsigned sdkMajor = 0, sdkMinor = 0, sdkMicro = 0; |
| 587 | + if (SDKInfo) { |
| 588 | + // Retrieve the SDK version. |
| 589 | + auto SDKVersion = SDKInfo->getVersion(); |
| 590 | + |
| 591 | + // For the Mac Catalyst environment, we have a macOS SDK with a macOS |
| 592 | + // SDK version. Map that to the corresponding iOS version number to pass |
| 593 | + // down to the linker. |
| 594 | + if (tripleIsMacCatalystEnvironment(triple)) { |
| 595 | + SDKVersion = remapVersion( |
| 596 | + SDKInfo->getVersionMap().MacOS2iOSMacMapping, SDKVersion) |
| 597 | + .getValueOr(llvm::VersionTuple(0, 0, 0)); |
| 598 | + } |
508 | 599 |
|
509 |
| - if (TargetVariant) { |
510 |
| - assert(triplesAreValidForZippering(Triple, *TargetVariant)); |
511 |
| - assert(TargetVariant->isMacOSX()); |
512 |
| - Arguments.push_back("-macosx_version_min"); |
513 |
| - unsigned major, minor, micro; |
514 |
| - TargetVariant->getMacOSXVersion(major, minor, micro); |
515 |
| - addVersionString(context.Args, Arguments, major, minor, micro); |
| 600 | + // Extract the version information. |
| 601 | + sdkMajor = SDKVersion.getMajor(); |
| 602 | + sdkMinor = SDKVersion.getMinor().getValueOr(0); |
| 603 | + sdkMicro = SDKVersion.getSubminor().getValueOr(0); |
516 | 604 | }
|
517 |
| - } else if (Triple.isWatchOS()) { |
518 |
| - if (tripleIsWatchSimulator(Triple)) |
519 |
| - Arguments.push_back("-watchos_simulator_version_min"); |
520 |
| - else |
521 |
| - Arguments.push_back("-watchos_version_min"); |
522 |
| - unsigned major, minor, micro; |
523 |
| - Triple.getOSVersion(major, minor, micro); |
524 |
| - addVersionString(context.Args, Arguments, major, minor, micro); |
525 |
| - } else { |
526 |
| - Arguments.push_back("-macosx_version_min"); |
527 |
| - unsigned major, minor, micro; |
528 |
| - Triple.getMacOSXVersion(major, minor, micro); |
| 605 | + |
| 606 | + Arguments.push_back("-platform_version"); |
| 607 | + Arguments.push_back(platformName); |
529 | 608 | addVersionString(context.Args, Arguments, major, minor, micro);
|
| 609 | + addVersionString(context.Args, Arguments, sdkMajor, sdkMinor, sdkMicro); |
| 610 | + }; |
530 | 611 |
|
531 |
| - if (TargetVariant) { |
532 |
| - assert(triplesAreValidForZippering(Triple, *TargetVariant)); |
533 |
| - assert(tripleIsMacCatalystEnvironment(*TargetVariant)); |
534 |
| - Arguments.push_back("-maccatalyst_version_min"); |
535 |
| - unsigned major, minor, micro; |
536 |
| - TargetVariant->getiOSVersion(major, minor, micro); |
537 |
| - addVersionString(context.Args, Arguments, major, minor, micro); |
538 |
| - } |
| 612 | + addPlatformVersionArg(getTriple()); |
| 613 | + |
| 614 | + if (auto targetVariant = getTargetVariant()) { |
| 615 | + assert(triplesAreValidForZippering(getTriple(), *targetVariant)); |
| 616 | + addPlatformVersionArg(*targetVariant); |
539 | 617 | }
|
540 | 618 | }
|
541 | 619 |
|
@@ -778,3 +856,20 @@ toolchains::Darwin::validateArguments(DiagnosticEngine &diags,
|
778 | 856 | diags.diagnose(SourceLoc(), diag::error_darwin_static_stdlib_not_supported);
|
779 | 857 | }
|
780 | 858 | }
|
| 859 | + |
| 860 | +void |
| 861 | +toolchains::Darwin::validateOutputInfo(DiagnosticEngine &diags, |
| 862 | + const OutputInfo &outputInfo) const { |
| 863 | + // If we are linking and have been provided with an SDK, go read the SDK |
| 864 | + // information. |
| 865 | + if (outputInfo.shouldLink() && !outputInfo.SDKPath.empty()) { |
| 866 | + auto SDKInfoOrErr = clang::driver::parseDarwinSDKInfo( |
| 867 | + *llvm::vfs::getRealFileSystem(), outputInfo.SDKPath); |
| 868 | + if (SDKInfoOrErr) { |
| 869 | + SDKInfo = *SDKInfoOrErr; |
| 870 | + } else { |
| 871 | + llvm::consumeError(SDKInfoOrErr.takeError()); |
| 872 | + diags.diagnose(SourceLoc(), diag::warn_drv_darwin_sdk_invalid_settings); |
| 873 | + } |
| 874 | + } |
| 875 | +} |
0 commit comments