Skip to content

Commit e1c4ea5

Browse files
authored
Merge pull request #37806 from egorzhdan/clang-executable-path-reapply
ClangImporter: run Clang with a proper executable path (pt 2)
2 parents a395ac5 + 6411327 commit e1c4ea5

File tree

12 files changed

+62
-3
lines changed

12 files changed

+62
-3
lines changed

include/swift/Basic/LangOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,10 @@ namespace swift {
670670
/// Options for controlling the behavior of the Clang importer.
671671
class ClangImporterOptions final {
672672
public:
673+
/// The path to the Clang compiler executable.
674+
/// Used to detect the default include paths.
675+
std::string clangPath = "clang";
676+
673677
/// The module cache path which the Clang importer should use.
674678
std::string ModuleCachePath;
675679

lib/ClangImporter/ClangImporter.cpp

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

lib/Driver/ToolChains.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI,
264264
inputArgs.AddLastArg(arguments, options::OPT_swift_version);
265265
inputArgs.AddLastArg(arguments, options::OPT_enforce_exclusivity_EQ);
266266
inputArgs.AddLastArg(arguments, options::OPT_stats_output_dir);
267+
inputArgs.AddLastArg(arguments, options::OPT_tools_directory);
267268
inputArgs.AddLastArg(arguments, options::OPT_trace_stats_events);
268269
inputArgs.AddLastArg(arguments, options::OPT_profile_stats_events);
269270
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
@@ -68,6 +68,11 @@ void CompilerInvocation::setMainExecutablePath(StringRef Path) {
6868
Path, FrontendOpts.UseSharedResourceFolder, LibPath);
6969
setRuntimeResourcePath(LibPath.str());
7070

71+
llvm::SmallString<128> clangPath(Path);
72+
llvm::sys::path::remove_filename(clangPath);
73+
llvm::sys::path::append(clangPath, "clang");
74+
ClangImporterOpts.clangPath = std::string(clangPath);
75+
7176
llvm::SmallString<128> DiagnosticDocsPath(Path);
7277
llvm::sys::path::remove_filename(DiagnosticDocsPath); // Remove /swift
7378
llvm::sys::path::remove_filename(DiagnosticDocsPath); // Remove /bin
@@ -990,6 +995,18 @@ static bool ParseClangImporterArgs(ClangImporterOptions &Opts,
990995
StringRef workingDirectory) {
991996
using namespace options;
992997

998+
if (const Arg *a = Args.getLastArg(OPT_tools_directory)) {
999+
// If a custom tools directory is specified, try to find Clang there.
1000+
// This is useful when the Swift executable is located in a different
1001+
// directory than the Clang/LLVM executables, for example, when building
1002+
// the Swift project itself.
1003+
llvm::SmallString<128> clangPath(a->getValue());
1004+
llvm::sys::path::append(clangPath, "clang");
1005+
if (llvm::sys::fs::exists(clangPath)) {
1006+
Opts.clangPath = std::string(clangPath);
1007+
}
1008+
}
1009+
9931010
if (const Arg *A = Args.getLastArg(OPT_module_cache_path)) {
9941011
Opts.ModuleCachePath = A->getValue();
9951012
}

stdlib/cmake/modules/SwiftSource.cmake

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,10 @@ function(_compile_swift_files
407407
compute_library_subdir(library_subdir
408408
"${library_subdir_sdk}" "${SWIFTFILE_ARCHITECTURE}")
409409

410+
if(NOT "${SWIFT_NATIVE_CLANG_TOOLS_PATH}" STREQUAL "")
411+
list(APPEND swift_flags "-tools-directory" "${SWIFT_NATIVE_CLANG_TOOLS_PATH}")
412+
endif()
413+
410414
# If we have a custom module cache path, use it.
411415
if (SWIFT_MODULE_CACHE_PATH)
412416
list(APPEND swift_flags "-module-cache-path" "${SWIFT_MODULE_CACHE_PATH}")

test/Interop/Cxx/stdlib/Inputs/fake-toolchain/bin/clang

Whitespace-only changes.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef TEST_INTEROP_CXX_STDLIB_INPUTS_FAKE_TOOLCHAIN_H
2+
#define TEST_INTEROP_CXX_STDLIB_INPUTS_FAKE_TOOLCHAIN_H
3+
4+
namespace FakeNamespace {
5+
6+
void foo(int x) {}
7+
8+
}; // namespace FakeNamespace
9+
10+
#endif
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module FakeToolchain [system] {
2+
header "fake-toolchain.h"
3+
export *
4+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %target-swift-ide-test -print-module -module-to-print=FakeToolchain -tools-directory %S/Inputs/fake-toolchain/bin -source-filename=x -enable-cxx-interop -Xcc -stdlib=libc++ | %FileCheck %s
2+
3+
// Clang driver on Windows doesn't support -stdlib=libc++
4+
// XFAIL: OS=windows-msvc
5+
6+
// CHECK: extension FakeNamespace {
7+
// CHECK: static func foo(_ x: Int32)
8+
// CHECK: }

test/ScanDependencies/module_deps.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ import SubE
127127
// CHECK-NEXT: "-frontend"
128128
// CHECK-NEXT: "-only-use-extra-clang-opts"
129129
// CHECK-NEXT: "-Xcc"
130-
// CHECK-NEXT: "clang"
130+
// CHECK-NEXT: "BUILD_DIR/bin/clang"
131131
// CHECK: "-fsystem-module",
132132
// CHECK-NEXT: "-emit-pcm",
133133
// CHECK-NEXT: "-module-name",

test/ScanDependencies/module_deps_cache_reuse.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ import SubE
111111
// CHECK-NEXT: "-frontend"
112112
// CHECK-NEXT: "-only-use-extra-clang-opts"
113113
// CHECK-NEXT: "-Xcc"
114-
// CHECK-NEXT: "clang"
114+
// CHECK-NEXT: "BUILD_DIR/bin/clang"
115115
// CHECK-NEXT: "-Xcc"
116116
// CHECK-NEXT: "-fsyntax-only",
117117
// CHECK: "-fsystem-module",

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

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

286+
static llvm::cl::opt<std::string>
287+
ToolsDirectory("tools-directory",
288+
llvm::cl::desc("Path to external executables (ld, clang, binutils)"),
289+
llvm::cl::cat(Category));
290+
286291
static llvm::cl::list<std::string>
287292
ModuleCachePath("module-cache-path", llvm::cl::desc("Clang module cache path"),
288293
llvm::cl::cat(Category));
@@ -3914,6 +3919,12 @@ int main(int argc, char *argv[]) {
39143919
InitInvok.getLangOptions().EffectiveLanguageVersion = actual.getValue();
39153920
}
39163921
}
3922+
if (!options::ToolsDirectory.empty()) {
3923+
SmallString<128> toolsDir(options::ToolsDirectory);
3924+
llvm::sys::path::append(toolsDir, "clang");
3925+
InitInvok.getClangImporterOptions().clangPath =
3926+
std::string(toolsDir);
3927+
}
39173928
if (!options::ModuleCachePath.empty()) {
39183929
// Honor the *last* -module-cache-path specified.
39193930
InitInvok.getClangImporterOptions().ModuleCachePath =

0 commit comments

Comments
 (0)