Hi Kevin,

Kevin Vigouroux <ke.vigour...@laposte.net> writes:

> Hi Maxim!
>
> The build process eventually fails. I also think it's a search path issue, 
> but I
> don't have enough knowledge to solve it. I'm looking for a solution but I feel
> like I'm going round in circles [1,2]. Alternatively, a Docker container will 
> do
> the job [2]. This is a little disappointing as `guix shell` is supposed to be 
> an
> alternative to Docker.

I've seen that failure when trying a libreCMC build.  Seems related to
the ordering of the include files, which gets messed up by
C_INCLUDE_PATH.

I've started looking into a gcc-toolchain-fhs variant that'd look up its
include directories from the usual FHS locations (/usr/include) instead
of relying on C_INCLUDE_PATH, which causes problems here, but it's not
trivial. I'm sharing some draft of the base of what I was building from:

```
2 files changed, 64 insertions(+), 17 deletions(-)
gnu/packages/commencement.scm | 11 ++++++++---
gnu/packages/gcc.scm          | 70 
++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------

modified   gnu/packages/commencement.scm
@@ -3635,13 +3635,15 @@ (define-public canonical-package
 ;;   (make-gcc-toolchain gcc glibc-2.27))
 
 (define* (make-gcc-toolchain gcc
-                            #:optional
-                            (libc #f))
+                            #:key
+                            libc
+                            name)
   "Return a complete toolchain for GCC. If LIBC is specified, target that 
libc."
   (let ((gcc (if libc (make-gcc-libc gcc libc) gcc))
         (libc (if libc libc glibc-final)))
     (package
-      (name (string-append (package-name gcc) "-toolchain"))
+      (name (or name
+                (string-append (package-name gcc) "-toolchain")))
       (version (package-version gcc))
       (source #f)
       (build-system trivial-build-system)
@@ -3745,6 +3747,9 @@ (define-public gcc-toolchain-15
 (define-public gcc-toolchain
   gcc-toolchain-14)
 
+(define-public gcc-toolchain-fhs
+  (make-gcc-toolchain gcc-for-fhs #:name "gcc-toolchain-fhs"))
+
 (define-public gcc-toolchain-aka-gcc
   ;; It's natural for users to try "guix install gcc".  This package
   ;; automatically "redirects" them to 'gcc-toolchain'.
modified   gnu/packages/gcc.scm
@@ -15,7 +15,7 @@
 ;;; Copyright © 2022 Greg Hogan <c...@greghogan.com>
 ;;; Copyright © 2024, 2025 Zheng Junjie <z572@z572.online>
 ;;; Copyright © 2023 Bruno Victal <mi...@makinata.eu>
-;;; Copyright © 2023 Maxim Cournoyer <maxim.courno...@gmail.com>
+;;; Copyright © 2023, 2025 Maxim Cournoyer <ma...@guixotic.coop>
 ;;; Copyright © 2024 Nguyễn Gia Phong <mcsi...@disroot.org>
 ;;; Copyright © 2025 Janneke Nieuwenhuizen <jann...@gnu.org>
 ;;; Copyright © 2025 Leo Nikkilä <he...@lnikki.la>
@@ -1195,40 +1195,82 @@ (define-public libiberty
 
 (define* (custom-gcc gcc name
                      #:key (separate-lib-output? #t)
+                     fhs?
                      languages
                      (search-paths (package-native-search-paths gcc)))
   "Return a custom version of GCC that supports LANGUAGES.  Use SEARCH-PATHS
-as the 'native-search-paths' field."
-  (let ((languages (or languages '("c" "c++" "objc" "obj-c++"))))
+as the 'native-search-paths' field.  If FHS? is #t, edit the GCC builtin specs
+so that it also looks for includes from /usr/include, and /usr/local."
+  (let* ((default-languages? (not languages))
+         (languages (or languages '("c" "c++" "objc" "obj-c++"))))
     (package/inherit gcc
       (name name)
       (outputs (if separate-lib-output?
                    (package-outputs gcc)
                    (delete "lib" (package-outputs gcc))))
-      (native-search-paths search-paths)
+      ;; Mixing C_INCLUDE_PATH & friends and the FHS can cause includes order
+      ;; problems; disable the GCC search paths to avoid these.
+      (native-search-paths (if fhs?
+                               '()
+                               search-paths))
       (arguments
        (substitute-keyword-arguments (package-arguments gcc)
+         ((#:imported-modules imported %default-gnu-imported-modules)
+          `(,@imported
+            (guix build union)))
          ((#:modules modules %default-gnu-modules)
           `(,@modules
+            (guix build union)
             (srfi srfi-1)
             (srfi srfi-26)
             (ice-9 regex)))
          ((#:configure-flags flags)
-          #~(cons (string-append "--enable-languages="
-                                 #$(string-join languages ","))
-                  (remove (cut string-match "--enable-languages.*" <>)
-                          #$flags)))
+          #~(append `(,(string-append "--enable-languages="
+                                      #$(string-join languages ","))
+                      "--with-build-sysroot=/tmp/sysroot")
+                    (remove (lambda (f)
+                              (any (cut string-prefix? <> f)
+                                   `("--enable-languages"
+                                     #$@(if fhs?
+                                            #~("--with-local-prefix"
+                                               
"--with-native-system-header-dir")
+                                            #~()))))
+                            #$flags)))
          ((#:phases phases)
           #~(modify-phases #$phases
-              (add-after 'install 'remove-broken-or-conflicting-files
-                (lambda* (#:key outputs #:allow-other-keys)
-                  (for-each
-                   delete-file
-                   (find-files (string-append (assoc-ref outputs "out") "/bin")
-                               
".*(c\\+\\+|cpp|g\\+\\+|gcov|gcc|lto)(-.*)?$"))))))))
+              #$@(if fhs?
+                     #~((add-before 'configure 'populate-build-sysroot
+                          (lambda* (#:key native-inputs inputs 
#:allow-other-keys)
+                            (let ((libc (assoc-ref (or native-inputs inputs)
+                                                   "libc")))
+                              (if libc
+                                  (begin
+                                    (mkdir "/tmp/sysroot")
+                                    (copy-recursively (string-append libc 
"/include")
+                                                      
"/tmp/sysroot/usr/include"))
+                                  (mkdir-p "/tmp/sysroot/usr/include"))))))
+                     #~())
+              #$@(if default-languages?
+                     #~()
+                     #~((add-after 'install 'remove-broken-or-conflicting-files
+                          (lambda _
+                            (for-each
+                             delete-file
+                             (find-files (string-append #$output "/bin")
+                                         (string-append 
".*(c\\+\\+|cpp|g\\+\\+\
+|gcov|gcc|lto)(-.*)?$")))))))))))
       (properties `((upstream-name . "gcc")
                     ,@(alist-delete 'hidden? (package-properties gcc)))))))
 
+(define-public gcc-for-fhs
+  (hidden-package
+   ;; This is just like our standard GCC, but adjusted to look up the regular
+   ;; FHS directories for headers and libraries.
+   ;; TODO: Revert to regular 'gcc' variable; gcc-15 is used because of a bug
+   ;; fix that would cause /usr/lib to not be added to the library search
+   ;; path (<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104707>).
+   (custom-gcc gcc-15 "gcc" #:fhs? #t)))
+
 (define %generic-search-paths
   ;; This is the language-neutral search path for GCC.  Entries in $CPATH are
   ;; not considered "system headers", which means GCC can raise warnings for
```

I think using the above I was able to build a libreCMC target once, but
I had to provide "glibc" to the manifest for some reason:

```
(specifications->manifest
 (list "bash"
       "bzip2"
       "coreutils"
       "diffutils"
       "file"
       "findutils"
       "flex"
       "gawk"
       ;; This FHS variant consults headers under /usr/include and
       ;; /usr/include/c++, which is necessary since OpenWrt unsets
       ;; C_INCLUDE_PATH & friends.
       "gcc-toolchain-fhs"
       "git-minimal"
       ;; Manually adding glibc is required as elfutils will look for its 
headers itself.
       "glibc"
       "grep"
       "gzip"
       "make"
       "ncurses"
       "nss-certs"
       "openssl"
       "patch"
       "perl"
       "pkg-config"
       "python-minimal"
       "python-jsmin"
       "python-distutils-extra"
       "rsync"
       "sed"
       "subversion"
       "tar"
       "unzip"
       "util-linux"
       "wget"
       "which"))
```       

A problem is that this still relies on LIBRARY_PATH, it'd need a patched
binutils-for-fhs variant to consult /usr/lib, but building GCC to use
that causes the GCC build to fail with includes ordering issues. Oof.

--8<---------------cut here---------------start------------->8---
modified   gnu/packages/base.scm
@@ -743,6 +743,15 @@ (define-public binutils
    (license gpl3+)
    (home-page "https://www.gnu.org/software/binutils/";)))
 
+;;; A binutils variant that searches for libraries at the usual locations, 
e.g. /usr/lib.
+(define-public binutils-for-fhs
+  (package/inherit binutils
+    (name "binutils-for-fhs")
+    (arguments
+     (substitute-keyword-arguments (package-arguments binutils)
+       ((#:configure-flags flags)
+        #~(delete "--with-lib-path=/no-ld-lib-path" #$flags))))))
+
 ;; FIXME: ath9k-firmware-htc-binutils.patch do not apply on 2.34 because of a
 ;; big refactoring of xtensa-modules.c (commit 567607c11fbf7105 upstream).
 ;; Keep this version around until the patch is updated.
--8<---------------cut here---------------end--------------->8---

If we could make this work, then it'd make sense to either

a) document the use of gcc-toolchain-fhs when using a --emulate-fhs
container
b) automatically adjust the provided gcc-toolchain package into a fhs
variant in this scenario, although that's perhaps too much magic.

-- 
Thanks,
Maxim

Reply via email to