[PATCH] Fix driver-related things for FreeBSD

Dimitry Andric dimitry at andric.com
Tue Apr 15 11:42:27 PDT 2014


Hi Viktor,

On 15 Apr 2014, at 19:26, Viktor Kutuzov <vkutuzov at accesssoftek.com> wrote:
> This patch adds libcxxrt when clang is invoked with -stdlib=libc++ on FreeBSD (which is necessary to build llvm against libc++ on FreeBSD 9.2). It also adds the default path to the libc++ headers (which is /usr/local/include/c++/v1 and not /usr/include/c++/v1 as clang currently expect). Furthermore, it fixes the path to the clang's headers (which is /usr/include/clang/X.Y.Z and not <resource-dir>/include).
> 
> http://reviews.llvm.org/D3381
> 
> Files:
>  lib/Driver/ToolChains.cpp
>  lib/Driver/ToolChains.h
>  lib/Frontend/InitHeaderSearch.cpp
> 
> Index: lib/Driver/ToolChains.cpp
> ===================================================================
> --- lib/Driver/ToolChains.cpp
> +++ lib/Driver/ToolChains.cpp
> @@ -2490,6 +2490,9 @@
>   case ToolChain::CST_Libcxx:
>     addSystemInclude(DriverArgs, CC1Args,
>                      getDriver().SysRoot + "/usr/include/c++/v1");
> +    // The libc++ port installs headers to /usr/local by default.
> +    addSystemInclude(DriverArgs, CC1Args,
> +                     getDriver().SysRoot + "/usr/local/include/c++/v1");
>     break;
>   case ToolChain::CST_Libstdcxx:
>     addSystemInclude(DriverArgs, CC1Args,
> @@ -2530,6 +2533,19 @@
>   return getSanitizerArgs().hasZeroBaseShadow();
> }

Paths to /usr/local should never be in the default compiler include path on FreeBSD.  This location is reserved for ports usage, and ports are supposed to add the correct paths using -I by themselves.

There is already a devel/libc++ port for the (older) FreeBSD releases which do not include libc++, and this also arranges for other dependent port to know where it installs the libc++ headers.  See <http://svnweb.freebsd.org/ports/head/devel/libc%2B%2B/Makefile?view=markup>


> +void FreeBSD::AddCXXStdlibLibArgs(const ArgList &Args,
> +                                 ArgStringList &CmdArgs) const {
> +  switch (GetCXXStdlibType(Args)) {
> +  case ToolChain::CST_Libcxx:
> +    CmdArgs.push_back("-lc++");
> +    CmdArgs.push_back("-lcxxrt");
> +    break;
> +  case ToolChain::CST_Libstdcxx:
> +    CmdArgs.push_back("-lstdc++");
> +    break;
> +  }
> +}

This part is not necessary, it is already taken care of via FreeBSD::GetCXXStdlibType() in lib/Driver/ToolChains.cpp, and ToolChain::AddCXXStdlibLibArgs() in lib/Driver/ToolChain.cpp.

In FreeBSD, we provide libc++.so as a linker script, which automatically pulls in the required runtime support, by default that is /usr/lib/libcxxrt.so:

$ cat /usr/lib/libc++.so
/* $FreeBSD: stable/9/lib/libc++/libc++.ldscript 258060 2013-11-12 18:43:35Z dim $ */
GROUP ( /usr/lib/libc++.so.1 /usr/lib/libcxxrt.so )

This makes it easy for the end user to switch to another C++ runtime library, if desired.  If you would hardcode it in the compiler, this becomes much more difficult.


> NetBSD::NetBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
> Index: lib/Driver/ToolChains.h
> ===================================================================
> --- lib/Driver/ToolChains.h
> +++ lib/Driver/ToolChains.h
> @@ -584,6 +584,8 @@
>   void
>   AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
>                                llvm::opt::ArgStringList &CC1Args) const override;
> +  void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
> +                           llvm::opt::ArgStringList &CmdArgs) const override;
>   bool IsIntegratedAssemblerDefault() const override {
>     if (getTriple().getArch() == llvm::Triple::ppc ||
>         getTriple().getArch() == llvm::Triple::ppc64)

Similar to the above hunk, this is already handled.


> Index: lib/Frontend/InitHeaderSearch.cpp
> ===================================================================
> --- lib/Frontend/InitHeaderSearch.cpp
> +++ lib/Frontend/InitHeaderSearch.cpp
> @@ -14,6 +14,7 @@
> #include "clang/Frontend/Utils.h"
> #include "clang/Basic/FileManager.h"
> #include "clang/Basic/LangOptions.h"
> +#include "clang/Basic/Version.h"
> #include "clang/Config/config.h" // C_INCLUDE_DIRS
> #include "clang/Lex/HeaderSearch.h"
> #include "clang/Lex/HeaderSearchOptions.h"
> @@ -242,11 +243,16 @@
>   // Builtin includes use #include_next directives and should be positioned
>   // just prior C include dirs.
>   if (HSOpts.UseBuiltinIncludes) {
> -    // Ignore the sys root, we *always* look for clang headers relative to
> -    // supplied path.
> -    SmallString<128> P = StringRef(HSOpts.ResourceDir);
> -    llvm::sys::path::append(P, "include");
> -    AddUnmappedPath(P.str(), ExternCSystem, false);
> +    // On FreeBSD the include path is not resource-dir-relative.
> +    if (os == llvm::Triple::FreeBSD) {
> +      AddPath("/usr/include/clang/" CLANG_VERSION_STRING, ExternCSystem, false);
> +    } else {
> +      // Ignore the sys root, we *always* look for clang headers relative to
> +      // supplied path.
> +      SmallString<128> P = StringRef(HSOpts.ResourceDir);
> +      llvm::sys::path::append(P, "include");
> +      AddUnmappedPath(P.str(), ExternCSystem, false);
> +    }

For this specific part, we have been using the following patch for years now:

http://svnweb.freebsd.org/base/head/contrib/llvm/patches/patch-r208961-clang-version-include.diff?view=co&revision=263320&content-type=text%2Fplain

Please use that instead.  If newer versions of clang use x.y.z as version numbering scheme, we should probably chop off the .z part (the patch version), if the internal headers are supposed to be compatible across patch versions.

-Dimitry


-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 203 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140415/4ae5a5de/attachment.sig>


More information about the llvm-commits mailing list