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

4
src/aclocal.m4 vendored
View file

@ -447,8 +447,10 @@ case "${host_os}" in
ECL_ADD_FEATURE([win32])
ECL_ADD_FEATURE([windows])
if test "x$host_cpu" = "xx86_64" ; then
ECL_ADD_FEATURE([win64])
ECL_ADD_FEATURE([win64])
fi
AC_CHECK_TOOL([WINDRES],[windres]) # set variable WINDRES to appropriate `windres' program
AC_SUBST(WINDRES)
;;
darwin*)
thehost='darwin'

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)

View file

@ -18,7 +18,8 @@
(setq *features* '(@LSP_FEATURES@ @COMPILATION_FEATURES@))
(when (member :ecl-min *host-features*)
(setq *features* (cons :ecl-min *features*)))
(when (member :uname *host-features*)
(when (and (member :uname *host-features*)
(not (member :windows *features*)))
(setq *features* (cons :uname *features*)))
(when (member :cross *host-features*)
(setq *features* (cons :cross *features*))))
@ -41,8 +42,9 @@
(progn
(c::update-compiler-features
:executable
#+(or windows cygwin mingw32) "build:ecl_min.exe"
#-(or windows cygwin mingw32) "build:@ECL_MIN@")
(if (intersection '(:windows :cygwin :mingw32) *host-features*)
"build:ecl_min.exe"
"build:@ECL_MIN@"))
(format t "~&;;; System features: ~A~%" c::*compiler-features*))
;;;
@ -375,7 +377,7 @@
(write-line "id ICON \"ecl.ico\"" s))
(ext:copy-file #p"src:util;ecl.ico" "ecl.ico")
#+msvc (ext:system "rc /nologo /r ecl.rc")
#-msvc (ext:system "windres ecl.rc -O coff ecl.res"))
#-msvc (ext:system "@WINDRES@ ecl.rc -O coff ecl.res"))
(si::pathname-translations "SYS" '(("**;*.*.*" "@true_builddir@/**/*.*")))

2230
src/configure vendored

File diff suppressed because it is too large Load diff