Skip to content

Commit fc80a9a

Browse files
authored
Merge pull request #36749 from egorzhdan/clang-executable-path
ClangImporter: run Clang with a proper executable path
2 parents e8b0398 + 6650a89 commit fc80a9a

File tree

7 files changed

+37
-2
lines changed

7 files changed

+37
-2
lines changed

include/swift/Basic/LangOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,10 @@ namespace swift {
629629
/// Options for controlling the behavior of the Clang importer.
630630
class ClangImporterOptions final {
631631
public:
632+
/// The path to the Clang compiler executable.
633+
/// Used to detect the default include paths.
634+
std::string clangPath = "clang";
635+
632636
/// The module cache path which the Clang importer should use.
633637
std::string ModuleCachePath;
634638

lib/ClangImporter/ClangImporter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -953,7 +953,7 @@ ClangImporter::getClangArguments(ASTContext &ctx) {
953953
std::vector<std::string> invocationArgStrs;
954954
// Clang expects this to be like an actual command line. So we need to pass in
955955
// "clang" for argv[0]
956-
invocationArgStrs.push_back("clang");
956+
invocationArgStrs.push_back(ctx.ClangImporterOpts.clangPath);
957957
switch (ctx.ClangImporterOpts.Mode) {
958958
case ClangImporterOptions::Modes::Normal:
959959
case ClangImporterOptions::Modes::PrecompiledModule:

lib/Driver/ToolChains.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI,
259259
inputArgs.AddLastArg(arguments, options::OPT_swift_version);
260260
inputArgs.AddLastArg(arguments, options::OPT_enforce_exclusivity_EQ);
261261
inputArgs.AddLastArg(arguments, options::OPT_stats_output_dir);
262+
inputArgs.AddLastArg(arguments, options::OPT_tools_directory);
262263
inputArgs.AddLastArg(arguments, options::OPT_trace_stats_events);
263264
inputArgs.AddLastArg(arguments, options::OPT_profile_stats_events);
264265
inputArgs.AddLastArg(arguments, options::OPT_profile_stats_entities);

lib/Frontend/CompilerInvocation.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ void CompilerInvocation::setMainExecutablePath(StringRef Path) {
6666
Path, FrontendOpts.UseSharedResourceFolder, LibPath);
6767
setRuntimeResourcePath(LibPath.str());
6868

69+
llvm::SmallString<128> clangPath(Path);
70+
llvm::sys::path::remove_filename(clangPath);
71+
llvm::sys::path::append(clangPath, "clang");
72+
ClangImporterOpts.clangPath = std::string(clangPath);
73+
6974
llvm::SmallString<128> DiagnosticDocsPath(Path);
7075
llvm::sys::path::remove_filename(DiagnosticDocsPath); // Remove /swift
7176
llvm::sys::path::remove_filename(DiagnosticDocsPath); // Remove /bin
@@ -936,6 +941,18 @@ static bool ParseClangImporterArgs(ClangImporterOptions &Opts,
936941
StringRef workingDirectory) {
937942
using namespace options;
938943

944+
if (const Arg *a = Args.getLastArg(OPT_tools_directory)) {
945+
// If a custom tools directory is specified, try to find Clang there.
946+
// This is useful when the Swift executable is located in a different
947+
// directory than the Clang/LLVM executables, for example, when building
948+
// the Swift project itself.
949+
llvm::SmallString<128> clangPath(a->getValue());
950+
llvm::sys::path::append(clangPath, "clang");
951+
if (llvm::sys::fs::exists(clangPath)) {
952+
Opts.clangPath = std::string(clangPath);
953+
}
954+
}
955+
939956
if (const Arg *A = Args.getLastArg(OPT_module_cache_path)) {
940957
Opts.ModuleCachePath = A->getValue();
941958
}

stdlib/cmake/modules/SwiftSource.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,8 @@ function(_compile_swift_files
403403
compute_library_subdir(library_subdir
404404
"${library_subdir_sdk}" "${SWIFTFILE_ARCHITECTURE}")
405405

406+
list(APPEND swift_flags "-tools-directory" "${SWIFT_NATIVE_CLANG_TOOLS_PATH}")
407+
406408
# If we have a custom module cache path, use it.
407409
if (SWIFT_MODULE_CACHE_PATH)
408410
list(APPEND swift_flags "-module-cache-path" "${SWIFT_MODULE_CACHE_PATH}")

test/ScanDependencies/module_deps.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ import SubE
122122
// CHECK-NEXT: "-frontend"
123123
// CHECK-NEXT: "-only-use-extra-clang-opts"
124124
// CHECK-NEXT: "-Xcc"
125-
// CHECK-NEXT: "clang"
125+
// CHECK-NEXT: "BUILD_DIR/bin/clang"
126126
// CHECK: "-fsystem-module",
127127
// CHECK-NEXT: "-emit-pcm",
128128
// CHECK-NEXT: "-module-name",

tools/swift-ide-test/swift-ide-test.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,11 @@ static llvm::cl::list<std::string>
277277
SwiftVersion("swift-version", llvm::cl::desc("Swift version"),
278278
llvm::cl::cat(Category));
279279

280+
static llvm::cl::opt<std::string>
281+
ToolsDirectory("tools-directory",
282+
llvm::cl::desc("Path to external executables (ld, clang, binutils)"),
283+
llvm::cl::cat(Category));
284+
280285
static llvm::cl::list<std::string>
281286
ModuleCachePath("module-cache-path", llvm::cl::desc("Clang module cache path"),
282287
llvm::cl::cat(Category));
@@ -3877,6 +3882,12 @@ int main(int argc, char *argv[]) {
38773882
InitInvok.getLangOptions().EffectiveLanguageVersion = actual.getValue();
38783883
}
38793884
}
3885+
if (!options::ToolsDirectory.empty()) {
3886+
SmallString<128> toolsDir(options::ToolsDirectory);
3887+
llvm::sys::path::append(toolsDir, "clang");
3888+
InitInvok.getClangImporterOptions().clangPath =
3889+
std::string(toolsDir);
3890+
}
38803891
if (!options::ModuleCachePath.empty()) {
38813892
// Honor the *last* -module-cache-path specified.
38823893
InitInvok.getClangImporterOptions().ModuleCachePath =

0 commit comments

Comments
 (0)