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