Skip to content

Commit ff07c9b

Browse files
authoredFeb 28, 2024··
[Driver] Unify InstalledDir and Dir (#80527)
`Driver::ClangExecutable` is derived from: * (-canonical-prefixes default): `realpath` on the executable path * (-no-canonical-prefixes) argv[0] (consult PATH if argv[0] is a word) `Dir` and `ResourceDir` are derived from `ClangExecutable`. Both variables are used to derive certain include and library paths. `InstalledDir` is a related concept used to derive certain other paths. `InstalledDir` is weird in the -canonical-prefixes mode: Clang calls `make_absolute` but does not follow symlinks (FIXME from 9ade6a9). This causes some search and library paths to be mix-and-matched. The "Do a PATH lookup, if there are no directory components." logic makes things worse. `InstalledDir` is different when you invoke it via `PATH`: ``` % which clang /usr/bin/clang % clang -v |& grep InstalledDir InstalledDir: /usr/bin % /usr/lib/llvm-16/bin/clang -v |& grep InstalledDir InstalledDir: /usr/lib/llvm-16/bin ``` I believe `InstalledDir` was a partial solution to `-no-canonical-prefixes` and should be eventually removed. This patch removes `SetInstallDir` and relies on Driver::Driver to set `InstalledDir` to `Dir`. The behavior for regular file `clang` or `-no-canonical-prefixes` is unchanged. If a user creates a symlink to the regular file `clang` and uses the default `-canonical-prefixes`, they now consistently get search and library paths relative to the regular file `clang`, not mix-and-match paths. If a user creates a symlink to the regular file `clang` and replaces some directorys from the actual installation, they should change the symlink to a wrapper that calls the underlying clang with `-no-canonical-prefixes`.
1 parent c345198 commit ff07c9b

File tree

7 files changed

+20
-39
lines changed

7 files changed

+20
-39
lines changed
 

‎clang/include/clang/Driver/Driver.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ class Driver {
160160
/// Target and driver mode components extracted from clang executable name.
161161
ParsedClangName ClangNameParts;
162162

163-
/// The path to the installed clang directory, if any.
163+
/// TODO: Remove this in favor of Dir.
164164
std::string InstalledDir;
165165

166166
/// The path to the compiler resource directory.
@@ -433,7 +433,6 @@ class Driver {
433433
return InstalledDir.c_str();
434434
return Dir.c_str();
435435
}
436-
void setInstalledDir(StringRef Value) { InstalledDir = std::string(Value); }
437436

438437
bool isSaveTempsEnabled() const { return SaveTemps != SaveTempsNone; }
439438
bool isSaveTempsObj() const { return SaveTemps == SaveTempsObj; }

‎clang/test/Driver/darwin-header-search-libcxx.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@
193193
// RUN: ln -sf %t/install/bin/clang %t/symlinked1/bin/clang
194194
// RUN: mkdir -p %t/symlinked1/include/c++/v1
195195

196-
// RUN: %t/symlinked1/bin/clang -### %s -fsyntax-only 2>&1 \
196+
// RUN: %t/symlinked1/bin/clang -### %s -no-canonical-prefixes -fsyntax-only 2>&1 \
197197
// RUN: --target=x86_64-apple-darwin \
198198
// RUN: -stdlib=libc++ \
199199
// RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \

‎clang/test/Driver/mingw-sysroot.cpp

+7-5
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,12 @@
5050
// CHECK_TESTROOT_GCC_EXPLICIT: "-internal-isystem" "{{[^"]+}}/testroot-gcc{{/|\\\\}}include"
5151

5252

53-
// If there's a matching sysroot next to the clang binary itself, prefer that
53+
// If -no-canonical-prefixes and there's a matching sysroot next to the clang binary itself, prefer that
5454
// over a gcc in the path:
5555

56-
// RUN: env "PATH=%T/testroot-gcc/bin:%PATH%" %T/testroot-clang/bin/x86_64-w64-mingw32-clang -target x86_64-w64-mingw32 -rtlib=compiler-rt -stdlib=libstdc++ --sysroot="" -c -### %s 2>&1 | FileCheck -check-prefix=CHECK_TESTROOT_CLANG %s
56+
// RUN: env "PATH=%T/testroot-gcc/bin:%PATH%" %T/testroot-clang/bin/x86_64-w64-mingw32-clang --target=x86_64-w64-mingw32 -rtlib=compiler-rt -stdlib=libstdc++ --sysroot="" -c -### %s 2>&1 | FileCheck -check-prefix=CHECK_TESTROOT_GCC2 %s
57+
// RUN: env "PATH=%T/testroot-gcc/bin:%PATH%" %T/testroot-clang/bin/x86_64-w64-mingw32-clang --target=x86_64-w64-mingw32 -rtlib=compiler-rt -stdlib=libstdc++ --sysroot="" -c -### %s -no-canonical-prefixes 2>&1 | FileCheck -check-prefix=CHECK_TESTROOT_CLANG %s
58+
// CHECK_TESTROOT_GCC2: "{{[^"]+}}/testroot-gcc{{/|\\\\}}x86_64-w64-mingw32{{/|\\\\}}include"
5759
// CHECK_TESTROOT_CLANG: "{{[^"]+}}/testroot-clang{{/|\\\\}}x86_64-w64-mingw32{{/|\\\\}}include"
5860

5961

@@ -82,7 +84,7 @@
8284
// that indicates that we did choose the right base, even if this particular directory
8385
// actually doesn't exist here.
8486

85-
// RUN: env "PATH=%T/testroot-gcc/bin:%PATH%" %T/testroot-clang-native/bin/clang -target x86_64-w64-mingw32 -rtlib=compiler-rt -stdlib=libstdc++ --sysroot="" -c -### %s 2>&1 | FileCheck -check-prefix=CHECK_TESTROOT_CLANG_NATIVE %s
87+
// RUN: env "PATH=%T/testroot-gcc/bin:%PATH%" %T/testroot-clang-native/bin/clang -no-canonical-prefixes --target=x86_64-w64-mingw32 -rtlib=compiler-rt -stdlib=libstdc++ --sysroot="" -c -### %s 2>&1 | FileCheck -check-prefix=CHECK_TESTROOT_CLANG_NATIVE %s
8688
// CHECK_TESTROOT_CLANG_NATIVE: "{{[^"]+}}/testroot-clang-native{{/|\\\\}}x86_64-w64-mingw32{{/|\\\\}}include"
8789

8890

@@ -93,12 +95,12 @@
9395
// that defaults to x86_64 mingw, but it's easier to test this in cross setups
9496
// with symlinks, like the other tests here.)
9597

96-
// RUN: env "PATH=%T/testroot-gcc/bin:%PATH%" %T/testroot-clang/bin/x86_64-w64-mingw32-clang --target=x86_64-w64-mingw32 -m32 -rtlib=compiler-rt -stdlib=libstdc++ --sysroot="" -c -### %s 2>&1 | FileCheck -check-prefix=CHECK_TESTROOT_CLANG_I686 %s
98+
// RUN: env "PATH=%T/testroot-gcc/bin:%PATH%" %T/testroot-clang/bin/x86_64-w64-mingw32-clang -no-canonical-prefixes --target=x86_64-w64-mingw32 -m32 -rtlib=compiler-rt -stdlib=libstdc++ --sysroot="" -c -### %s 2>&1 | FileCheck -check-prefix=CHECK_TESTROOT_CLANG_I686 %s
9799
// CHECK_TESTROOT_CLANG_I686: "{{[^"]+}}/testroot-clang{{/|\\\\}}i686-w64-mingw32{{/|\\\\}}include"
98100

99101

100102
// If the user calls clang with a custom literal triple, make sure this maps
101103
// to sysroots with the matching spelling.
102104

103-
// RUN: %T/testroot-custom-triple/bin/clang --target=x86_64-w64-mingw32foo -rtlib=compiler-rt -stdlib=libstdc++ --sysroot="" -c -### %s 2>&1 | FileCheck -check-prefix=CHECK_TESTROOT_CUSTOM_TRIPLE %s
105+
// RUN: %T/testroot-custom-triple/bin/clang -no-canonical-prefixes --target=x86_64-w64-mingw32foo -rtlib=compiler-rt -stdlib=libstdc++ --sysroot="" -c -### %s 2>&1 | FileCheck -check-prefix=CHECK_TESTROOT_CUSTOM_TRIPLE %s
104106
// CHECK_TESTROOT_CUSTOM_TRIPLE: "{{[^"]+}}/testroot-custom-triple{{/|\\\\}}x86_64-w64-mingw32foo{{/|\\\\}}include"

‎clang/test/Driver/no-canonical-prefixes.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
// RUN: | FileCheck --check-prefix=NON-CANONICAL %s
2727
//
2828
// FIXME: This should really be '.real'.
29-
// CANONICAL: InstalledDir: {{.*}}.fake
29+
// CANONICAL: InstalledDir: {{.*}}bin
3030
// CANONICAL: {{[/|\\]*}}clang{{.*}}" -cc1
3131
//
3232
// NON-CANONICAL: InstalledDir: .{{$}}

‎clang/test/Driver/program-path-priority.c

+8-5
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
// RUN: touch %t/notreal-none-elf-gcc && chmod +x %t/notreal-none-elf-gcc
3737
// RUN: env "PATH=" %t/clang -### -target notreal-none-elf %s 2>&1 | \
3838
// RUN: FileCheck --check-prefix=PROG_PATH_NOTREAL_GCC %s
39-
// PROG_PATH_NOTREAL_GCC: notreal-none-elf-gcc"
39+
// PROG_PATH_NOTREAL_GCC: notreal-none-unknown-elf
4040

4141
/// <triple>-gcc on the PATH is found
4242
// RUN: mkdir -p %t/env
@@ -57,7 +57,7 @@
5757
// RUN: touch %t/gcc && chmod +x %t/gcc
5858
// RUN: env "PATH=" %t/clang -### -target notreal-none-elf %s 2>&1 | \
5959
// RUN: FileCheck --check-prefix=NOTREAL_GCC_PREFERRED %s
60-
// NOTREAL_GCC_PREFERRED: notreal-none-elf-gcc"
60+
// NOTREAL_GCC_PREFERRED: notreal-none-unknown-elf"
6161
// NOTREAL_GCC_PREFERRED-NOT: /gcc"
6262

6363
/// <triple>-gcc on the PATH is preferred to gcc in program path
@@ -125,6 +125,9 @@
125125
/// Only if there is nothing in the prefix will we search other paths
126126
/// -f in case $DEFAULT_TRIPLE == %target_triple
127127
// RUN: rm -f %t/prefix/$DEFAULT_TRIPLE-gcc %t/prefix/%target_triple-gcc %t/prefix/gcc
128-
// RUN: env "PATH=" %t/clang -### -target notreal-none-elf %s -B %t/prefix 2>&1 | \
129-
// RUN: FileCheck --check-prefix=EMPTY_PREFIX_DIR %s
130-
// EMPTY_PREFIX_DIR: notreal-none-elf-gcc"
128+
// RUN: env "PATH=" %t/clang -### -canonical-prefixes --target=notreal-none-elf %s -B %t/prefix 2>&1 | \
129+
// RUN: FileCheck --check-prefix=EMPTY_PREFIX_DIR1 %s
130+
// EMPTY_PREFIX_DIR1: gcc"
131+
// RUN: env "PATH=" %t/clang -### -no-canonical-prefixes --target=notreal-none-elf %s -B %t/prefix 2>&1 | \
132+
// RUN: FileCheck --check-prefix=EMPTY_PREFIX_DIR2 %s
133+
// EMPTY_PREFIX_DIR2: notreal-none-elf-gcc"

‎clang/test/Driver/rocm-detect.hip

+2-2
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@
102102
// RUN: rm -rf %t/rocm-spack
103103
// RUN: cp -r %S/Inputs/rocm-spack %t
104104
// RUN: ln -fs %clang %t/rocm-spack/llvm-amdgpu-4.0.0-ieagcs7inf7runpyfvepqkurasoglq4z/bin/clang
105-
// RUN: %t/rocm-spack/llvm-amdgpu-4.0.0-ieagcs7inf7runpyfvepqkurasoglq4z/bin/clang -### -v \
105+
// RUN: %t/rocm-spack/llvm-amdgpu-4.0.0-ieagcs7inf7runpyfvepqkurasoglq4z/bin/clang -### -no-canonical-prefixes -v \
106106
// RUN: -resource-dir=%t/rocm-spack/llvm-amdgpu-4.0.0-ieagcs7inf7runpyfvepqkurasoglq4z/lib/clang \
107107
// RUN: -target x86_64-linux-gnu --cuda-gpu-arch=gfx900 --print-rocm-search-dirs %s 2>&1 \
108108
// RUN: | FileCheck -check-prefixes=SPACK %s
@@ -111,7 +111,7 @@
111111
// ROCm release. --hip-path and --rocm-device-lib-path can be used to specify them.
112112

113113
// RUN: cp -r %t/rocm-spack/hip-* %t/rocm-spack/hip-4.0.0-abcd
114-
// RUN: %t/rocm-spack/llvm-amdgpu-4.0.0-ieagcs7inf7runpyfvepqkurasoglq4z/bin/clang -### -v \
114+
// RUN: %t/rocm-spack/llvm-amdgpu-4.0.0-ieagcs7inf7runpyfvepqkurasoglq4z/bin/clang -### -no-canonical-prefixes -v \
115115
// RUN: -target x86_64-linux-gnu --cuda-gpu-arch=gfx900 \
116116
// RUN: --hip-path=%t/rocm-spack/hip-4.0.0-abcd \
117117
// RUN: %s 2>&1 | FileCheck -check-prefixes=SPACK-SET %s

‎clang/tools/driver/driver.cpp

-23
Original file line numberDiff line numberDiff line change
@@ -323,28 +323,6 @@ static void FixupDiagPrefixExeName(TextDiagnosticPrinter *DiagClient,
323323
DiagClient->setPrefix(std::string(ExeBasename));
324324
}
325325

326-
static void SetInstallDir(SmallVectorImpl<const char *> &argv,
327-
Driver &TheDriver, bool CanonicalPrefixes) {
328-
// Attempt to find the original path used to invoke the driver, to determine
329-
// the installed path. We do this manually, because we want to support that
330-
// path being a symlink.
331-
SmallString<128> InstalledPath(argv[0]);
332-
333-
// Do a PATH lookup, if there are no directory components.
334-
if (llvm::sys::path::filename(InstalledPath) == InstalledPath)
335-
if (llvm::ErrorOr<std::string> Tmp = llvm::sys::findProgramByName(
336-
llvm::sys::path::filename(InstalledPath.str())))
337-
InstalledPath = *Tmp;
338-
339-
// FIXME: We don't actually canonicalize this, we just make it absolute.
340-
if (CanonicalPrefixes)
341-
llvm::sys::fs::make_absolute(InstalledPath);
342-
343-
StringRef InstalledPathParent(llvm::sys::path::parent_path(InstalledPath));
344-
if (llvm::sys::fs::exists(InstalledPathParent))
345-
TheDriver.setInstalledDir(InstalledPathParent);
346-
}
347-
348326
static int ExecuteCC1Tool(SmallVectorImpl<const char *> &ArgV,
349327
const llvm::ToolContext &ToolContext) {
350328
// If we call the cc1 tool from the clangDriver library (through
@@ -484,7 +462,6 @@ int clang_main(int Argc, char **Argv, const llvm::ToolContext &ToolContext) {
484462
ProcessWarningOptions(Diags, *DiagOpts, /*ReportDiags=*/false);
485463

486464
Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags);
487-
SetInstallDir(Args, TheDriver, CanonicalPrefixes);
488465
auto TargetAndMode = ToolChain::getTargetAndModeFromProgramName(ProgName);
489466
TheDriver.setTargetAndMode(TargetAndMode);
490467
// If -canonical-prefixes is set, GetExecutablePath will have resolved Path

0 commit comments

Comments
 (0)
Please sign in to comment.