@@ -81,11 +81,13 @@ const char *usage =
81
81
#include < libkern/OSByteOrder.h>
82
82
#include < uuid/uuid.h>
83
83
#include < dispatch/dispatch.h>
84
+ #include < copyfile.h>
85
+ #include < dirent.h>
86
+ #include < libgen.h>
84
87
85
88
#include < algorithm>
86
89
#include < vector>
87
90
#include < string>
88
- #include < filesystem>
89
91
#include < unordered_map>
90
92
#include < unordered_set>
91
93
#include < mutex>
@@ -424,7 +426,7 @@ ssize_t pread_all(int fd, void *buf, size_t count, off_t offset)
424
426
425
427
template <typename T>
426
428
int parse_macho (int fd, uint32_t offset, uint32_t size,
427
- void (^dylibVisitor)(std::filesystem::path const &path),
429
+ void (^dylibVisitor)(std::string const &path),
428
430
void (^uuidVisitor)(uuid_t const uuid))
429
431
{
430
432
ssize_t readed;
@@ -485,7 +487,7 @@ int parse_macho(int fd, uint32_t offset, uint32_t size,
485
487
486
488
487
489
int parse_macho (int fd, uint32_t offset, uint32_t size,
488
- void (^dylibVisitor)(std::filesystem::path const &path),
490
+ void (^dylibVisitor)(std::string const &path),
489
491
void (^uuidVisitor)(uuid_t const uuid))
490
492
{
491
493
uint32_t magic;
@@ -513,7 +515,7 @@ int parse_macho(int fd, uint32_t offset, uint32_t size,
513
515
514
516
515
517
int parse_fat (int fd, off_t fsize, char *buffer, size_t size,
516
- void (^dylibVisitor)(std::filesystem::path const &path),
518
+ void (^dylibVisitor)(std::string const &path),
517
519
void (^uuidVisitor)(uuid_t const uuid))
518
520
{
519
521
uint32_t magic;
@@ -607,7 +609,7 @@ int parse_fat(int fd, off_t fsize, char *buffer, size_t size,
607
609
}
608
610
609
611
610
- void process (std::filesystem::path const & path, void (^dylibVisitor)(std::filesystem::path const &),
612
+ void process (std::string const & path, void (^dylibVisitor)(std::string const &),
611
613
void (^uuidVisitor)(uuid_t const ))
612
614
{
613
615
log_vv (" Scanning %s..." , path.c_str ());
@@ -640,29 +642,42 @@ bool operator <= (const struct timespec &lhs, const struct timespec &rhs)
640
642
return lhs.tv_sec <= rhs.tv_sec ;
641
643
}
642
644
645
+ std::string parentPath (std::string path) {
646
+ const char *pathCstr = path.c_str ();
647
+ char parent[MAXPATHLEN];
648
+
649
+ return dirname_r (pathCstr, parent) ? parent : pathCstr;
650
+ }
651
+
652
+ std::string filename (std::string path) {
653
+ const char *pathCstr = path.c_str ();
654
+ char filename[MAXPATHLEN];
655
+
656
+ return basename_r (pathCstr, filename) ? filename : pathCstr;
657
+ }
643
658
644
659
// This executable's own path.
645
- std::filesystem::path self_executable = []() -> std::filesystem::path {
660
+ std::string self_executable = []() -> std::string {
646
661
char path[MAXPATHLEN] = {0 };
647
662
uint32_t len = sizeof (path);
648
663
_NSGetExecutablePath (path, &len);
649
- return std::filesystem::path (path);
664
+ return std::string (path);
650
665
}();
651
666
652
667
653
668
// This executable's own xctoolchain path.
654
- std::filesystem::path self_toolchain = []() -> std::filesystem::path {
669
+ std::string self_toolchain = []() -> std::string {
655
670
auto result = self_executable;
656
671
657
672
// Remove the executable name.
658
- result = result. parent_path ( );
673
+ result = parentPath (result );
659
674
660
675
// Remove trailing /usr/bin, if any
661
- if (result. filename () == std::filesystem::path ( " bin" ) ) {
662
- result = result. parent_path ( );
676
+ if (filename (result ) == " bin" ) {
677
+ result = parentPath (result );
663
678
}
664
- if (result. filename () == std::filesystem::path ( " usr" ) ) {
665
- result = result. parent_path ( );
679
+ if (filename (result ) == " usr" ) {
680
+ result = parentPath (result );
666
681
}
667
682
return result;
668
683
}();
@@ -761,7 +776,7 @@ int xcrunToolCommand(std::vector<std::string> commandAndArguments, XcrunToolBloc
761
776
}
762
777
763
778
764
- void copyAndStripBitcode (std::filesystem::path src, std::filesystem::path dst)
779
+ void copyAndStripBitcode (std::string src, std::string dst)
765
780
{
766
781
// -r removes bitcode
767
782
std::vector<std::string> commandAndArgs = {" bitcode_strip" , src, " -r" , " -o" , dst};
@@ -774,14 +789,12 @@ void copyAndStripBitcode(std::filesystem::path src, std::filesystem::path dst)
774
789
}
775
790
}
776
791
777
-
778
- void
779
- copyFile (std::filesystem::path src, std::filesystem::path dst, bool stripBitcode)
792
+ void copyFile (std::string src, std::string dst, bool stripBitcode)
780
793
{
781
794
if (stripBitcode) {
782
795
copyAndStripBitcode (src, dst);
783
796
} else {
784
- if (! std::filesystem::copy_file (src, dst) ) {
797
+ if (copyfile (src. c_str () , dst. c_str (), NULL , COPYFILE_ALL) != 0 ) {
785
798
fail (" Couldn't copy %s to %s: %s" , src.c_str (), dst.c_str (), strerror (errno));
786
799
}
787
800
}
@@ -793,16 +806,19 @@ std::string uuidString(uuid_t const uuid) {
793
806
return buffer;
794
807
}
795
808
796
- void copyLibraries (std::filesystem::path src_dir, std::filesystem::path dst_dir,
809
+ void copyLibraries (std::string src_dir, std::string dst_dir,
797
810
std::unordered_map<std::string,
798
811
std::unordered_set<std::string>> const &libs,
799
812
bool stripBitcode)
800
813
{
801
814
mkpath_np (dst_dir.c_str (), S_IRWXU | S_IRWXG | S_IRWXO);
802
815
803
- for (auto const &[lib, srcUUIDs]: libs) {
804
- std::filesystem::path src = src_dir/lib;
805
- std::filesystem::path dst = dst_dir/lib;
816
+ for (auto const &pair : libs) {
817
+ auto const &lib = pair.first ;
818
+ auto const &srcUUIDs = pair.second ;
819
+
820
+ std::string src = src_dir + " /" + lib;
821
+ std::string dst = dst_dir + " /" + lib;
806
822
807
823
// Compare UUIDs of src and dst and don't copy if they're the same.
808
824
// Do not use mod times for this task: the dst copy gets code-signed
@@ -843,7 +859,7 @@ void copyLibraries(std::filesystem::path src_dir, std::filesystem::path dst_dir,
843
859
dst_dir.c_str ());
844
860
845
861
unlink (dst.c_str ());
846
- copyFile (std::filesystem::canonical ( src) , dst, stripBitcode);
862
+ copyFile (src, dst, stripBitcode);
847
863
}
848
864
}
849
865
@@ -858,11 +874,35 @@ std::vector<uint8_t> query_code_signature(std::string file) {
858
874
return d;
859
875
}
860
876
877
+ template <typename F>
878
+ void enumerateDirectory (std::string directory, F&& func) {
879
+ DIR *dir = opendir (directory.c_str ());
880
+ if (dir == NULL ) {
881
+ return ;
882
+ }
883
+
884
+ struct dirent *entry;
885
+ while ((entry = readdir (dir)) != NULL ) {
886
+ std::string path = directory + " /" + entry->d_name ;
887
+ if (entry->d_type == DT_REG) {
888
+ func (path);
889
+ } else if (entry->d_type == DT_DIR) {
890
+ // check if . or ..
891
+ if (strncmp (entry->d_name , " .." , entry->d_namlen )) {
892
+ continue ;
893
+ }
894
+ enumerateDirectory (path, func);
895
+ }
896
+ }
897
+ }
898
+
899
+
900
+
861
901
int main (int argc, const char *argv[])
862
902
{
863
903
// Executables to scan for Swift references.
864
904
// --scan-executable
865
- std::vector<std::filesystem::path > executables;
905
+ std::vector<std::string > executables;
866
906
867
907
// Directories to scan for more executables.
868
908
// --scan-folder
@@ -876,12 +916,12 @@ int main(int argc, const char *argv[])
876
916
// Copy source.
877
917
// --source-libraries
878
918
// or /path/to/swift-stdlib-tool/../../lib/swift/<--platform>
879
- std::filesystem::path src_dir;
919
+ std::string src_dir;
880
920
881
921
// Copy destinations, signed and unsigned.
882
922
// --destination and --unsigned-destination
883
- std::filesystem::path dst_dir;
884
- std::filesystem::path unsigned_dst_dir;
923
+ std::string dst_dir;
924
+ std::string unsigned_dst_dir;
885
925
886
926
// Resource copy destination.
887
927
// --resource-destination
@@ -923,10 +963,10 @@ int main(int argc, const char *argv[])
923
963
}
924
964
925
965
if (0 == strcmp (argv[i], " --destination" )) {
926
- dst_dir = std::filesystem::path (argv[++i]);
966
+ dst_dir = std::string (argv[++i]);
927
967
}
928
968
if (0 == strcmp (argv[i], " --unsigned-destination" )) {
929
- unsigned_dst_dir = std::filesystem::path (argv[++i]);
969
+ unsigned_dst_dir = std::string (argv[++i]);
930
970
}
931
971
932
972
if (0 == strcmp (argv[i], " --sign" )) {
@@ -959,19 +999,19 @@ int main(int argc, const char *argv[])
959
999
} else if (src_dir.empty ()) {
960
1000
// platform is set but src_dir is not.
961
1001
// Use platform to set src_dir relative to us.
962
- src_dir = self_executable. parent_path (). parent_path ()/
963
- " lib " / " swift-5.0" / platform;
1002
+ src_dir = parentPath ( parentPath (self_executable)) + " / " + " lib " +
1003
+ " swift-5.0" + " / " + platform;
964
1004
} else if (platform.empty ()) {
965
1005
// src_dir is set but platform is not.
966
1006
// Pick platform from src_dir's name.
967
- platform = src_dir. filename () ;
1007
+ platform = src_dir;
968
1008
}
969
1009
970
1010
// Add the platform to unsigned_dst_dir if it is not already present.
971
1011
if (!unsigned_dst_dir.empty ()) {
972
- auto const unsigned_platform = unsigned_dst_dir. filename () ;
1012
+ auto const unsigned_platform = unsigned_dst_dir;
973
1013
if (platform != unsigned_platform) {
974
- unsigned_dst_dir = unsigned_dst_dir/ platform;
1014
+ unsigned_dst_dir = unsigned_dst_dir + " / " + platform;
975
1015
}
976
1016
}
977
1017
@@ -985,15 +1025,13 @@ int main(int argc, const char *argv[])
985
1025
986
1026
// Collect executables from the --scan-folder locations.
987
1027
for (auto const &embedDir : embedDirs) {
988
- for (auto const &entry : std::filesystem::recursive_directory_iterator (embedDir)) {
989
- if (entry.exists () && !entry.is_directory () &&
990
- 0 == access (entry.path ().c_str (), X_OK))
991
- {
992
- executables.push_back (entry.path ());
1028
+ enumerateDirectory (embedDir, [&](std::string entry) {
1029
+ if (0 == access (entry.c_str (), X_OK)) {
1030
+ executables.push_back (entry);
993
1031
} else {
994
- log_vv (" %s is not an executable file" , entry.path (). c_str ());
1032
+ log_vv (" %s is not an executable file" , entry.c_str ());
995
1033
}
996
- }
1034
+ });
997
1035
}
998
1036
999
1037
// Collect Swift library names from the input files.
@@ -1003,9 +1041,9 @@ int main(int argc, const char *argv[])
1003
1041
std::unordered_set<std::string>> swiftLibs;
1004
1042
for (auto const &path : executables) {
1005
1043
process (path,
1006
- ^(std::filesystem::path const &linkedLib) {
1007
- auto const linkedSrc = src_dir/ linkedLib;
1008
- if (std::filesystem::exists (linkedSrc) ) {
1044
+ ^(std::string const &linkedLib) {
1045
+ auto const linkedSrc = src_dir + " / " + linkedLib;
1046
+ if (access (linkedSrc. c_str (), F_OK) == 0 ) {
1009
1047
swiftLibs[linkedLib] = std::unordered_set<std::string>();
1010
1048
}
1011
1049
},
@@ -1016,18 +1054,18 @@ int main(int argc, const char *argv[])
1016
1054
// Also collect the Swift libraries' UUIDs.
1017
1055
__block std::vector<std::string> worklist;
1018
1056
worklist.reserve (swiftLibs.size ());
1019
- for (auto const &[lib, _] : swiftLibs) {
1020
- worklist.push_back (lib );
1057
+ for (auto const &pair : swiftLibs) {
1058
+ worklist.push_back (pair. first );
1021
1059
}
1022
1060
while (worklist.size ()) {
1023
1061
auto const lib = worklist.back ();
1024
1062
worklist.pop_back ();
1025
- auto const path = src_dir/ lib;
1063
+ auto const path = src_dir + " / " + lib;
1026
1064
process (path,
1027
- ^(std::filesystem::path const &linkedLib) {
1028
- auto const linkedSrc = src_dir/ linkedLib;
1065
+ ^(std::string const &linkedLib) {
1066
+ auto const linkedSrc = src_dir + " / " + linkedLib;
1029
1067
if (swiftLibs.count (linkedLib) == 0 &&
1030
- std::filesystem::exists (linkedSrc) )
1068
+ access (linkedSrc. c_str (), F_OK) == 0 )
1031
1069
{
1032
1070
swiftLibs[linkedLib] = std::unordered_set<std::string>();
1033
1071
worklist.push_back (linkedLib);
@@ -1043,26 +1081,26 @@ int main(int argc, const char *argv[])
1043
1081
__block std::unordered_map<std::string,
1044
1082
std::unordered_set<std::string>> swiftLibsForResources;
1045
1083
for (auto const &lib : resourceLibraries) {
1046
- auto const libSrc = src_dir/ lib;
1047
- if (std::filesystem::exists (libSrc) ) {
1084
+ auto const libSrc = src_dir + " / " + lib;
1085
+ if (access (libSrc. c_str (), F_OK) == 0 ) {
1048
1086
swiftLibsForResources[lib] = std::unordered_set<std::string>();
1049
1087
}
1050
1088
}
1051
1089
1052
1090
// Collect dependencies of --resource-library libs.
1053
1091
worklist.clear ();
1054
- for (auto const &[lib, _] : swiftLibsForResources) {
1055
- worklist.push_back (lib );
1092
+ for (auto const &pair : swiftLibsForResources) {
1093
+ worklist.push_back (pair. first );
1056
1094
}
1057
1095
while (worklist.size ()) {
1058
1096
auto const lib = worklist.back ();
1059
1097
worklist.pop_back ();
1060
- auto const path = src_dir/ lib;
1098
+ auto const path = src_dir + " / " + lib;
1061
1099
process (path,
1062
- ^(std::filesystem::path const &linkedLib) {
1063
- auto const linkedSrc = src_dir/ linkedLib;
1100
+ ^(std::string const &linkedLib) {
1101
+ auto const linkedSrc = src_dir + " / " + linkedLib;
1064
1102
if (swiftLibsForResources.count (linkedLib) == 0 &&
1065
- std::filesystem::exists (linkedSrc) )
1103
+ access (linkedSrc. c_str (), F_OK) == 0 )
1066
1104
{
1067
1105
swiftLibsForResources[linkedLib] = std::unordered_set<std::string>();
1068
1106
worklist.push_back (linkedLib);
@@ -1076,7 +1114,7 @@ int main(int argc, const char *argv[])
1076
1114
// Print the Swift libraries (full path to toolchain's copy)
1077
1115
if (print) {
1078
1116
for (auto const &lib : swiftLibs) {
1079
- printf (" %s\n " , (src_dir/ lib.first ).c_str ());
1117
+ printf (" %s\n " , (src_dir + " / " + lib.first ).c_str ());
1080
1118
}
1081
1119
}
1082
1120
@@ -1111,7 +1149,8 @@ int main(int argc, const char *argv[])
1111
1149
__block bool signedOne = false ;
1112
1150
std::mutex signingLock;
1113
1151
1114
- for (auto const &[lib, _] : swiftLibs) {
1152
+ for (auto const &pair : swiftLibs) {
1153
+ auto const &lib = pair.first ;
1115
1154
// Work around authentication UI problems
1116
1155
// by signing one synchronously and then signing the rest.
1117
1156
signingLock.lock ();
@@ -1126,13 +1165,13 @@ int main(int argc, const char *argv[])
1126
1165
// to preserve it in case it does not change. We can use
1127
1166
// this to avoid unnecessary copies during delta installs
1128
1167
// to devices.
1129
- auto const dst = dst_dir/ lib;
1168
+ auto const dst = dst_dir + " / " + lib;
1130
1169
auto const oldSignatureData = query_code_signature (dst);
1131
1170
const char *tmpFilePath = 0 ;
1132
1171
if (!oldSignatureData.empty ()) {
1133
1172
// Make a copy of the existing file, with permissions and
1134
1173
// mtime preserved.
1135
- auto tmpFile = dst. string () + " .original" ;
1174
+ auto tmpFile = dst + " .original" ;
1136
1175
tmpFilePath = tmpFile.c_str ();
1137
1176
xcrunToolCommand ({" cp" , " -p" , dst, tmpFile});
1138
1177
}
0 commit comments