}
}
-// Search for all possible combinations of `{root}/{name}.{extension}`.
-// If \p extensions are not specified, then just search for `{root}/{name}`.
-static Optional<StringRef>
-findPathCombination(const Twine &name, const std::vector<StringRef> &roots,
- ArrayRef<StringRef> extensions = {""}) {
- SmallString<261> base;
- for (StringRef dir : roots) {
- base = dir;
- path::append(base, name);
- for (StringRef ext : extensions) {
- Twine location = base + ext;
- if (fs::exists(location))
- return saver.save(location.str());
- else
- depTracker->logFileNotFound(location);
- }
- }
- return {};
-}
-
static Optional<StringRef> findLibrary(StringRef name) {
if (config->searchDylibsFirst) {
if (Optional<StringRef> path = findPathCombination(
{".tbd", ".dylib", ".a"});
}
-// If -syslibroot is specified, absolute paths to non-object files may be
-// rerooted.
-static StringRef rerootPath(StringRef path) {
- if (!path::is_absolute(path, path::Style::posix) || path.endswith(".o"))
- return path;
-
- if (Optional<StringRef> rerootedPath =
- findPathCombination(path, config->systemLibraryRoots))
- return *rerootedPath;
-
- return path;
-}
-
static Optional<std::string> findFramework(StringRef name) {
SmallString<260> symlink;
StringRef suffix;
std::vector<ArchiveMember> v;
Error err = Error::success();
- // Thin archives refer to .o files, so --reproduces needs the .o files too.
+ // Thin archives refer to .o files, so --reproduce needs the .o files too.
bool addToTar = archive->isThin() && tar;
for (const Archive::Child &c : archive->children(err)) {
return true;
}
+ config = make<Configuration>();
+ symtab = make<SymbolTable>();
+ target = createTargetInfo(args);
+ depTracker =
+ make<DependencyTracker>(args.getLastArgValue(OPT_dependency_info));
+
+ config->systemLibraryRoots = getSystemLibraryRoots(args);
if (const char *path = getReproduceOption(args)) {
// Note that --reproduce is a debug option so you can ignore it
// if you are trying to understand the whole picture of the code.
}
}
- config = make<Configuration>();
- symtab = make<SymbolTable>();
- target = createTargetInfo(args);
-
- depTracker =
- make<DependencyTracker>(args.getLastArgValue(OPT_dependency_info, ""));
-
if (auto *arg = args.getLastArg(OPT_threads_eq)) {
StringRef v(arg->getValue());
unsigned threads = 0;
config->undefinedSymbolTreatment = getUndefinedSymbolTreatment(args);
- config->systemLibraryRoots = getSystemLibraryRoots(args);
config->librarySearchPaths =
getLibrarySearchPaths(args, config->systemLibraryRoots);
config->frameworkSearchPaths =
DylibFile *umbrella = nullptr,
bool isBundleLoader = false);
+// Search for all possible combinations of `{root}/{name}.{extension}`.
+// If \p extensions are not specified, then just search for `{root}/{name}`.
+llvm::Optional<llvm::StringRef>
+findPathCombination(const llvm::Twine &name,
+ const std::vector<llvm::StringRef> &roots,
+ ArrayRef<llvm::StringRef> extensions = {""});
+
+// If -syslibroot is specified, absolute paths to non-object files may be
+// rerooted.
+llvm::StringRef rerootPath(llvm::StringRef path);
+
llvm::Optional<InputFile *> loadArchiveMember(MemoryBufferRef, uint32_t modTime,
StringRef archiveName,
bool objCOnly);
return std::string(s);
}
+static std::string rewriteInputPath(StringRef s) {
+ // Don't bother rewriting "absolute" paths that are actually under the
+ // syslibroot; simply rewriting the syslibroot is sufficient.
+ if (rerootPath(s) == s && fs::exists(s))
+ return relativeToRoot(s);
+ return std::string(s);
+}
+
// Reconstructs command line arguments so that so that you can re-run
// the same command with the same inputs. This is for --reproduce.
std::string macho::createResponseFile(const InputArgList &args) {
case OPT_reproduce:
break;
case OPT_INPUT:
- os << quote(rewritePath(arg->getValue())) << "\n";
+ os << quote(rewriteInputPath(arg->getValue())) << "\n";
break;
case OPT_o:
os << "-o " << quote(path::filename(arg->getValue())) << "\n";
case OPT_filelist:
if (Optional<MemoryBufferRef> buffer = readFile(arg->getValue()))
for (StringRef path : args::getLines(*buffer))
- os << quote(rewritePath(path)) << "\n";
+ os << quote(rewriteInputPath(path)) << "\n";
+ break;
+ case OPT_force_load:
+ case OPT_weak_library:
+ os << arg->getSpelling() << " "
+ << quote(rewriteInputPath(arg->getValue())) << "\n";
break;
case OPT_F:
case OPT_L:
case OPT_bundle_loader:
case OPT_exported_symbols_list:
- case OPT_force_load:
case OPT_order_file:
case OPT_rpath:
case OPT_syslibroot:
return file;
}
+Optional<StringRef>
+macho::findPathCombination(const Twine &name,
+ const std::vector<StringRef> &roots,
+ ArrayRef<StringRef> extensions) {
+ SmallString<261> base;
+ for (StringRef dir : roots) {
+ base = dir;
+ path::append(base, name);
+ for (StringRef ext : extensions) {
+ Twine location = base + ext;
+ if (fs::exists(location))
+ return saver.save(location.str());
+ else
+ depTracker->logFileNotFound(location);
+ }
+ }
+ return {};
+}
+
+StringRef macho::rerootPath(StringRef path) {
+ if (!path::is_absolute(path, path::Style::posix) || path.endswith(".o"))
+ return path;
+
+ if (Optional<StringRef> rerootedPath =
+ findPathCombination(path, config->systemLibraryRoots))
+ return *rerootedPath;
+
+ return path;
+}
+
Optional<InputFile *> macho::loadArchiveMember(MemoryBufferRef mb,
uint32_t modTime,
StringRef archiveName,
# RUN: %lld -dylib %t/bar.o -o %t/%:t/libbar.dylib
## Test our various file-loading flags to make sure all bases are covered.
-# RUN: %lld -lSystem -syslibroot %t %t/foo.a %t/bar.a %t/test.o -o /dev/null -t | FileCheck %s -DDIR="%t/%:t"
-# RUN: %lld -lSystem -syslibroot %t -force_load %t/foo.a -force_load %t/bar.a %t/test.o -o /dev/null -t | FileCheck %s -DDIR="%t/%:t"
-# RUN: %lld -lSystem -syslibroot %t %t/libfoo.dylib %t/libbar.dylib %t/test.o -o /dev/null -t | FileCheck %s -DDIR="%t/%:t"
-# RUN: %lld -lSystem -syslibroot %t -weak_library %t/libfoo.dylib -weak_library %t/libbar.dylib %t/test.o -o /dev/null -t | FileCheck %s -DDIR="%t/%:t"
+# RUN: %lld --reproduce %t/repro1.tar -lSystem -syslibroot %t %t/foo.a %t/bar.a %t/test.o -o /dev/null -t | FileCheck %s -DDIR="%t/%:t"
+# RUN: tar xf %t/repro1.tar -C %t
+# RUN: cd %t/repro1; ld64.lld @response.txt | FileCheck %s -DDIR="%:t/%:t"
+
+# RUN: %lld --reproduce %t/repro2.tar -lSystem -syslibroot %t -force_load %t/foo.a -force_load %t/bar.a %t/test.o -o /dev/null -t | FileCheck %s -DDIR="%t/%:t"
+# RUN: tar xf %t/repro2.tar -C %t
+# RUN: cd %t/repro2; ld64.lld @response.txt | FileCheck %s -DDIR="%:t/%:t"
+
+# RUN: %lld --reproduce %t/repro3.tar -lSystem -syslibroot %t %t/libfoo.dylib %t/libbar.dylib %t/test.o -o /dev/null -t | FileCheck %s -DDIR="%t/%:t"
+# RUN: tar xf %t/repro3.tar -C %t
+# RUN: cd %t/repro3; ld64.lld @response.txt | FileCheck %s -DDIR="%:t/%:t"
+
+# RUN: %lld --reproduce %t/repro4.tar -lSystem -syslibroot %t -weak_library %t/libfoo.dylib -weak_library %t/libbar.dylib %t/test.o -o /dev/null -t | FileCheck %s -DDIR="%t/%:t"
+# RUN: tar xf %t/repro4.tar -C %t
+# RUN: cd %t/repro4; ld64.lld @response.txt | FileCheck %s -DDIR="%:t/%:t"
+
# RUN: echo "%t/libfoo.dylib" > %t/filelist
# RUN: echo "%t/libbar.dylib" >> %t/filelist
-# RUN: %lld -lSystem -syslibroot %t -filelist %t/filelist %t/test.o -o /dev/null -t | FileCheck %s -DDIR="%t/%:t"
-# CHECK: [[DIR]]/{{(lib)?}}bar
+# RUN: %lld --reproduce %t/repro5.tar -lSystem -syslibroot %t -filelist %t/filelist %t/test.o -o /dev/null -t | FileCheck %s -DDIR="%t/%:t"
+# RUN: tar xf %t/repro5.tar -C %t
+# RUN: cd %t/repro5; ld64.lld @response.txt | FileCheck %s -DDIR="%:t/%:t"
+
+## The {{^}} ensures that we only match relative paths if DIR is relative.
+# CHECK: {{^}}[[DIR]]/{{(lib)?}}bar
## Paths to object files don't get rerooted.
# RUN: mv %t/bar.o %t/%:t/bar.o
## rerooted path takes precedence over the original path. We will get an
## undefined symbol error since we aren't loading %t/libfoo.dylib.
# RUN: cp %t/%:t/libbar.dylib %t/%:t/libfoo.dylib
-# RUN: not %lld -lSystem -syslibroot %t %t/libfoo.dylib %t/libbar.dylib %t/test.o \
-# RUN: -o /dev/null 2>&1 | FileCheck %s --check-prefix=UNDEF
+# RUN: not %lld --reproduce %t/repro6.tar -lSystem -syslibroot %t %t/libfoo.dylib %t/libbar.dylib %t/test.o \
+# RUN: -o /dev/null -t 2> %t/error | FileCheck %s -DDIR="%t/%:t" --check-prefix=FOO
+# RUN: FileCheck %s --check-prefix=UNDEF < %t/error
+
+# RUN: tar xf %t/repro6.tar -C %t
+# RUN: cd %t/repro6; not ld64.lld @response.txt 2> %t/error | FileCheck %s -DDIR="%:t/%:t" --check-prefix=FOO
+# RUN: FileCheck %s --check-prefix=UNDEF < %t/error
+
+# FOO: [[DIR]]/libfoo.dylib
# UNDEF: error: undefined symbol: _foo
#--- foo.s