From 9db37cd0aa8fa6ec840bfd9166090be5a39b691a Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Sun, 23 Jun 2013 11:28:48 +0000 Subject: [PATCH] Fix the addition of Clang's profile runtime library to the link step when specifying --coverage (or related) flags. The system for doing this was based on the old LLVM-hosted profile_rt library, and hadn't been updated for Linux to use the new compiler-rt library. Also, it couldn't possibly work on multiarch or biarch systems in many cases. The whole thing now works much the same as the sanitizer libraries that are built and used out of the compiler-rt repo. Note that other target OSes haven't been updated because I don't know if they're doing anything special with the installation path of profile_rt. I suspect however that *all* of these are wrong and would encourage maintainers of each target to take a hard look at how compiler-rt runtime libraries are linked on their platforms. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@184666 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Driver/Tools.cpp | 20 +++++++++++++++++++- test/Driver/coverage-ld.c | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 test/Driver/coverage-ld.c diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 87071742ba..050db6c0b1 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -1674,6 +1674,24 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, const ArgList &Args) } } +static void addProfileRTLinux( + const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { + if (!(Args.hasArg(options::OPT_fprofile_arcs) || + Args.hasArg(options::OPT_fprofile_generate) || + Args.hasArg(options::OPT_fcreate_profile) || + Args.hasArg(options::OPT_coverage))) + return; + + // The profile runtime is located in the Linux library directory and has name + // "libclang_rt.profile-.a". + SmallString<128> LibProfile(TC.getDriver().ResourceDir); + llvm::sys::path::append( + LibProfile, "lib", "linux", + Twine("libclang_rt.profile-") + TC.getArchName() + ".a"); + + CmdArgs.push_back(Args.MakeArgString(LibProfile)); +} + static void addSanitizerRTLinkFlagsLinux( const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs, const StringRef Sanitizer, bool BeforeLibStdCXX, @@ -6244,7 +6262,7 @@ void gnutools::Link::ConstructJob(Compilation &C, const JobAction &JA, } } - addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple()); + addProfileRTLinux(getToolChain(), Args, CmdArgs); C.addCommand(new Command(JA, *this, ToolChain.Linker.c_str(), CmdArgs)); } diff --git a/test/Driver/coverage-ld.c b/test/Driver/coverage-ld.c new file mode 100644 index 0000000000..2ec0486c32 --- /dev/null +++ b/test/Driver/coverage-ld.c @@ -0,0 +1,19 @@ +// Test coverage ld flags. +// +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target i386-unknown-linux --coverage \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree \ +// RUN: | FileCheck --check-prefix=CHECK-LINUX-I386 %s +// +// CHECK-LINUX-I386: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" +// CHECK-LINUX-I386: "{{.*}}/Inputs/resource_dir/lib/linux/libclang_rt.profile-i386.a" +// +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target x86_64-unknown-linux --coverage \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree \ +// RUN: | FileCheck --check-prefix=CHECK-LINUX-X86-64 %s +// +// CHECK-LINUX-X86-64: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" +// CHECK-LINUX-X86-64: "{{.*}}/Inputs/resource_dir/lib/linux/libclang_rt.profile-x86_64.a" -- 2.40.0