Jan Nieuwenhuizen skribis: > The fact that almost every little change triggers a full world rebuild > makes creating a cross build on Guix quite annoying, though. I wonder > if we would like to make this friendlier, even if only to bootstrap > cross builds. I think it’s always possible to create variants of the core packages while testing a new feature, such that you don’t end up rebuilding the world. > Our old GUB cross build system has two features that vastly reduce the > number of toolchain/world rebuilds > > * every package (class Name) can possbly have a architecture-specific > specialisation: class Name__, that the build system looks > for and uses if present > > * there is a `-x,--no-dependencies' option that says: just rebuild > this package, even if some of its dependencies are out of date > > I can speficy e.g. a modified Gcc for mingw only (GUB uses Python, my > favourite before I changed to Guile) like so > > class Gcc (cross.AutoBuild): > ... > > class Gcc_core (Gcc): > ...build minimal c-only compiler to build a libc... > > class Gcc__mingw (Gcc): > ...add a patch for the c++ compiler to build... > > Then the native toolchain won't be rebuilt when experimenting with > mingw. To avoid rebuilding the core gcc and the c library when > working to get the c++ compiler built, I can use --no-dependencies > until it works, then suffer a full rebuild only once at the end. Here what I would recommend is to temporary switch to your own GCC variant in cross-base.scm, for the purposes for accelerating testing. In some cases, one could use ‘replacement’ fields, which in effect is equivalent, AIUI, to --no-dependencies. >> My main concern is the complexity of the cross-base stuff. Why is >> ‘cross-gcc-core’ needed, for instance? > > It is needed to break a circular bootstrap dependency. To build a new c > library, you need a cross compiler. A full flegded gcc can only be > built when you have a c library: the circular dependency. This simple, > minimal `core-gcc' can be built with only the headers of the new c > library; breaking the circle. I understand, but ‘cross-gcc’ already handles that: it can be called with or without a libc. In the latter case, it produces a “sans-libc” GCC that is then used to build the C library. So I’m under the impression that ‘core-gcc’ duplicates this logic. Or am I missing something? Some comments on the “easy” parts: > From aaff9752fd10b7860bdba62fba3107fe8133367f Mon Sep 17 00:00:00 2001 > From: Jan Nieuwenhuizen > Date: Tue, 12 Apr 2016 15:22:51 +0200 > Subject: [PATCH 5/9] gnu: gmp: build shared library for mingw. > > * gnu/packages/multiprecision.scm (gmp)[MINGW]: Use --enable-shared. [...] > + ,@(cond ((equal? (%current-target-system) "i686-w64-mingw32") I think we should have a procedure like this in (guix utils), below ‘%current-target-system’: (define* (mingw-target? #:optional (target (%current-target-system))) (and target (string-suffix? "-mingw32" target))) and use that in all such cases. > + `("--enable-shared" > + "--disable-static")) In general, I think it’s important to add a comment to justify such changes, because ideally MinGW wouldn’t diverge from other systems, and because we want to be able to maintain such workarounds in the future. > From 6e1d4f58d4a7dca54dbbfeacc45f187bf31451ba Mon Sep 17 00:00:00 2001 > From: Jan Nieuwenhuizen > Date: Tue, 12 Apr 2016 15:15:04 +0200 > Subject: [PATCH 6/9] gnu: Add libiconv. > > * gnu/packages/libiconv.scm: New file. > gnu-system.am: Add it. Could you please add it to base.scm? Make sure to run ‘guix lint’, which will suggest a synopsis and description, among other things. > From 2e676615104f1605357eabe80fa7d716d80bc486 Mon Sep 17 00:00:00 2001 > From: Jan Nieuwenhuizen > Date: Tue, 12 Apr 2016 15:24:53 +0200 > Subject: [PATCH 7/9] gnu: ncurses: support mingw. > > * gnu/packages/patches/ncurses-mingw.patch: New file. > * gnu/packages/ncurses.scm (ncurses)[MINGW]: Support mingw. [...] > (format p "INPUT (-l~aw)~%" lib))))) > + '("curses" "ncurses" "form" "panel" "menu"))) > + (with-directory-excursion (string-append out "/bin") > + (for-each (lambda (lib) > + (define lib.dll > + (string-append "lib" lib ".dll")) > + (define libw6.dll > + (string-append "lib" lib "w6.dll")) > + (when (file-exists? libw6.dll) > + (format #t "creating symlinks for `lib~a'~%" lib) > + (symlink libw6.dll lib.dll))) > '("curses" "ncurses" "form" "panel" "menu"))))))) Obviously this would need to be made conditional. :-) [...] > - `("--with-shared" "--without-debug" "--enable-widec" > + (append > + `("--with-shared" "--without-debug" "--enable-widec" > > - ;; By default headers land in an `ncursesw' subdir, which is not > - ;; what users expect. > - ,(string-append "--includedir=" (assoc-ref %outputs "out") > - "/include") > - "--enable-overwrite" ;really honor --includedir > + ;; By default headers land in an `ncursesw' subdir, which is not > + ;; what users expect. > + ,(string-append "--includedir=" (assoc-ref %outputs "out") > + "/include") > + "--enable-overwrite" ;really honor --includedir > > - ;; Make sure programs like 'tic', 'reset', and 'clear' have a > - ;; correct RUNPATH. > - ,(string-append "LDFLAGS=-Wl,-rpath=" (assoc-ref %outputs "out") > - "/lib")) > + ;; Make sure programs like 'tic', 'reset', and 'clear' have a > + ;; correct RUNPATH. > + ,(string-append "LDFLAGS=-Wl,-rpath=" (assoc-ref %outputs "out") > + "/lib")) It seems there are no functional changes above. > + (cond ((equal? ,(%current-target-system) "i686-w64-mingw32") > + '("--enable-term-driver" > + "--without-cxx" > + "--without-cxx-binding")) This would need to be justified. > + ,@(cond ((equal? (%current-target-system) "i686-w64-mingw32") > + `((delete 'validate-runpath))) > + (else '())) Use #:validate-runpath? #f instead. If the reason is that RUNPATH does not exist on Windows, then we should instead do something like: