Fix kernel-headers path in clang

  • Open
  • quality assurance status badge
Details
2 participants
  • Carl Dong
  • Mathieu Othacehe
Owner
unassigned
Submitted by
Mathieu Othacehe
Severity
normal
M
M
Mathieu Othacehe wrote on 19 Nov 2019 17:19
(name . guix-patches@gnu.org)(address . guix-patches@gnu.org)
871ru34z62.fsf@gmail.com
Hello,

Indexing tools such as ccls use "clang" package (and more specifically
the libclang library it provides) to analyse code.

In that use case, clang cannot find kernel headers path. This is because
it is normally set as propagated inputs of gcc-toolchain and clang-toolchain, an
thus available via CPATH.

This patch proposes to hardcode kernel headers path into clang.

What do you think?

Mathieu
From 198e59f7645bffbc2ba1e68db2747b8c07997ad6 Mon Sep 17 00:00:00 2001
From: Mathieu Othacehe <m.othacehe@gmail.com>
Date: Tue, 19 Nov 2019 16:41:33 +0100
Subject: [PATCH] gnu: clang-from-llvm: Add kernel-headers to default include
directories.

Stand-alone "clang" binary is not able to find kernel headers because they are
normally set as propagated inputs of gcc-toolchain and clang-toolchain, an
thus available via CPATH.

As some code indexers rely on libclang, kernel-headers include path needs to
be hard-coded.

* gnu/packages/llvm.scm (clang-from-llvm):
---
gnu/packages/llvm.scm | 2 ++
1 file changed, 2 insertions(+)

Toggle diff (15 lines)
diff --git a/gnu/packages/llvm.scm b/gnu/packages/llvm.scm
index 863d43d7d6..c5bc1e2c5c 100644
--- a/gnu/packages/llvm.scm
+++ b/gnu/packages/llvm.scm
@@ -195,6 +195,8 @@ compiler. In LLVM this library is called \"compiler-rt\".")
;; Use a sane default include directory.
(string-append "-DC_INCLUDE_DIRS="
(assoc-ref %build-inputs "libc")
+ "/include:"
+ (assoc-ref %build-inputs "kernel-headers")
"/include"))
;; Don't use '-g' during the build to save space.
--
2.24.0
C
C
Carl Dong wrote on 19 Nov 2019 17:52
(name . Mathieu Othacehe)(address . m.othacehe@gmail.com)(address . 38276@debbugs.gnu.org)
15D73ED1-72C9-4F58-B250-7A6426981752@carldong.me
Hi Mathieu!

I have been using the Guix clang with the following patch, which should accomplish what you want and also allow for the proper handling of --sysroot. I included an extended explanation in the comments in the patch. Let me know what you think! :-)

Cheers,
Carl Dong
contact@carldong.me
"I fight for the users”

-----

Toggle diff (424 lines)
diff --git a/gnu/packages/llvm.scm b/gnu/packages/llvm.scm
index 9ee5062429..33fb53d65e 100644
--- a/gnu/packages/llvm.scm
+++ b/gnu/packages/llvm.scm
@@ -186,7 +186,12 @@ compiler. In LLVM this library is called \"compiler-rt\".")
;; Find libgcc_s, crtbegin.o, and crtend.o.
(string-append "-DGCC_INSTALL_PREFIX="
- (assoc-ref %build-inputs "gcc-lib")))
+ (assoc-ref %build-inputs "gcc-lib"))
+
+ ;; Use a sane default include directory.
+ (string-append "-DC_INCLUDE_DIRS="
+ (assoc-ref %build-inputs "libc")
+ "/include"))
;; Don't use '-g' during the build to save space.
#:build-type "Release"
@@ -197,8 +202,6 @@ compiler. In LLVM this library is called \"compiler-rt\".")
(lambda* (#:key inputs #:allow-other-keys)
(let ((libc (assoc-ref inputs "libc"))
(compiler-rt (assoc-ref inputs "clang-runtime"))
- (gcc (assoc-ref inputs "gcc"))
- (kernel-headers (assoc-ref inputs "kernel-headers"))
(version
(string->number
,(version-major (package-version clang-runtime)))))
@@ -218,10 +221,7 @@ compiler. In LLVM this library is called \"compiler-rt\".")
;; Make sure libc's libdir is on the search path, to
;; allow crt1.o & co. to be found.
(("@GLIBC_LIBDIR@")
- (string-append libc "/lib"))
- (("@C_EXTRA_INCLUDE_DIRS@")
- (string-append libc "/include" ":"
- kernel-headers "/include"))))
+ (string-append libc "/lib"))))
(else
(substitute* "lib/Driver/Tools.cpp"
;; Patch the 'getLinuxDynamicLinker' function so that
diff --git a/gnu/packages/patches/clang-3.5-libc-search-path.patch b/gnu/packages/patches/clang-3.5-libc-search-path.patch
index 54fb9be7d8..50e4480239 100644
--- a/gnu/packages/patches/clang-3.5-libc-search-path.patch
+++ b/gnu/packages/patches/clang-3.5-libc-search-path.patch
@@ -8,7 +8,7 @@ to make sure Clang also works on non-GuixSD systems.
--- cfe-3.6.0.src/lib/Driver/ToolChains.cpp 2015-02-18 22:03:07.000000000 +0100
+++ cfe-3.6.0.src/lib/Driver/ToolChains.cpp 2015-06-19 16:37:20.459701044 +0200
-@@ -3040,6 +3040,9 @@
+@@ -2931,6 +2931,9 @@ Linux::Linux(const Driver &D, const llvm
Linker = GetLinkerPath();
@@ -18,7 +18,7 @@ to make sure Clang also works on non-GuixSD systems.
Distro Distro = DetectDistro(Arch);
if (IsOpenSUSE(Distro) || IsUbuntu(Distro)) {
-@@ -3082,6 +3085,7 @@
+@@ -2973,6 +2976,7 @@ Linux::Linux(const Driver &D, const llvm
if (IsOpenSUSE(Distro))
ExtraOpts.push_back("--enable-new-dtags");
@@ -26,49 +26,41 @@ to make sure Clang also works on non-GuixSD systems.
// The selection of paths to try here is designed to match the patterns which
// the GCC driver itself uses, as this is part of the GCC-compatible driver.
-@@ -3194,6 +3198,10 @@
+@@ -3043,14 +3047,12 @@ Linux::Linux(const Driver &D, const llvm
+ addPathIfExists(D.Dir + "/../" + OSLibDir, Paths);
+ }
- addPathIfExists(SysRoot + "/lib", Paths);
- addPathIfExists(SysRoot + "/usr/lib", Paths);
-+
+- addPathIfExists(SysRoot + "/lib/" + MultiarchTriple, Paths);
+- addPathIfExists(SysRoot + "/lib/../" + OSLibDir, Paths);
+- addPathIfExists(SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
+- addPathIfExists(SysRoot + "/usr/lib/../" + OSLibDir, Paths);
+-
+ // Try walking via the GCC triple path in case of biarch or multiarch GCC
+ // installations with strange symlinks.
+ if (GCCInstallation.isValid()) {
++ // The following code would end up adding things like
++ // "/usr/lib/x86_64-unknown-linux-gnu/../../lib64" to the search path.
++#if 0
+ addPathIfExists(SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() +
+ "/../../" + OSLibDir, Paths);
+
+@@ -3060,6 +3062,7 @@ Linux::Linux(const Driver &D, const llvm
+ addPathIfExists(GCCInstallation.getInstallPath() +
+ BiarchSibling.gccSuffix(), Paths);
+ }
++#endif
+
+ // See comments above on the multilib variant for details of why this is
+ // included even from outside the sysroot.
+@@ -3083,8 +3086,9 @@ Linux::Linux(const Driver &D, const llvm
+ if (StringRef(D.Dir).startswith(SysRoot))
+ addPathIfExists(D.Dir + "/../lib", Paths);
+
+- addPathIfExists(SysRoot + "/lib", Paths);
+- addPathIfExists(SysRoot + "/usr/lib", Paths);
+ // Add libc's lib/ directory to the search path, so that crt1.o, crti.o,
+ // and friends can be found.
+ addPathIfExists("@GLIBC_LIBDIR@", Paths);
}
bool Linux::HasNativeLLVMSupport() const {
-@@ -3384,6 +3392,34 @@
- addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include");
-
- addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
-+
-+ // Check for configure-time "extra" C include directories. When constructing a
-+ // toolchain, @C_EXTRA_INCLUDE_DIRS@ should be replaced with something like a
-+ // colon-separated string of the include dirs of libc and kernel headers.
-+ //
-+ // The reason why we use this mechanism instead of C_INCLUDE_DIRS above is
-+ // because when a user supplies clang with --sysroot, the normal expectation
-+ // is that clang will detect and add the proper $SYSROOT/$MULTIARCHINCL,
-+ // $SYSROOT/include, and $SYSROOT/usr/include to its list of search paths.
-+ // However, if C_INCLUDE_DIRS is not empty, this function will return early
-+ // and not attempt to add the aforementioned search paths, which is not
-+ // desirable.
-+ //
-+ // By adding our configure-time "extra" C include directories here, after
-+ // we've added $SYSROOT/include and $SYSROOT/usr/include, we make sure that IF
-+ // --sysroot is supplied on the command line, we pick up the expected search
-+ // paths in the $SYSROOT, and that they come before our configure-time "extra"
-+ // C include directories.
-+ StringRef CExtraIncludeDirs("@C_EXTRA_INCLUDE_DIRS@");
-+ if (CExtraIncludeDirs != "") {
-+ SmallVector<StringRef, 5> dirs;
-+ CExtraIncludeDirs.split(dirs, ":");
-+ for (StringRef dir : dirs) {
-+ StringRef Prefix =
-+ llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : "";
-+ addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
-+ }
-+ }
- }
-
- /// \brief Helper to add the variant paths of a libstdc++ installation.
diff --git a/gnu/packages/patches/clang-3.8-libc-search-path.patch b/gnu/packages/patches/clang-3.8-libc-search-path.patch
index 243d167755..0f7d0a4add 100644
--- a/gnu/packages/patches/clang-3.8-libc-search-path.patch
+++ b/gnu/packages/patches/clang-3.8-libc-search-path.patch
@@ -29,49 +29,41 @@ changes in clang 3.8.
// The selection of paths to try here is designed to match the patterns which
// the GCC driver itself uses, as this is part of the GCC-compatible driver.
-@@ -3817,6 +3821,10 @@
+@@ -3771,14 +3775,12 @@
+ addPathIfExists(D, D.Dir + "/../" + OSLibDir, Paths);
+ }
- addPathIfExists(D, SysRoot + "/lib", Paths);
- addPathIfExists(D, SysRoot + "/usr/lib", Paths);
-+
+- addPathIfExists(D, SysRoot + "/lib/" + MultiarchTriple, Paths);
+- addPathIfExists(D, SysRoot + "/lib/../" + OSLibDir, Paths);
+- addPathIfExists(D, SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
+- addPathIfExists(D, SysRoot + "/usr/lib/../" + OSLibDir, Paths);
+-
+ // Try walking via the GCC triple path in case of biarch or multiarch GCC
+ // installations with strange symlinks.
+ if (GCCInstallation.isValid()) {
++ // The following code would end up adding things like
++ // "/usr/lib/x86_64-unknown-linux-gnu/../../lib64" to the search path.
++#if 0
+ addPathIfExists(D,
+ SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() +
+ "/../../" + OSLibDir,
+@@ -3791,6 +3793,7 @@
+ BiarchSibling.gccSuffix(),
+ Paths);
+ }
++#endif
+
+ // See comments above on the multilib variant for details of why this is
+ // included even from outside the sysroot.
+@@ -3815,8 +3818,9 @@
+ if (StringRef(D.Dir).startswith(SysRoot))
+ addPathIfExists(D, D.Dir + "/../lib", Paths);
+
+- addPathIfExists(D, SysRoot + "/lib", Paths);
+- addPathIfExists(D, SysRoot + "/usr/lib", Paths);
+ // Add libc's lib/ directory to the search path, so that crt1.o, crti.o,
+ // and friends can be found.
+ addPathIfExists(D, "@GLIBC_LIBDIR@", Paths);
}
bool Linux::HasNativeLLVMSupport() const { return true; }
-@@ -4026,6 +4034,34 @@
- addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include");
-
- addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
-+
-+ // Check for configure-time "extra" C include directories. When constructing a
-+ // toolchain, @C_EXTRA_INCLUDE_DIRS@ should be replaced with something like a
-+ // colon-separated string of the include dirs of libc and kernel headers.
-+ //
-+ // The reason why we use this mechanism instead of C_INCLUDE_DIRS above is
-+ // because when a user supplies clang with --sysroot, the normal expectation
-+ // is that clang will detect and add the proper $SYSROOT/$MULTIARCHINCL,
-+ // $SYSROOT/include, and $SYSROOT/usr/include to its list of search paths.
-+ // However, if C_INCLUDE_DIRS is not empty, this function will return early
-+ // and not attempt to add the aforementioned search paths, which is not
-+ // desirable.
-+ //
-+ // By adding our configure-time "extra" C include directories here, after
-+ // we've added $SYSROOT/include and $SYSROOT/usr/include, we make sure that IF
-+ // --sysroot is supplied on the command line, we pick up the expected search
-+ // paths in the $SYSROOT, and that they come before our configure-time "extra"
-+ // C include directories.
-+ StringRef CExtraIncludeDirs("@C_EXTRA_INCLUDE_DIRS@");
-+ if (CExtraIncludeDirs != "") {
-+ SmallVector<StringRef, 5> dirs;
-+ CExtraIncludeDirs.split(dirs, ":");
-+ for (StringRef dir : dirs) {
-+ StringRef Prefix =
-+ llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : "";
-+ addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
-+ }
-+ }
- }
-
-
diff --git a/gnu/packages/patches/clang-6.0-libc-search-path.patch b/gnu/packages/patches/clang-6.0-libc-search-path.patch
index d80c798467..a62e8063c2 100644
--- a/gnu/packages/patches/clang-6.0-libc-search-path.patch
+++ b/gnu/packages/patches/clang-6.0-libc-search-path.patch
@@ -8,17 +8,18 @@ to make sure Clang also works on non-GuixSD systems.
--- cfe-6.0.0.src/lib/Driver/ToolChains/Linux.cpp
+++ cfe-6.0.0.src/lib/Driver/ToolChains/Linux.cpp
-@@ -208,6 +208,9 @@
+@@ -207,7 +207,9 @@
+ PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
GCCInstallation.getTriple().str() + "/bin")
.str());
-
+-
+ // Comment out the distro-specific tweaks so that they don't bite when
+ // using Guix on a foreign distro.
+#if 0
Distro Distro(D.getVFS());
if (Distro.IsAlpineLinux()) {
-@@ -255,6 +258,7 @@
+@@ -255,6 +257,7 @@
if (IsAndroid || Distro.IsOpenSUSE())
ExtraOpts.push_back("--enable-new-dtags");
@@ -26,49 +27,41 @@ to make sure Clang also works on non-GuixSD systems.
// The selection of paths to try here is designed to match the patterns which
// the GCC driver itself uses, as this is part of the GCC-compatible driver.
-@@ -375,6 +379,10 @@
+@@ -329,14 +332,12 @@
+ addPathIfExists(D, D.Dir + "/../" + OSLibDir, Paths);
+ }
+
+- addPathIfExists(D, SysRoot + "/lib/" + MultiarchTriple, Paths);
+- addPathIfExists(D, SysRoot + "/lib/../" + OSLibDir, Paths);
+- addPathIfExists(D, SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
+- addPathIfExists(D, SysRoot + "/usr/lib/../" + OSLibDir, Paths);
+-
+ // Try walking via the GCC triple path in case of biarch or multiarch GCC
+ // installations with strange symlinks.
+ if (GCCInstallation.isValid()) {
++ // The following code would end up adding things like
++ // "/usr/lib/x86_64-unknown-linux-gnu/../../lib64" to the search path.
++#if 0
+ addPathIfExists(D,
+ SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() +
+ "/../../" + OSLibDir,
+@@ -349,6 +350,7 @@
+ BiarchSibling.gccSuffix(),
+ Paths);
+ }
++#endif
- addPathIfExists(D, SysRoot + "/lib", Paths);
- addPathIfExists(D, SysRoot + "/usr/lib", Paths);
-+
+ // See comments above on the multilib variant for details of why this is
+ // included even from outside the sysroot.
+@@ -373,8 +375,9 @@
+ if (StringRef(D.Dir).startswith(SysRoot))
+ addPathIfExists(D, D.Dir + "/../lib", Paths);
+
+- addPathIfExists(D, SysRoot + "/lib", Paths);
+- addPathIfExists(D, SysRoot + "/usr/lib", Paths);
+ // Add libc's lib/ directory to the search path, so that crt1.o, crti.o,
+ // and friends can be found.
+ addPathIfExists(D, "@GLIBC_LIBDIR@", Paths);
}
bool Linux::HasNativeLLVMSupport() const { return true; }
-@@ -710,6 +718,34 @@
- addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include");
-
- addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
-+
-+ // Check for configure-time "extra" C include directories. When constructing a
-+ // toolchain, @C_EXTRA_INCLUDE_DIRS@ should be replaced with something like a
-+ // colon-separated string of the include dirs of libc and kernel headers.
-+ //
-+ // The reason why we use this mechanism instead of C_INCLUDE_DIRS above is
-+ // because when a user supplies clang with --sysroot, the normal expectation
-+ // is that clang will detect and add the proper $SYSROOT/$MULTIARCHINCL,
-+ // $SYSROOT/include, and $SYSROOT/usr/include to its list of search paths.
-+ // However, if C_INCLUDE_DIRS is not empty, this function will return early
-+ // and not attempt to add the aforementioned search paths, which is not
-+ // desirable.
-+ //
-+ // By adding our configure-time "extra" C include directories here, after
-+ // we've added $SYSROOT/include and $SYSROOT/usr/include, we make sure that IF
-+ // --sysroot is supplied on the command line, we pick up the expected search
-+ // paths in the $SYSROOT, and that they come before our configure-time "extra"
-+ // C include directories.
-+ StringRef CExtraIncludeDirs("@C_EXTRA_INCLUDE_DIRS@");
-+ if (CExtraIncludeDirs != "") {
-+ SmallVector<StringRef, 5> dirs;
-+ CExtraIncludeDirs.split(dirs, ":");
-+ for (StringRef dir : dirs) {
-+ StringRef Prefix =
-+ llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : "";
-+ addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
-+ }
-+ }
- }
-
- static std::string DetectLibcxxIncludePath(StringRef base) {
diff --git a/gnu/packages/patches/clang-7.0-libc-search-path.patch b/gnu/packages/patches/clang-7.0-libc-search-path.patch
index 445b5d17ac..07ff8c90bd 100644
--- a/gnu/packages/patches/clang-7.0-libc-search-path.patch
+++ b/gnu/packages/patches/clang-7.0-libc-search-path.patch
@@ -8,7 +8,7 @@ to make sure Clang also works on non-GuixSD systems.
--- a/lib/Driver/ToolChains/Linux.cpp
+++ b/lib/Driver/ToolChains/Linux.cpp
-@@ -225,7 +225,9 @@
+@@ -225,7 +225,9 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
GCCInstallation.getTriple().str() + "/bin")
.str());
@@ -19,7 +19,7 @@ to make sure Clang also works on non-GuixSD systems.
Distro Distro(D.getVFS());
if (Distro.IsAlpineLinux()) {
-@@ -284,6 +286,7 @@
+@@ -284,6 +286,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
if (IsAndroid || Distro.IsOpenSUSE())
ExtraOpts.push_back("--enable-new-dtags");
@@ -27,49 +27,56 @@ to make sure Clang also works on non-GuixSD systems.
// The selection of paths to try here is designed to match the patterns which
// the GCC driver itself uses, as this is part of the GCC-compatible driver.
-@@ -431,6 +434,10 @@
+@@ -342,7 +345,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
+ // the cross. Note that GCC does include some of these directories in some
+ // configurations but this seems somewhere between questionable and simply
+ // a bug.
+- if (StringRef(LibPath).startswith(SysRoot)) {
++ if (0) {
+ addPathIfExists(D, LibPath + "/" + MultiarchTriple, Paths);
+ addPathIfExists(D, LibPath + "/../" + OSLibDir, Paths);
+ }
+@@ -361,6 +364,8 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
+ addPathIfExists(D, SysRoot + "/lib/" + MultiarchTriple, Paths);
+ addPathIfExists(D, SysRoot + "/lib/../" + OSLibDir, Paths);
- addPathIfExists(D, SysRoot + "/lib", Paths);
- addPathIfExists(D, SysRoot + "/usr/lib", Paths);
-+
++ // This requires the commented distro tweaks above.
++#if 0
+ if (IsAndroid) {
+ // Android sysroots contain a library directory for each supported OS
+ // version as well as some unversioned libraries in the usual multiarch
+@@ -389,10 +394,14 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
+ addPathIfExists(D, SysRoot + "/" + OSLibDir + "/" + ABIName, Paths);
+ addPathIfExists(D, SysRoot + "/usr/" + OSLibDir + "/" + ABIName, Paths);
+ }
++#endif
+
+ // Try walking via the GCC triple path in case of biarch or multiarch GCC
+ // installations with strange symlinks.
+ if (GCCInstallation.isValid()) {
++ // The following code would end up adding things like
++ // "/usr/lib/x86_64-unknown-linux-gnu/../../lib64" to the search path.
++#if 0
+ addPathIfExists(D,
+ SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() +
+ "/../../" + OSLibDir,
+@@ -405,6 +414,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
+ BiarchSibling.gccSuffix(),
+ Paths);
+ }
++#endif
+
+ // See comments above on the multilib variant for details of why this is
+ // included even from outside the sysroot.
+@@ -429,8 +439,9 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
+ if (StringRef(D.Dir).startswith(SysRoot))
+ addPathIfExists(D, D.Dir + "/../lib", Paths);
+
+- addPathIfExists(D, SysRoot + "/lib", Paths);
+- addPathIfExists(D, SysRoot + "/usr/lib", Paths);
+ // Add libc's lib/ directory to the search path, so that crt1.o, crti.o,
+ // and friends can be found.
+ addPathIfExists(D, "@GLIBC_LIBDIR@", Paths);
}
bool Linux::HasNativeLLVMSupport() const { return true; }
-@@ -794,6 +801,34 @@
- addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include");
-
- addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
-+
-+ // Check for configure-time "extra" C include directories. When constructing a
-+ // too
This message was truncated. Download the full message here.
M
M
Mathieu Othacehe wrote on 20 Nov 2019 15:04
(name . Carl Dong)(address . contact@carldong.me)(address . 38276@debbugs.gnu.org)
87pnhmwsoe.fsf@gmail.com
Hello Carl,

Toggle quote (5 lines)
> +- addPathIfExists(SysRoot + "/lib/" + MultiarchTriple, Paths);
> +- addPathIfExists(SysRoot + "/lib/../" + OSLibDir, Paths);
> +- addPathIfExists(SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
> +- addPathIfExists(SysRoot + "/usr/lib/../" + OSLibDir, Paths);

I'm not sure to understand the benefit of this patch versus hardcoding
libc and kernel-headers path into clang at build time.

Plus, in general patching so heavily the sources of a package proves to
be very hard to maintain.

Mathieu
C
C
Carl Dong wrote on 20 Nov 2019 22:28
(name . Mathieu Othacehe)(address . m.othacehe@gmail.com)(address . 38276@debbugs.gnu.org)
079E8E67-5A3F-4B08-AB9E-2880559C0570@carldong.me
Hi Mathieu,

I want to apologize for the confusion with that last patch I sent… That was actually the exact opposite patch of what I intended :-)
I’ve attached the correct patch below, and some explanation:

Toggle quote (3 lines)
> Plus, in general patching so heavily the sources of a package proves to
> be very hard to maintain.

These are already patches that we carry (see gnu/packages/patches/clang-*-libc-search-path.patch), I’m simply modifying them.

Toggle quote (3 lines)
> I'm not sure to understand the benefit of this patch versus hardcoding
> libc and kernel-headers path into clang at build time.

This patch _does_ hardcode libc and kernel-headers path into clang at build time, BUT it does so in a way that also retains sane behaviour when --sysroot is supplied to clang. Explanation from the patch:

Toggle quote (18 lines)
> ++ // Check for configure-time "extra" C include directories. When constructing a
> ++ // toolchain, @C_EXTRA_INCLUDE_DIRS@ should be replaced with something like a
> ++ // colon-separated string of the include dirs of libc and kernel headers.
> ++ //
> ++ // The reason why we use this mechanism instead of C_INCLUDE_DIRS above is
> ++ // because when a user supplies clang with --sysroot, the normal expectation
> ++ // is that clang will detect and add the proper $SYSROOT/$MULTIARCHINCL,
> ++ // $SYSROOT/include, and $SYSROOT/usr/include to its list of search paths.
> ++ // However, if C_INCLUDE_DIRS is not empty, this function will return early
> ++ // and not attempt to add the aforementioned search paths, which is not
> ++ // desirable.
> ++ //
> ++ // By adding our configure-time "extra" C include directories here, after
> ++ // we've added $SYSROOT/include and $SYSROOT/usr/include, we make sure that IF
> ++ // --sysroot is supplied on the command line, we pick up the expected search
> ++ // paths in the $SYSROOT, and that they come before our configure-time "extra"
> ++ // C include directories.

Again, sorry for the confusion, and I look forward to hearing what you and others think!

Cheers,
Carl Dong

-----

Toggle diff (74 lines)
diff --git a/gnu/packages/llvm.scm b/gnu/packages/llvm.scm
index 33fb53d65e..9ee5062429 100644
--- a/gnu/packages/llvm.scm
+++ b/gnu/packages/llvm.scm
@@ -186,12 +186,7 @@ compiler. In LLVM this library is called \"compiler-rt\".")
;; Find libgcc_s, crtbegin.o, and crtend.o.
(string-append "-DGCC_INSTALL_PREFIX="
- (assoc-ref %build-inputs "gcc-lib"))
-
- ;; Use a sane default include directory.
- (string-append "-DC_INCLUDE_DIRS="
- (assoc-ref %build-inputs "libc")
- "/include"))
+ (assoc-ref %build-inputs "gcc-lib")))
;; Don't use '-g' during the build to save space.
#:build-type "Release"
@@ -202,6 +197,8 @@ compiler. In LLVM this library is called \"compiler-rt\".")
(lambda* (#:key inputs #:allow-other-keys)
(let ((libc (assoc-ref inputs "libc"))
(compiler-rt (assoc-ref inputs "clang-runtime"))
+ (gcc (assoc-ref inputs "gcc"))
+ (kernel-headers (assoc-ref inputs "kernel-headers"))
(version
(string->number
,(version-major (package-version clang-runtime)))))
@@ -221,7 +218,10 @@ compiler. In LLVM this library is called \"compiler-rt\".")
;; Make sure libc's libdir is on the search path, to
;; allow crt1.o & co. to be found.
(("@GLIBC_LIBDIR@")
- (string-append libc "/lib"))))
+ (string-append libc "/lib"))
+ (("@C_EXTRA_INCLUDE_DIRS@")
+ (string-append libc "/include" ":"
+ kernel-headers "/include"))))
(else
(substitute* "lib/Driver/Tools.cpp"
;; Patch the 'getLinuxDynamicLinker' function so that
diff --git a/gnu/packages/patches/clang-3.5-libc-search-path.patch b/gnu/packages/patches/clang-3.5-libc-search-path.patch
index 50e4480239..54fb9be7d8 100644
--- a/gnu/packages/patches/clang-3.5-libc-search-path.patch
+++ b/gnu/packages/patches/clang-3.5-libc-search-path.patch
@@ -8,7 +8,7 @@ to make sure Clang also works on non-GuixSD systems.
--- cfe-3.6.0.src/lib/Driver/ToolChains.cpp 2015-02-18 22:03:07.000000000 +0100
+++ cfe-3.6.0.src/lib/Driver/ToolChains.cpp 2015-06-19 16:37:20.459701044 +0200
-@@ -2931,6 +2931,9 @@ Linux::Linux(const Driver &D, const llvm
+@@ -3040,6 +3040,9 @@
Linker = GetLinkerPath();
@@ -18,7 +18,7 @@ to make sure Clang also works on non-GuixSD systems.
Distro Distro = DetectDistro(Arch);
if (IsOpenSUSE(Distro) || IsUbuntu(Distro)) {
-@@ -2973,6 +2976,7 @@ Linux::Linux(const Driver &D, const llvm
+@@ -3082,6 +3085,7 @@
if (IsOpenSUSE(Distro))
ExtraOpts.push_back("--enable-new-dtags");
@@ -26,41 +26,49 @@ to make sure Clang also works on non-GuixSD systems.
// The selection of paths to try here is designed to match the patterns which
// the GCC driver itself uses, as this is part of the GCC-compatible driver.
-@@ -3043,14 +3047,12 @@ Linux::Linux(const Driver &D, const llvm
- addPathIfExists(D.Dir + "/../" + OSLibDir, Paths);
- }
+@@ -3194,6 +3198,10 @@
-- addPathIfExists(SysRoot + "/lib/" + MultiarchTriple, Paths);
-- addPathIfExists(SysRoot + "/lib/../" + OSLibDir, Paths);
-- addPathIfExists(SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
-- addPathIfExists(SysRoot + "/usr/lib/../" + OSLibDir, Paths);
--
- // Try walking via the GCC triple path in case of biarch or multiarch GCC
- // installations with strange symlinks.
- if (GCCInstallation.isValid()) {
-+ // The following code would end up adding things like
-+ // "/usr/lib/x86_64-unknown-linux-gnu/../../lib64" to the search path.
-+#if 0
- addPathIfExists(SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() +
- "/../../" + OSLibDir, Paths);
-
-@@ -3060,6 +3062,7 @@ Linux::Linux(const Driver &D, const llvm
- addPathIfExists(GCCInstallation.getInstallPath() +
- BiarchSibling.gccSuffix(), Paths);
- }
-+#endif
-
- // See comments above on the multilib variant for details of why this is
- // included even from outside the sysroot.
-@@ -3083,8 +3086,9 @@ Linux::Linux(const Driver &D, const llvm
- if (StringRef(D.Dir).startswith(SysRoot))
- addPathIfExists(D.Dir + "/../lib", Paths);
-
-- addPathIfExists(SysRoot + "/lib", Paths);
-- addPathIfExists(SysRoot + "/usr/lib", Paths);
+ addPathIfExists(SysRoot + "/lib", Paths);
+ addPathIfExists(SysRoot + "/usr/lib", Paths);
++
+ // Add libc's lib/ directory to the search path, so that crt1.o, crti.o,
+ // and friends can be found.
+ addPathIfExists("@GLIBC_LIBDIR@", Paths);
}
bool Linux::HasNativeLLVMSupport() const {
+@@ -3384,6 +3392,34 @@
+ addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include");
+
+ addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
++
++ // Check for configure-time "extra" C include directories. When constructing a
++ // toolchain, @C_EXTRA_INCLUDE_DIRS@ should be replaced with something like a
++ // colon-separated string of the include dirs of libc and kernel headers.
++ //
++ // The reason why we use this mechanism instead of C_INCLUDE_DIRS above is
++ // because when a user supplies clang with --sysroot, the normal expectation
++ // is that clang will detect and add the proper $SYSROOT/$MULTIARCHINCL,
++ // $SYSROOT/include, and $SYSROOT/usr/include to its list of search paths.
++ // However, if C_INCLUDE_DIRS is not empty, this function will return early
++ // and not attempt to add the aforementioned search paths, which is not
++ // desirable.
++ //
++ // By adding our configure-time "extra" C include directories here, after
++ // we've added $SYSROOT/include and $SYSROOT/usr/include, we make sure that IF
++ // --sysroot is supplied on the command line, we pick up the expected search
++ // paths in the $SYSROOT, and that they come before our configure-time "extra"
++ // C include directories.
++ StringRef CExtraIncludeDirs("@C_EXTRA_INCLUDE_DIRS@");
++ if (CExtraIncludeDirs != "") {
++ SmallVector<StringRef, 5> dirs;
++ CExtraIncludeDirs.split(dirs, ":");
++ for (StringRef dir : dirs) {
++ StringRef Prefix =
++ llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : "";
++ addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
++ }
++ }
+ }
+
+ /// \brief Helper to add the variant paths of a libstdc++ installation.
Toggle diff (17 lines)
diff --git a/gnu/packages/patches/clang-3.8-libc-search-path.patch b/gnu/packages/patches/clang-3.8-libc-search-path.patch
index 0f7d0a4add..243d167755 100644
--- a/gnu/packages/patches/clang-3.8-libc-search-path.patch
+++ b/gnu/packages/patches/clang-3.8-libc-search-path.patch
@@ -29,41 +29,49 @@ changes in clang 3.8.
// The selection of paths to try here is designed to match the patterns which
// the GCC driver itself uses, as this is part of the GCC-compatible driver.
-@@ -3771,14 +3775,12 @@
- addPathIfExists(D, D.Dir + "/../" + OSLibDir, Paths);
- }
+@@ -3817,6 +3821,10 @@
-- addPathIfExists(D, SysRoot + "/lib/" + MultiarchTriple, Paths);
-- addPathIfExists(D, SysRoot + "/lib/../" + OSLibDir, Paths);
-- addPathIfExists(D, SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
-- addPathIfExists(D, SysRoot + "/usr/lib/../" + OSLibDir, Paths);
--
- // Try walking via the GCC triple path in case of biarch or multiarch GCC
- // installations with strange symlinks.
- if (GCCInstallation.isValid()) {
-+ // The following code would end up adding things like
-+ // "/usr/lib/x86_64-unknown-linux-gnu/../../lib64" to the search path.
-+#if 0
- addPathIfExists(D,
- SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() +
- "/../../" + OSLibDir,
-@@ -3791,6 +3793,7 @@
- BiarchSibling.gccSuffix(),
- Paths);
- }
-+#endif
-
- // See comments above on the multilib variant for details of why this is
- // included even from outside the sysroot.
-@@ -3815,8 +3818,9 @@
- if (StringRef(D.Dir).startswith(SysRoot))
- addPathIfExists(D, D.Dir + "/../lib", Paths);
-
-- addPathIfExists(D, SysRoot + "/lib", Paths);
-- addPathIfExists(D, SysRoot + "/usr/lib", Paths);
+ addPathIfExists(D, SysRoot + "/lib", Paths);
+ addPathIfExists(D, SysRoot + "/usr/lib", Paths);
++
+ // Add libc's lib/ directory to the search path, so that crt1.o, crti.o,
+ // and friends can be found.
+ addPathIfExists(D, "@GLIBC_LIBDIR@", Paths);
}
bool Linux::HasNativeLLVMSupport() const { return true; }
+@@ -4026,6 +4034,34 @@
+ addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include");
+
+ addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
++
++ // Check for configure-time "extra" C include directories. When constructing a
++ // toolchain, @C_EXTRA_INCLUDE_DIRS@ should be replaced with something like a
++ // colon-separated string of the include dirs of libc and kernel headers.
++ //
++ // The reason why we use this mechanism instead of C_INCLUDE_DIRS above is
++ // because when a user supplies clang with --sysroot, the normal expectation
++ // is that clang will detect and add the proper $SYSROOT/$MULTIARCHINCL,
++ // $SYSROOT/include, and $SYSROOT/usr/include to its list of search paths.
++ // However, if C_INCLUDE_DIRS is not empty, this function will return early
++ // and not attempt to add the aforementioned search paths, which is not
++ // desirable.
++ //
++ // By adding our configure-time "extra" C include directories here, after
++ // we've added $SYSROOT/include and $SYSROOT/usr/include, we make sure that IF
++ // --sysroot is supplied on the command line, we pick up the expected search
++ // paths in the $SYSROOT, and that they come before our configure-time "extra"
++ // C include directories.
++ StringRef CExtraIncludeDirs("@C_EXTRA_INCLUDE_DIRS@");
++ if (CExtraIncludeDirs != "") {
++ SmallVector<StringRef, 5> dirs;
++ CExtraIncludeDirs.split(dirs, ":");
++ for (StringRef dir : dirs) {
++ StringRef Prefix =
++ llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : "";
++ addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
++ }
++ }
+ }
+
+
Toggle diff (13 lines)
diff --git a/gnu/packages/patches/clang-6.0-libc-search-path.patch b/gnu/packages/patches/clang-6.0-libc-search-path.patch
index a62e8063c2..d80c798467 100644
--- a/gnu/packages/patches/clang-6.0-libc-search-path.patch
+++ b/gnu/packages/patches/clang-6.0-libc-search-path.patch
@@ -8,18 +8,17 @@ to make sure Clang also works on non-GuixSD systems.
--- cfe-6.0.0.src/lib/Driver/ToolChains/Linux.cpp
+++ cfe-6.0.0.src/lib/Driver/ToolChains/Linux.cpp
-@@ -207,7 +207,9 @@
- PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
+@@ -208,6 +208,9 @@
GCCInstallation.getTriple().str() + "/bin")
.str());
--
+
+ // Comment out the distro-specific tweaks so that they don't bite when
+ // using Guix on a foreign distro.
+#if 0
Distro Distro(D.getVFS());
if (Distro.IsAlpineLinux()) {
-@@ -255,6 +257,7 @@
+@@ -255,6 +258,7 @@
if (IsAndroid || Distro.IsOpenSUSE())
ExtraOpts.push_back("--enable-new-dtags");
@@ -27,41 +26,49 @@ to make sure Clang also works on non-GuixSD systems.
// The selection of paths to try here is designed to match the patterns which
// the GCC driver itself uses, as this is part of the GCC-compatible driver.
-@@ -329,14 +332,12 @@
- addPathIfExists(D, D.Dir + "/../" + OSLibDir, Paths);
- }
-
-- addPathIfExists(D, SysRoot + "/lib/" + MultiarchTriple, Paths);
-- addPathIfExists(D, SysRoot + "/lib/../" + OSLibDir, Paths);
-- addPathIfExists(D, SysRoot + "/usr/lib/" + MultiarchTriple, Paths);
-- addPathIfExists(D, SysRoot + "/usr/lib/../" + OSLibDir, Paths);
--
- // Try walking via the GCC triple path in case of biarch or multiarch GCC
- // installations with strange symlinks.
- if (GCCInstallation.isValid()) {
-+ // The following code would end up adding things like
-+ // "/usr/lib/x86_64-unknown-linux-gnu/../../lib64" to the search path.
-+#if 0
- addPathIfExists(D,
- SysRoot + "/usr/lib/" + GCCInstallation.getTriple().str() +
- "/../../" + OSLibDir,
-@@ -349,6 +350,7 @@
- BiarchSibling.gccSuffix(),
- Paths);
- }
-+#endif
+@@ -375,6 +379,10 @@
- // See comments above on the multilib variant for details of why this is
- // included even from outside the sysroot.
-@@ -373,8 +375,9 @@
- if (StringRef(D.Dir).startswith(SysRoot))
- addPathIfExists(D, D.Dir + "/../lib", Paths);
-
-- addPathIfExists(D, SysRoot + "/lib", Paths);
-- addPathIfExists(D, SysRoot + "/usr/lib", Paths);
+ addPathIfExists(D, SysRoot + "/lib", Paths);
+ addPathIfExists(D, SysRoot + "/usr/lib", Paths);
++
+ // Add libc's lib/ directory to the search path, so that crt1.o, crti.o,
+ // and friends can be found.
+ addPathIfExists(D, "@GLIBC_LIBDIR@", Paths);
}
bool Linux::HasNativeLLVMSupport() const { return true; }
+@@ -710,6 +718,34 @@
+ addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include");
+
+ addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include");
++
++ // Check for configure-time "extra" C include directories. When constructing a
++ // toolchain, @C_EXTRA_INCLUDE_DIRS@ should be replaced with something like a
++ // colon-separated string of the include dirs of libc and kernel headers.
++ //
++ // The reason why we use this mechanism instead of C_INCLUDE_DIRS above is
++ // because when a user supplies clang with --sysroot, the normal expectation
++ // is that clang will detect and add the proper $SYSROOT/$MULTIARCHINCL,
++ // $SYSROOT/include, and $SYSROOT/usr/include to its list of search paths.
++ // However, if C_INCLUDE_DIRS is not empty, this function will return early
++ // and not attempt to add the aforementioned search paths, which is not
++ // desirable.
++ //
++ // By adding our configure-time "extra" C include directories here, after
++ // we've added $SYSROOT/include and $SYSROOT/usr/include, we make sure that IF
++ // --sysroot is supplied on the command line, we pick up the expected search
++ // paths in the $SYSROOT, and that they come before our configure-time "extra"
++ // C include directories.
++ StringRef CExtraIncludeDirs("@C_EXTRA_INCLUDE_DIRS@");
++ if (CExtraIncludeDirs != "") {
++ SmallVector<StringRef, 5> dirs;
++ CExtraIncludeDirs.split(dirs, ":");
++ for (StringRef dir : dirs) {
++ StringRef Prefix =
++ llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : "";
++ addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
++ }
++ }
+ }
+
+ static std::string DetectLibcxxIncludePath(StringRef base) {
Toggle diff (52 lines)
diff --git a/gnu/packages/patches/clang-7.0-libc-search-path.patch b/gnu/packages/patches/clang-7.0-libc-search-path.patch
index 07ff8c90bd..445b5d17ac 100644
--- a/gnu/packages/patches/clang-7.0-libc-search-path.patch
+++ b/gnu/packages/patches/clang-7.0-libc-search-path.patch
@@ -8,7 +8,7 @@ to make sure Clang also works on non-GuixSD systems.
--- a/lib/Driver/ToolChains/Linux.cpp
+++ b/lib/Driver/ToolChains/Linux.cpp
-@@ -225,7 +225,9 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
+@@ -225,7 +225,9 @@
PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" +
GCCInstallation.getTriple().str() + "/bin")
.str());
@@ -19,7 +19,7 @@ to make sure Clang also works on non-GuixSD systems.
Distro Distro(D.getVFS());
if (Distro.IsAlpineLinux()) {
-@@ -284,6 +286,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
+@@ -284,6 +286,7 @@
if (IsAndroid || Distro.IsOpenSUSE())
ExtraOpts.push_back("--enable-new-dtags");
@@ -27,56 +27,49 @@ to make sure Clang also works on non-GuixSD systems.
// The selection of paths to try here is designed to match the patterns which
// the GCC driver itself uses, as this is part of the GCC-compatible driver.
-@@ -342,7 +345,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
- // the cross. Note that GCC does include some of these directories in some
- // configurations but this seems somewhere between questionable and simply
- // a bug.
-- if (StringRef(LibPath).startswith(SysRoot)) {
-+ if (0) {
- addPathIfExists(D, LibPath + "/" + MultiarchTriple, Paths);
- addPathIfExists(D, LibPath + "/../" + OSLibDir, Paths);
- }
-@@ -361,6 +364,8 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
- addPathIfExists(D, SysRoot + "/lib/" + MultiarchTriple, Paths);
- addPathIfExists(D, SysRoot + "/lib/../" + OSLibDir, Paths);
+@@ -431,6 +434,10 @@
-+ // This requires the commented distro tweaks above.
-+#if 0
- if (IsAndroid) {
- // Android sysroots contain a library directory for each supported OS
- // version as well as some unversioned libraries in the usual multiarch
-@@ -389,10 +394,14 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
- addPathIfExists(D, SysRoot + "/" + OSLibDir + "/" + ABIName, Paths);
- addPathIfExists(D, SysRoot + "/usr/" + OSLibDir + "/" + ABIName, Paths);
- }
-+#endif
-
-
This message was truncated. Download the full message here.
?