fix cross compilation to a Windows target

Cross compilation of ECL itself:

- The windres program comes with the usual cross compilation target
  prefixes, use AC_CHECK_TOOL to select the right one.
- For c::update-compiler-features, we need to check the features of the
  host system instead of the target because that determines the
  executable prefix of the ecl_min stub.

Cross compilation of user code: We just have to replace some read time
conditionals by runtime checks.

Further notes on Windows cross compilation using mingw:

- Our old copy of libgmp doesn't work, one needs to update that before
  compiling.
- ASDF fails to compile unless XDG_CACHE_HOME is set (it tries and
  fails to find a Windows cache directory if XDG_CACHE_HOME is empty).
- The `windres` program may be located in a separate package from the
  mingw compiler. On debian, I had to install binutils-mingw-w64 and
  gcc-mingw-w64.
This commit is contained in:
Marius Gerbershagen 2025-11-08 18:33:04 +01:00
parent 9365e7abe7
commit 7932ffb1be
5 changed files with 1316 additions and 971 deletions

View file

@ -375,8 +375,8 @@ filesystem or in the database of ASDF modules."
(list (concatenate 'string "/LIBPATH:"
(ecl-library-directory))
(concatenate 'string "/IMPLIB:" implib)))))
#+mingw32
(setf ld-flags (list* "-shared" ld-flags))
(when (member :mingw32 *features*)
(setf ld-flags (list* "-shared" ld-flags)))
(linker-cc o-pathname object-files :type :dll
:ld-flags ld-flags :ld-libs ld-libs)))
@ -399,8 +399,8 @@ filesystem or in the database of ASDF modules."
(concatenate 'string "/LIBPATH:"
(ecl-library-directory))
(concatenate 'string "/IMPLIB:" implib)))))
#+mingw32
(setf ld-flags (list* "-shared" "-Wl,--export-all-symbols" ld-flags))
(when (member :mingw32 *features*)
(setf ld-flags (list* "-shared" "-Wl,--export-all-symbols" ld-flags)))
(linker-cc o-pathname object-files :type :fasl
:ld-flags ld-flags :ld-libs ld-libs)))
@ -508,7 +508,6 @@ extern int
}
")
#+:win32
(defconstant +lisp-program-winmain+ "
#include <windows.h>
int
@ -570,7 +569,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
(main-name nil)
(prologue-code "")
(epilogue-code (when (eq target :program) '(SI::TOP-LEVEL T)))
#+:win32 (system :console)
(system :console)
&aux
(*suppress-compiler-messages* (or *suppress-compiler-messages*
(not *compile-verbose*)))
@ -678,10 +677,9 @@ output = si_safe_eval(2, ecl_read_from_cstring(lisp_code), ECL_NIL);
;; we don't need wrapper in the program, we have main for that
;(format c-file +lisp-init-wrapper+ wrap-name init-name)
(format c-file
#+:win32 (ecase system
(:console +lisp-program-main+)
(:windows +lisp-program-winmain+))
#-:win32 +lisp-program-main+
(ecase system
(:console +lisp-program-main+)
(:windows +lisp-program-winmain+))
prologue-code init-name epilogue-code)
(close c-file)
(compiler-cc c-name o-name)

View file

@ -59,19 +59,18 @@
(defun data-c-dump (filename)
(labels ((produce-strings ()
;; Only Windows has a size limit in the strings it creates.
#-windows
(let ((s (data-dump-array)))
(when (plusp (length s))
(list s)))
#+windows
(loop with string = (data-dump-array)
with max-string-size = 65530
with l = (length string)
for i from 0 below l by max-string-size
for this-l = (min (- l i) max-string-size)
collect (make-array this-l :displaced-to string
:element-type (array-element-type string)
:displaced-index-offset i)))
(if (member :windows *features*)
(loop with string = (data-dump-array)
with max-string-size = 65530
with l = (length string)
for i from 0 below l by max-string-size
for this-l = (min (- l i) max-string-size)
collect (make-array this-l :displaced-to string
:element-type (array-element-type string)
:displaced-index-offset i))
(let ((s (data-dump-array)))
(when (plusp (length s))
(list s)))))
(output-one-c-string (name string stream)
(let* ((*wt-string-size* 0)
(*wt-data-column* 80)