@@ -81,11 +81,13 @@ const char *usage =
8181#include < libkern/OSByteOrder.h>
8282#include < uuid/uuid.h>
8383#include < dispatch/dispatch.h>
84+ #include < copyfile.h>
85+ #include < dirent.h>
86+ #include < libgen.h>
8487
8588#include < algorithm>
8689#include < vector>
8790#include < string>
88- #include < filesystem>
8991#include < unordered_map>
9092#include < unordered_set>
9193#include < mutex>
@@ -424,7 +426,7 @@ ssize_t pread_all(int fd, void *buf, size_t count, off_t offset)
424426
425427template <typename T>
426428int 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),
428430 void (^uuidVisitor)(uuid_t const uuid))
429431{
430432 ssize_t readed;
@@ -485,7 +487,7 @@ int parse_macho(int fd, uint32_t offset, uint32_t size,
485487
486488
487489int 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),
489491 void (^uuidVisitor)(uuid_t const uuid))
490492{
491493 uint32_t magic;
@@ -513,7 +515,7 @@ int parse_macho(int fd, uint32_t offset, uint32_t size,
513515
514516
515517int 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),
517519 void (^uuidVisitor)(uuid_t const uuid))
518520{
519521 uint32_t magic;
@@ -607,7 +609,7 @@ int parse_fat(int fd, off_t fsize, char *buffer, size_t size,
607609}
608610
609611
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 &),
611613 void (^uuidVisitor)(uuid_t const ))
612614{
613615 log_vv (" Scanning %s..." , path.c_str ());
@@ -640,29 +642,42 @@ bool operator <= (const struct timespec &lhs, const struct timespec &rhs)
640642 return lhs.tv_sec <= rhs.tv_sec ;
641643}
642644
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+ }
643658
644659// This executable's own path.
645- std::filesystem::path self_executable = []() -> std::filesystem::path {
660+ std::string self_executable = []() -> std::string {
646661 char path[MAXPATHLEN] = {0 };
647662 uint32_t len = sizeof (path);
648663 _NSGetExecutablePath (path, &len);
649- return std::filesystem::path (path);
664+ return std::string (path);
650665}();
651666
652667
653668// This executable's own xctoolchain path.
654- std::filesystem::path self_toolchain = []() -> std::filesystem::path {
669+ std::string self_toolchain = []() -> std::string {
655670 auto result = self_executable;
656671
657672 // Remove the executable name.
658- result = result. parent_path ( );
673+ result = parentPath (result );
659674
660675 // 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 );
663678 }
664- if (result. filename () == std::filesystem::path ( " usr" ) ) {
665- result = result. parent_path ( );
679+ if (filename (result ) == " usr" ) {
680+ result = parentPath (result );
666681 }
667682 return result;
668683}();
@@ -761,7 +776,7 @@ int xcrunToolCommand(std::vector<std::string> commandAndArguments, XcrunToolBloc
761776}
762777
763778
764- void copyAndStripBitcode (std::filesystem::path src, std::filesystem::path dst)
779+ void copyAndStripBitcode (std::string src, std::string dst)
765780{
766781 // -r removes bitcode
767782 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)
774789 }
775790}
776791
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)
780793{
781794 if (stripBitcode) {
782795 copyAndStripBitcode (src, dst);
783796 } else {
784- if (! std::filesystem::copy_file (src, dst) ) {
797+ if (copyfile (src. c_str () , dst. c_str (), NULL , COPYFILE_ALL) != 0 ) {
785798 fail (" Couldn't copy %s to %s: %s" , src.c_str (), dst.c_str (), strerror (errno));
786799 }
787800 }
@@ -793,16 +806,19 @@ std::string uuidString(uuid_t const uuid) {
793806 return buffer;
794807}
795808
796- void copyLibraries (std::filesystem::path src_dir, std::filesystem::path dst_dir,
809+ void copyLibraries (std::string src_dir, std::string dst_dir,
797810 std::unordered_map<std::string,
798811 std::unordered_set<std::string>> const &libs,
799812 bool stripBitcode)
800813{
801814 mkpath_np (dst_dir.c_str (), S_IRWXU | S_IRWXG | S_IRWXO);
802815
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;
806822
807823 // Compare UUIDs of src and dst and don't copy if they're the same.
808824 // 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,
843859 dst_dir.c_str ());
844860
845861 unlink (dst.c_str ());
846- copyFile (std::filesystem::canonical ( src) , dst, stripBitcode);
862+ copyFile (src, dst, stripBitcode);
847863 }
848864}
849865
@@ -858,11 +874,35 @@ std::vector<uint8_t> query_code_signature(std::string file) {
858874 return d;
859875}
860876
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+
861901int main (int argc, const char *argv[])
862902{
863903 // Executables to scan for Swift references.
864904 // --scan-executable
865- std::vector<std::filesystem::path > executables;
905+ std::vector<std::string > executables;
866906
867907 // Directories to scan for more executables.
868908 // --scan-folder
@@ -876,12 +916,12 @@ int main(int argc, const char *argv[])
876916 // Copy source.
877917 // --source-libraries
878918 // or /path/to/swift-stdlib-tool/../../lib/swift/<--platform>
879- std::filesystem::path src_dir;
919+ std::string src_dir;
880920
881921 // Copy destinations, signed and unsigned.
882922 // --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;
885925
886926 // Resource copy destination.
887927 // --resource-destination
@@ -923,10 +963,10 @@ int main(int argc, const char *argv[])
923963 }
924964
925965 if (0 == strcmp (argv[i], " --destination" )) {
926- dst_dir = std::filesystem::path (argv[++i]);
966+ dst_dir = std::string (argv[++i]);
927967 }
928968 if (0 == strcmp (argv[i], " --unsigned-destination" )) {
929- unsigned_dst_dir = std::filesystem::path (argv[++i]);
969+ unsigned_dst_dir = std::string (argv[++i]);
930970 }
931971
932972 if (0 == strcmp (argv[i], " --sign" )) {
@@ -959,19 +999,19 @@ int main(int argc, const char *argv[])
959999 } else if (src_dir.empty ()) {
9601000 // platform is set but src_dir is not.
9611001 // 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;
9641004 } else if (platform.empty ()) {
9651005 // src_dir is set but platform is not.
9661006 // Pick platform from src_dir's name.
967- platform = src_dir. filename () ;
1007+ platform = src_dir;
9681008 }
9691009
9701010 // Add the platform to unsigned_dst_dir if it is not already present.
9711011 if (!unsigned_dst_dir.empty ()) {
972- auto const unsigned_platform = unsigned_dst_dir. filename () ;
1012+ auto const unsigned_platform = unsigned_dst_dir;
9731013 if (platform != unsigned_platform) {
974- unsigned_dst_dir = unsigned_dst_dir/ platform;
1014+ unsigned_dst_dir = unsigned_dst_dir + " / " + platform;
9751015 }
9761016 }
9771017
@@ -985,15 +1025,13 @@ int main(int argc, const char *argv[])
9851025
9861026 // Collect executables from the --scan-folder locations.
9871027 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);
9931031 } 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 ());
9951033 }
996- }
1034+ });
9971035 }
9981036
9991037 // Collect Swift library names from the input files.
@@ -1003,9 +1041,9 @@ int main(int argc, const char *argv[])
10031041 std::unordered_set<std::string>> swiftLibs;
10041042 for (auto const &path : executables) {
10051043 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 ) {
10091047 swiftLibs[linkedLib] = std::unordered_set<std::string>();
10101048 }
10111049 },
@@ -1016,18 +1054,18 @@ int main(int argc, const char *argv[])
10161054 // Also collect the Swift libraries' UUIDs.
10171055 __block std::vector<std::string> worklist;
10181056 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 );
10211059 }
10221060 while (worklist.size ()) {
10231061 auto const lib = worklist.back ();
10241062 worklist.pop_back ();
1025- auto const path = src_dir/ lib;
1063+ auto const path = src_dir + " / " + lib;
10261064 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;
10291067 if (swiftLibs.count (linkedLib) == 0 &&
1030- std::filesystem::exists (linkedSrc) )
1068+ access (linkedSrc. c_str (), F_OK) == 0 )
10311069 {
10321070 swiftLibs[linkedLib] = std::unordered_set<std::string>();
10331071 worklist.push_back (linkedLib);
@@ -1043,26 +1081,26 @@ int main(int argc, const char *argv[])
10431081 __block std::unordered_map<std::string,
10441082 std::unordered_set<std::string>> swiftLibsForResources;
10451083 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 ) {
10481086 swiftLibsForResources[lib] = std::unordered_set<std::string>();
10491087 }
10501088 }
10511089
10521090 // Collect dependencies of --resource-library libs.
10531091 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 );
10561094 }
10571095 while (worklist.size ()) {
10581096 auto const lib = worklist.back ();
10591097 worklist.pop_back ();
1060- auto const path = src_dir/ lib;
1098+ auto const path = src_dir + " / " + lib;
10611099 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;
10641102 if (swiftLibsForResources.count (linkedLib) == 0 &&
1065- std::filesystem::exists (linkedSrc) )
1103+ access (linkedSrc. c_str (), F_OK) == 0 )
10661104 {
10671105 swiftLibsForResources[linkedLib] = std::unordered_set<std::string>();
10681106 worklist.push_back (linkedLib);
@@ -1076,7 +1114,7 @@ int main(int argc, const char *argv[])
10761114 // Print the Swift libraries (full path to toolchain's copy)
10771115 if (print) {
10781116 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 ());
10801118 }
10811119 }
10821120
@@ -1111,7 +1149,8 @@ int main(int argc, const char *argv[])
11111149 __block bool signedOne = false ;
11121150 std::mutex signingLock;
11131151
1114- for (auto const &[lib, _] : swiftLibs) {
1152+ for (auto const &pair : swiftLibs) {
1153+ auto const &lib = pair.first ;
11151154 // Work around authentication UI problems
11161155 // by signing one synchronously and then signing the rest.
11171156 signingLock.lock ();
@@ -1126,13 +1165,13 @@ int main(int argc, const char *argv[])
11261165 // to preserve it in case it does not change. We can use
11271166 // this to avoid unnecessary copies during delta installs
11281167 // to devices.
1129- auto const dst = dst_dir/ lib;
1168+ auto const dst = dst_dir + " / " + lib;
11301169 auto const oldSignatureData = query_code_signature (dst);
11311170 const char *tmpFilePath = 0 ;
11321171 if (!oldSignatureData.empty ()) {
11331172 // Make a copy of the existing file, with permissions and
11341173 // mtime preserved.
1135- auto tmpFile = dst. string () + " .original" ;
1174+ auto tmpFile = dst + " .original" ;
11361175 tmpFilePath = tmpFile.c_str ();
11371176 xcrunToolCommand ({" cp" , " -p" , dst, tmpFile});
11381177 }
0 commit comments