llvm.org GIT mirror llvm / 2c69bbf
Revert "[llvm-ar] Fix relative thin archive path handling" This reverts commit r362407. It broke compilation of llvm/lib/Object/ArchiveWriter.cpp: error: type 'llvm::sys::path::const_iterator' does not provide a call operator git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362413 91177308-0d34-0410-b5e6-96231b3b80d8 Dmitri Gribenko 2 months ago
8 changed file(s) with 40 addition(s) and 137 deletion(s). Raw diff Collapse all Expand all
3535 bool Deterministic);
3636 };
3737
38 Expected computeArchiveRelativePath(StringRef From, StringRef To);
38 std::string computeArchiveRelativePath(StringRef From, StringRef To);
3939
4040 Error writeArchive(StringRef ArcName, ArrayRef NewMembers,
4141 bool WriteSymtab, object::Archive::Kind Kind,
493493 }
494494
495495 namespace llvm {
496
497 static ErrorOr> canonicalizePath(StringRef P) {
498 SmallString<128> Ret = P;
499 std::error_code Err = sys::fs::make_absolute(Ret);
500 if (Err)
501 return Err;
502 sys::path::remove_dots(Ret, /*removedotdot*/ true);
503 return Ret;
504 }
505
506496 // Compute the relative path from From to To.
507 Expected computeArchiveRelativePath(StringRef From, StringRef To) {
508 ErrorOr> PathToOrErr = canonicalizePath(To);
509 ErrorOr> DirFromOrErr = canonicalizePath(From);
510 if (!PathToOrErr || !DirFromOrErr)
511 return errorCodeToError(std::error_code(errno, std::generic_category()));
512
513 const SmallString<128> &PathTo = *PathToOrErr;
514 const SmallString<128> &DirFrom = sys::path::parent_path(*DirFromOrErr);
515
516 // Can't construct a relative path between different roots
517 if (sys::path::root_name(PathTo) != sys::path::root_name(DirFrom))
518 return sys::path::convert_to_slash(PathTo);
519
520 // Skip common prefixes
521 auto FromTo =
522 std::mismatch(sys::path::begin(DirFrom), sys::path::end(DirFrom),
523 sys::path::begin(PathTo), sys::path::end(PathTo));
524 auto FromI = FromTo.first;
525 auto ToI = FromTo.second;
526
527 // Construct relative path
497 std::string computeArchiveRelativePath(StringRef From, StringRef To) {
498 if (sys::path::is_absolute(From) || sys::path::is_absolute(To))
499 return To;
500
501 StringRef DirFrom = sys::path::parent_path(From);
502 auto FromI = sys::path::begin(DirFrom);
503 auto ToI = sys::path::begin(To);
504 while (*FromI == *ToI) {
505 ++FromI;
506 ++ToI;
507 }
508
528509 SmallString<128> Relative;
529510 for (auto FromE = sys::path::end(DirFrom); FromI != FromE; ++FromI)
530 sys::path::append(Relative, sys::path::Style::posix, "..");
531
532 for (auto ToE = sys::path::end(PathTo); ToI != ToE; ++ToI)
533 sys::path::append(Relative, sys::path::Style::posix, *ToI);
534
535 return Relative.str();
511 sys::path::append(Relative, "..");
512
513 for (auto ToE = sys::path::end(To); ToI != ToE; ++ToI)
514 sys::path::append(Relative, *ToI);
515
516 // Replace backslashes with slashes so that the path is portable between *nix
517 // and Windows.
518 return sys::path::convert_to_slash(Relative);
536519 }
537520
538521 Error writeArchive(StringRef ArcName, ArrayRef NewMembers,
210210 // llvm-lib uses relative paths for both regular and thin archives, unlike
211211 // standard GNU ar, which only uses relative paths for thin archives and
212212 // basenames for regular archives.
213 for (NewArchiveMember &Member : Members) {
214 if (sys::path::is_relative(Member.MemberName)) {
215 Expected PathOrErr =
216 computeArchiveRelativePath(OutputPath, Member.MemberName);
217 if (PathOrErr)
218 Member.MemberName = Saver.save(*PathOrErr);
219 }
220 }
213 for (NewArchiveMember &Member : Members)
214 Member.MemberName =
215 Saver.save(computeArchiveRelativePath(OutputPath, Member.MemberName));
221216
222217 if (Error E =
223218 writeArchive(OutputPath, Members,
+0
-10
test/tools/llvm-ar/reduce-thin-path.test less more
None RUN: rm -rf %t && mkdir -p %t/foo/bar/
1 RUN: mkdir -p %t/baz/
2 RUN: yaml2obj %S/Inputs/elf.yaml -o %t/elf.o
3
4 RUN: cd %t && llvm-ar rTc %t/baz/internal.ar elf.o
5 RUN: cd %t/foo && llvm-ar rTc %t/foo/bar/external.ar ../baz/internal.ar
6
7 RUN: FileCheck -input-file=%t/foo/bar/external.ar %s
8
9 CHECK: {{^}}../../elf.o/
+0
-45
test/tools/llvm-ar/thin-archive.test less more
None RUN: rm -rf %t && mkdir -p %t/foo/bar/
1
2 RUN: yaml2obj %S/Inputs/elf.yaml -o %t/foo/elf.o
3 RUN: cp %t/foo/elf.o %t/foo/bar/elf.o
4 RUN: cp %t/foo/bar/elf.o %t/delete.o
5
6 Test that modules can be added with absolute paths when the archive is created using an absolute path
7
8 RUN: llvm-ar rTc %t/absolute-1.ar %t/foo/elf.o %t/delete.o %t/foo/bar/elf.o
9 RUN: llvm-ar dT %t/absolute-1.ar delete.o
10
11 RUN: FileCheck -input-file=%t/absolute-1.ar --check-prefixes=THIN,CHECK %s -DPATH=%/t/
12 RUN: llvm-ar t %t/absolute-1.ar | FileCheck %s -DPATH=%/t/
13
14 Test that modules can be added with absolute paths when the archive is created using a relative path
15
16 RUN: llvm-ar rTc Output/%basename_t.tmp/absolute-2.ar %t/foo/elf.o %t/delete.o %t/foo/bar/elf.o
17 RUN: llvm-ar dT Output/%basename_t.tmp/absolute-2.ar %t/delete.o
18
19 RUN: FileCheck -input-file=%t/absolute-2.ar --check-prefixes=THIN,CHECK %s -DPATH=%/t/
20 RUN: llvm-ar t %t/absolute-2.ar | FileCheck %s -DPATH=%/t/
21
22 These tests must be run in %t/foo. cd %t is included on each line to make debugging this test case easier.
23
24 Test that modules can be added with relative paths when the archive is created using a relative path
25
26 RUN: cd %t/foo && llvm-ar rTc ../relative-1.ar elf.o ../delete.o bar/elf.o
27 RUN: cd %t/foo && llvm-ar dT ../relative-1.ar delete.o
28
29 RUN: FileCheck -input-file=%t/relative-1.ar --check-prefixes=THIN,CHECK %s -DPATH=
30 RUN: llvm-ar t %t/relative-1.ar | FileCheck %s -DPATH=%/t/
31
32 Test that modules can be added with relative paths when the archive is created using a absolute path
33
34 RUN: cd %t/foo && llvm-ar rTc %t/relative-2.ar elf.o ../delete.o bar/elf.o
35 RUN: cd %t/foo && llvm-ar dT %t/relative-2.ar delete.o
36
37 RUN: FileCheck -input-file=%t/relative-2.ar --check-prefixes=THIN,CHECK %s -DPATH=
38 RUN: llvm-ar t %t/relative-2.ar | FileCheck %s -DPATH=%/t/
39
40 THIN: !
41
42 CHECK-NOT: delete.o
43 CHECK: {{^}}[[PATH]]foo/elf.o
44 CHECK: {{^}}[[PATH]]foo/bar/elf.o
2222 # RUN: llvm-ar rcT %t.thin1.a %t1.o %s
2323 # RUN: llvm-ar rcT %t.thin2.a %t2.o %s
2424
25 # RUN: not llvm-objcopy --strip-debug %/t.thin1.a 2>&1 \
26 # RUN: | FileCheck %s --check-prefix=THIN -DARCHIVE=%/t.thin1.a -DMEMBER=%/s
27 # RUN: not llvm-strip --strip-debug %/t.thin2.a 2>&1 \
28 # RUN: | FileCheck %s --check-prefix=THIN -DARCHIVE=%/t.thin2.a -DMEMBER=%/s
25 # RUN: not llvm-objcopy --strip-debug %t.thin1.a 2>&1 \
26 # RUN: | FileCheck %s --check-prefix=THIN -DARCHIVE=%t.thin1.a -DMEMBER=%s
27 # RUN: not llvm-strip --strip-debug %t.thin2.a 2>&1 \
28 # RUN: | FileCheck %s --check-prefix=THIN -DARCHIVE=%t.thin2.a -DMEMBER=%s
2929 ## Verify that the first member was not modified, if a later member could not
3030 ## be recognized.
3131 # RUN: cmp %t.o %t1.o
2222 # RUN: llvm-ar rcT c/absolute.a %t/a/b/1.o
2323
2424 # Show that absolute paths in the file header printing are correct.
25 # RUN: llvm-readobj --file-headers c/absolute.a | FileCheck %s --check-prefix=ABS -DDIR=%/t
25 # RUN: llvm-readobj --file-headers c/absolute.a | FileCheck %s --check-prefix=ABS -DDIR=%t
2626 # ABS: File: [[DIR]]/a/b/1.o
2727
2828 # Show that absolute paths in an error message for both archive and member are correct.
2929 # RUN: rm a/b/1.o
30 # RUN: not llvm-readobj --file-headers %/t/c/absolute.a 2>&1 | FileCheck %s --check-prefix=ERR2 -DDIR=%/t
31 # RUN: not llvm-readelf --file-headers %/t/c/absolute.a 2>&1 | FileCheck %s --check-prefix=ERR2 -DDIR=%/t
30 # RUN: not llvm-readobj --file-headers %t/c/absolute.a 2>&1 | FileCheck %s --check-prefix=ERR2 -DDIR=%t
31 # RUN: not llvm-readelf --file-headers %t/c/absolute.a 2>&1 | FileCheck %s --check-prefix=ERR2 -DDIR=%t
3232 # ERR2: error: '[[DIR]]/c/absolute.a': '[[DIR]]/a/b/1.o': {{[Nn]}}o such file or directory
463463 }
464464
465465 if (C.getParent()->isThin()) {
466 if (!sys::path::is_absolute(Name)) {
467 StringRef ParentDir = sys::path::parent_path(ArchiveName);
468 if (!ParentDir.empty())
469 outs() << sys::path::convert_to_slash(ParentDir) << '/';
470 }
466 StringRef ParentDir = sys::path::parent_path(ArchiveName);
467 if (!ParentDir.empty())
468 outs() << ParentDir << '/';
471469 }
472470 outs() << Name << "\n";
473471 }
594592 // the archive it's in, so the file resolves correctly.
595593 if (Thin && FlattenArchive) {
596594 StringSaver Saver(Alloc);
597 Expected FileNameOrErr = M.getName();
595 Expected FileNameOrErr = M.getFullName();
598596 failIfError(FileNameOrErr.takeError());
599 if (sys::path::is_absolute(*FileNameOrErr)) {
600 NMOrErr->MemberName = Saver.save(sys::path::convert_to_slash(*FileNameOrErr));
601 } else {
602 FileNameOrErr = M.getFullName();
603 failIfError(FileNameOrErr.takeError());
604 Expected PathOrErr =
605 computeArchiveRelativePath(ArchiveName, *FileNameOrErr);
606 NMOrErr->MemberName = Saver.save(
607 PathOrErr ? *PathOrErr : sys::path::convert_to_slash(*FileNameOrErr));
608 }
597 NMOrErr->MemberName =
598 Saver.save(computeArchiveRelativePath(ArchiveName, *FileNameOrErr));
609599 }
610600 if (FlattenArchive &&
611601 identify_magic(NMOrErr->Buf->getBuffer()) == file_magic::archive) {
634624 // For regular archives, use the basename of the object path for the member
635625 // name. For thin archives, use the full relative paths so the file resolves
636626 // correctly.
637 if (!Thin) {
638 NMOrErr->MemberName = sys::path::filename(NMOrErr->MemberName);
639 } else {
640 if (sys::path::is_absolute(FileName))
641 NMOrErr->MemberName = Saver.save(sys::path::convert_to_slash(FileName));
642 else {
643 Expected PathOrErr =
644 computeArchiveRelativePath(ArchiveName, FileName);
645 NMOrErr->MemberName = Saver.save(
646 PathOrErr ? *PathOrErr : sys::path::convert_to_slash(FileName));
647 }
648 }
649
627 NMOrErr->MemberName =
628 Thin ? Saver.save(computeArchiveRelativePath(ArchiveName, FileName))
629 : sys::path::filename(NMOrErr->MemberName);
650630 if (FlattenArchive &&
651631 identify_magic(NMOrErr->Buf->getBuffer()) == file_magic::archive) {
652632 object::Archive &Lib = readLibrary(FileName);