Created
January 11, 2025 00:01
-
-
Save Kreijstal/52657932968fcca8785de5131ed7291f to your computer and use it in GitHub Desktop.
Attempting to manually debug a guix build system
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; I want to build a package phase by phase, how hard can it be? | |
(use-modules (guix store) | |
(guix derivations) | |
(guix packages) ; Ensure this module is imported | |
(guix build-system gnu) | |
(guix build utils) | |
(gnu packages wine) | |
(guix build gnu-build-system) | |
(guix download) ; Import the download module | |
(guix base16) ; Import the base16 module for hash conversion | |
(ice-9 match) ; Import match for pattern matching | |
(srfi srfi-1)) ; Import SRFI-1 for `find` | |
;; Access the internal `%standard-phases` variable | |
(define phases | |
(let ((module (resolve-interface '(guix build gnu-build-system)))) | |
(module-ref module '%standard-phases))) | |
;; Function to fetch sources | |
(define (fetch-sources store source) | |
(let ((uri (if (string? source) | |
source | |
(origin-uri source)))) | |
(let ((source-path (download-to-store store uri))) | |
(format #t "Fetched source to: ~a~%" source-path) | |
source-path))) | |
;; Function to extract source info from the `package-source` field | |
(define (extract-source-info source) | |
;; Debug: Print the source object | |
(format #t "Inspecting source: ~a~%" source) | |
;; Check if the source is a string | |
(if (string? source) | |
(begin | |
(format #t "Source is a plain string (URI): ~a~%" source) | |
(list source #f)) ; No hash available for plain strings | |
;; Otherwise, check if it's an `origin` record | |
(if (struct? source) | |
(begin | |
;; Debug: Print the struct and its vtable | |
(format #t "Source is a struct.~%") | |
(format #t "Struct vtable: ~a~%" (struct-vtable source)) | |
(format #t "Expected <origin> vtable: ~a~%" (@@ (guix packages) <origin>)) | |
;; Check if the struct is an `origin` record | |
(if (eq? (struct-vtable source) (@@ (guix packages) <origin>)) | |
(begin | |
(format #t "Source is an <origin> record.~%") | |
(let ((uri (origin-uri source)) | |
(hash (origin-hash source))) | |
(format #t "URI: ~a~%" uri) | |
(format #t "Hash: ~a~%" hash) | |
;; Convert the hash to a string | |
(list uri (bytevector->base16-string (content-hash-value hash))))) | |
(begin | |
(format #t "Source is a struct but not an <origin> record.~%") | |
(error "Unsupported source type:" source)))) | |
;; Handle unsupported types | |
(error "Unsupported source type:" source)))) | |
(define* (custom-configure-phase #:key inputs outputs source build-directory | |
#:allow-other-keys) | |
(format #t "Running custom-configure-phase~%") | |
(format #t "Inputs: ~a~%" inputs) | |
(format #t "Outputs: ~a~%" outputs) | |
(format #t "Source: ~a~%" source) | |
(format #t "Build directory: ~a~%" build-directory) | |
;; Print environment variables | |
(format #t "PATH: ~a~%" (getenv "PATH")) | |
(format #t "CC: ~a~%" (getenv "CC")) | |
(format #t "CXX: ~a~%" (getenv "CXX")) | |
;; Call the original `configure` phase | |
((assoc-ref %standard-phases 'configure) | |
#:inputs inputs | |
#:outputs outputs | |
#:source source | |
#:build-directory build-directory)) | |
;; Replace the `configure` phase in `%standard-phases` | |
(define %custom-phases | |
(alist-replace 'configure custom-configure-phase %standard-phases)) | |
(define (build-phase-by-phase drv store) | |
(format #t "Starting build-phase-by-phase~%") | |
(let* ((output (derivation->output-path drv)) | |
(inputs (map (lambda (input) | |
(let ((drv (derivation-input-derivation input)) | |
(sub-drvs (derivation-input-sub-derivations input))) | |
(cons (derivation-name drv) | |
(derivation->output-path drv (car sub-drvs))))) | |
(derivation-inputs drv))) | |
(source (package-source wine-staging)) | |
(source-info (extract-source-info source)) | |
(source-uri (car source-info)) | |
(source-hash (cadr source-info)) | |
(source-path (fetch-sources store source)) | |
(build-directory (string-append (getcwd) "/wine-9.0"))) ; Set build directory to wine-9.0 | |
;; Debugging: Print the inputs and source | |
(format #t "Inputs: ~a~%" inputs) | |
(format #t "Source input: ~a~%" source-path) | |
(format #t "Output: ~a~%" output) | |
(format #t "Build directory: ~a~%" build-directory) | |
;; Locate GCC in the inputs | |
(define (find-gcc inputs) | |
(let ((gcc-package (find (lambda (input) | |
(string-prefix? "gcc" (car input))) | |
inputs))) | |
(if gcc-package | |
(cdr gcc-package) | |
(error "GCC not found in inputs")))) | |
(let ((gcc (find-gcc inputs))) | |
;; Set PATH to include the bin directories of all inputs | |
(setenv "PATH" (string-append (getenv "PATH") ":" | |
(string-join (map (lambda (input) | |
(string-append (cdr input) "/bin")) | |
inputs) | |
":"))) | |
;; Set CC and CXX to point to the gcc and g++ binaries | |
(setenv "CC" (string-append gcc "/bin/gcc")) | |
(setenv "CXX" (string-append gcc "/bin/g++")) | |
(format #t "PATH: ~a~%" (getenv "PATH")) | |
(format #t "CC: ~a~%" (getenv "CC")) | |
(format #t "CXX: ~a~%" (getenv "CXX"))) | |
;; Run the phases | |
(for-each (lambda (phase) | |
(format #t "Running phase: ~a~%" phase) | |
(let ((phase-proc (assoc-ref %standard-phases phase))) | |
(if phase-proc | |
(begin | |
;; Change to the build directory before running the phase | |
(when (equal? phase 'configure) | |
(format #t "Changing to build directory: ~a~%" build-directory) | |
(chdir build-directory)) | |
(phase-proc #:source source-path | |
#:outputs (list (cons "out" output)) ; Ensure "out" is present | |
#:inputs inputs | |
#:native-inputs inputs ; Pass native-inputs | |
#:target #f ; Pass target | |
#:configure-flags '() ; Pass configure-flags | |
#:out-of-source? #f ; Pass out-of-source? | |
#:build-directory build-directory)) | |
(format #t "Phase ~a not found~%" phase)))) | |
'(set-paths unpack patch-source-shebangs configure build check install)))) | |
;; Open a connection to the store | |
(define store (open-connection)) | |
;; Get the derivation for wine-staging | |
(define bag (package->bag wine-staging (%current-system))) | |
(define mval (bag->derivation bag wine-staging)) | |
(define drv (run-with-store store mval)) | |
;; Run the phases | |
(build-phase-by-phase drv store) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment