Index: include/clang/Driver/ToolChain.h =================================================================== --- include/clang/Driver/ToolChain.h +++ include/clang/Driver/ToolChain.h @@ -299,6 +299,11 @@ const char *getCompilerRTArgString(const llvm::opt::ArgList &Args, StringRef Component, bool Shared = false) const; + + // Returns /lib//. This is used by runtimes (such + // as OpenMP) to find arch-specific libraries. + const std::string getArchSpecificLibPath() const; + /// needsProfileRT - returns true if instrumentation profile is on. static bool needsProfileRT(const llvm::opt::ArgList &Args); Index: lib/Driver/ToolChain.cpp =================================================================== --- lib/Driver/ToolChain.cpp +++ lib/Driver/ToolChain.cpp @@ -320,6 +320,14 @@ return Args.MakeArgString(getCompilerRT(Args, Component, Shared)); } +const std::string ToolChain::getArchSpecificLibPath() const { + SmallString<128> Path(getDriver().ResourceDir); + StringRef OSLibName = getTriple().isOSFreeBSD() ? "freebsd" : getOS(); + llvm::sys::path::append(Path, "lib", OSLibName, + getArchName()); + return Path.str(); +} + bool ToolChain::needsProfileRT(const ArgList &Args) { if (Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs, false) || Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -3260,6 +3260,12 @@ options::OPT_fno_openmp, false)) return; + // Add /lib// to the linker search path if it + // exists. + std::string CandidateLibPath = TC.getArchSpecificLibPath(); + if (llvm::sys::fs::is_directory(CandidateLibPath)) + CmdArgs.push_back(Args.MakeArgString("-L" + CandidateLibPath)); + switch (TC.getDriver().getOpenMPRuntime(Args)) { case Driver::OMPRT_OMP: CmdArgs.push_back("-lomp"); @@ -10316,6 +10322,12 @@ // FIXME: Does this really make sense for all GNU toolchains? WantPthread = true; + // Add /lib// to the linker search path if it + // exists. + std::string CandidateLibPath = ToolChain.getArchSpecificLibPath(); + if (llvm::sys::fs::is_directory(CandidateLibPath)) + CmdArgs.push_back(Args.MakeArgString("-L" + CandidateLibPath)); + // Also link the particular OpenMP runtimes. switch (ToolChain.getDriver().getOpenMPRuntime(Args)) { case Driver::OMPRT_OMP: Index: test/Driver/openmp-arch-dir.c =================================================================== --- /dev/null +++ test/Driver/openmp-arch-dir.c @@ -0,0 +1,57 @@ +// Test that the driver adds an arch-specific subdirectory in +// {RESOURCE_DIR}/lib/linux to the search path. This allows multilib toolchains +// to package libomp.so for multiple architectures. + +// Directory resource_dir_with_arch_subdir is setup only for Linux +// REQUIRES: linux +// +// RUN: %clang %s -### 2>&1 -fopenmp -target i686-unknown-linux \ +// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \ +// RUN: | FileCheck --check-prefix=CHECK-ARCHDIR \ +// RUN: --check-prefix=CHECK-LOMP %s +// +// RUN: %clang %s -### 2>&1 -fopenmp -target i686-unknown-linux \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: | FileCheck --check-prefix=CHECK-NO-ARCHDIR \ +// RUN: --check-prefix=CHECK-LOMP %s +// +// RUN: %clang %s -### 2>&1 -fopenmp -target x86_64-unknown-linux \ +// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \ +// RUN: | FileCheck --check-prefix=CHECK-ARCHDIR \ +// RUN: --check-prefix=CHECK-LOMP %s +// +// RUN: %clang %s -### 2>&1 -fopenmp -target x86_64-unknown-linux \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: | FileCheck --check-prefix=CHECK-NO-ARCHDIR \ +// RUN: --check-prefix=CHECK-LOMP %s +// +// RUN: %clang %s -### 2>&1 -fopenmp -target arm-unknown-linux \ +// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \ +// RUN: | FileCheck --check-prefix=CHECK-ARCHDIR \ +// RUN: --check-prefix=CHECK-LOMP %s +// +// RUN: %clang %s -### 2>&1 -fopenmp -target arm-unknown-linux \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: | FileCheck --check-prefix=CHECK-NO-ARCHDIR \ +// RUN: --check-prefix=CHECK-LOMP %s +// +// RUN: %clang %s -### 2>&1 -fopenmp -target aarch64-unknown-linux \ +// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \ +// RUN: | FileCheck --check-prefix=CHECK-ARCHDIR \ +// RUN: --check-prefix=CHECK-LOMP %s +// +// RUN: %clang %s -### 2>&1 -fopenmp -target aarch64-unknown-linux \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: | FileCheck --check-prefix=CHECK-NO-ARCHDIR \ +// RUN: --check-prefix=CHECK-LOMP %s +// +// Check correctness when -fopenmp is omitted +// RUN: %clang %s -### 2>&1 -target arm-unknown-linux \ +// RUN: -resource-dir=%S/Inputs/resource_dir_with_arch_subdir \ +// RUN: | FileCheck --check-prefix=CHECK-NO-ARCHDIR \ +// RUN: --check-prefix=CHECK-NO-LOMP %s +// +// CHECK-ARCHDIR: -L{{.*}}/Inputs/resource_dir_with_arch_subdir/lib/linux +// CHECK-NO-ARCHDIR-NOT: -L{{.*}}Inputs/resource_dir +// CHECK-LOMP: -lomp +// CHECK-NO-LOMP-NOT: -lomp