mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[llvm-ar] Make llvm-lib behave more like the MSVC archiver
Summary: Use the filepath used to open the archive member as the archive member name instead of the file basename. This path might be absolute or relative. This is important because the archive member name will show up in the PDB, and we want our PDBs to look as much like MSVC's as possible. This also helps avoid an issue in our PDB module descriptor writing code, which assumes that all module names are unique. Relative paths still aren't guaranteed to be unique, but they're much better than basenames, which definitely aren't unique. Reviewers: ruiu, zturner Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D33575 llvm-svn: 305223
This commit is contained in:
parent
511fe48bfd
commit
f2fcc61612
@ -22,6 +22,7 @@ namespace llvm {
|
||||
|
||||
struct NewArchiveMember {
|
||||
std::unique_ptr<MemoryBuffer> Buf;
|
||||
StringRef MemberName;
|
||||
sys::TimePoint<std::chrono::seconds> ModTime;
|
||||
unsigned UID = 0, GID = 0, Perms = 0644;
|
||||
|
||||
|
@ -36,7 +36,8 @@
|
||||
using namespace llvm;
|
||||
|
||||
NewArchiveMember::NewArchiveMember(MemoryBufferRef BufRef)
|
||||
: Buf(MemoryBuffer::getMemBuffer(BufRef, false)) {}
|
||||
: Buf(MemoryBuffer::getMemBuffer(BufRef, false)),
|
||||
MemberName(BufRef.getBufferIdentifier()) {}
|
||||
|
||||
Expected<NewArchiveMember>
|
||||
NewArchiveMember::getOldMember(const object::Archive::Child &OldMember,
|
||||
@ -48,6 +49,7 @@ NewArchiveMember::getOldMember(const object::Archive::Child &OldMember,
|
||||
NewArchiveMember M;
|
||||
assert(M.IsNew == false);
|
||||
M.Buf = MemoryBuffer::getMemBuffer(*BufOrErr, false);
|
||||
M.MemberName = M.Buf->getBufferIdentifier();
|
||||
if (!Deterministic) {
|
||||
auto ModTimeOrErr = OldMember.getLastModified();
|
||||
if (!ModTimeOrErr)
|
||||
@ -97,6 +99,7 @@ Expected<NewArchiveMember> NewArchiveMember::getFile(StringRef FileName,
|
||||
NewArchiveMember M;
|
||||
M.IsNew = true;
|
||||
M.Buf = std::move(*MemberBufferOrErr);
|
||||
M.MemberName = M.Buf->getBufferIdentifier();
|
||||
if (!Deterministic) {
|
||||
M.ModTime = std::chrono::time_point_cast<std::chrono::seconds>(
|
||||
Status.getLastModificationTime());
|
||||
@ -185,7 +188,7 @@ printBSDMemberHeader(raw_fd_ostream &Out, StringRef Name,
|
||||
}
|
||||
|
||||
static bool useStringTable(bool Thin, StringRef Name) {
|
||||
return Thin || Name.size() >= 16;
|
||||
return Thin || Name.size() >= 16 || Name.contains('/');
|
||||
}
|
||||
|
||||
static void
|
||||
@ -239,7 +242,7 @@ static void writeStringTable(raw_fd_ostream &Out, StringRef ArcName,
|
||||
unsigned StartOffset = 0;
|
||||
for (const NewArchiveMember &M : Members) {
|
||||
StringRef Path = M.Buf->getBufferIdentifier();
|
||||
StringRef Name = sys::path::filename(Path);
|
||||
StringRef Name = M.MemberName;
|
||||
if (!useStringTable(Thin, Name))
|
||||
continue;
|
||||
if (StartOffset == 0) {
|
||||
@ -423,9 +426,8 @@ llvm::writeArchive(StringRef ArcName,
|
||||
if (Kind == object::Archive::K_DARWIN)
|
||||
Padding = OffsetToAlignment(M.Buf->getBufferSize(), 8);
|
||||
|
||||
printMemberHeader(Out, Kind, Thin,
|
||||
sys::path::filename(M.Buf->getBufferIdentifier()),
|
||||
StringMapIndexIter, M.ModTime, M.UID, M.GID, M.Perms,
|
||||
printMemberHeader(Out, Kind, Thin, M.MemberName, StringMapIndexIter,
|
||||
M.ModTime, M.UID, M.GID, M.Perms,
|
||||
M.Buf->getBufferSize() + Padding);
|
||||
|
||||
if (!Thin)
|
||||
|
24
test/LibDriver/use-paths.test
Normal file
24
test/LibDriver/use-paths.test
Normal file
@ -0,0 +1,24 @@
|
||||
llvm-lib should behave like "link.exe /lib" and use relative paths to describe
|
||||
archive members.
|
||||
|
||||
First, get in a clean working directory.
|
||||
RUN: rm -rf %t && mkdir -p %t && cd %t
|
||||
|
||||
Make foo/a.obj and foo/b.obj.
|
||||
RUN: mkdir foo
|
||||
RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o foo/a.obj %S/Inputs/a.s
|
||||
RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o foo/b.obj %S/Inputs/b.s
|
||||
|
||||
RUN: llvm-lib -out:foo.lib foo/a.obj foo/b.obj
|
||||
RUN: llvm-ar t foo.lib | FileCheck %s
|
||||
|
||||
FIXME: We should probably use backslashes on Windows to better match MSVC tools.
|
||||
CHECK: foo/a.obj
|
||||
CHECK: foo/b.obj
|
||||
|
||||
Do it again with absolute paths and see that we get something.
|
||||
RUN: llvm-lib -out:foo.lib %t/foo/a.obj %t/foo/b.obj
|
||||
RUN: llvm-ar t foo.lib | FileCheck %s --check-prefix=ABS
|
||||
|
||||
ABS: {{.*}}/foo/a.obj
|
||||
ABS: {{.*}}/foo/b.obj
|
@ -473,6 +473,10 @@ static void addMember(std::vector<NewArchiveMember> &Members,
|
||||
Expected<NewArchiveMember> NMOrErr =
|
||||
NewArchiveMember::getFile(FileName, Deterministic);
|
||||
failIfError(NMOrErr.takeError(), FileName);
|
||||
|
||||
// Use the basename of the object path for the member name.
|
||||
NMOrErr->MemberName = sys::path::filename(NMOrErr->MemberName);
|
||||
|
||||
if (Pos == -1)
|
||||
Members.push_back(std::move(*NMOrErr));
|
||||
else
|
||||
|
Loading…
x
Reference in New Issue
Block a user