forked from OSchip/llvm-project
[LLD] Fix Microsoft precompiled headers cross-compile on Linux
Differential revision: https://reviews.llvm.org/D54122 llvm-svn: 346403
This commit is contained in:
parent
b917740ac3
commit
4b2957243b
|
@ -645,7 +645,7 @@ PDBLinker::mergeInPrecompHeaderObj(ObjFile *File, const CVType &FirstType,
|
|||
|
||||
auto E = aquirePrecompObj(File, Precomp);
|
||||
if (!E)
|
||||
return createFileError(Precomp.getPrecompFilePath().str(), E.takeError());
|
||||
return E.takeError();
|
||||
|
||||
const CVIndexMap &PrecompIndexMap = *E;
|
||||
assert(PrecompIndexMap.IsPrecompiledTypeMap);
|
||||
|
@ -670,28 +670,18 @@ static bool equals_path(StringRef path1, StringRef path2) {
|
|||
#endif
|
||||
}
|
||||
|
||||
// Find an OBJ provided on the command line, either by name or full path
|
||||
static Optional<std::pair<ObjFile *, std::string>>
|
||||
findObjByName(StringRef NameOrPath) {
|
||||
// Find by name an OBJ provided on the command line
|
||||
static ObjFile *findObjByName(StringRef FileNameOnly) {
|
||||
SmallString<128> CurrentPath;
|
||||
|
||||
StringRef FileNameOnly = sys::path::filename(NameOrPath);
|
||||
|
||||
for (ObjFile *F : ObjFile::Instances) {
|
||||
CurrentPath = F->getName();
|
||||
sys::fs::make_absolute(CurrentPath);
|
||||
StringRef CurrentFileName = sys::path::filename(F->getName());
|
||||
|
||||
// First compare with the full path name
|
||||
if (equals_path(CurrentPath, NameOrPath))
|
||||
return std::make_pair(F, CurrentPath.str().str());
|
||||
|
||||
StringRef CurrentFileName = sys::path::filename(CurrentPath);
|
||||
|
||||
// Otherwise compare based solely on the file name (link.exe behavior)
|
||||
// Compare based solely on the file name (link.exe behavior)
|
||||
if (equals_path(CurrentFileName, FileNameOnly))
|
||||
return std::make_pair(F, CurrentPath.str().str());
|
||||
return F;
|
||||
}
|
||||
return {};
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::pair<CVIndexMap &, bool /*already there*/>
|
||||
|
@ -715,29 +705,29 @@ PDBLinker::aquirePrecompObj(ObjFile *File, PrecompRecord Precomp) {
|
|||
|
||||
CVIndexMap &IndexMap = R.first;
|
||||
|
||||
SmallString<128> PrecompPath = Precomp.getPrecompFilePath();
|
||||
sys::fs::make_absolute(PrecompPath);
|
||||
|
||||
// Cross-compile warning: given that Clang doesn't generate LF_PRECOMP
|
||||
// records, we assume the OBJ comes from a Windows build of cl.exe. Thusly,
|
||||
// the paths embedded in the OBJs are in the Windows format.
|
||||
sys::path::native(PrecompPath, sys::path::Style::windows);
|
||||
SmallString<128> PrecompFileName = sys::path::filename(
|
||||
Precomp.getPrecompFilePath(), sys::path::Style::windows);
|
||||
|
||||
// link.exe requires that a precompiled headers object must always be provided
|
||||
// on the command-line, even if that's not necessary.
|
||||
auto PrecompFilePath = findObjByName(PrecompPath);
|
||||
if (!PrecompFilePath)
|
||||
return errorCodeToError(std::error_code(ENOENT, std::generic_category()));
|
||||
auto PrecompFile = findObjByName(PrecompFileName);
|
||||
if (!PrecompFile)
|
||||
return createFileError(
|
||||
PrecompFileName.str(),
|
||||
make_error<pdb::PDBError>(pdb::pdb_error_code::external_cmdline_ref));
|
||||
|
||||
ObjFile *CurrentFile = PrecompFilePath->first;
|
||||
addObjFile(PrecompFile, &IndexMap);
|
||||
|
||||
addObjFile(CurrentFile, &IndexMap);
|
||||
if (!PrecompFile->EndPrecomp)
|
||||
fatal(PrecompFile->getName() + " is not a precompiled headers object");
|
||||
|
||||
if (!CurrentFile->EndPrecomp)
|
||||
fatal(PrecompFilePath->second + " is not a precompiled headers object");
|
||||
|
||||
if (Precomp.getSignature() != CurrentFile->EndPrecomp->getSignature())
|
||||
return make_error<pdb::PDBError>(pdb::pdb_error_code::signature_out_of_date);
|
||||
if (Precomp.getSignature() != PrecompFile->EndPrecomp->getSignature())
|
||||
return createFileError(
|
||||
Precomp.getPrecompFilePath().str(),
|
||||
make_error<pdb::PDBError>(pdb::pdb_error_code::signature_out_of_date));
|
||||
|
||||
return IndexMap;
|
||||
}
|
||||
|
|
|
@ -241,6 +241,11 @@ void SymbolTable::reportRemainingUndefines() {
|
|||
}
|
||||
}
|
||||
|
||||
// We don't want to report missing Microsoft precompiled headers symbols.
|
||||
// A proper message will be emitted instead in PDBLinker::aquirePrecompObj
|
||||
if (Name.contains("_PchSym_"))
|
||||
continue;
|
||||
|
||||
if (Config->MinGW && handleMinGWAutomaticImport(Sym, Name))
|
||||
continue;
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
REQUIRES: system-windows
|
||||
|
||||
RUN: lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj %S/Inputs/precomp.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf
|
||||
RUN: llvm-pdbutil dump -types %t.pdb | FileCheck %s
|
||||
|
||||
|
@ -8,9 +6,14 @@ RUN: llvm-pdbutil dump -types %t.pdb | FileCheck %s
|
|||
|
||||
RUN: lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-invalid.obj %S/Inputs/precomp.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf 2>&1 | FileCheck %s -check-prefix FAILURE
|
||||
|
||||
RUN: not lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf 2>&1 | FileCheck %s -check-prefix FAILURE-MISSING-PRECOMPOBJ
|
||||
|
||||
FAILURE: warning: Cannot use debug info for 'precomp-invalid.obj'
|
||||
FAILURE-NEXT: failed to load reference '{{.*}}precomp.obj': The signature does not match; the file(s) might be out of date.
|
||||
|
||||
FAILURE-MISSING-PRECOMPOBJ: warning: Cannot use debug info for 'precomp-a.obj'
|
||||
FAILURE-MISSING-PRECOMPOBJ-NEXT: failed to load reference 'precomp.obj': The path to this file must be provided on the command-line
|
||||
|
||||
CHECK: Types (TPI Stream)
|
||||
CHECK-NOT: LF_PRECOMP
|
||||
CHECK-NOT: LF_ENDPRECOMP
|
||||
|
|
|
@ -21,6 +21,7 @@ enum class pdb_error_code {
|
|||
dia_sdk_not_present,
|
||||
dia_failed_loading,
|
||||
signature_out_of_date,
|
||||
external_cmdline_ref,
|
||||
unspecified,
|
||||
};
|
||||
} // namespace pdb
|
||||
|
|
|
@ -34,6 +34,8 @@ public:
|
|||
return "The PDB file path is an invalid UTF8 sequence.";
|
||||
case pdb_error_code::signature_out_of_date:
|
||||
return "The signature does not match; the file(s) might be out of date.";
|
||||
case pdb_error_code::external_cmdline_ref:
|
||||
return "The path to this file must be provided on the command-line.";
|
||||
}
|
||||
llvm_unreachable("Unrecognized generic_error_code");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue