@@ -456,17 +456,13 @@ struct FrameworkBuilder {
456
456
buildingCarthage: buildingCarthage) {
457
457
return buildingCarthage
458
458
}
459
- // Copy the module map to the destination.
460
- let moduleDir = destination. appendingPathComponent ( " Modules " )
461
- do {
462
- try FileManager . default. createDirectory ( at: moduleDir, withIntermediateDirectories: true )
463
- } catch {
464
- let frameworkName : String = frameworks. first? . lastPathComponent ?? " <UNKNOWN "
465
- fatalError ( " Could not create Modules directory for framework: \( frameworkName) . \( error) " )
466
- }
467
- let modulemap = moduleDir. appendingPathComponent ( " module.modulemap " )
459
+
460
+ let modulemapURL = destination
461
+ . appendingPathComponent ( " Modules " )
462
+ . appendingPathComponent ( " module.modulemap " )
463
+ . resolvingSymlinksInPath ( )
468
464
do {
469
- try moduleMapContents. write ( to: modulemap , atomically: true , encoding: . utf8)
465
+ try moduleMapContents. write ( to: modulemapURL , atomically: true , encoding: . utf8)
470
466
} catch {
471
467
let frameworkName : String = frameworks. first? . lastPathComponent ?? " <UNKNOWN "
472
468
fatalError ( " Could not write modulemap to disk for \( frameworkName) : \( error) " )
@@ -496,64 +492,7 @@ struct FrameworkBuilder {
496
492
} else if buildingCarthage {
497
493
return true
498
494
}
499
- guard let first = swiftModules. first,
500
- let swiftModule = URL ( string: first) else {
501
- fatalError ( " Failed to get swiftmodule in \( moduleDir) . " )
502
- }
503
- let destModuleDir = destination. appendingPathComponent ( " Modules " )
504
- if !fileManager. directoryExists ( at: destModuleDir) {
505
- do {
506
- try fileManager. copyItem ( at: moduleDir, to: destModuleDir)
507
- } catch {
508
- fatalError ( " Could not copy Modules from \( moduleDir) to " +
509
- " \( destModuleDir) : \( error) " )
510
- }
511
- } else {
512
- // If the Modules directory is already there, only copy in the architecture specific files
513
- // from the *.swiftmodule subdirectory.
514
- do {
515
- let files = try fileManager. contentsOfDirectory ( at: swiftModule,
516
- includingPropertiesForKeys: nil )
517
- . compactMap { $0. path }
518
- let destSwiftModuleDir = destModuleDir
519
- . appendingPathComponent ( swiftModule. lastPathComponent)
520
- for file in files {
521
- let fileURL = URL ( fileURLWithPath: file)
522
- let projectDir = swiftModule. appendingPathComponent ( " Project " )
523
- if fileURL. lastPathComponent == " Project " ,
524
- fileManager. directoryExists ( at: projectDir) {
525
- // The Project directory (introduced with Xcode 11.4) already exists, only copy in
526
- // new contents.
527
- let projectFiles = try fileManager. contentsOfDirectory ( at: projectDir,
528
- includingPropertiesForKeys: nil )
529
- . compactMap { $0. path }
530
- let destProjectDir = destSwiftModuleDir. appendingPathComponent ( " Project " )
531
- for projectFile in projectFiles {
532
- let projectFileURL = URL ( fileURLWithPath: projectFile)
533
- do {
534
- try fileManager. copyItem ( at: projectFileURL, to:
535
- destProjectDir. appendingPathComponent ( projectFileURL. lastPathComponent) )
536
- } catch {
537
- fatalError ( " Could not copy Project file from \( projectFileURL) to " +
538
- " \( destProjectDir) : \( error) " )
539
- }
540
- }
541
- } else {
542
- do {
543
- try fileManager. copyItem ( at: fileURL, to:
544
- destSwiftModuleDir
545
- . appendingPathComponent ( fileURL. lastPathComponent) )
546
- } catch {
547
- fatalError ( " Could not copy Swift module file from \( fileURL) to " +
548
- " \( destSwiftModuleDir) : \( error) " )
549
- }
550
- }
551
- }
552
- } catch {
553
- fatalError ( " Failed to get Modules directory contents - \( moduleDir) : " +
554
- " \( error. localizedDescription) " )
555
- }
556
- }
495
+
557
496
do {
558
497
// If this point is reached, the framework contains a Swift module,
559
498
// so it's built from either Swift sources or Swift & C Family
@@ -564,7 +503,7 @@ struct FrameworkBuilder {
564
503
// that the framework was built from mixed language sources because
565
504
// those additional headers are public headers for the C Family
566
505
// Language sources.
567
- let headersDir = destination. appendingPathComponent ( " Headers " )
506
+ let headersDir = destination. appendingPathComponent ( " Headers " ) . resolvingSymlinksInPath ( )
568
507
let headers = try fileManager. contentsOfDirectory (
569
508
at: headersDir,
570
509
includingPropertiesForKeys: nil
@@ -585,6 +524,7 @@ struct FrameworkBuilder {
585
524
}
586
525
"""
587
526
let modulemapURL = destination. appendingPathComponents ( [ " Modules " , " module.modulemap " ] )
527
+ . resolvingSymlinksInPath ( )
588
528
try newModuleMapContents. write ( to: modulemapURL, atomically: true , encoding: . utf8)
589
529
}
590
530
} catch {
@@ -626,78 +566,52 @@ struct FrameworkBuilder {
626
566
}
627
567
}
628
568
629
- // Group the thin frameworks into three groups: device, simulator, and Catalyst (all represented
630
- // by the `TargetPlatform` enum. The slices need to be packaged that way with lipo before
631
- // creating a .framework that works for similar grouped architectures. If built separately,
632
- // `-create-xcframework` will return an error and fail:
633
- // `Both ios-arm64 and ios-armv7 represent two equivalent library definitions`
634
- var frameworksBuilt : [ URL ] = [ ]
635
- for (platform, frameworkPath) in slicedFrameworks {
569
+ return slicedFrameworks. map { platform, frameworkPath in
636
570
// Create the following structure in the platform frameworks directory:
637
571
// - platform_frameworks
638
572
// └── $(PLATFORM)
639
573
// └── $(FRAMEWORK).framework
640
574
let platformFrameworkDir = platformFrameworksDir
641
575
. appendingPathComponent ( platform. buildName)
642
- . appendingPathComponent ( fromFolder. lastPathComponent)
576
+ . appendingPathComponent ( framework + " .framework " )
577
+
643
578
do {
644
- try fileManager. createDirectory ( at: platformFrameworkDir, withIntermediateDirectories: true )
579
+ // Create `platform_frameworks/$(PLATFORM)` subdirectory.
580
+ try fileManager. createDirectory (
581
+ at: platformFrameworkDir. deletingLastPathComponent ( ) ,
582
+ withIntermediateDirectories: true
583
+ )
584
+
585
+ // Copy the built framework to the `platform_frameworks/$(PLATFORM)/$(FRAMEWORK).framework`.
586
+ try fileManager. copyItem ( at: frameworkPath, to: platformFrameworkDir)
645
587
} catch {
646
- fatalError ( " Could not create directory for architecture slices on \( platform) for " +
588
+ fatalError ( " Could not copy directory for architecture slices on \( platform) for " +
647
589
" \( framework) : \( error) " )
648
590
}
649
591
650
- processPrivacyManifests ( fileManager, frameworkPath, platformFrameworkDir)
651
-
652
- // Headers from slice
653
- do {
654
- let headersSrc : URL = frameworkPath. appendingPathComponent ( " Headers " )
655
- . resolvingSymlinksInPath ( )
656
- // The macOS slice's `Headers` directory may have a `Headers` file in
657
- // it that symbolically links to nowhere. For example, in the 8.0.0
658
- // zip distribution, see the `Headers` directory in the macOS slice
659
- // of the `PromisesObjC.xcframework`. Delete it here to avoid putting
660
- // it in the zip or crashing the Carthage hash generation. Because
661
- // this will throw an error for cases where the file does not exist,
662
- // the error is ignored.
663
- try ? fileManager. removeItem ( at: headersSrc. appendingPathComponent ( " Headers " ) )
664
-
665
- try fileManager. copyItem (
666
- at: headersSrc,
667
- to: platformFrameworkDir. appendingPathComponent ( " Headers " )
592
+ // CocoaPods creates a `_CodeSignature` directory. Delete it.
593
+ // Note that the build only produces a `_CodeSignature` directory for
594
+ // macOS and macCatalyst, but we try to delete it for other platforms
595
+ // just in case it were to appear.
596
+ let codeSignatureDir = platformFrameworkDir
597
+ . appendingPathComponent (
598
+ platform == . catalyst || platform == . macOS ? " Versions/A/ " : " "
668
599
)
669
- } catch {
670
- fatalError ( " Could not create framework directory needed to build \( framework) : \( error) " )
671
- }
600
+ . appendingPathComponent ( " _CodeSignature " )
601
+ try ? fileManager. removeItem ( at: codeSignatureDir)
672
602
673
- // Copy the binary and Info.plist to the right location.
674
- let binaryName = frameworkPath. lastPathComponent. replacingOccurrences ( of: " .framework " ,
675
- with: " " )
676
- let fatBinary = frameworkPath. appendingPathComponent ( binaryName) . resolvingSymlinksInPath ( )
677
- let plistPathComponents = {
678
- if platform == . catalyst || platform == . macOS {
679
- // Frameworks for macOS and macCatalyst have a different directory
680
- // structure so the framework-level `Info.plist` is found in a
681
- // different spot.
682
- return [ " Versions " , " A " , " Resources " , " Info.plist " ]
683
- } else {
684
- return [ " Info.plist " ]
685
- }
686
- } ( )
687
- let infoPlist = frameworkPath. appendingPathComponents ( plistPathComponents)
688
- . resolvingSymlinksInPath ( )
689
- let infoPlistDestination = platformFrameworkDir. appendingPathComponent ( " Info.plist " )
690
- let fatBinaryDestination = platformFrameworkDir. appendingPathComponent ( framework)
691
- do {
692
- try fileManager. copyItem ( at: fatBinary, to: fatBinaryDestination)
693
- } catch {
694
- fatalError ( " Could not copy fat binary to framework directory for \( framework) : \( error) " )
695
- }
603
+ // The minimum OS version is set to 100.0 to work around b/327020913.
604
+ // TODO(ncooke3): Revert this logic once b/327020913 is fixed.
605
+ // TODO(ncooke3): Does this need to happen on macOS?
696
606
do {
697
- // The minimum OS version is set to 100.0 to work around b/327020913.
698
- // TODO(ncooke3): Revert this logic once b/327020913 is fixed.
607
+ let frameworkInfoPlistURL = platformFrameworkDir
608
+ . appendingPathComponent (
609
+ platform == . catalyst || platform == . macOS ? " Resources " : " "
610
+ )
611
+ . resolvingSymlinksInPath ( )
612
+ . appendingPathComponent ( " Info.plist " )
699
613
var plistDictionary = try PropertyListSerialization . propertyList (
700
- from: Data ( contentsOf: infoPlist ) , format: nil
614
+ from: Data ( contentsOf: frameworkInfoPlistURL ) , format: nil
701
615
) as! [ AnyHashable : Any ]
702
616
plistDictionary [ " MinimumOSVersion " ] = " 100.0 "
703
617
@@ -707,22 +621,46 @@ struct FrameworkBuilder {
707
621
options: 0
708
622
)
709
623
710
- try updatedPlistData. write ( to: infoPlistDestination )
624
+ try updatedPlistData. write ( to: frameworkInfoPlistURL )
711
625
} catch {
712
626
fatalError (
713
- " Could not copy framework-level plist to framework directory for \( framework) : \( error) "
627
+ " Could not modify framework-level plist for b/327020913 in framework directory \( framework) : \( error) "
714
628
)
715
629
}
716
630
631
+ // The macOS slice's `PrivateHeaders` directory may have a
632
+ // `PrivateHeaders` file in it that symbolically links to nowhere. Delete
633
+ // it here to avoid putting it in the zip or crashing the Carthage hash
634
+ // generation. Because this will throw an error for cases where the file
635
+ // does not exist, the error is ignored.
636
+ let privateHeadersDir = platformFrameworkDir. appendingPathComponent ( " PrivateHeaders " )
637
+ if fileManager. directoryExists ( at: privateHeadersDir. resolvingSymlinksInPath ( ) ) {
638
+ try ? fileManager
639
+ . removeItem ( at: privateHeadersDir. resolvingSymlinksInPath ( )
640
+ . appendingPathComponent ( " PrivateHeaders " ) )
641
+ } else {
642
+ try ? fileManager. removeItem ( at: privateHeadersDir)
643
+ }
644
+ let headersDir = platformFrameworkDir. appendingPathComponent ( " Headers " )
645
+ . resolvingSymlinksInPath ( )
646
+ try ? fileManager. removeItem ( at: headersDir. appendingPathComponent ( " Headers " ) )
647
+
648
+ // Move privacy manifest containing resource bundles into the framework.
649
+ let resourceDir = platformFrameworkDir
650
+ . appendingPathComponent (
651
+ platform == . catalyst || platform == . macOS ? " Resources " : " "
652
+ )
653
+ . resolvingSymlinksInPath ( )
654
+ processPrivacyManifests ( fileManager, frameworkPath, resourceDir)
655
+
717
656
// Use the appropriate moduleMaps
718
657
packageModuleMaps ( inFrameworks: [ frameworkPath] ,
719
658
frameworkName: framework,
720
659
moduleMapContents: moduleMapContents,
721
660
destination: platformFrameworkDir)
722
661
723
- frameworksBuilt . append ( platformFrameworkDir)
662
+ return platformFrameworkDir
724
663
}
725
- return frameworksBuilt
726
664
}
727
665
728
666
/// Process privacy manifests.
0 commit comments