@@ -494,29 +494,46 @@ computeMemberData(raw_ostream &StringTable, raw_ostream &SymNames,
494
494
}
495
495
496
496
namespace llvm {
497
+
498
+ static ErrorOr<SmallString<128 >> canonicalizePath (StringRef P) {
499
+ SmallString<128 > Ret = P;
500
+ std::error_code Err = sys::fs::make_absolute (Ret);
501
+ if (Err)
502
+ return Err;
503
+ sys::path::remove_dots (Ret, /* removedotdot*/ true );
504
+ return Ret;
505
+ }
506
+
497
507
// Compute the relative path from From to To.
498
- std::string computeArchiveRelativePath (StringRef From, StringRef To) {
499
- if (sys::path::is_absolute (From) || sys::path::is_absolute (To))
500
- return To;
501
-
502
- StringRef DirFrom = sys::path::parent_path (From);
503
- auto FromI = sys::path::begin (DirFrom);
504
- auto ToI = sys::path::begin (To);
505
- while (*FromI == *ToI) {
506
- ++FromI;
507
- ++ToI;
508
- }
508
+ Expected<std::string> computeArchiveRelativePath (StringRef From, StringRef To) {
509
+ ErrorOr<SmallString<128 >> PathToOrErr = canonicalizePath (To);
510
+ ErrorOr<SmallString<128 >> DirFromOrErr = canonicalizePath (From);
511
+ if (!PathToOrErr || !DirFromOrErr)
512
+ return errorCodeToError (std::error_code (errno, std::generic_category ()));
513
+
514
+ const SmallString<128 > &PathTo = *PathToOrErr;
515
+ const SmallString<128 > &DirFrom = sys::path::parent_path (*DirFromOrErr);
516
+
517
+ // Can't construct a relative path between different roots
518
+ if (sys::path::root_name (PathTo) != sys::path::root_name (DirFrom))
519
+ return sys::path::convert_to_slash (PathTo);
520
+
521
+ // Skip common prefixes
522
+ auto FromTo =
523
+ std::mismatch (sys::path::begin (DirFrom), sys::path::end (DirFrom),
524
+ sys::path::begin (PathTo), sys::path::end (PathTo));
525
+ auto FromI = FromTo.first ;
526
+ auto ToI = FromTo.second ;
509
527
528
+ // Construct relative path
510
529
SmallString<128 > Relative;
511
530
for (auto FromE = sys::path::end (DirFrom); FromI != FromE; ++FromI)
512
- sys::path::append (Relative, " .." );
531
+ sys::path::append (Relative, sys::path:: Style ::posix, " .." );
513
532
514
- for (auto ToE = sys::path::end (To ); ToI != ToE; ++ToI)
515
- sys::path::append (Relative, *ToI);
533
+ for (auto ToE = sys::path::end (PathTo ); ToI != ToE; ++ToI)
534
+ sys::path::append (Relative, sys::path:: Style ::posix, *ToI);
516
535
517
- // Replace backslashes with slashes so that the path is portable between *nix
518
- // and Windows.
519
- return sys::path::convert_to_slash (Relative);
536
+ return Relative.str ();
520
537
}
521
538
522
539
Error writeArchive (StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
0 commit comments