This is an archive of the discontinued LLVM Phabricator instance.

Fix driver-related things for FreeBSD
ClosedPublic

Authored by kutuzov.viktor.84 on Apr 15 2014, 10:26 AM.

Details

Summary

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).

Diff Detail

Event Timeline

Ed, this patch refers to /usr/include/clang/X.Y.Z while the current practice is /usr/include/clang/X.Y . Do you think we can fix FreeBSD so there is no clash if there are several versions of clang installed that only differ in the minor number?

Hi Viktor,

  • {F53971, layout=link}
dim added a comment.Apr 15 2014, 12:48 PM

Since the mailing list reply seems to have eaten most of my comments, I'll repost them here.

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.

kutuzov.viktor.84 updated this revision to Unknown Object (????).Apr 18 2014, 7:08 AM

Updated to address concerns mentioned by the FreeBSD community:

  • no need for the /usr/local/include include path;
  • no need to add -lcxxrt as newcoming FreeBSD versions (9.3+ and 10.0+) take care of this by providing libc++.so in the form of a linker script that refers to the corresponding run-time library; the note is that there's still a way to pull the -lcxxrt option with the CMAKE_EXE_LINKER_FLAGS variable on FreeBSD 9.2, so not a problem;
  • switch the path for internal clang headers from /usr/include/clang/X.Y.Z to /usr/include/clang/X.Y.

Also, I propose that we do not add the resource-dir-related include path on FreeBSD unless the FreeBSD's directory structure is reworked respectively. (Currently, we add an include path that should never exist on FreeBSD.)

compnerd added inline comments.Apr 29 2014, 10:24 PM
include/clang/Basic/Version.h
26–27

Rather than using the non-descript XYZ, could you change this to MAJOR_MINOR_PATCH please?

30–37

Similariy, MAJOR_MINOR.

kutuzov.viktor.84 edited edge metadata.

Two changes:

  • the clang version macros are renamed as suggested and
  • the resource-dir-relative include path reverted back as LLVM rely on it when build the sanitizers tests.

Thanks for reviewing.

compnerd accepted this revision.May 7 2014, 7:17 PM
compnerd edited edge metadata.

LGTM

lib/Frontend/InitHeaderSearch.cpp
247

The braces aren't necessary.

This revision is now accepted and ready to land.May 7 2014, 7:17 PM

Looks like patch was not committed.

dim closed this revision.Oct 4 2016, 3:15 AM

Looks like patch was not committed.

Indeed, please don't commit it at all. In FreeBSD, we've now switched to the default layout for internal includes, e.g. we now install them in /usr/lib/clang/x.y.z/include, like on every other platform. (Note that this caused quite some grumbling because people like to find headers easily, but we pointed out the gcc does something similar.)