diff mbox

[10/12] gnu: ncurses: build mingw with libtool.

Message ID 20160818060851.2853-11-janneke@gnu.org
State New
Headers show

Commit Message

Jan Nieuwenhuizen Aug. 18, 2016, 6:08 a.m. UTC
* gnu/packages/ncurses.scm (ncurses)[MINGW]: Build with libtool, as
recommended; enables dlopen'ing.
---
 gnu/packages/ncurses.scm | 33 +++++++++++++++++++++++++--------
 1 file changed, 25 insertions(+), 8 deletions(-)

Comments

Ludovic Courtès Dec. 7, 2016, 9:36 a.m. UTC | #1
Hello Guix!

After all this time I’m happy to report that I’ve finally merged MinGW
cross-compilation support, woohoo!

So we should now be able to do:

  guix build --target=i686-w64-mingw32 guile

to cross-compile Guile to MinGW.

Hydra will build the cross-compilation toolchain and some example
packages.

I didn’t merge the cross-libtool patch and this one:

Jan Nieuwenhuizen <janneke@gnu.org> skribis:

> * gnu/packages/ncurses.scm (ncurses)[MINGW]: Build with libtool, as
> recommended; enables dlopen'ing.

I’m not sure what this means (and the explanation should be as a comment
in the code).  Could you explain a bit more?

The idea of Libtool is normally to bundle it in the package tarball.
That ncurses can optionally take an externally-provided Libtool is weird
and I’d rather avoid relying on that if possible.


Adding a new cross-compilation target is a commitment.  So I hope you
and others will make sure it remains functional and useful!

I also think that together with Manolis and everyone else who’s played
with cross-compilation, we must clean up the mess that this has become.
;-)  Namely, we must more clearly separate target-specific things and
also separate build-side from host-side code (in cross-base.scm).

Suggestions and hacks welcome!

Thanks,
Ludo’.
Manolis Ragkousis Dec. 7, 2016, 10:53 a.m. UTC | #2
Hello everyone,

On 12/07/16 11:36, Ludovic Courtès wrote:
> Hello Guix!
> 
> After all this time I’m happy to report that I’ve finally merged MinGW
> cross-compilation support, woohoo!
> 
> So we should now be able to do:
> 
>   guix build --target=i686-w64-mingw32 guile
> 
> to cross-compile Guile to MinGW.
> 
> Hydra will build the cross-compilation toolchain and some example
> packages.

Yay! Well done!

> 
> Adding a new cross-compilation target is a commitment.  So I hope you
> and others will make sure it remains functional and useful!
> 
> I also think that together with Manolis and everyone else who’s played
> with cross-compilation, we must clean up the mess that this has become.
> ;-)  Namely, we must more clearly separate target-specific things and
> also separate build-side from host-side code (in cross-base.scm).

You are right, now and then cross-compilation breaks with no apparent
reason as the code gets bigger and more complex (especially after adding
non-Linux targets).

I was thinking that maybe we need to abstract and remove all the target
specific from cross-base.scm into new files. I haven't thought about the
actual implementation yet, but it could be something like what I did
with (cross-kernel-headers ...), which simplifies how (cross-libc ...)
chooses which headers to use.

Everyone please share any ideas you have :-)

Manolis
Chris Marusich Dec. 7, 2016, 11:17 a.m. UTC | #3
ludo@gnu.org (Ludovic Courtès) writes:

> Hello Guix!
>
> After all this time I’m happy to report that I’ve finally merged MinGW
> cross-compilation support, woohoo!

That's very cool!  I don't have much to contribute in that area right
now since I'm not really a cross-compilation or MinGW expert, but I do
think this is cool, so I just wanted to cheer you all on!
Jan Nieuwenhuizen Dec. 7, 2016, 2:09 p.m. UTC | #4
Ludovic Courtès writes:

> After all this time I’m happy to report that I’ve finally merged MinGW
> cross-compilation support, woohoo!

Yay, thanks Ludovic, Manolis and Mark!!!

> Hydra will build the cross-compilation toolchain and some example
> packages.

Great!

> I didn’t merge the cross-libtool patch and this one:
>
> Jan Nieuwenhuizen <janneke@gnu.org> skribis:
>
>> * gnu/packages/ncurses.scm (ncurses)[MINGW]: Build with libtool, as
>> recommended; enables dlopen'ing.
>
> I’m not sure what this means (and the explanation should be as a comment
> in the code).  Could you explain a bit more?

The ncurses README.MinGW says

   I recommend using libtool to build ncurses on MinGW, because libtool
   knows exactly how to build dll's on Windows for use with MinGW.

and if you use libtool, it will generate .la files that are necessary
to dlopen the DLLs.

> The idea of Libtool is normally to bundle it in the package tarball.
> That ncurses can optionally take an externally-provided Libtool is weird
> and I’d rather avoid relying on that if possible.

I agree; this is quite a trick silly setup, esp. using cross builds.
I thought there was a better reason for doing this; that it was needed
to build readline or use readline from guile.exe...I can't remember;
we'll find out.

> Adding a new cross-compilation target is a commitment.  So I hope you
> and others will make sure it remains functional and useful!

Yes.  There are two things I want to do next.  I have another 10 patches
bitrotting around that enable cross building LilyPond.  I want to clean
them up and merge them one by one.  Also I'd like to look into deploying
guile.exe on Wine/Windows; maybe this should be a first.  I could do
with some ideas here.  Create packages that can be installed/unpacked,
or port some minimal part of guix so that it can fetch and install
binaries from the store?

> I also think that together with Manolis and everyone else who’s played
> with cross-compilation, we must clean up the mess that this has become.
> ;-)  Namely, we must more clearly separate target-specific things and
> also separate build-side from host-side code (in cross-base.scm).

That would be nice!
Greetings,
Jan
Ludovic Courtès Dec. 7, 2016, 9:34 p.m. UTC | #5
Hey!

Manolis Ragkousis <manolis837@gmail.com> skribis:

> On 12/07/16 11:36, Ludovic Courtès wrote:

[...]

>> Adding a new cross-compilation target is a commitment.  So I hope you
>> and others will make sure it remains functional and useful!
>> 
>> I also think that together with Manolis and everyone else who’s played
>> with cross-compilation, we must clean up the mess that this has become.
>> ;-)  Namely, we must more clearly separate target-specific things and
>> also separate build-side from host-side code (in cross-base.scm).
>
> You are right, now and then cross-compilation breaks with no apparent
> reason as the code gets bigger and more complex (especially after adding
> non-Linux targets).
>
> I was thinking that maybe we need to abstract and remove all the target
> specific from cross-base.scm into new files. I haven't thought about the
> actual implementation yet, but it could be something like what I did
> with (cross-kernel-headers ...), which simplifies how (cross-libc ...)
> chooses which headers to use.
>
> Everyone please share any ideas you have :-)

I moved code that relates to phases to a new (gnu build cross-toolchain)
module in commit 3593e5d5c50b08cf69739aac98cd7c89247fa6da.  We could
probably do the same configure flags and make flags.

Going further I was thinking we could have an abstract representation of
“platform” to cater to GNU/Linux (including on ARM), GNU/Hurd, and maybe
MinGW, say:

  ;; Description of a platform supported by the GNU system.
  (define-record-type* <platform> platform make-platform
    platform?
    (triplet            platform-triplet)            ;"x86_64-linux-gnu"
    (system-type        platform-system-type)        ;"x86_64-linux"
    (linux-architecture platform-linux-architecture) ;"amd64"
    (kernel             platform-kernel)             ;<package>
    (ld.so              platform-ld.so)              ;"ld-linux-x86-64.so.2"
    (gcc                platform-gcc)                ;<package>
    (binutils           platform-binutils)           ;<package>
    (libc               platform-libc))              ;<package>

Probably this should include cross-compilation hints somehow.

Ideally it should be something like “sysdeps” in glibc: a mechanism that
allows us to separate platform-specific code from generic code.

Ludo’.
Ludovic Courtès Dec. 7, 2016, 9:39 p.m. UTC | #6
Jan Nieuwenhuizen <janneke@gnu.org> skribis:

> Ludovic Courtès writes:
>
>> After all this time I’m happy to report that I’ve finally merged MinGW
>> cross-compilation support, woohoo!
>
> Yay, thanks Ludovic, Manolis and Mark!!!

Well, thank *you*!  There were a lot of iterations on this patch series,
a lot of work, probably a lot of time waiting for compilations to finish
;-), and then a lot of time waiting for the thing to be finally merged.

>> I didn’t merge the cross-libtool patch and this one:
>>
>> Jan Nieuwenhuizen <janneke@gnu.org> skribis:
>>
>>> * gnu/packages/ncurses.scm (ncurses)[MINGW]: Build with libtool, as
>>> recommended; enables dlopen'ing.
>>
>> I’m not sure what this means (and the explanation should be as a comment
>> in the code).  Could you explain a bit more?
>
> The ncurses README.MinGW says
>
>    I recommend using libtool to build ncurses on MinGW, because libtool
>    knows exactly how to build dll's on Windows for use with MinGW.
>
> and if you use libtool, it will generate .la files that are necessary
> to dlopen the DLLs.
>
>> The idea of Libtool is normally to bundle it in the package tarball.
>> That ncurses can optionally take an externally-provided Libtool is weird
>> and I’d rather avoid relying on that if possible.
>
> I agree; this is quite a trick silly setup, esp. using cross builds.
> I thought there was a better reason for doing this; that it was needed
> to build readline or use readline from guile.exe...I can't remember;
> we'll find out.

OK!

>> Adding a new cross-compilation target is a commitment.  So I hope you
>> and others will make sure it remains functional and useful!
>
> Yes.  There are two things I want to do next.  I have another 10 patches
> bitrotting around that enable cross building LilyPond.  I want to clean
> them up and merge them one by one.  Also I'd like to look into deploying
> guile.exe on Wine/Windows; maybe this should be a first.  I could do
> with some ideas here.  Create packages that can be installed/unpacked,
> or port some minimal part of guix so that it can fetch and install
> binaries from the store?

When we have ‘guix pack’ (a generalization of “make
guix-binary.x86_64-linux.tar.xz”), that will be a simple way to transfer
a bunch of store items to a Windows box.

Besides, having a test that runs guile.exe in Wine could be useful.

(Though now that Windows implements the Linux syscalls we should make
sure the investment is worth it!)

Ludo’.
diff mbox

Patch

diff --git a/gnu/packages/ncurses.scm b/gnu/packages/ncurses.scm
index 4d26fde..74a8470 100644
--- a/gnu/packages/ncurses.scm
+++ b/gnu/packages/ncurses.scm
@@ -27,6 +27,11 @@ 
   #:use-module (guix utils)
   #:use-module (guix build-system gnu))
 
+(define* (cross-libtool #:optional (target (%current-target-system)))
+  (let* ((libtool (resolve-interface '(gnu packages cross-base)))
+         (cross-libtool (module-ref libtool 'cross-libtool)))
+    `(("xlibtool" ,(cross-libtool target)))))
+
 (define-public ncurses
   (package
     (name "ncurses")
@@ -41,6 +46,9 @@ 
               (patches (if (target-mingw?)
                            (search-patches "ncurses-mingw.patch")
                            '()))))
+    (native-inputs `(,@(if (target-mingw?)
+                           `(,@(cross-libtool))
+                           '())))
     (build-system gnu-build-system)
     (outputs '("out"
                "doc"))                ;1 MiB of man pages
@@ -92,12 +100,12 @@ 
                             (lambda (lib)
                               (define lib.dll
                                 (string-append "lib" lib ".dll"))
-                              (define libw6.dll
-                                (string-append "lib" lib "w6.dll"))
+                              (define libw-6.dll
+                                (string-append "lib" lib "w-6.dll"))
 
-                              (when (file-exists? libw6.dll)
+                              (when (file-exists? libw-6.dll)
                                 (format #t "creating symlinks for `lib~a'~%" lib)
-                                (symlink libw6.dll lib.dll)))
+                                (symlink libw-6.dll lib.dll)))
                             '("curses" "ncurses" "form" "panel" "menu"))))
                        '())
                  (with-directory-excursion (string-append out "/lib")
@@ -114,7 +122,10 @@ 
                                          (string-append "lib" lib ".so.6"))
                                        (define lib.so
                                          (string-append "lib" lib ".so")))
-                                     '())
+                                     '((define libw.la
+                                         (string-append "lib" lib "w.la"))
+                                       (define lib.la
+                                         (string-append "lib" lib ".la"))))
 
                                (when (file-exists? libw.a)
                                  (format #t "creating symlinks for `lib~a'~%" lib)
@@ -125,7 +136,13 @@ 
                                          (call-with-output-file lib.so
                                            (lambda (p)
                                              (format p "INPUT (-l~aw)~%" lib))))
-                                       '())))
+                                       '()))
+
+                               ,@(if (target-mingw?)
+                                     '((when (file-exists? libw.la)
+                                         (format #t "creating symlinks for `lib~a'~%" lib)
+                                         (symlink libw.la lib.la)))
+                                     '()))
                              '("curses" "ncurses" "form" "panel" "menu")))))))
        `(#:configure-flags
          ,(cons*
@@ -142,8 +159,8 @@ 
               ;; correct RUNPATH.
               ,(list 'unquote '(string-append "LDFLAGS=-Wl,-rpath=" (assoc-ref %outputs "out")
                                               "/lib"))
-              ;; MinGW: Use term-driver created for the MinGW port.
-              ,@(if (target-mingw?) '("--enable-term-driver") '()))))
+              ;; MinGW: Use term-driver created for the MinGW port, libtool.
+              ,@(if (target-mingw?) '("--enable-term-driver" "--with-libtool") '()))))
          #:tests? #f                  ; no "check" target
          #:phases (modify-phases %standard-phases
                     (replace 'configure ,configure-phase)